feat: docker compose maybe
This commit is contained in:
7
node_modules/@skeletonlabs/skeleton/dist/utilities/Popup/popup.d.ts
generated
vendored
Normal file
7
node_modules/@skeletonlabs/skeleton/dist/utilities/Popup/popup.d.ts
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { type Writable } from 'svelte/store';
|
||||
import type { PopupSettings } from './types.js';
|
||||
export declare const storePopup: Writable<any>;
|
||||
export declare function popup(triggerNode: HTMLElement, args: PopupSettings): {
|
||||
update(newArgs: PopupSettings): void;
|
||||
destroy(): void;
|
||||
};
|
237
node_modules/@skeletonlabs/skeleton/dist/utilities/Popup/popup.js
generated
vendored
Normal file
237
node_modules/@skeletonlabs/skeleton/dist/utilities/Popup/popup.js
generated
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
import { get, writable } from 'svelte/store';
|
||||
// Use a store to pass the Floating UI import references
|
||||
export const storePopup = writable(undefined);
|
||||
export function popup(triggerNode, args) {
|
||||
// Floating UI Modules
|
||||
const { computePosition, autoUpdate, offset, shift, flip, arrow, size, autoPlacement, hide, inline } = get(storePopup);
|
||||
// Local State
|
||||
const popupState = {
|
||||
open: false,
|
||||
autoUpdateCleanup: () => { }
|
||||
};
|
||||
const focusableAllowedList = ':is(a[href], button, input, textarea, select, details, [tabindex]):not([tabindex="-1"])';
|
||||
let focusablePopupElements;
|
||||
const documentationLink = 'https://www.skeleton.dev/utilities/popups';
|
||||
// Elements
|
||||
let elemPopup;
|
||||
let elemArrow;
|
||||
function setDomElements() {
|
||||
elemPopup = document.querySelector(`[data-popup="${args.target}"]`) ?? document.createElement('div');
|
||||
elemArrow = elemPopup.querySelector(`.arrow`) ?? document.createElement('div');
|
||||
}
|
||||
setDomElements(); // init
|
||||
// Render Floating UI Popup
|
||||
function render() {
|
||||
// Error handling for required Floating UI modules
|
||||
if (!elemPopup)
|
||||
throw new Error(`The data-popup="${args.target}" element was not found. ${documentationLink}`);
|
||||
if (!computePosition)
|
||||
throw new Error(`Floating UI 'computePosition' not found for data-popup="${args.target}". ${documentationLink}`);
|
||||
if (!offset)
|
||||
throw new Error(`Floating UI 'offset' not found for data-popup="${args.target}". ${documentationLink}`);
|
||||
if (!shift)
|
||||
throw new Error(`Floating UI 'shift' not found for data-popup="${args.target}". ${documentationLink}`);
|
||||
if (!flip)
|
||||
throw new Error(`Floating UI 'flip' not found for data-popup="${args.target}". ${documentationLink}`);
|
||||
if (!arrow)
|
||||
throw new Error(`Floating UI 'arrow' not found for data-popup="${args.target}". ${documentationLink}`);
|
||||
// Bundle optional middleware
|
||||
const optionalMiddleware = [];
|
||||
// https://floating-ui.com/docs/size
|
||||
if (size)
|
||||
optionalMiddleware.push(size(args.middleware?.size));
|
||||
// https://floating-ui.com/docs/autoPlacement
|
||||
if (autoPlacement)
|
||||
optionalMiddleware.push(autoPlacement(args.middleware?.autoPlacement));
|
||||
// https://floating-ui.com/docs/hide
|
||||
if (hide)
|
||||
optionalMiddleware.push(hide(args.middleware?.hide));
|
||||
// https://floating-ui.com/docs/inline
|
||||
if (inline)
|
||||
optionalMiddleware.push(inline(args.middleware?.inline));
|
||||
// Floating UI Compute Position
|
||||
// https://floating-ui.com/docs/computePosition
|
||||
computePosition(triggerNode, elemPopup, {
|
||||
placement: args.placement ?? 'bottom',
|
||||
// Middleware - NOTE: the order matters:
|
||||
// https://floating-ui.com/docs/middleware#ordering
|
||||
middleware: [
|
||||
// https://floating-ui.com/docs/offset
|
||||
offset(args.middleware?.offset ?? 8),
|
||||
// https://floating-ui.com/docs/shift
|
||||
shift(args.middleware?.shift ?? { padding: 8 }),
|
||||
// https://floating-ui.com/docs/flip
|
||||
flip(args.middleware?.flip),
|
||||
// https://floating-ui.com/docs/arrow
|
||||
arrow(args.middleware?.arrow ?? { element: elemArrow || null }),
|
||||
// Implement optional middleware
|
||||
...optionalMiddleware
|
||||
]
|
||||
}).then(({ x, y, placement, middlewareData }) => {
|
||||
Object.assign(elemPopup.style, {
|
||||
left: `${x}px`,
|
||||
top: `${y}px`
|
||||
});
|
||||
// Handle Arrow Placement:
|
||||
// https://floating-ui.com/docs/arrow
|
||||
if (elemArrow) {
|
||||
const { x: arrowX, y: arrowY } = middlewareData.arrow;
|
||||
// @ts-expect-error implicit any
|
||||
const staticSide = {
|
||||
top: 'bottom',
|
||||
right: 'left',
|
||||
bottom: 'top',
|
||||
left: 'right'
|
||||
}[placement.split('-')[0]];
|
||||
Object.assign(elemArrow.style, {
|
||||
left: arrowX != null ? `${arrowX}px` : '',
|
||||
top: arrowY != null ? `${arrowY}px` : '',
|
||||
right: '',
|
||||
bottom: '',
|
||||
[staticSide]: '-4px'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// State Handlers
|
||||
function open() {
|
||||
if (!elemPopup)
|
||||
return;
|
||||
// Set open state to on
|
||||
popupState.open = true;
|
||||
// Return the current state
|
||||
if (args.state)
|
||||
args.state({ state: popupState.open });
|
||||
// Update render settings
|
||||
render();
|
||||
// Update the DOM
|
||||
elemPopup.style.display = 'block';
|
||||
elemPopup.style.opacity = '1';
|
||||
elemPopup.style.pointerEvents = 'auto';
|
||||
// enable popup interactions
|
||||
elemPopup.removeAttribute('inert');
|
||||
// Trigger Floating UI autoUpdate (open only)
|
||||
// https://floating-ui.com/docs/autoUpdate
|
||||
popupState.autoUpdateCleanup = autoUpdate(triggerNode, elemPopup, render);
|
||||
// Focus the first focusable element within the popup
|
||||
focusablePopupElements = Array.from(elemPopup?.querySelectorAll(focusableAllowedList));
|
||||
}
|
||||
function close(callback) {
|
||||
if (!elemPopup)
|
||||
return;
|
||||
// Set transition duration
|
||||
const cssTransitionDuration = parseFloat(window.getComputedStyle(elemPopup).transitionDuration.replace('s', '')) * 1000;
|
||||
setTimeout(() => {
|
||||
// Set open state to off
|
||||
popupState.open = false;
|
||||
// Return the current state
|
||||
if (args.state)
|
||||
args.state({ state: popupState.open });
|
||||
// Update the DOM
|
||||
elemPopup.style.opacity = '0';
|
||||
// disable popup interactions
|
||||
elemPopup.setAttribute('inert', '');
|
||||
// Cleanup Floating UI autoUpdate (close only)
|
||||
if (popupState.autoUpdateCleanup)
|
||||
popupState.autoUpdateCleanup();
|
||||
// Trigger callback
|
||||
if (callback)
|
||||
callback();
|
||||
}, cssTransitionDuration);
|
||||
}
|
||||
// Event Handlers
|
||||
function toggle() {
|
||||
popupState.open === false ? open() : close();
|
||||
}
|
||||
function onWindowClick(event) {
|
||||
// Return if the popup is not yet open
|
||||
if (popupState.open === false)
|
||||
return;
|
||||
// Return if click is the trigger element
|
||||
if (triggerNode.contains(event.target))
|
||||
return;
|
||||
// If click it outside the popup
|
||||
if (elemPopup && elemPopup.contains(event.target) === false) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
// Handle Close Query State
|
||||
const closeQueryString = args.closeQuery === undefined ? 'a[href], button' : args.closeQuery;
|
||||
const closableMenuElements = elemPopup?.querySelectorAll(closeQueryString);
|
||||
closableMenuElements?.forEach((elem) => {
|
||||
if (elem.contains(event.target))
|
||||
close();
|
||||
});
|
||||
}
|
||||
// Keyboard Interactions for A11y
|
||||
const onWindowKeyDown = (event) => {
|
||||
if (popupState.open === false)
|
||||
return;
|
||||
// Handle keys
|
||||
const key = event.key;
|
||||
// On Esc key
|
||||
if (key === 'Escape') {
|
||||
event.preventDefault();
|
||||
triggerNode.focus();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
// Update focusable elements (important for Autocomplete)
|
||||
focusablePopupElements = Array.from(elemPopup?.querySelectorAll(focusableAllowedList));
|
||||
// On Tab or ArrowDown key
|
||||
const triggerMenuFocused = popupState.open && document.activeElement === triggerNode;
|
||||
if (triggerMenuFocused &&
|
||||
(key === 'ArrowDown' || key === 'Tab') &&
|
||||
focusableAllowedList.length > 0 &&
|
||||
focusablePopupElements.length > 0) {
|
||||
event.preventDefault();
|
||||
focusablePopupElements[0].focus();
|
||||
}
|
||||
};
|
||||
// Event Listeners
|
||||
switch (args.event) {
|
||||
case 'click':
|
||||
triggerNode.addEventListener('click', toggle, true);
|
||||
window.addEventListener('click', onWindowClick, true);
|
||||
break;
|
||||
case 'hover':
|
||||
triggerNode.addEventListener('mouseover', open, true);
|
||||
triggerNode.addEventListener('mouseleave', () => close(), true);
|
||||
break;
|
||||
case 'focus-blur':
|
||||
triggerNode.addEventListener('focus', toggle, true);
|
||||
triggerNode.addEventListener('blur', () => close(), true);
|
||||
break;
|
||||
case 'focus-click':
|
||||
triggerNode.addEventListener('focus', open, true);
|
||||
window.addEventListener('click', onWindowClick, true);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Event value of '${args.event}' is not supported. ${documentationLink}`);
|
||||
}
|
||||
window.addEventListener('keydown', onWindowKeyDown, true);
|
||||
// Render popup on initialization
|
||||
render();
|
||||
// Lifecycle
|
||||
return {
|
||||
update(newArgs) {
|
||||
close(() => {
|
||||
args = newArgs;
|
||||
render();
|
||||
setDomElements();
|
||||
});
|
||||
},
|
||||
destroy() {
|
||||
// Trigger Events
|
||||
triggerNode.removeEventListener('click', toggle, true);
|
||||
triggerNode.removeEventListener('mouseover', open, true);
|
||||
triggerNode.removeEventListener('mouseleave', () => close(), true);
|
||||
triggerNode.removeEventListener('focus', toggle, true);
|
||||
triggerNode.removeEventListener('focus', open, true);
|
||||
triggerNode.removeEventListener('blur', () => close(), true);
|
||||
// Window Events
|
||||
window.removeEventListener('click', onWindowClick, true);
|
||||
window.removeEventListener('keydown', onWindowKeyDown, true);
|
||||
}
|
||||
};
|
||||
}
|
40
node_modules/@skeletonlabs/skeleton/dist/utilities/Popup/types.d.ts
generated
vendored
Normal file
40
node_modules/@skeletonlabs/skeleton/dist/utilities/Popup/types.d.ts
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/** Placement https://floating-ui.com/docs/computePosition#placement */
|
||||
type Direction = 'top' | 'bottom' | 'left' | 'right';
|
||||
type Placement = Direction | `${Direction}-start` | `${Direction}-end`;
|
||||
export interface Middleware {
|
||||
/** Offset middleware settings: https://floating-ui.com/docs/offset */
|
||||
offset?: number | Record<string, any>;
|
||||
/** Shift middleware settings: https://floating-ui.com/docs/shift */
|
||||
shift?: Record<string, any>;
|
||||
/** Flip middleware settings: https://floating-ui.com/docs/flip */
|
||||
flip?: Record<string, any>;
|
||||
/** Arrow middleware settings: https://floating-ui.com/docs/arrow */
|
||||
arrow?: {
|
||||
element: string;
|
||||
} & Record<string, any>;
|
||||
/** Size middleware settings: https://floating-ui.com/docs/size */
|
||||
size?: Record<string, any>;
|
||||
/** Auto Placement middleware settings: https://floating-ui.com/docs/autoPlacement */
|
||||
autoPlacement?: Record<string, any>;
|
||||
/** Hide middleware settings: https://floating-ui.com/docs/hide */
|
||||
hide?: Record<string, any>;
|
||||
/** Inline middleware settings: https://floating-ui.com/docs/inline */
|
||||
inline?: Record<string, any>;
|
||||
}
|
||||
export interface PopupSettings {
|
||||
/** Provide the event type. */
|
||||
event: 'click' | 'hover' | 'focus-blur' | 'focus-click';
|
||||
/** Match the popup data value `data-popup="targetNameHere"` */
|
||||
target: string;
|
||||
/** Set the placement position. Defaults 'bottom'. */
|
||||
placement?: Placement;
|
||||
/** Query elements that close the popup when clicked. Defaults `'a[href], button'`. */
|
||||
closeQuery?: string;
|
||||
/** Optional callback function that reports state change. */
|
||||
state?: (event: {
|
||||
state: boolean;
|
||||
}) => void;
|
||||
/** Provide Floating UI middleware settings. */
|
||||
middleware?: Middleware;
|
||||
}
|
||||
export {};
|
2
node_modules/@skeletonlabs/skeleton/dist/utilities/Popup/types.js
generated
vendored
Normal file
2
node_modules/@skeletonlabs/skeleton/dist/utilities/Popup/types.js
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// Popup Types
|
||||
export {};
|
Reference in New Issue
Block a user