Skip to content
Snippets Groups Projects
Verified Commit 11fca424 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

refactor: move popper to layout namespace #190 #189

parent 7e903cca
No related branches found
No related tags found
No related merge requests found
Showing
with 402 additions and 485 deletions
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="color-scheme" content="dark light">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Popper - the monster component library</title>
<script type="module" src="scripts/monster.mjs"></script>
<style>
*:not(:defined) {
visibility: hidden;
}
</style>
</head>
<body>
<monster-panel>
<monster-split-panel data-monster-option-splittype="vertical" data-monster-option-dimension-initial="0%"
data-monster-option-dimension-min="0%" data-monster-option-dimension-max="100%">
<monster-panel slot="start">
</monster-panel>
<monster-panel slot="end">
<main class="container">
<div class="deco"></div>
<div class="to-overview">
<a href="/" class="back-link">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
viewBox="0 0 16 16">
<path d="M8 6.982C9.664 5.309 13.825 8.236 8 12 2.175 8.236 6.336 5.309 8 6.982"/>
<path d="M8.707 1.5a1 1 0 0 0-1.414 0L.646 8.146a.5.5 0 0 0 .708.707L2 8.207V13.5A1.5 1.5 0 0 0 3.5 15h9a1.5 1.5 0 0 0 1.5-1.5V8.207l.646.646a.5.5 0 0 0 .708-.707L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293zM13 7.207V13.5a.5.5 0 0 1-.5.5h-9a.5.5 0 0 1-.5-.5V7.207l5-5z"/>
</svg>
Back to overview
</a>
</div>
<h1>Popper</h1>
<p>A beautiful popper that can make your life easier and also looks good.</p>
<div class="info-grid">
<div>Import</div>
<div><img alt="the javascript logo" title="how to import"
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 630 630'%3E%3Crect width='630' height='630' fill='%23f7df1e'/%3E%3Cpath d='m423.2 492.19c12.69 20.72 29.2 35.95 58.4 35.95 24.53 0 40.2-12.26 40.2-29.2 0-20.3-16.1-27.49-43.1-39.3l-14.8-6.35c-42.72-18.2-71.1-41-71.1-89.2 0-44.4 33.83-78.2 86.7-78.2 37.64 0 64.7 13.1 84.2 47.4l-46.1 29.6c-10.15-18.2-21.1-25.37-38.1-25.37-17.34 0-28.33 11-28.33 25.37 0 17.76 11 24.95 36.4 35.95l14.8 6.34c50.3 21.57 78.7 43.56 78.7 93 0 53.3-41.87 82.5-98.1 82.5-54.98 0-90.5-26.2-107.88-60.54zm-209.13 5.13c9.3 16.5 17.76 30.45 38.1 30.45 19.45 0 31.72-7.61 31.72-37.2v-201.3h59.2v202.1c0 61.3-35.94 89.2-88.4 89.2-47.4 0-74.85-24.53-88.81-54.075z'/%3E%3C/svg%3E">
</div>
<div><code
class="language-javascript">import { Popper } from "@schukai/monster/source/components/layout/popper.mjs";</code>
</div>
<div>Source</div>
<div><img alt="the git logo" title="View source code"
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='92pt' height='92pt' viewBox='0 0 92 92'%3E%3Cdefs%3E%3CclipPath id='a'%3E%3Cpath d='M0 .113h91.887V92H0Zm0 0'/%3E%3C/clipPath%3E%3C/defs%3E%3Cg clip-path='url(%23a)'%3E%3Cpath style='stroke:none;fill-rule:nonzero;fill:%23f03c2e;fill-opacity:1' d='M90.156 41.965 50.036 1.848a5.918 5.918 0 0 0-8.372 0l-8.328 8.332 10.566 10.566a7.03 7.03 0 0 1 7.23 1.684 7.034 7.034 0 0 1 1.669 7.277l10.187 10.184a7.028 7.028 0 0 1 7.278 1.672 7.04 7.04 0 0 1 0 9.957 7.05 7.05 0 0 1-9.965 0 7.044 7.044 0 0 1-1.528-7.66l-9.5-9.497V59.36a7.04 7.04 0 0 1 1.86 11.29 7.04 7.04 0 0 1-9.957 0 7.04 7.04 0 0 1 0-9.958 7.06 7.06 0 0 1 2.304-1.539V33.926a7.049 7.049 0 0 1-3.82-9.234L29.242 14.272 1.73 41.777a5.925 5.925 0 0 0 0 8.371L41.852 90.27a5.925 5.925 0 0 0 8.37 0l39.934-39.934a5.925 5.925 0 0 0 0-8.371'/%3E%3C/g%3E%3C/svg%3E">
</div>
<div>
<a target="_blank"
href="https://gitlab.schukai.com/oss/libraries/javascript/monster/-/blob/master/source/components/layout/popper.mjs">View
source code</a></div>
<div>Package</div>
<div><img alt="the npm logo" title="View on npm"
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E%3Cpath d='M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z'/%3E%3C/svg%3E">
</div>
<div><a target="_blank" href="https://npmjs.com/package/@schukai/monster">@schukai/monster</a></div>
<div>Since</div>
<div></div>
<div>1.66.0</div>
</div>
<div class="show-it"><monster-popper>
<div slot="button"
style="border:1px solid var(--monster-color-primary-2); padding: 10px; cursor: pointer;width: 100%; display:flex;align-items:center;justify-content:center;">
Hover me!
</div>
Should I Stay or Should I Go?
</monster-popper></div>
<monster-tabs>
<div data-monster-button-label="Overview"
class="active"
data-monster-button-icon="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='m8 2.42-.717-.737c-1.13-1.161-3.243-.777-4.01.72-.35.685-.451 1.707.236 3.062C4.16 6.753 5.52 8.32 8 10.042c2.479-1.723 3.839-3.29 4.491-4.577.687-1.355.587-2.377.236-3.061-.767-1.498-2.88-1.882-4.01-.721zm-.49 8.5c-10.78-7.44-3-13.155.359-10.063q.068.062.132.129.065-.067.132-.129c3.36-3.092 11.137 2.624.357 10.063l.235.468a.25.25 0 1 1-.448.224l-.008-.017c.008.11.02.202.037.29.054.27.161.488.419 1.003.288.578.235 1.15.076 1.629-.157.469-.422.867-.588 1.115l-.004.007a.25.25 0 1 1-.416-.278c.168-.252.4-.6.533-1.003.133-.396.163-.824-.049-1.246l-.013-.028c-.24-.48-.38-.758-.448-1.102a3 3 0 0 1-.052-.45l-.04.08a.25.25 0 1 1-.447-.224l.235-.468ZM6.013 2.06c-.649-.18-1.483.083-1.85.798-.131.258-.245.689-.08 1.335.063.244.414.198.487-.043.21-.697.627-1.447 1.359-1.692.217-.073.304-.337.084-.398'/%3E%3C/svg%3E">
<h2>Introduction</h2>
<p>
This is the Monster Popper component. It is a versatile and customizable control element
to an interactive and engaging user experience that integrates seamlessly into various web applications.
Whether you are developing a simple website or a complex enterprise application, the Monster
Popper is designed to increase user interaction and satisfaction.
</p>
<h2>Key Features</h2>
<ul>
<li><strong>Dynamic interaction</strong>: Users can interact with content dynamically,
making the Web experience more intuitive and user-centric.
</li>
<li><strong>Customizable appearance</strong>: Customize the appearance of the Popper
to match the design of your brand or application to improve visual consistency.
</li>
<li><strong>Accessibility</strong>: Designed with accessibility in mind to ensure all
users have a seamless experience regardless of their browsing context.
</li>
<li><strong>Programmatic Control</strong>: Provides methods such as click, focus,
and blur to programmatically control the behavior of the Popper, giving developers flexibility.
</li>
</ul>
<h2>Improving the user experience</h2>
<p>
The Monster Popper goes beyond the traditional functions of a Popper to provide an enhanced
and interactive user experience.
</p>
<p>
These improvements are supported by user studies that show a positive impact on user
commitment and satisfaction.
</p>
<h2>Efficiency in the development process</h2>
<p>
Integrating the Monster Popper into your development process is easy. Its compatibility with
standard web technologies and ease of customization allow for seamless integration with
your existing tools and libraries. Whether you are working on a small project or a large
application, Monster Popper's modular design guarantees easy integration that streamlines
your development process and increases your productivity.
</p>
</div>
<div data-monster-button-label="Usage"
data-monster-button-icon="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M9.752 6.193c.599.6 1.73.437 2.528-.362s.96-1.932.362-2.531c-.599-.6-1.73-.438-2.528.361-.798.8-.96 1.933-.362 2.532'/%3E%3Cpath d='M15.811 3.312c-.363 1.534-1.334 3.626-3.64 6.218l-.24 2.408a2.56 2.56 0 0 1-.732 1.526L8.817 15.85a.51.51 0 0 1-.867-.434l.27-1.899c.04-.28-.013-.593-.131-.956a9 9 0 0 0-.249-.657l-.082-.202c-.815-.197-1.578-.662-2.191-1.277-.614-.615-1.079-1.379-1.275-2.195l-.203-.083a10 10 0 0 0-.655-.248c-.363-.119-.675-.172-.955-.132l-1.896.27A.51.51 0 0 1 .15 7.17l2.382-2.386c.41-.41.947-.67 1.524-.734h.006l2.4-.238C9.005 1.55 11.087.582 12.623.208c.89-.217 1.59-.232 2.08-.188.244.023.435.06.57.093q.1.026.16.045c.184.06.279.13.351.295l.029.073a3.5 3.5 0 0 1 .157.721c.055.485.051 1.178-.159 2.065m-4.828 7.475.04-.04-.107 1.081a1.54 1.54 0 0 1-.44.913l-1.298 1.3.054-.38c.072-.506-.034-.993-.172-1.418a9 9 0 0 0-.164-.45c.738-.065 1.462-.38 2.087-1.006M5.205 5c-.625.626-.94 1.351-1.004 2.09a9 9 0 0 0-.45-.164c-.424-.138-.91-.244-1.416-.172l-.38.054 1.3-1.3c.245-.246.566-.401.91-.44l1.08-.107zm9.406-3.961c-.38-.034-.967-.027-1.746.163-1.558.38-3.917 1.496-6.937 4.521-.62.62-.799 1.34-.687 2.051.107.676.483 1.362 1.048 1.928.564.565 1.25.941 1.924 1.049.71.112 1.429-.067 2.048-.688 3.079-3.083 4.192-5.444 4.556-6.987.183-.771.18-1.345.138-1.713a3 3 0 0 0-.045-.283 3 3 0 0 0-.3-.041Z'/%3E%3Cpath d='M7.009 12.139a7.6 7.6 0 0 1-1.804-1.352A7.6 7.6 0 0 1 3.794 8.86c-1.102.992-1.965 5.054-1.839 5.18.125.126 3.936-.896 5.054-1.902Z'/%3E%3C/svg%3E">
<h2>Popper Simple</h2>
<monster-tabs>
<div class="active"
data-monster-button-label="Component">
<p>
This is a simple popper example. It is a popper with the text "Should I Stay or Should I Go?".
Nothing more, nothing less.
</p>
<div class="show-it">
<monster-popper>
<div slot="button"
style="border:1px solid var(--monster-color-primary-2); padding: 10px; cursor: pointer;width: 100%; display:flex;align-items:center;justify-content:center;">
Hover me!
</div>
Should I Stay or Should I Go?
</monster-popper>
</div>
</div>
<div data-monster-button-label="Code">
<h3>Javascript</h3>
<pre><code class="language-javascript example-code">import "@schukai/monster/source/components/layout/popper.mjs";</code></pre>
<h3>HTML</h3>
<pre><code class="language-html example-code">&lt;monster-popper&gt;
&lt;div slot="button"
style="border:1px solid var(--monster-color-primary-2); padding: 10px; cursor: pointer;width: 100%; display:flex;align-items:center;justify-content:center;"&gt;
Hover me!
&lt;/div&gt;
Should I Stay or Should I Go?
&lt;/monster-popper&gt;</code></pre>
<h3>Stylesheet</h3>
<pre><code class="language-css example-code">/** no additional stylesheet is defined **/</code></pre>
</div>
</monster-tabs>
<h2>Popper Click</h2>
<monster-tabs>
<div class="active"
data-monster-button-label="Component">
<p>
This is a popper example, which is triggered by a click. It is a popper with the text "Should I Stay or Should I Go?".
The attribute <code>data-monster-option-mode="click"</code> makes the trick. The popper will be shown when the button is clicked.
</p>
<div class="show-it">
<monster-popper data-monster-option-mode="click">
<div slot="button"
style="border:1px solid var(--monster-color-primary-2); padding: 10px; cursor: pointer;width: 100%; display:flex;align-items:center;justify-content:center;">
Click me!
</div>
Should I Stay or Should I Go?
</monster-popper>
</div>
</div>
<div data-monster-button-label="Code">
<h3>Javascript</h3>
<pre><code class="language-javascript example-code">import "@schukai/monster/source/components/layout/popper.mjs";</code></pre>
<h3>HTML</h3>
<pre><code class="language-html example-code">&lt;monster-popper data-monster-option-mode="click"&gt;
&lt;div slot="button"
style="border:1px solid var(--monster-color-primary-2); padding: 10px; cursor: pointer;width: 100%; display:flex;align-items:center;justify-content:center;"&gt;
Click me!
&lt;/div&gt;
Should I Stay or Should I Go?
&lt;/monster-popper&gt;</code></pre>
<h3>Stylesheet</h3>
<pre><code class="language-css example-code">/** no additional stylesheet is defined **/</code></pre>
</div>
</monster-tabs>
</div>
<div data-monster-button-label="Design"
data-monster-button-icon="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M6.192 2.78c-.458-.677-.927-1.248-1.35-1.643a3 3 0 0 0-.71-.515c-.217-.104-.56-.205-.882-.02-.367.213-.427.63-.43.896-.003.304.064.664.173 1.044.196.687.556 1.528 1.035 2.402L.752 8.22c-.277.277-.269.656-.218.918.055.283.187.593.36.903.348.627.92 1.361 1.626 2.068.707.707 1.441 1.278 2.068 1.626.31.173.62.305.903.36.262.05.64.059.918-.218l5.615-5.615c.118.257.092.512.05.939-.03.292-.068.665-.073 1.176v.123h.003a1 1 0 0 0 1.993 0H14v-.057a1 1 0 0 0-.004-.117c-.055-1.25-.7-2.738-1.86-3.494a4 4 0 0 0-.211-.434c-.349-.626-.92-1.36-1.627-2.067S8.857 3.052 8.23 2.704c-.31-.172-.62-.304-.903-.36-.262-.05-.64-.058-.918.219zM4.16 1.867c.381.356.844.922 1.311 1.632l-.704.705c-.382-.727-.66-1.402-.813-1.938a3.3 3.3 0 0 1-.131-.673q.137.09.337.274m.394 3.965c.54.852 1.107 1.567 1.607 2.033a.5.5 0 1 0 .682-.732c-.453-.422-1.017-1.136-1.564-2.027l1.088-1.088q.081.181.183.365c.349.627.92 1.361 1.627 2.068.706.707 1.44 1.278 2.068 1.626q.183.103.365.183l-4.861 4.862-.068-.01c-.137-.027-.342-.104-.608-.252-.524-.292-1.186-.8-1.846-1.46s-1.168-1.32-1.46-1.846c-.147-.265-.225-.47-.251-.607l-.01-.068zm2.87-1.935a2.4 2.4 0 0 1-.241-.561c.135.033.324.11.562.241.524.292 1.186.8 1.846 1.46.45.45.83.901 1.118 1.31a3.5 3.5 0 0 0-1.066.091 11 11 0 0 1-.76-.694c-.66-.66-1.167-1.322-1.458-1.847z'/%3E%3C/svg%3E">
<h2>Design</h2>
<p>The control element can be adapted to your own requirements. To do this, the control element
can be designed with CSS like almost any other HTML element.</p>
<p>However, there are a few things to bear in mind. As the innards of the control are located
in a ShadowRoot, they cannot be accessed directly with CSS selectors. Only the elements specified
for this purpose can be accessed. These elements have the attribute <i>part</i>.</p>
<p>In CSS, these parts can then be used for styling via a CSS pseudo-element Parts.
Here you can see an example of how you can use this.</p>
<pre><code class="language-css">
::part(container) {
border: 1px solid red;
}
</code></pre>
<!-- p>The following diagram shows the parts and the slots.</p>
<img src="assets/Components.Navigation.{{CLASSNAME_LOWER}}.svg" alt="Parts and slots of the TableOfContent"-->
</div>
<div data-monster-button-label="API"
data-monster-button-icon="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M6 0a.5.5 0 0 1 .5.5V3h3V.5a.5.5 0 0 1 1 0V3h1a.5.5 0 0 1 .5.5v3A3.5 3.5 0 0 1 8.5 10c-.002.434-.01.845-.04 1.22-.041.514-.126 1.003-.317 1.424a2.08 2.08 0 0 1-.97 1.028C6.725 13.9 6.169 14 5.5 14c-.998 0-1.61.33-1.974.718A1.92 1.92 0 0 0 3 16H2c0-.616.232-1.367.797-1.968C3.374 13.42 4.261 13 5.5 13c.581 0 .962-.088 1.218-.219.241-.123.4-.3.514-.55.121-.266.193-.621.23-1.09.027-.34.035-.718.037-1.141A3.5 3.5 0 0 1 4 6.5v-3a.5.5 0 0 1 .5-.5h1V.5A.5.5 0 0 1 6 0M5 4v2.5A2.5 2.5 0 0 0 7.5 9h1A2.5 2.5 0 0 0 11 6.5V4z'/%3E%3C/svg%3E">
<h2>HTML Structure</h2>
<pre><code class="language-html">&lt;monster-popper&gt;&lt;/monster-popper&gt;</code></pre>
<h2>JavaScript Initialization</h2>
<pre><code class="language-js">const element = document.createElement('monster-popper');
document.body.appendChild(element);</code></pre>
<h2>Options</h2>
<div class="option-grid">
<div class="option-headline">Option</div>
<div class="option-headline">Type</div>
<div class="option-headline">Default</div>
<div class="option-headline">Description</div>
<div>templates</div><div>object</div><div></div><div>templates - The templates for the control.</div>
<div>templates.main</div><div>string</div><div></div><div>templates.main - The main template.</div>
<div>mode</div><div>string</div><div></div><div>mode - The mode of the popper. Possible values are `click`, `enter`, `manual`, `focus`, "auto" or a combination of them.</div>
<div>content</div><div>string</div><div></div><div>content - The content of the popper.</div>
<div>popper</div><div>object</div><div></div><div>popper - The popper options.</div>
<div>popper.placement</div><div>string</div><div></div><div>popper.placement - The placement of the popper. Possible values are `top`, `bottom`, `left` and `right`.</div>
<div>popper.middleware</div><div>array<function></div><div></div><div>popper.middleware - The middleware functions of the popper.</div>
<div>popper.middlewareInit</div><div>array<function></div><div></div><div>popper.middlewareInit - The middleware init functions of the popper.</div>
<div>features</div><div>object</div><div></div><div>features - The features of the popper.</div>
<div>features.preventPropagateOpenEvents</div><div>boolean</div><div></div><div>features.preventPropagateOpenEvents - Prevents the open event from being sent.</div>
</div><br>
<h2>Properties and Attributes</h2>
<ul>
<li><code>data-monster-options</code>: Sets the configuration options for the collapse
component when used as an HTML attribute.
</li>
<li><code>data-monster-option-[name]</name></code>: Sets the value of the configuration
option <code>[name]</code> for the collapse component when used as an HTML attribute.
</li>
</ul>
<h2>Methods</h2>
<h3>Other methods</h3><div class="method-grid"><div class='method-signature'><code class='language-javascript'>assembleMethodSymbol()</code></div><div><strong>Returns</strong><ul><li>{Popper}</li></ul> </div><div class='method-description'>
</div>
<div class='method-signature'><code class='language-javascript'>connectedCallback()</code></div><div><strong>Returns</strong><ul><li>{void}</li></ul> </div><div class='method-description'> </div>
<div class='method-signature'><code class='language-javascript'>disconnectedCallback()</code></div><div><strong>Returns</strong><ul><li>{void}</li></ul> </div><div class='method-description'> </div>
<div class='method-signature'><code class='language-javascript'>getCSSStyleSheet()</code></div><div><strong>Returns</strong><ul><li>{Array<CSSStyleSheet>}</li></ul> </div><div class='method-description'> </div>
<div class='method-signature'><code class='language-javascript'>getTag()</code></div><div><strong>Returns</strong><ul><li>{string}</li></ul> </div><div class='method-description'> </div>
<div class='method-signature'><code class='language-javascript'>hideDialog()</code></div><div><strong>Returns</strong><ul><li>{Popper}</li></ul> </div><div class='method-description'> </div>
<div class='method-signature'><code class='language-javascript'>instanceSymbol()</code></div><div> </div><div class='method-description'>
This method is called by the <code>instanceof</code> operator. </div>
<div class='method-signature'><code class='language-javascript'>showDialog()</code></div><div><strong>Returns</strong><ul><li>{Popper}</li></ul> </div><div class='method-description'> </div>
<div class='method-signature'><code class='language-javascript'>toggleDialog()</code></div><div><strong>Returns</strong><ul><li>{Popper}</li></ul> </div><div class='method-description'> </div></div><br>
<h2>Events</h2>
<p>The component emits the following events:</p><ul><li><code>monster-popper-hide</code> fired when the popper is hide.</li>
<li><code>monster-popper-hidden</code> fired when the popper is hidden.</li>
<li><code>monster-popper-open</code> fired when the popper is open.</li>
<li><code>monster-popper-opened</code> fired when the popper is opened.</li></ul><p>For more information on how to handle events, see the <a target='_blank' href="https://developer.mozilla.org/en-US/docs/Web/Events">mdn documentation</a>.</p>
</div>
</monster-tabs>
</main>
<footer>
<p>© 2024 Powered by schukai GmbH - All rights reserved.</p>
<p>Code and documentation licensed by <a target="_blank"
href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPLv3
License</a> or commercial license.</p>
</footer>
</monster-panel>
</monster-split-panel>
</monster-panel>
</body>
</html>
<monster-popper data-monster-option-mode="click">
<div slot="button"
style="border:1px solid var(--monster-color-primary-2); padding: 10px; cursor: pointer;width: 100%; display:flex;align-items:center;justify-content:center;">
Click me!
</div>
Should I Stay or Should I Go?
</monster-popper>
<p>
This is a popper example, which is triggered by a click. It is a popper with the text "Should I Stay or Should I Go?".
The attribute <code>data-monster-option-mode="click"</code> makes the trick. The popper will be shown when the button is clicked.
</p>
\ No newline at end of file
import "@schukai/monster/source/components/layout/popper.mjs";
<monster-popper>
<div slot="button"
style="border:1px solid var(--monster-color-primary-2); padding: 10px; cursor: pointer;width: 100%; display:flex;align-items:center;justify-content:center;">
Hover me!
</div>
Should I Stay or Should I Go?
</monster-popper>
<p>
This is a simple popper example. It is a popper with the text "Should I Stay or Should I Go?".
Nothing more, nothing less.
</p>
\ No newline at end of file
import "@schukai/monster/source/components/layout/popper.mjs";
<h2>Design</h2>
<p>The control element can be adapted to your own requirements. To do this, the control element
can be designed with CSS like almost any other HTML element.</p>
<p>However, there are a few things to bear in mind. As the innards of the control are located
in a ShadowRoot, they cannot be accessed directly with CSS selectors. Only the elements specified
for this purpose can be accessed. These elements have the attribute <i>part</i>.</p>
<p>In CSS, these parts can then be used for styling via a CSS pseudo-element Parts.
Here you can see an example of how you can use this.</p>
<pre><code class="language-css">
::part(container) {
border: 1px solid red;
}
</code></pre>
<!-- p>The following diagram shows the parts and the slots.</p>
<img src="assets/Components.Navigation.{{CLASSNAME_LOWER}}.svg" alt="Parts and slots of the TableOfContent"-->
\ No newline at end of file
<h2>Introduction</h2>
<p>
This is the Monster Popper component. It is a versatile and customizable control element
to an interactive and engaging user experience that integrates seamlessly into various web applications.
Whether you are developing a simple website or a complex enterprise application, the Monster
Popper is designed to increase user interaction and satisfaction.
</p>
<h2>Key Features</h2>
<ul>
<li><strong>Dynamic interaction</strong>: Users can interact with content dynamically,
making the Web experience more intuitive and user-centric.
</li>
<li><strong>Customizable appearance</strong>: Customize the appearance of the Popper
to match the design of your brand or application to improve visual consistency.
</li>
<li><strong>Accessibility</strong>: Designed with accessibility in mind to ensure all
users have a seamless experience regardless of their browsing context.
</li>
<li><strong>Programmatic Control</strong>: Provides methods such as click, focus,
and blur to programmatically control the behavior of the Popper, giving developers flexibility.
</li>
</ul>
<h2>Improving the user experience</h2>
<p>
The Monster Popper goes beyond the traditional functions of a Popper to provide an enhanced
and interactive user experience.
</p>
<p>
These improvements are supported by user studies that show a positive impact on user
commitment and satisfaction.
</p>
<h2>Efficiency in the development process</h2>
<p>
Integrating the Monster Popper into your development process is easy. Its compatibility with
standard web technologies and ease of customization allow for seamless integration with
your existing tools and libraries. Whether you are working on a small project or a large
application, Monster Popper's modular design guarantees easy integration that streamlines
your development process and increases your productivity.
</p>
<monster-popper>
<div slot="button"
style="border:1px solid var(--monster-color-primary-2); padding: 10px; cursor: pointer;width: 100%; display:flex;align-items:center;justify-content:center;">
Hover me!
</div>
Should I Stay or Should I Go?
</monster-popper>
Source diff could not be displayed: it is too large. Options to address this: view the blob.
This diff is collapsed.
/**
* Copyright schukai GmbH and contributors 2023. All Rights Reserved.
* Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
* Node module: @schukai/monster
* This file is licensed under the AGPLv3 License.
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
*/
import { instanceSymbol } from "../../constants.mjs";
import {
addAttributeToken,
removeAttributeToken,
} from "../../dom/attributes.mjs";
import { ATTRIBUTE_ROLE } from "../../dom/constants.mjs";
import {
assembleMethodSymbol,
registerCustomElement,
} from "../../dom/customelement.mjs";
import { fireCustomEvent } from "../../dom/events.mjs";
import { getDocument } from "../../dom/util.mjs";
import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
import { Button } from "./button.mjs";
import { STYLE_DISPLAY_MODE_BLOCK } from "./constants.mjs";
import { positionPopper } from "./util/floating-ui.mjs";
import { CustomControl } from "../../dom/customcontrol.mjs";
import { PopperStyleSheet } from "./stylesheet/popper.mjs";
import { isArray } from "../../types/is.mjs";
export { Popper };
/**
* @private
* @type {symbol}
*/
const timerCallbackSymbol = Symbol("timerCallback");
/**
* local symbol
* @private
* @type {symbol}
*/
const resizeObserverSymbol = Symbol("resizeObserver");
/**
* local symbol
* @private
* @type {symbol}
*/
const closeEventHandler = Symbol("closeEventHandler");
/**
* @private
* @type {symbol}
*/
const controlElementSymbol = Symbol("controlElement");
/**
* @private
* @type {symbol}
*/
const buttonElementSymbol = Symbol("buttonElement");
/**
* local symbol
* @private
* @type {symbol}
*/
const popperElementSymbol = Symbol("popperElement");
/**
* local symbol
* @private
* @type {symbol}
*/
const arrowElementSymbol = Symbol("arrowElement");
/**
* This action callback executes the actions when a button is clicked.
*
* @callback Monster.Components.Form~exampleActionCallback
* @param {Event} e Event
* @memberOf Monster.Components.Form
* @this {CustomControl}
*/
/**
* The Popper ist an element that can be used to display a popper.
*
* <img src="./images/popper.png">
*
* Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library
* as well as [pooperjs](https://popper.js.org/docs/v2/).
*
* You can create this control either by specifying the HTML tag <monster-popper-button />` directly in the HTML or using
* Javascript via the `document.createElement('monster-popper');` method.
*
* ```html
* <monster-popper></monster-popper>
* ```
*
* Or you can create this CustomControl directly in Javascript:
*
* ```js
* import {Popper} from '@schukai/component-form/source/popper.js';
* document.createElement('monster-popper');
* ```
*
* @startuml popper.png
* skinparam monochrome true
* skinparam shadowing false
* HTMLElement <|-- CustomElement
* CustomElement <|-- CustomControl
* CustomControl <|-- Popper
* @enduml
*
* @copyright schukai GmbH
* @memberOf Monster.Components.Form
* @summary A popper button
*/
class Popper extends CustomControl {
/**
* This method is called by the `instanceof` operator.
* @returns {symbol}
*/
static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/components/form/popper@@instance");
}
/**
* To set the options via the html tag the attribute `data-monster-options` must be used.
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
*
* The individual configuration values can be found in the table.
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* @property {Object} templates - The templates for the control.
* @property {string} templates.main - The main template.
* @property {string} mode - The mode of the popper. Possible values are `click`, `enter` `hover`, `manual`, `focus`, "auto" or a combination of them.
* @property {string} content - The content of the popper.
* @property {object} popper - The popper options.
* @property {string} popper.placement - The placement of the popper. Possible values are `top`, `bottom`, `left` and `right`.
* @property {Array<function>} popper.middleware - The middleware functions of the popper.
* @property {Array<function>} popper.middlewareInit - The middleware init functions of the popper.
* @property {Object} features - The features of the popper.
* @property {boolean} features.preventPropagateOpenEvents - Prevents the open event from being sent.
* @extends {Button}
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/
get defaults() {
return Object.assign({}, super.defaults, {
templates: {
main: getTemplate(),
},
mode: "hover focus",
content: "<slot>Should I Stay or Should I Go?</slot>",
popper: {
placement: "top",
middleware: ["autoPlacement", "offset:10", "arrow"],
},
features: {
preventOpenEventSent: false,
},
});
}
/**
*
* @return {Monster.Components.Form.Popper}
*/
[assembleMethodSymbol]() {
super[assembleMethodSymbol]();
initControlReferences.call(this);
initEventHandler.call(this);
return this;
}
/**
* @return {string}
*/
static getTag() {
return "monster-popper";
}
/**
* @return {Array<CSSStyleSheet>}
*/
static getCSSStyleSheet() {
return [PopperStyleSheet];
}
/**
* @return {void}
*/
connectedCallback() {
super.connectedCallback();
import {Popper as NewPopper} from "../layout/popper.mjs";
const document = getDocument();
for (const [, type] of Object.entries(["click", "touch"])) {
// close on outside ui-events
document.addEventListener(type, this[closeEventHandler]);
}
updatePopper.call(this);
attachResizeObserver.call(this);
}
/**
* @return {void}
*/
disconnectedCallback() {
super.disconnectedCallback();
// close on outside ui-events
for (const [, type] of Object.entries(["click", "touch"])) {
document.removeEventListener(type, this[closeEventHandler]);
}
disconnectResizeObserver.call(this);
}
/**
*
* @return {Monster.Components.Form.Popper}
*/
showDialog() {
show.call(this);
return this;
}
/**
*
* @return {Monster.Components.Form.Popper}
*/
hideDialog() {
hide.call(this);
return this;
}
/**
*
* @return {Monster.Components.Form.Popper}
*/
toggleDialog() {
if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
this.hideDialog();
} else {
this.showDialog();
}
return this;
}
}
/**
* @private
* @return {Monster.Components.Form.Popper}
*/
function initEventHandler() {
this[closeEventHandler] = (event) => {
const path = event.composedPath();
for (const [, element] of Object.entries(path)) {
if (element === this) {
return;
}
}
hide.call(this);
};
let modes = null;
const modeOption = this.getOption("mode");
if (typeof modeOption === "string") {
modes = modeOption.split(" ");
}
if (
modes === null ||
modes === undefined ||
isArray(modes) === false ||
modes.length === 0
) {
modes = ["manual"];
}
for (const [, mode] of Object.entries(modes)) {
initEventHandlerByMode.call(this, mode);
}
return this;
}
/**
* @private
* @param mode
* @return {Monster.Components.Form.Popper}
* @throws Error
*/
function initEventHandlerByMode(mode) {
switch (mode) {
case "manual":
break;
case "focus":
this[buttonElementSymbol].addEventListener("focus", (event) => {
if (this.getOption("features.preventOpenEventSent") === true) {
event.preventDefault();
}
this.showDialog();
});
this[buttonElementSymbol].addEventListener("blur", (event) => {
if (this.getOption("features.preventOpenEventSent") === true) {
event.preventDefault();
}
this.hideDialog();
});
break;
case "click":
this[buttonElementSymbol].addEventListener("click", (event) => {
if (this.getOption("features.preventOpenEventSent") === true) {
event.preventDefault();
}
this.toggleDialog();
});
break;
case "enter":
this[buttonElementSymbol].addEventListener("mouseenter", (event) => {
if (this.getOption("features.preventOpenEventSent") === true) {
event.preventDefault();
}
this.showDialog();
});
break;
case "auto": // is hover
this[buttonElementSymbol].addEventListener("mouseenter", (event) => {
if (this.getOption("features.preventOpenEventSent") === true) {
event.preventDefault();
}
this.showDialog();
});
this[buttonElementSymbol].addEventListener("mouseleave", (event) => {
if (this.getOption("features.preventOpenEventSent") === true) {
event.preventDefault();
}
this.hideDialog();
});
break;
default:
throw new Error(`Unknown mode ${mode}`);
}
}
/**
* @private
*/
function attachResizeObserver() {
// against flickering
this[resizeObserverSymbol] = new ResizeObserver((entries) => {
if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
try {
this[timerCallbackSymbol].touch();
return;
} catch (e) {
delete this[timerCallbackSymbol];
}
}
this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
updatePopper.call(this);
});
});
this[resizeObserverSymbol].observe(this.parentElement);
}
function disconnectResizeObserver() {
if (this[resizeObserverSymbol] instanceof ResizeObserver) {
this[resizeObserverSymbol].disconnect();
}
}
/**
* @private
*/
function hide() {
const self = this;
fireCustomEvent(self, "monster-popper-hide", {
self,
});
self[popperElementSymbol].style.display = "none";
removeAttributeToken(self[controlElementSymbol], "class", "open");
setTimeout(() => {
fireCustomEvent(self, "monster-popper-hidden", {
self,
});
}, 0);
}
/**
* @private
* @this PopperButton
*/
function show() {
const self = this;
if (self.getOption("disabled", false) === true) {
return;
}
if (self[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
return;
}
fireCustomEvent(self, "monster-popper-open", {
self,
});
self[popperElementSymbol].style.visibility = "hidden";
self[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
addAttributeToken(self[controlElementSymbol], "class", "open");
updatePopper.call(self);
setTimeout(() => {
fireCustomEvent(self, "monster-popper-opened", {
self,
});
}, 0);
}
/**
* @private
*/
function updatePopper() {
if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
return;
}
if (this.getOption("disabled", false) === true) {
return;
}
positionPopper.call(
this,
this[controlElementSymbol],
this[popperElementSymbol],
this.getOption("popper", {}),
);
}
/**
* @private
* @return {Monster.Components.Form.Popper}
*/
function initControlReferences() {
this[controlElementSymbol] = this.shadowRoot.querySelector(
`[${ATTRIBUTE_ROLE}=control]`,
);
this[buttonElementSymbol] = this.shadowRoot.querySelector(
`[${ATTRIBUTE_ROLE}=button]`,
);
this[popperElementSymbol] = this.shadowRoot.querySelector(
`[${ATTRIBUTE_ROLE}=popper]`,
);
this[arrowElementSymbol] = this.shadowRoot.querySelector(
`[${ATTRIBUTE_ROLE}=arrow]`,
);
return this;
}
export {Popper};
/**
* @private
* @return {string}
* @since 1.10.0
* @copyright schukai GmbH
* @deprecated since 3.66.0 use {@link Monster.Components.Layout.Popper}
*/
function getTemplate() {
// language=HTML
return `
<div data-monster-role="control" part="control">
<slot name="button" data-monster-role="button"></slot>
class Popper extends NewPopper {
<div data-monster-role="popper" part="popper" tabindex="-1" class="monster-color-primary-1">
<div data-monster-role="arrow"></div>
<div part="content" class="flex" data-monster-replace="path:content">
</div>
</div>
</div>
`;
}
\ No newline at end of file
registerCustomElement(Popper);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment