chore: copy overlays docs assets inside ui pkg
This commit is contained in:
parent
a0fefee88b
commit
473cd0ffc4
6 changed files with 658 additions and 79 deletions
|
|
@ -1,38 +0,0 @@
|
|||
import { directive } from 'lit/directive.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('@lion/ui/core.js').PropertyPart} PropertyPart
|
||||
*/
|
||||
|
||||
/** @type {WeakSet<Element>} */
|
||||
const cache = new WeakSet();
|
||||
|
||||
/**
|
||||
* @desc Allows to have references to different parts of your lit template.
|
||||
* Without it, seperate renders to different nodes would have been needed, leading to more verbose,
|
||||
* less readable and less performant code.
|
||||
* Inspired by Angular template refeference variables:
|
||||
* https://angular.io/guide/template-syntax#ref-vars
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const refObj = {};
|
||||
* ```
|
||||
* ```html
|
||||
* <my-element #myElement=${ref(refObj)}>
|
||||
* <button @click=${() => refObj.myElement.publicMethod()}>click</button>
|
||||
* </my-element>
|
||||
*```
|
||||
*
|
||||
* @param {object} refObj will be used to store reference to attribute names like #myElement
|
||||
*/
|
||||
export const ref = directive(refObj => (/** @type {PropertyPart} */ part) => {
|
||||
if (cache.has(part.committer.element)) {
|
||||
return;
|
||||
}
|
||||
cache.add(part.committer.element);
|
||||
const attrName = part.committer.name;
|
||||
const key = attrName.replace(/^#/, '');
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
refObj[key] = part.committer.element;
|
||||
});
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { css } from 'lit';
|
||||
|
||||
const applyDemoOverlayStyles = () => {
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import { html, LitElement } from 'lit';
|
||||
import { OverlayMixin } from '@lion/ui/overlays.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('@lion/ui/types/overlays.js').OverlayConfig} OverlayConfig
|
||||
*/
|
||||
class DemoElUsingOverlayMixin extends OverlayMixin(LitElement) {
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
_defineOverlayConfig() {
|
||||
return /** @type {OverlayConfig} */ ({
|
||||
placementMode: 'global',
|
||||
});
|
||||
}
|
||||
|
||||
_setupOpenCloseListeners() {
|
||||
super._setupOpenCloseListeners();
|
||||
|
||||
if (this._overlayInvokerNode) {
|
||||
this._overlayInvokerNode.addEventListener('click', this.toggle);
|
||||
}
|
||||
}
|
||||
|
||||
_teardownOpenCloseListeners() {
|
||||
super._teardownOpenCloseListeners();
|
||||
|
||||
if (this._overlayInvokerNode) {
|
||||
this._overlayInvokerNode.removeEventListener('click', this.toggle);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<slot name="invoker"></slot>
|
||||
<slot name="backdrop"></slot>
|
||||
<div id="overlay-content-node-wrapper">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
customElements.define('demo-el-using-overlaymixin', DemoElUsingOverlayMixin);
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/* eslint-disable max-classes-per-file */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { html, LitElement, css } from 'lit';
|
||||
import { OverlayMixin } from '@lion/ui/overlays.js';
|
||||
import { LionButton } from '@lion/ui/button.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('@lion/ui/types/overlays.js').OverlayConfig} OverlayConfig
|
||||
*/
|
||||
class DemoElUsingOverlayMixin extends OverlayMixin(LitElement) {
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
_defineOverlayConfig() {
|
||||
return /** @type {OverlayConfig} */ ({
|
||||
placementMode: 'global',
|
||||
});
|
||||
}
|
||||
|
||||
_setupOpenCloseListeners() {
|
||||
super._setupOpenCloseListeners();
|
||||
|
||||
if (this._overlayInvokerNode) {
|
||||
this._overlayInvokerNode.addEventListener('click', this.toggle);
|
||||
}
|
||||
}
|
||||
|
||||
_teardownOpenCloseListeners() {
|
||||
super._teardownOpenCloseListeners();
|
||||
|
||||
if (this._overlayInvokerNode) {
|
||||
this._overlayInvokerNode.removeEventListener('click', this.toggle);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<slot name="invoker"></slot>
|
||||
<slot name="backdrop"></slot>
|
||||
<slot name="content"></slot>
|
||||
`;
|
||||
}
|
||||
}
|
||||
customElements.define('demo-el-using-overlaymixin', DemoElUsingOverlayMixin);
|
||||
|
||||
class DemoOverlay extends OverlayMixin(LitElement) {
|
||||
static get styles() {
|
||||
return [
|
||||
css`
|
||||
::slotted([slot='content']) {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
padding: 4px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
_defineOverlayConfig() {
|
||||
return /** @type {OverlayConfig} */ ({
|
||||
placementMode: 'global',
|
||||
});
|
||||
}
|
||||
|
||||
_setupOpenCloseListeners() {
|
||||
super._setupOpenCloseListeners();
|
||||
|
||||
if (this._overlayInvokerNode) {
|
||||
this._overlayInvokerNode.addEventListener('click', this.toggle);
|
||||
}
|
||||
}
|
||||
|
||||
_teardownOpenCloseListeners() {
|
||||
super._teardownOpenCloseListeners();
|
||||
|
||||
if (this._overlayInvokerNode) {
|
||||
this._overlayInvokerNode.removeEventListener('click', this.toggle);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<slot name="invoker"></slot>
|
||||
<slot name="backdrop"></slot>
|
||||
<div id="overlay-content-node-wrapper">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
customElements.define('demo-overlay', DemoOverlay);
|
||||
|
||||
class DemoCloseButton extends LionButton {
|
||||
static get styles() {
|
||||
return [
|
||||
css`
|
||||
::host {
|
||||
background: none;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
this.innerText = '⨯';
|
||||
this.setAttribute('aria-label', 'Close');
|
||||
}
|
||||
}
|
||||
customElements.define('demo-close-button', DemoCloseButton);
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { css, LitElement } from 'lit';
|
||||
|
||||
/**
|
||||
|
|
@ -0,0 +1,537 @@
|
|||
/* eslint-disable max-classes-per-file */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { html, LitElement, css } from 'lit';
|
||||
import { ref, createRef } from 'lit/directives/ref.js';
|
||||
import { OverlayMixin } from '@lion/ui/overlays.js';
|
||||
import './demo-el-using-overlaymixin.mjs';
|
||||
|
||||
/**
|
||||
* @typedef {import('@lion/ui/types/overlays.js').OverlayConfig} OverlayConfig
|
||||
* @typedef {import('@lion/ui/types/overlays.js').OverlayHost} OverlayHost
|
||||
* @typedef {import('@lion/ui/button.js').LionButton} LionButton
|
||||
* @typedef {'top-start'|'top'|'top-end'|'right-start'|'right'|'right-end'|'bottom-start'|'bottom'|'bottom-end'|'left-start'|'left'|'left-end'} LocalPlacement
|
||||
* @typedef {'center'|'top-left'|'top'|'top-right'|'right'|'bottom-right'|'bottom'|'bottom-left'|'left'} ViewportPlacement
|
||||
* @typedef {{refs: { contentNodeWrapper:{ref: {value:HTMLElement}}; closeButton: {ref: {value:HTMLButtonElement|LionButton}; label:string} }}} TemplateDataForOverlay
|
||||
*/
|
||||
class DemoOverlayEl extends OverlayMixin(LitElement) {
|
||||
/** @type {any} */
|
||||
static get properties() {
|
||||
return {
|
||||
simulateViewport: { type: Boolean, attribute: 'simulate-viewport', reflect: true },
|
||||
noDialogEl: { type: Boolean, attribute: 'no-dialog-el' },
|
||||
useAbsolute: { type: Boolean, attribute: 'use-absolute', reflect: true },
|
||||
};
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
super.styles || [],
|
||||
css`
|
||||
:host([use-absolute]) dialog {
|
||||
position: absolute !important;
|
||||
}
|
||||
|
||||
:host([simulate-viewport]) {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
:host([simulate-viewport]) dialog {
|
||||
position: absolute !important;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
:host([simulate-viewport]) #overlay-content-node-wrapper.overlays__overlay-container {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/*=== demo invoker and content ===*/
|
||||
|
||||
:host ::slotted([slot='invoker']) {
|
||||
border: 4px dashed;
|
||||
height: 24px;
|
||||
min-width: 24px;
|
||||
}
|
||||
|
||||
:host ::slotted([slot='content']) {
|
||||
background-color: black;
|
||||
color: white;
|
||||
height: 54px;
|
||||
min-width: 54px;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.simulateViewport = false;
|
||||
this._noDialogEl = false;
|
||||
this.useAbsolute = false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
_defineOverlayConfig() {
|
||||
return /** @type {OverlayConfig} */ ({
|
||||
placementMode: 'local',
|
||||
noDialogEl: this._noDialogEl,
|
||||
popperConfig: { strategy: this.useAbsolute ? 'absolute' : 'fixed' },
|
||||
});
|
||||
}
|
||||
|
||||
_setupOpenCloseListeners() {
|
||||
super._setupOpenCloseListeners();
|
||||
|
||||
if (this._overlayInvokerNode) {
|
||||
this._overlayInvokerNode.addEventListener('click', this.toggle);
|
||||
}
|
||||
}
|
||||
|
||||
_teardownOpenCloseListeners() {
|
||||
super._teardownOpenCloseListeners();
|
||||
|
||||
if (this._overlayInvokerNode) {
|
||||
this._overlayInvokerNode.removeEventListener('click', this.toggle);
|
||||
}
|
||||
}
|
||||
|
||||
refs = {
|
||||
invokerSlot: /** @type {{value: HTMLSlotElement}} */ (createRef()),
|
||||
backdropSlot: /** @type {{value: HTMLSlotElement}} */ (createRef()),
|
||||
contentSlot: /** @type {{value: HTMLSlotElement}} */ (createRef()),
|
||||
closeButton: /** @type {{value: HTMLButtonElement|LionButton}} */ (createRef()),
|
||||
contentNodeWrapper: /** @type {{value: HTMLElement}} */ (createRef()),
|
||||
};
|
||||
|
||||
/**
|
||||
* @overridable
|
||||
* @type {TemplateDataForOverlay}
|
||||
*/
|
||||
get _templateData() {
|
||||
return {
|
||||
refs: {
|
||||
contentNodeWrapper: {
|
||||
ref: this.refs.contentNodeWrapper,
|
||||
},
|
||||
closeButton: {
|
||||
ref: this.refs.closeButton,
|
||||
label: 'close dialog',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static templates = {
|
||||
main: (/** @type {TemplateDataForOverlay} */ { refs }) => html`
|
||||
<slot name="invoker"></slot>
|
||||
<slot name="backdrop"></slot>
|
||||
<div ${ref(refs.contentNodeWrapper.ref)} id="overlay-content-node-wrapper">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
||||
render() {
|
||||
const ctor = /** @type {typeof DemoOverlayEl} */ (this.constructor);
|
||||
const templates = this.templates || ctor.templates;
|
||||
return templates.main(this._templateData);
|
||||
}
|
||||
}
|
||||
customElements.define('demo-overlay-el', DemoOverlayEl);
|
||||
|
||||
class DemoOverlayPositioning extends LitElement {
|
||||
static properties = {
|
||||
placementMode: { attribute: 'placement-mode', type: String },
|
||||
simulateViewport: { type: Boolean, attribute: 'simulate-viewport', reflect: true },
|
||||
_activePos: { type: String, reflect: true, attribute: 'active-pos' },
|
||||
_activeConfig: { type: Object, state: true },
|
||||
};
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
css`
|
||||
/*=== .pos-container ===*/
|
||||
|
||||
.pos-container {
|
||||
padding: 0.5rem;
|
||||
overflow: hidden;
|
||||
place-items: center;
|
||||
height: 20rem;
|
||||
display: grid;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/*=== .pos-btn-wrapper ===*/
|
||||
|
||||
/**
|
||||
* We need a wrapper for position transforms, so that we can apply scale transforms on .pos-btn hover
|
||||
*/
|
||||
|
||||
.pos-btn-wrapper {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.pos-container--local .pos-btn-wrapper--bottom-start,
|
||||
.pos-container--local .pos-btn-wrapper--bottom-end,
|
||||
.pos-container--local .pos-btn-wrapper--top-start,
|
||||
.pos-container--local .pos-btn-wrapper--top-end,
|
||||
.pos-container--local .pos-btn-wrapper--top,
|
||||
.pos-container--local .pos-btn-wrapper--bottom {
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.pos-container--local .pos-btn-wrapper--top-start,
|
||||
.pos-container--local .pos-btn-wrapper--top-end,
|
||||
.pos-container--local .pos-btn-wrapper--top {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.pos-container--local .pos-btn-wrapper--bottom-start,
|
||||
.pos-container--local .pos-btn-wrapper--bottom-end,
|
||||
.pos-container--local .pos-btn-wrapper--bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.pos-container--local .pos-btn-wrapper--left-start,
|
||||
.pos-container--local .pos-btn-wrapper--left-end,
|
||||
.pos-container--local .pos-btn-wrapper--right-start,
|
||||
.pos-container--local .pos-btn-wrapper--right-end,
|
||||
.pos-container--local .pos-btn-wrapper--left,
|
||||
.pos-container--local .pos-btn-wrapper--right {
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.pos-container--local .pos-btn-wrapper--left-start,
|
||||
.pos-container--local .pos-btn-wrapper--left-end,
|
||||
.pos-container--local .pos-btn-wrapper--left {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.pos-container--local .pos-btn-wrapper--right-start,
|
||||
.pos-container--local .pos-btn-wrapper--right-end,
|
||||
.pos-container--local .pos-btn-wrapper--right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.pos-container--local .pos-btn-wrapper--bottom-start,
|
||||
.pos-container--local .pos-btn-wrapper--top-start {
|
||||
transform: translateX(-50%) translateX(-48px);
|
||||
}
|
||||
|
||||
.pos-container--local .pos-btn-wrapper--bottom-end,
|
||||
.pos-container--local .pos-btn-wrapper--top-end {
|
||||
transform: translateX(-50%) translateX(48px);
|
||||
}
|
||||
|
||||
.pos-container--local .pos-btn-wrapper--left-start,
|
||||
.pos-container--local .pos-btn-wrapper--right-start {
|
||||
transform: translateY(calc(-50% - 48px));
|
||||
}
|
||||
|
||||
.pos-container--local .pos-btn-wrapper--left-end,
|
||||
.pos-container--local .pos-btn-wrapper--right-end {
|
||||
transform: translateY(calc(-50% + 48px));
|
||||
}
|
||||
|
||||
.pos-container--global .pos-btn-wrapper {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.pos-container--global .pos-btn-wrapper--center {
|
||||
transform: translateY(-50%) translateX(-50%);
|
||||
}
|
||||
|
||||
.pos-container--global .pos-btn-wrapper--top-left {
|
||||
transform: translateY(-50%) translateX(-50%) translateY(-48px) translateX(-48px);
|
||||
}
|
||||
|
||||
.pos-container--global .pos-btn-wrapper--top {
|
||||
transform: translateY(-50%) translateX(-50%) translateY(-48px);
|
||||
}
|
||||
|
||||
.pos-container--global .pos-btn-wrapper--top-right {
|
||||
transform: translateY(-50%) translateX(-50%) translateY(-48px) translateX(48px);
|
||||
}
|
||||
|
||||
.pos-container--global .pos-btn-wrapper--bottom-left {
|
||||
transform: translateY(-50%) translateX(-50%) translateY(48px) translateX(-48px);
|
||||
}
|
||||
|
||||
.pos-container--global .pos-btn-wrapper--bottom {
|
||||
transform: translateY(-50%) translateX(-50%) translateY(48px);
|
||||
}
|
||||
|
||||
.pos-container--global .pos-btn-wrapper--bottom-right {
|
||||
transform: translateY(-50%) translateX(-50%) translateY(48px) translateX(48px);
|
||||
}
|
||||
|
||||
.pos-container--global .pos-btn-wrapper--right {
|
||||
transform: translateY(-50%) translateX(-50%) translateX(48px);
|
||||
}
|
||||
|
||||
.pos-container--global .pos-btn-wrapper--left {
|
||||
transform: translateY(-50%) translateX(-50%) translateX(-48px);
|
||||
}
|
||||
|
||||
/*=== .pos-btn ===*/
|
||||
|
||||
.pos-btn {
|
||||
padding: 1rem;
|
||||
cursor: pointer;
|
||||
-webkit-appearance: button;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
text-transform: none;
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
border: 0 solid #bfc3d9;
|
||||
}
|
||||
|
||||
.pos-btn__inner {
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
border-radius: 100%;
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
}
|
||||
|
||||
.pos-btn:hover {
|
||||
transform: scaleX(2) scaleY(2);
|
||||
}
|
||||
|
||||
.pos-btn--active .pos-btn__inner {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
/*=== .reference-btn ===*/
|
||||
|
||||
.reference-btn {
|
||||
background: white;
|
||||
box-sizing: border-box;
|
||||
border: 5px dashed black;
|
||||
cursor: pointer;
|
||||
padding: 1rem;
|
||||
width: 8rem;
|
||||
height: 8rem;
|
||||
}
|
||||
|
||||
.pos-container--global .reference-btn {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
/*=== .close-btn ===*/
|
||||
|
||||
.close-btn {
|
||||
background: transparent;
|
||||
border: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.close-btn::after {
|
||||
content: '';
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/*=== .overlay-content ===*/
|
||||
|
||||
.overlay-content {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid black;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
background-color: #000;
|
||||
padding: 1rem;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
:host([active-pos^='center']) .pos-container--global .overlay-content {
|
||||
width: 14rem;
|
||||
height: 16rem;
|
||||
}
|
||||
|
||||
:host([active-pos^='bottom']) .pos-container--global .overlay-content,
|
||||
:host([active-pos^='top']) .pos-container--global .overlay-content {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
:host([active-pos^='left']) .pos-container--global .overlay-content,
|
||||
:host([active-pos^='right']) .pos-container--global .overlay-content {
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
:host([active-pos^='center']) .pos-btn {
|
||||
color: white;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
refs = {
|
||||
overlay: /** @type {{value: OverlayHost}} */ (createRef()),
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.placementMode = 'local';
|
||||
/** @type {ViewportPlacement[]|LocalPlacement[]} */
|
||||
this._placements = [];
|
||||
this.simulateViewport = false;
|
||||
this._activePos = 'top';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {{pos:ViewportPlacement|LocalPlacement}} opts
|
||||
*/
|
||||
async _updatePos({ pos }) {
|
||||
this._activePos = pos;
|
||||
|
||||
const overlayEl = this.refs.overlay.value;
|
||||
|
||||
// @ts-ignore allow protected
|
||||
if (overlayEl?._overlayCtrl) {
|
||||
overlayEl.config = /** @type {Partial<OverlayConfig>} */ ({
|
||||
popperConfig: { placement: pos },
|
||||
viewportConfig: { placement: pos },
|
||||
});
|
||||
// TODO: these hacks below should not be needed. Fix when moving to floating-ui
|
||||
// => animate different positions
|
||||
// @ts-ignore allow protected
|
||||
await overlayEl._overlayCtrl.hide();
|
||||
// @ts-ignore allow protected
|
||||
overlayEl._overlayCtrl.show();
|
||||
overlayEl.config = /** @type {Partial<OverlayConfig>} */ ({
|
||||
popperConfig: { placement: pos },
|
||||
viewportConfig: { placement: pos },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('lit').PropertyValues } changedProperties
|
||||
*/
|
||||
firstUpdated(changedProperties) {
|
||||
super.firstUpdated(changedProperties);
|
||||
|
||||
this._updatePos({ pos: this.placementMode === 'local' ? 'top' : 'center' });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('lit').PropertyValues } changedProperties
|
||||
*/
|
||||
update(changedProperties) {
|
||||
if (changedProperties.has('placementMode')) {
|
||||
if (this.placementMode === 'local') {
|
||||
this._placements = [
|
||||
`top-start`,
|
||||
`top`,
|
||||
`top-end`,
|
||||
`right-start`,
|
||||
`right`,
|
||||
`right-end`,
|
||||
`bottom-start`,
|
||||
`bottom`,
|
||||
`bottom-end`,
|
||||
`left-start`,
|
||||
`left`,
|
||||
`left-end`,
|
||||
];
|
||||
} else {
|
||||
this._placements = [
|
||||
`center`,
|
||||
`top-left`,
|
||||
`top`,
|
||||
`top-right`,
|
||||
`right`,
|
||||
`bottom-right`,
|
||||
`bottom`,
|
||||
`bottom-left`,
|
||||
`left`,
|
||||
];
|
||||
}
|
||||
}
|
||||
super.update(changedProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('lit').PropertyValues } changedProperties
|
||||
*/
|
||||
updated(changedProperties) {
|
||||
super.updated(changedProperties);
|
||||
|
||||
if (changedProperties.has('placementMode')) {
|
||||
this._activeConfig = {
|
||||
placementMode: this.placementMode,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{pos:string}} opts
|
||||
* @returns
|
||||
*/
|
||||
_isActivePosBtn({ pos }) {
|
||||
return pos === this._activePos;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="pos-container pos-container--${this.placementMode}">
|
||||
${this._placements.map(
|
||||
pos =>
|
||||
html`
|
||||
<div class="pos-btn-wrapper pos-btn-wrapper--${pos}">
|
||||
<button
|
||||
@click="${() => this._updatePos({ pos })}"
|
||||
class="pos-btn ${this._isActivePosBtn({ pos }) ? 'pos-btn--active' : ''}"
|
||||
aria-label="${pos}"
|
||||
>
|
||||
<div class="pos-btn__inner"></div>
|
||||
</button>
|
||||
</div>
|
||||
`,
|
||||
)}
|
||||
|
||||
<demo-overlay-el
|
||||
opened
|
||||
?simulate-viewport="${this.simulateViewport}"
|
||||
${ref(
|
||||
// @ts-ignore
|
||||
this.refs.overlay,
|
||||
)}
|
||||
.config="${this._activeConfig}"
|
||||
>
|
||||
<button class="reference-btn" slot="invoker"></button>
|
||||
<div class="overlay-content" slot="content"></div>
|
||||
</demo-overlay-el>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
customElements.define('demo-overlay-positioning', DemoOverlayPositioning);
|
||||
Loading…
Reference in a new issue