DuyTa's picture
Upload folder using huggingface_hub
bc20498 verified
import { addMeltEventListener, makeElement, createElHelpers, derivedVisible, effect, executeCallbacks, getPortalDestination, handleFocus, isBrowser, isElement, isHTMLElement, kbd, noop, omit, overridable, removeScroll, styleToString, toWritableStores, portalAttr, generateIds, } from '../../internal/helpers/index.js';
import { useEscapeKeydown, usePopper, usePortal, } from '../../internal/actions/index.js';
import { safeOnMount } from '../../internal/helpers/lifecycle.js';
import { tick } from 'svelte';
import { writable } from 'svelte/store';
const defaults = {
positioning: {
placement: 'bottom',
},
arrowSize: 8,
defaultOpen: false,
disableFocusTrap: false,
closeOnEscape: true,
preventScroll: false,
onOpenChange: undefined,
closeOnOutsideClick: true,
portal: undefined,
forceVisible: false,
openFocus: undefined,
closeFocus: undefined,
onOutsideClick: undefined,
};
const { name } = createElHelpers('popover');
export const popoverIdParts = ['trigger', 'content'];
export function createPopover(args) {
const withDefaults = { ...defaults, ...args };
const options = toWritableStores(omit(withDefaults, 'open', 'ids'));
const { positioning, arrowSize, disableFocusTrap, preventScroll, closeOnEscape, closeOnOutsideClick, portal, forceVisible, openFocus, closeFocus, onOutsideClick, } = options;
const openWritable = withDefaults.open ?? writable(withDefaults.defaultOpen);
const open = overridable(openWritable, withDefaults?.onOpenChange);
const activeTrigger = writable(null);
const ids = toWritableStores({ ...generateIds(popoverIdParts), ...withDefaults.ids });
safeOnMount(() => {
activeTrigger.set(document.getElementById(ids.trigger.get()));
});
function handleClose() {
open.set(false);
const triggerEl = document.getElementById(ids.trigger.get());
handleFocus({ prop: closeFocus.get(), defaultEl: triggerEl });
}
const isVisible = derivedVisible({ open, activeTrigger, forceVisible });
const content = makeElement(name('content'), {
stores: [isVisible, portal, ids.content],
returned: ([$isVisible, $portal, $contentId]) => {
return {
hidden: $isVisible && isBrowser ? undefined : true,
tabindex: -1,
style: styleToString({
display: $isVisible ? undefined : 'none',
}),
id: $contentId,
'data-state': $isVisible ? 'open' : 'closed',
'data-portal': portalAttr($portal),
};
},
action: (node) => {
let unsubPopper = noop;
const unsubDerived = effect([
isVisible,
activeTrigger,
positioning,
disableFocusTrap,
closeOnEscape,
closeOnOutsideClick,
portal,
], ([$isVisible, $activeTrigger, $positioning, $disableFocusTrap, $closeOnEscape, $closeOnOutsideClick, $portal,]) => {
unsubPopper();
if (!$isVisible || !$activeTrigger)
return;
tick().then(() => {
const popper = usePopper(node, {
anchorElement: $activeTrigger,
open,
options: {
floating: $positioning,
focusTrap: $disableFocusTrap
? null
: {
returnFocusOnDeactivate: false,
clickOutsideDeactivates: true,
escapeDeactivates: true,
},
modal: {
shouldCloseOnInteractOutside: shouldCloseOnInteractOutside,
onClose: handleClose,
open: $isVisible,
closeOnInteractOutside: $closeOnOutsideClick,
},
escapeKeydown: $closeOnEscape
? {
handler: () => {
handleClose();
},
}
: null,
portal: getPortalDestination(node, $portal),
},
});
if (popper && popper.destroy) {
unsubPopper = popper.destroy;
}
});
});
return {
destroy() {
unsubDerived();
unsubPopper();
},
};
},
});
function toggleOpen(triggerEl) {
open.update((prev) => {
return !prev;
});
if (triggerEl) {
activeTrigger.set(triggerEl);
}
}
function shouldCloseOnInteractOutside(e) {
onOutsideClick.get()?.(e);
if (e.defaultPrevented)
return false;
const target = e.target;
const triggerEl = document.getElementById(ids.trigger.get());
if (triggerEl && isElement(target)) {
if (target === triggerEl || triggerEl.contains(target))
return false;
}
return true;
}
const trigger = makeElement(name('trigger'), {
stores: [isVisible, ids.content, ids.trigger],
returned: ([$isVisible, $contentId, $triggerId]) => {
return {
role: 'button',
'aria-haspopup': 'dialog',
'aria-expanded': $isVisible ? 'true' : 'false',
'data-state': stateAttr($isVisible),
'aria-controls': $contentId,
id: $triggerId,
};
},
action: (node) => {
const unsub = executeCallbacks(addMeltEventListener(node, 'click', () => {
toggleOpen(node);
}), addMeltEventListener(node, 'keydown', (e) => {
if (e.key !== kbd.ENTER && e.key !== kbd.SPACE)
return;
e.preventDefault();
toggleOpen(node);
}));
return {
destroy: unsub,
};
},
});
const overlay = makeElement(name('overlay'), {
stores: [isVisible],
returned: ([$isVisible]) => {
return {
hidden: $isVisible ? undefined : true,
tabindex: -1,
style: styleToString({
display: $isVisible ? undefined : 'none',
}),
'aria-hidden': 'true',
'data-state': stateAttr($isVisible),
};
},
action: (node) => {
let unsubEscapeKeydown = noop;
if (closeOnEscape.get()) {
const escapeKeydown = useEscapeKeydown(node, {
handler: () => {
handleClose();
},
});
if (escapeKeydown && escapeKeydown.destroy) {
unsubEscapeKeydown = escapeKeydown.destroy;
}
}
const unsubPortal = effect([portal], ([$portal]) => {
if ($portal === null)
return noop;
const portalDestination = getPortalDestination(node, $portal);
if (portalDestination === null)
return noop;
const portalAction = usePortal(node, portalDestination);
if (portalAction && portalAction.destroy) {
return portalAction.destroy;
}
else {
return noop;
}
});
return {
destroy() {
unsubEscapeKeydown();
unsubPortal();
},
};
},
});
const arrow = makeElement(name('arrow'), {
stores: arrowSize,
returned: ($arrowSize) => ({
'data-arrow': true,
style: styleToString({
position: 'absolute',
width: `var(--arrow-size, ${$arrowSize}px)`,
height: `var(--arrow-size, ${$arrowSize}px)`,
}),
}),
});
const close = makeElement(name('close'), {
returned: () => ({
type: 'button',
}),
action: (node) => {
const unsub = executeCallbacks(addMeltEventListener(node, 'click', (e) => {
if (e.defaultPrevented)
return;
handleClose();
}), addMeltEventListener(node, 'keydown', (e) => {
if (e.defaultPrevented)
return;
if (e.key !== kbd.ENTER && e.key !== kbd.SPACE)
return;
e.preventDefault();
toggleOpen();
}));
return {
destroy: unsub,
};
},
});
effect([open, activeTrigger, preventScroll], ([$open, $activeTrigger, $preventScroll]) => {
if (!isBrowser)
return;
const unsubs = [];
if ($open) {
if (!$activeTrigger) {
tick().then(() => {
const triggerEl = document.getElementById(ids.trigger.get());
if (!isHTMLElement(triggerEl))
return;
activeTrigger.set(triggerEl);
});
}
if ($preventScroll) {
unsubs.push(removeScroll());
}
const triggerEl = $activeTrigger ?? document.getElementById(ids.trigger.get());
handleFocus({ prop: openFocus.get(), defaultEl: triggerEl });
}
return () => {
unsubs.forEach((unsub) => unsub());
};
});
return {
ids,
elements: {
trigger,
content,
arrow,
close,
overlay,
},
states: {
open,
},
options,
};
}
function stateAttr(open) {
return open ? 'open' : 'closed';
}