@k2b/ui 0.38.1 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/actions/Dropdown.js +42 -6
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/SelectionToolbar.js +11 -6
- package/dist/browser/actions/SelectionToolbar.js.map +1 -1
- package/dist/browser/actions/Toolbar.js +5 -1
- package/dist/browser/actions/Toolbar.js.map +1 -1
- package/dist/browser/actions/index.js.map +1 -1
- package/dist/browser/chat/ChatComposer.js +11 -2
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/text-editor/TextEditor.js +331 -214
- package/dist/browser/text-editor/TextEditor.js.map +1 -1
- package/dist/browser/text-editor/table.js +43 -6
- package/dist/browser/text-editor/table.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +38 -6
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/SelectionToolbar.js +11 -6
- package/dist/ssr/actions/SelectionToolbar.js.map +1 -1
- package/dist/ssr/actions/Toolbar.js +5 -1
- package/dist/ssr/actions/Toolbar.js.map +1 -1
- package/dist/ssr/actions/index.js.map +1 -1
- package/dist/ssr/chat/ChatComposer.js +10 -2
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/text-editor/TextEditor.js +225 -96
- package/dist/ssr/text-editor/TextEditor.js.map +1 -1
- package/dist/ssr/text-editor/table.js +43 -6
- package/dist/ssr/text-editor/table.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/Dropdown.d.ts +15 -1
- package/dist/types/actions/Toolbar.d.ts +6 -1
- package/dist/types/actions/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -41,6 +41,10 @@ const closeOnSelectOf = item => "closeOnSelect" in item ? item.closeOnSelect : u
|
|
|
41
41
|
const hrefOf = item => "href" in item ? item.href : undefined;
|
|
42
42
|
const externalOf = item => "external" in item ? item.external : undefined;
|
|
43
43
|
|
|
44
|
+
/** Where a menu opened without its trigger appears: an element, or any box such as a point inside one. */
|
|
45
|
+
|
|
46
|
+
/** Where focus returns as a menu opened by `openAt` closes, read at that moment when it is a function. */
|
|
47
|
+
|
|
44
48
|
/** A second, smaller action at the end of a row, such as "Only" beside a checkbox; it keeps the menu open. */
|
|
45
49
|
|
|
46
50
|
/** Declarative radio or checkbox row for compact action menus. */
|
|
@@ -462,6 +466,10 @@ function DropdownRoot(props) {
|
|
|
462
466
|
const [internalOpen, setInternalOpen] = createSignal(false);
|
|
463
467
|
const [entriesShown, setEntriesShown] = createSignal(!props.lazy);
|
|
464
468
|
let triggerRef;
|
|
469
|
+
/** Set while the menu is open from `openAt`: it appears beside `anchor`, and focus returns to `origin`. */
|
|
470
|
+
let anchor;
|
|
471
|
+
let origin;
|
|
472
|
+
const originElement = () => typeof origin === "function" ? origin() : origin;
|
|
465
473
|
let menuRef;
|
|
466
474
|
let triggerRing = true;
|
|
467
475
|
let mounted = false;
|
|
@@ -472,8 +480,9 @@ function DropdownRoot(props) {
|
|
|
472
480
|
const isOpen = () => props.open ?? internalOpen();
|
|
473
481
|
const position = () => typeof props.position === "function" ? props.position() : props.position ?? (props.align === "end" ? "bottom-left" : "bottom-right");
|
|
474
482
|
const place = () => {
|
|
475
|
-
|
|
476
|
-
|
|
483
|
+
const at = anchor ?? triggerRef;
|
|
484
|
+
if (!at || !menuRef) return;
|
|
485
|
+
const rect = dropdownPosition(at.getBoundingClientRect(), menuRef.getBoundingClientRect(), position(), {
|
|
477
486
|
width: window.innerWidth,
|
|
478
487
|
height: window.innerHeight
|
|
479
488
|
});
|
|
@@ -503,7 +512,7 @@ function DropdownRoot(props) {
|
|
|
503
512
|
};
|
|
504
513
|
const close = (restoreFocus = true) => {
|
|
505
514
|
// Before hiding, so the popover does not return focus on its own.
|
|
506
|
-
if (restoreFocus) returnFocus(triggerRef, triggerRing);
|
|
515
|
+
if (restoreFocus) returnFocus(originElement() ?? triggerRef, triggerRing);
|
|
507
516
|
if (menuRef?.matches(":popover-open")) menuRef.hidePopover();
|
|
508
517
|
// Like `open`, expose the closed state now: the toggle event can arrive after the next key press, and a trigger
|
|
509
518
|
// that still reads as open would ignore Enter (Escape, then Enter at once, must reopen).
|
|
@@ -512,7 +521,7 @@ function DropdownRoot(props) {
|
|
|
512
521
|
};
|
|
513
522
|
const open = (focus = "first") => {
|
|
514
523
|
if (props.disabled || !menuRef || menuRef.matches(":popover-open")) return;
|
|
515
|
-
triggerRing = ringOnReturn(triggerRef);
|
|
524
|
+
triggerRing = ringOnReturn(originElement() ?? triggerRef);
|
|
516
525
|
// A lazy menu's entries exist before it shows, so it places and focuses them as any other.
|
|
517
526
|
setEntriesShown(true);
|
|
518
527
|
menuRef.showPopover();
|
|
@@ -534,6 +543,11 @@ function DropdownRoot(props) {
|
|
|
534
543
|
if (sheet) return;
|
|
535
544
|
const current = new AbortController();
|
|
536
545
|
sheet = current;
|
|
546
|
+
// A sheet opened without its trigger returns focus to its own target, which an entry may have moved,
|
|
547
|
+
// rather than to whatever had focus as it opened.
|
|
548
|
+
const anchored = origin !== undefined;
|
|
549
|
+
const ring = anchored && ringOnReturn(originElement());
|
|
550
|
+
if (anchored && document.activeElement instanceof HTMLElement) document.activeElement.blur();
|
|
537
551
|
// The sheet is this menu's open state: the trigger reports it and the owner hears both ends.
|
|
538
552
|
setInternalOpen(true);
|
|
539
553
|
props.onOpenChange?.(true);
|
|
@@ -546,6 +560,10 @@ function DropdownRoot(props) {
|
|
|
546
560
|
signal: current.signal
|
|
547
561
|
}).finally(() => {
|
|
548
562
|
sheet = undefined;
|
|
563
|
+
// An entry that moved focus elsewhere, such as into a field, keeps it.
|
|
564
|
+
const target = anchored ? originElement() : undefined;
|
|
565
|
+
const focused = document.activeElement;
|
|
566
|
+
if (target?.isConnected && (!focused || focused === document.body)) returnFocus(target, ring);
|
|
549
567
|
setInternalOpen(false);
|
|
550
568
|
props.onOpenChange?.(false);
|
|
551
569
|
props.onClose?.();
|
|
@@ -560,7 +578,7 @@ function DropdownRoot(props) {
|
|
|
560
578
|
event.preventDefault();
|
|
561
579
|
} else if (event.key === "Escape") {
|
|
562
580
|
event.preventDefault();
|
|
563
|
-
returnFocus(triggerRef, triggerRing);
|
|
581
|
+
returnFocus(originElement() ?? triggerRef, triggerRing);
|
|
564
582
|
requestOpen(false);
|
|
565
583
|
} else if (event.key === "Tab") {
|
|
566
584
|
requestOpen(false);
|
|
@@ -573,7 +591,10 @@ function DropdownRoot(props) {
|
|
|
573
591
|
registerTrigger: element => {
|
|
574
592
|
triggerRef = element;
|
|
575
593
|
},
|
|
576
|
-
toggle: () =>
|
|
594
|
+
toggle: () => {
|
|
595
|
+
if (!isOpen()) anchor = origin = undefined;
|
|
596
|
+
requestOpen(!isOpen());
|
|
597
|
+
},
|
|
577
598
|
triggerKeyDown: event => {
|
|
578
599
|
if (!["Enter", " ", "ArrowDown", "ArrowUp"].includes(event.key)) return;
|
|
579
600
|
event.preventDefault();
|
|
@@ -582,6 +603,7 @@ function DropdownRoot(props) {
|
|
|
582
603
|
focusMenuItem(menuRef, event.key === "ArrowUp" ? -1 : 0);
|
|
583
604
|
return;
|
|
584
605
|
}
|
|
606
|
+
anchor = origin = undefined;
|
|
585
607
|
keyFocus = event.key === "ArrowUp" ? "last" : "first";
|
|
586
608
|
requestOpen(true, keyFocus);
|
|
587
609
|
keyFocus = false;
|
|
@@ -598,6 +620,16 @@ function DropdownRoot(props) {
|
|
|
598
620
|
sheet?.abort();
|
|
599
621
|
if (mounted) close(false);
|
|
600
622
|
});
|
|
623
|
+
props.openAt?.((at, focus) => {
|
|
624
|
+
if (isOpen()) return;
|
|
625
|
+
anchor = at;
|
|
626
|
+
origin = focus;
|
|
627
|
+
requestOpen(true);
|
|
628
|
+
});
|
|
629
|
+
props.closeWith?.(() => {
|
|
630
|
+
sheet?.abort();
|
|
631
|
+
if (isOpen()) close();
|
|
632
|
+
});
|
|
601
633
|
onMount(() => {
|
|
602
634
|
mounted = true;
|
|
603
635
|
if (props.open) open(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["actions/Dropdown.tsx"],"sourcesContent":["import {\n createContext,\n createEffect,\n createSignal,\n createUniqueId,\n For,\n type JSX,\n mergeProps,\n onCleanup,\n onMount,\n Show,\n splitProps,\n untrack,\n useContext,\n} from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\nimport { Tooltip, type TooltipPlacement, useLabelTooltip } from \"../feedback/Tooltip\";\nimport { returnFocus, ringOnReturn } from \"../internal/focus-return\";\nimport { KeyedFor } from \"../internal/keyed-for\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { Button, type ButtonProps, type ButtonSize, type ButtonVariant, iconTitle } from \"./Button\";\nimport { focusMenuRow, focusRowSegment } from \"./menu-rows\";\nimport { openMenuSheet, prefersMenuSheet } from \"./menu-sheet\";\n\n// Resolved outside JSX: a conditional attribute compiles to a lazy memo, which would be created inside the click handler.\nconst selectAction = (item: { action?: () => void }) => item.action;\nconst closeOnSelectOf = (item: DropdownAction) => (\"closeOnSelect\" in item ? item.closeOnSelect : undefined);\nconst hrefOf = (item: DropdownAction) => (\"href\" in item ? item.href : undefined);\nconst externalOf = (item: DropdownAction) => (\"external\" in item ? item.external : undefined);\n\nexport type DropdownPosition = \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\" | \"right-start\";\n\nexport type DropdownActionBase = {\n class?: string;\n disabled?: boolean;\n icon?: string;\n image?: string;\n label: string;\n /**\n * Accessible name when it must say more than the visible label, such as the current value and what the next\n * activation does. It must contain the visible label.\n */\n ariaLabel?: string;\n description?: string;\n /** Quiet trailing information, such as a count. */\n trailing?: JSX.Element;\n variant?: \"danger\";\n};\n\nexport type DropdownAction =\n | (DropdownActionBase & {\n action: () => void;\n /**\n * Set `false` for an action that changes a value in place, such as cycling a setting: the menu stays open and\n * the focus stays on the row. Defaults to `true`.\n */\n closeOnSelect?: boolean;\n /**\n * In a phone sheet, run while the tap still counts as the person's gesture, before the sheet closes, as browsers\n * require for clipboard writes. Other actions run after the sheet has left the history. Such an action must\n * not navigate or open a dialog.\n */\n immediate?: boolean;\n href?: never;\n external?: never;\n })\n | (DropdownActionBase & {\n href: string;\n external?: boolean;\n /** Runs on a plain click instead of following the link; modified clicks, middle-click, and the link's menu keep it. */\n action?: () => void;\n })\n | (DropdownActionBase & {\n disabled: true;\n action?: never;\n href?: never;\n external?: never;\n });\n\n/** A second, smaller action at the end of a row, such as \"Only\" beside a checkbox; it keeps the menu open. */\nexport type DropdownSecondaryAction = {\n label: string;\n /** Accessible name when the visible label alone does not say what it acts on, such as \"Only Team Logistik\". */\n ariaLabel?: string;\n action: () => void;\n};\n\n/** Declarative radio or checkbox row for compact action menus. */\nexport type DropdownChoice = DropdownActionBase & {\n action: () => void;\n checked: boolean | (() => boolean);\n choice: \"checkbox\" | \"radio\";\n href?: string;\n closeOnSelect?: boolean;\n color?: string;\n /**\n * A second action at the end of the row. It shows while the row is hovered or focused, always on a touch screen,\n * and keeps its place when hidden, so the row never changes width. Right and Left move between the two.\n */\n secondary?: DropdownSecondaryAction;\n};\n\nexport type DropdownSection = {\n sectionLabel?: string;\n /**\n * `row` sets a few short radio choices, such as a sort direction, side by side as one segmented row. Give it a\n * `sectionLabel`: the label names the choice above the row and for screen readers.\n */\n layout?: \"row\";\n /** A quiet action at the end of the section label, such as \"All\"; it needs a `sectionLabel` and keeps the menu open. */\n labelAction?: DropdownSecondaryAction;\n items: readonly (DropdownAction | DropdownChoice)[];\n};\n\nexport type DropdownItem = DropdownAction | DropdownChoice | DropdownSection;\n\nexport type DropdownProps = {\n items: readonly DropdownItem[];\n children: JSX.Element;\n position?: DropdownPosition | (() => DropdownPosition);\n /** Larger menu rows and typography for touch. Defaults to `default`. */\n variant?: \"default\" | \"touch\";\n /**\n * Exact menu width as a CSS length. Without it the menu sizes to its longest\n * entry: at least `12rem` (`18rem` for touch), at most the viewport width\n * less `1rem` per side, where longer entries wrap.\n */\n width?: string;\n class?: string;\n menuClass?: string;\n onClose?: () => void;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n disabled?: boolean;\n label?: string;\n align?: \"start\" | \"end\";\n /**\n * `sheet` opens the same items as a bottom sheet on phones (below 48rem) instead of a menu beside the trigger.\n * Defaults to `menu`. A controlled menu (`open`) always stays a menu.\n */\n phone?: \"menu\" | \"sheet\";\n /** Content above the phone sheet's menu. `close` dismisses it with normal history and focus restoration. */\n sheetTop?: (close: () => void) => JSX.Element;\n /**\n * Renders the entries only once the menu first opens, for a menu repeated on every row of a long list: the page\n * then carries each row's trigger, not each row's entries. Fixed for the menu's lifetime.\n */\n lazy?: boolean;\n};\n\nexport type DropdownTriggerProps = Omit<\n ButtonProps,\n \"aria-controls\" | \"aria-expanded\" | \"aria-haspopup\" | \"children\" | \"disabled\" | \"onClick\" | \"onKeyDown\"\n> & {\n children: JSX.Element;\n /** Use `plain` when a specialized component class owns the complete visual treatment. */\n appearance?: \"button\" | \"plain\";\n disabled?: boolean;\n iconOnly?: boolean;\n label?: string;\n size?: ButtonSize;\n tooltip?: JSX.Element | false;\n tooltipDelay?: number;\n tooltipPlacement?: TooltipPlacement;\n variant?: ButtonVariant;\n};\n\nexport type DropdownItemProps = {\n children: JSX.Element;\n closeOnSelect?: boolean;\n ariaLabel?: string;\n icon?: string;\n image?: string;\n description?: string;\n /** Quiet trailing information, such as a count. */\n trailing?: JSX.Element;\n disabled?: boolean;\n danger?: boolean;\n variant?: \"danger\";\n href?: string;\n external?: boolean;\n /** Runs when the item is chosen. With `href`, a plain click runs it instead of following the link. */\n onSelect?: () => void;\n class?: string;\n};\n\ntype MenuContextValue = {\n close: (restoreFocus?: boolean) => void;\n};\n\ntype DropdownContextValue = {\n disabled: () => boolean;\n menuId: string;\n open: () => boolean;\n registerTrigger: (element: HTMLButtonElement) => void;\n toggle: () => void;\n triggerKeyDown: JSX.EventHandlerUnion<HTMLButtonElement, KeyboardEvent>;\n};\n\nconst MenuContext = createContext<MenuContextValue>();\nconst DropdownContext = createContext<DropdownContextValue>();\n\nconst actionableItems = (menu: HTMLElement | undefined): HTMLElement[] =>\n menu\n ? Array.from(\n menu.querySelectorAll<HTMLElement>(\n [\n \"[role='menuitem']:not([aria-disabled='true'])\",\n \"[role='menuitemcheckbox']:not([aria-disabled='true'])\",\n \"[role='menuitemradio']:not([aria-disabled='true'])\",\n ].join(\", \"),\n ),\n )\n : [];\n\nconst focusMenuItem = (menu: HTMLElement | undefined, index: number): void => {\n const items = actionableItems(menu).filter((item) => !item.classList.contains(\"k2b-dropdown__secondary\"));\n if (items.length === 0) return;\n items[(index + items.length) % items.length]?.focus();\n};\n\nexport const dropdownPosition = (\n trigger: DOMRect,\n menu: Pick<DOMRect, \"width\" | \"height\">,\n position: DropdownPosition,\n viewport: { width: number; height: number },\n gap = 4,\n): { left: number; top: number } => {\n let left = trigger.left;\n let top = trigger.bottom + gap;\n\n if (position === \"bottom-left\" || position === \"top-left\") left = trigger.right - menu.width;\n if (position === \"top-right\" || position === \"top-left\") top = trigger.top - menu.height - gap;\n if (position === \"right-start\") {\n left = trigger.right + gap;\n top = trigger.top;\n }\n\n return {\n left: Math.max(8, Math.min(left, viewport.width - menu.width - 8)),\n top: Math.max(8, Math.min(top, viewport.height - menu.height - 8)),\n };\n};\n\nconst itemContent = (props: {\n description?: string;\n icon?: string;\n image?: string;\n trailing?: JSX.Element;\n children: JSX.Element;\n}): JSX.Element => (\n <>\n <Show when={props.image} fallback={<Show when={props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>}>\n {(image) => <img class=\"k2b-dropdown__image\" src={image()} alt=\"\" />}\n </Show>\n <span class=\"k2b-dropdown__copy\">\n <span>{props.children}</span>\n <Show when={props.description}>{(description) => <small>{description()}</small>}</Show>\n </span>\n {props.trailing}\n </>\n);\n\nexport function DropdownItem(props: DropdownItemProps): JSX.Element {\n const menu = useContext(MenuContext);\n const danger = () => props.danger || props.variant === \"danger\";\n const content = itemContent(props);\n\n return (\n <Show\n when={!props.disabled ? props.href : undefined}\n fallback={\n <button\n type=\"button\"\n role=\"menuitem\"\n aria-label={props.ariaLabel}\n tabIndex={-1}\n class={`k2b-dropdown__item ${props.class ?? \"\"}`}\n data-danger={danger() ? \"true\" : undefined}\n disabled={props.disabled}\n aria-disabled={props.disabled ? \"true\" : undefined}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (props.closeOnSelect !== false) menu?.close();\n props.onSelect?.();\n }}\n >\n {content}\n </button>\n }\n >\n {(href) => (\n <a\n href={href()}\n target={props.external ? \"_blank\" : undefined}\n rel={props.external ? \"noopener noreferrer\" : undefined}\n role=\"menuitem\"\n aria-label={props.ariaLabel}\n tabIndex={-1}\n class={`k2b-dropdown__item ${props.class ?? \"\"}`}\n data-danger={danger() ? \"true\" : undefined}\n onClick={(event) => {\n // With `onSelect`, a plain click runs it in place of the link; a modified click keeps its browser meaning.\n if (props.onSelect && !(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {\n event.preventDefault();\n menu?.close();\n props.onSelect();\n return;\n }\n menu?.close(false);\n }}\n >\n {content}\n </a>\n )}\n </Show>\n );\n}\n\nfunction DropdownChoiceItem(props: DropdownChoice): JSX.Element {\n return (\n <Show when={props.secondary} fallback={<DropdownChoiceRow {...props} />}>\n {(secondary) => (\n <div class=\"k2b-dropdown__pair\">\n <DropdownChoiceRow {...props} />\n <DropdownSecondaryButton {...secondary()} class=\"k2b-dropdown__secondary\" />\n </div>\n )}\n </Show>\n );\n}\n\nfunction DropdownSecondaryButton(props: DropdownSecondaryAction & { class: string }): JSX.Element {\n return (\n <button\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n class={props.class}\n aria-label={props.ariaLabel}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n props.action();\n }}\n >\n {props.label}\n </button>\n );\n}\n\nfunction DropdownChoiceRow(props: DropdownChoice): JSX.Element {\n const menu = useContext(MenuContext);\n const checked = () => (typeof props.checked === \"function\" ? props.checked() : props.checked);\n let element: HTMLElement | undefined;\n return (\n <Dynamic\n ref={(node: HTMLAnchorElement | HTMLButtonElement) => {\n element = node;\n }}\n component={!props.disabled && props.href ? \"a\" : \"button\"}\n href={!props.disabled ? props.href : undefined}\n type={!props.disabled && props.href ? undefined : \"button\"}\n role={props.choice === \"checkbox\" ? \"menuitemcheckbox\" : \"menuitemradio\"}\n aria-label={props.ariaLabel}\n aria-checked={checked()}\n aria-disabled={props.disabled ? \"true\" : undefined}\n tabIndex={-1}\n class={`k2b-dropdown__item ${props.class ?? \"\"}`}\n data-selected={checked() ? \"true\" : undefined}\n disabled={props.disabled}\n onClick={(event: MouseEvent) => {\n if (props.href && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {\n menu?.close(false);\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n if (props.closeOnSelect !== false) menu?.close();\n props.action();\n }}\n onKeyDown={(event: KeyboardEvent) => {\n // A link answers only Enter; as a menu choice it also answers Space, like the button form.\n if (event.key !== \" \" || props.disabled || !props.href) return;\n event.preventDefault();\n element?.click();\n }}\n >\n <Show when={props.choice === \"checkbox\"}>\n <span class=\"k2b-dropdown__checkbox\" aria-hidden=\"true\">\n <Show when={checked()}>\n <i class=\"ti ti-check\" />\n </Show>\n </span>\n </Show>\n <Show when={props.image} fallback={<Show when={props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>}>\n {(image) => <img class=\"k2b-dropdown__image\" src={image()} alt=\"\" />}\n </Show>\n <Show when={props.color}>\n {(color) => <span class=\"k2b-dropdown__color\" style={{ \"--k2b-dropdown-color\": color() }} aria-hidden=\"true\" />}\n </Show>\n <span class=\"k2b-dropdown__copy\">\n <span>{props.label}</span>\n <Show when={props.description}>{(description) => <small>{description()}</small>}</Show>\n </span>\n {props.trailing}\n {/* Always present for radios, so selecting the widest entry cannot widen a content-sized menu. */}\n <Show when={props.choice === \"radio\"}>\n <i class=\"ti ti-check k2b-dropdown__check\" data-hidden={checked() ? undefined : \"true\"} aria-hidden=\"true\" />\n </Show>\n </Dynamic>\n );\n}\n\nexport function DropdownItems(props: { items: readonly DropdownItem[]; close: (restoreFocus?: boolean) => void }): JSX.Element {\n const messages = useUiMessages();\n // Rows read their current item: a host that rebuilds equal items while the menu is open keeps each row element (#2140).\n const renderItem = (item: () => DropdownAction | DropdownChoice): JSX.Element => {\n const initial = untrack(item);\n if (\"choice\" in initial) return <DropdownChoiceItem {...mergeProps(() => item() as DropdownChoice)} />;\n const action = () => item() as DropdownAction;\n return (\n <DropdownItem\n ariaLabel={action().ariaLabel}\n closeOnSelect={closeOnSelectOf(action())}\n icon={action().icon}\n image={action().image}\n description={action().description}\n trailing={action().trailing}\n variant={action().variant}\n disabled={action().disabled}\n class={action().class}\n href={hrefOf(action())}\n external={externalOf(action())}\n onSelect={selectAction(action())}\n >\n {action().label}\n </DropdownItem>\n );\n };\n\n return (\n <MenuContext.Provider value={{ close: props.close }}>\n <KeyedFor each={props.items} by={(item) => (\"items\" in item ? `section:${item.sectionLabel ?? \"\"}` : `item:${item.label}`)}>\n {(current, index) => {\n const item = current();\n return (\n <Show when={\"items\" in item} fallback={renderItem(current as () => DropdownAction | DropdownChoice)}>\n <div\n class=\"k2b-dropdown__section\"\n data-divided={index() > 0 ? \"true\" : undefined}\n role=\"group\"\n // A row of choices is no set of actions: without a label it stays unnamed rather than misnamed.\n aria-label={\n (current() as DropdownSection).sectionLabel ??\n ((current() as DropdownSection).layout === \"row\" ? undefined : messages().actions)\n }\n >\n <Show when={(current() as DropdownSection).sectionLabel}>\n {(label) => (\n <Show when={(current() as DropdownSection).labelAction} fallback={<div class=\"k2b-dropdown__label\">{label()}</div>}>\n {(action) => (\n <div class=\"k2b-dropdown__label k2b-dropdown__label--action\">\n <span>{label()}</span>\n <DropdownSecondaryButton {...action()} class=\"k2b-dropdown__label-action\" />\n </div>\n )}\n </Show>\n )}\n </Show>\n <Show\n when={(current() as DropdownSection).layout === \"row\"}\n fallback={\n <KeyedFor each={(current() as DropdownSection).items} by={(row) => row.label}>\n {renderItem}\n </KeyedFor>\n }\n >\n <div class=\"k2b-dropdown__row\">\n <KeyedFor each={(current() as DropdownSection).items} by={(row) => row.label}>\n {renderItem}\n </KeyedFor>\n </div>\n </Show>\n </div>\n </Show>\n );\n }}\n </KeyedFor>\n </MenuContext.Provider>\n );\n}\n\nfunction DropdownTrigger(props: DropdownTriggerProps): JSX.Element {\n const context = useContext(DropdownContext);\n if (!context) throw new Error(\"Dropdown.Trigger must be used inside Dropdown.Root\");\n const [local, rest] = splitProps(props, [\n \"appearance\",\n \"children\",\n \"class\",\n \"disabled\",\n \"iconOnly\",\n \"label\",\n \"ref\",\n \"size\",\n \"tabIndex\",\n \"title\",\n \"tooltip\",\n \"tooltipDelay\",\n \"tooltipPlacement\",\n \"type\",\n \"variant\",\n ]);\n let target: HTMLButtonElement | undefined;\n const disabled = () => Boolean(context.disabled() || local.disabled);\n // An icon-only trigger shows its label as a hint, like IconButton.\n const tooltip = useLabelTooltip(\n () => local.tooltip,\n () => (local.iconOnly ? (local.title ?? local.label) : undefined),\n );\n const register = (element: HTMLButtonElement) => {\n target = element;\n context.registerTrigger(element);\n if (typeof local.ref === \"function\") local.ref(element);\n };\n const click: JSX.EventHandlerUnion<HTMLButtonElement, MouseEvent> = (event) => {\n event.stopPropagation();\n context.toggle();\n };\n\n if (local.appearance !== \"plain\") {\n return (\n <Button\n {...rest}\n ref={register}\n aria-controls={context.menuId}\n aria-expanded={context.open()}\n aria-haspopup=\"menu\"\n aria-label={local.label}\n disabled={disabled()}\n tabIndex={disabled() ? -1 : local.tabIndex}\n onClick={click}\n onKeyDown={context.triggerKeyDown}\n type={local.type ?? \"button\"}\n class={`${local.iconOnly ? \"k2b-icon-button\" : \"\"} k2b-dropdown__trigger ${local.class ?? \"\"}`}\n size={local.size}\n variant={local.variant ?? (local.iconOnly ? \"ghost\" : undefined)}\n title={iconTitle(local.title, tooltip())}\n tooltip={tooltip()}\n tooltipDelay={local.tooltipDelay}\n tooltipPlacement={local.tooltipPlacement}\n >\n {local.children}\n </Button>\n );\n }\n\n return (\n <>\n <button\n {...rest}\n ref={register}\n aria-controls={context.menuId}\n aria-expanded={context.open()}\n aria-haspopup=\"menu\"\n aria-label={local.label}\n disabled={disabled()}\n tabIndex={disabled() ? -1 : local.tabIndex}\n onClick={click}\n onKeyDown={context.triggerKeyDown}\n type={local.type ?? \"button\"}\n class={`k2b-dropdown__trigger ${local.class ?? \"\"}`}\n title={iconTitle(local.title, tooltip())}\n >\n {local.children}\n </button>\n <Show when={tooltip() !== false && tooltip() !== undefined}>\n <Tooltip\n content={tooltip() as JSX.Element}\n target={() => target}\n delay={local.tooltipDelay}\n disabled={disabled()}\n placement={local.tooltipPlacement}\n />\n </Show>\n </>\n );\n}\n\n/** Accessible top-layer menu with explicit trigger ownership. */\nfunction DropdownRoot(props: DropdownProps): JSX.Element {\n const messages = useUiMessages();\n const locale = useLocale();\n /** The open phone sheet's cancel switch: it closes when the menu goes or is disabled, as the popover does. */\n let sheet: AbortController | undefined;\n const id = createUniqueId().replace(/[^a-zA-Z0-9_-]/g, \"-\");\n const menuId = `k2b-dropdown-${id}`;\n const [internalOpen, setInternalOpen] = createSignal(false);\n const [entriesShown, setEntriesShown] = createSignal(!props.lazy);\n let triggerRef: HTMLButtonElement | undefined;\n let menuRef: HTMLDivElement | undefined;\n let triggerRing = true;\n let mounted = false;\n /** Where a key on the trigger asked the focus to go; a controlled menu opens later, in its owner's update. */\n let keyFocus: \"first\" | \"last\" | false = false;\n let viewportListenersAttached = false;\n let resizeObserver: ResizeObserver | undefined;\n\n const isOpen = () => props.open ?? internalOpen();\n const position = (): DropdownPosition =>\n typeof props.position === \"function\" ? props.position() : (props.position ?? (props.align === \"end\" ? \"bottom-left\" : \"bottom-right\"));\n\n const place = () => {\n if (!triggerRef || !menuRef) return;\n const rect = dropdownPosition(triggerRef.getBoundingClientRect(), menuRef.getBoundingClientRect(), position(), {\n width: window.innerWidth,\n height: window.innerHeight,\n });\n menuRef.style.left = `${rect.left}px`;\n menuRef.style.top = `${rect.top}px`;\n };\n const reposition = () => {\n if (isOpen()) place();\n };\n const attachViewportListeners = () => {\n if (viewportListenersAttached) return;\n viewportListenersAttached = true;\n window.addEventListener(\"resize\", reposition);\n window.addEventListener(\"scroll\", reposition, true);\n // A content-sized menu changes size when its items change while it is open.\n if (menuRef && typeof ResizeObserver !== \"undefined\") {\n resizeObserver ??= new ResizeObserver(reposition);\n resizeObserver.observe(menuRef);\n }\n };\n const detachViewportListeners = () => {\n if (!viewportListenersAttached) return;\n viewportListenersAttached = false;\n window.removeEventListener(\"resize\", reposition);\n window.removeEventListener(\"scroll\", reposition, true);\n resizeObserver?.disconnect();\n };\n const close = (restoreFocus = true) => {\n // Before hiding, so the popover does not return focus on its own.\n if (restoreFocus) returnFocus(triggerRef, triggerRing);\n if (menuRef?.matches(\":popover-open\")) menuRef.hidePopover();\n // Like `open`, expose the closed state now: the toggle event can arrive after the next key press, and a trigger\n // that still reads as open would ignore Enter (Escape, then Enter at once, must reopen).\n setInternalOpen(false);\n detachViewportListeners();\n };\n const open = (focus: \"first\" | \"last\" | false = \"first\") => {\n if (props.disabled || !menuRef || menuRef.matches(\":popover-open\")) return;\n triggerRing = ringOnReturn(triggerRef);\n // A lazy menu's entries exist before it shows, so it places and focuses them as any other.\n setEntriesShown(true);\n menuRef.showPopover();\n // The toggle event arrives a task later; expose the open state before focus moves into the menu.\n setInternalOpen(true);\n attachViewportListeners();\n place();\n queueMicrotask(() => {\n if (focus) focusMenuItem(menuRef, focus === \"first\" ? 0 : -1);\n });\n };\n const requestOpen = (next: boolean, focus: \"first\" | \"last\" | false = \"first\") => {\n if (props.disabled && next) return;\n if (props.open !== undefined) {\n props.onOpenChange?.(next);\n return;\n }\n if (next && props.phone === \"sheet\" && prefersMenuSheet()) {\n if (sheet) return;\n const current = new AbortController();\n sheet = current;\n // The sheet is this menu's open state: the trigger reports it and the owner hears both ends.\n setInternalOpen(true);\n props.onOpenChange?.(true);\n void openMenuSheet({\n Items: DropdownItems,\n items: props.items,\n label: props.label ?? messages().dropdownMenu,\n locale: locale(),\n top: props.sheetTop,\n signal: current.signal,\n }).finally(() => {\n sheet = undefined;\n setInternalOpen(false);\n props.onOpenChange?.(false);\n props.onClose?.();\n });\n return;\n }\n if (next) open(focus);\n else close(false);\n };\n const handleMenuKeyDown = (event: KeyboardEvent) => {\n const items = actionableItems(menuRef);\n if (focusMenuRow(items, event.key) || focusRowSegment(items, event.key)) {\n event.preventDefault();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n returnFocus(triggerRef, triggerRing);\n requestOpen(false);\n } else if (event.key === \"Tab\") {\n requestOpen(false);\n }\n };\n\n const context: DropdownContextValue = {\n disabled: () => Boolean(props.disabled),\n menuId,\n open: isOpen,\n registerTrigger: (element) => {\n triggerRef = element;\n },\n toggle: () => requestOpen(!isOpen()),\n triggerKeyDown: (event) => {\n if (![\"Enter\", \" \", \"ArrowDown\", \"ArrowUp\"].includes(event.key)) return;\n event.preventDefault();\n event.stopPropagation();\n if (isOpen()) {\n focusMenuItem(menuRef, event.key === \"ArrowUp\" ? -1 : 0);\n return;\n }\n keyFocus = event.key === \"ArrowUp\" ? \"last\" : \"first\";\n requestOpen(true, keyFocus);\n keyFocus = false;\n },\n };\n\n createEffect(() => {\n const controlled = props.open;\n if (!mounted || controlled === undefined || !menuRef) return;\n if (controlled && !menuRef.matches(\":popover-open\")) open(keyFocus);\n if (!controlled && menuRef.matches(\":popover-open\")) close(false);\n });\n createEffect(() => {\n if (!props.disabled) return;\n sheet?.abort();\n if (mounted) close(false);\n });\n onMount(() => {\n mounted = true;\n if (props.open) open(false);\n onCleanup(detachViewportListeners);\n });\n onCleanup(() => sheet?.abort());\n\n return (\n <DropdownContext.Provider value={context}>\n <span class={`k2b-dropdown ${props.class ?? \"\"}`}>\n {props.children}\n <div\n ref={menuRef}\n id={menuId}\n popover=\"auto\"\n role=\"menu\"\n aria-label={props.label ?? messages().dropdownMenu}\n class={`k2b-dropdown__menu ${props.menuClass ?? \"\"}`}\n style={props.width ? { \"--k2b-dropdown-width\": props.width } : undefined}\n data-width={props.width ? \"fixed\" : undefined}\n data-variant={props.variant ?? \"default\"}\n data-position={position()}\n onKeyDown={handleMenuKeyDown}\n onToggle={(event) => {\n const nextOpen = (event as ToggleEvent).newState === \"open\";\n const wasOpen = (event as ToggleEvent).oldState === \"open\";\n setInternalOpen(nextOpen);\n if (nextOpen) setEntriesShown(true);\n if (nextOpen) attachViewportListeners();\n else detachViewportListeners();\n if (props.open === undefined || props.open !== nextOpen) props.onOpenChange?.(nextOpen);\n if (wasOpen && !nextOpen) props.onClose?.();\n if (!nextOpen && props.open === true) queueMicrotask(() => props.open === true && open(false));\n }}\n >\n <Show when={entriesShown()}>\n <DropdownItems items={props.items} close={close} />\n </Show>\n </div>\n </span>\n </DropdownContext.Provider>\n );\n}\n\ntype DropdownComponent = ((props: DropdownProps) => JSX.Element) & {\n Root: (props: DropdownProps) => JSX.Element;\n Trigger: (props: DropdownTriggerProps) => JSX.Element;\n Item: (props: DropdownItemProps) => JSX.Element;\n};\n\nexport const Dropdown = DropdownRoot as DropdownComponent;\nDropdown.Root = DropdownRoot;\nDropdown.Trigger = DropdownTrigger;\nDropdown.Item = DropdownItem;\n\nexport default Dropdown;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["actions/Dropdown.tsx"],"sourcesContent":["import {\n createContext,\n createEffect,\n createSignal,\n createUniqueId,\n For,\n type JSX,\n mergeProps,\n onCleanup,\n onMount,\n Show,\n splitProps,\n untrack,\n useContext,\n} from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\nimport { Tooltip, type TooltipPlacement, useLabelTooltip } from \"../feedback/Tooltip\";\nimport { returnFocus, ringOnReturn } from \"../internal/focus-return\";\nimport { KeyedFor } from \"../internal/keyed-for\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { Button, type ButtonProps, type ButtonSize, type ButtonVariant, iconTitle } from \"./Button\";\nimport { focusMenuRow, focusRowSegment } from \"./menu-rows\";\nimport { openMenuSheet, prefersMenuSheet } from \"./menu-sheet\";\n\n// Resolved outside JSX: a conditional attribute compiles to a lazy memo, which would be created inside the click handler.\nconst selectAction = (item: { action?: () => void }) => item.action;\nconst closeOnSelectOf = (item: DropdownAction) => (\"closeOnSelect\" in item ? item.closeOnSelect : undefined);\nconst hrefOf = (item: DropdownAction) => (\"href\" in item ? item.href : undefined);\nconst externalOf = (item: DropdownAction) => (\"external\" in item ? item.external : undefined);\n\nexport type DropdownPosition = \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\" | \"right-start\";\n/** Where a menu opened without its trigger appears: an element, or any box such as a point inside one. */\nexport type DropdownAnchor = { getBoundingClientRect(): Pick<DOMRect, \"left\" | \"top\" | \"right\" | \"bottom\"> };\n/** Where focus returns as a menu opened by `openAt` closes, read at that moment when it is a function. */\nexport type DropdownReturnFocus = HTMLElement | (() => HTMLElement | undefined);\n\nexport type DropdownActionBase = {\n class?: string;\n disabled?: boolean;\n icon?: string;\n image?: string;\n label: string;\n /**\n * Accessible name when it must say more than the visible label, such as the current value and what the next\n * activation does. It must contain the visible label.\n */\n ariaLabel?: string;\n description?: string;\n /** Quiet trailing information, such as a count. */\n trailing?: JSX.Element;\n variant?: \"danger\";\n};\n\nexport type DropdownAction =\n | (DropdownActionBase & {\n action: () => void;\n /**\n * Set `false` for an action that changes a value in place, such as cycling a setting: the menu stays open and\n * the focus stays on the row. Defaults to `true`.\n */\n closeOnSelect?: boolean;\n /**\n * In a phone sheet, run while the tap still counts as the person's gesture, before the sheet closes, as browsers\n * require for clipboard writes. Other actions run after the sheet has left the history. Such an action must\n * not navigate or open a dialog.\n */\n immediate?: boolean;\n href?: never;\n external?: never;\n })\n | (DropdownActionBase & {\n href: string;\n external?: boolean;\n /** Runs on a plain click instead of following the link; modified clicks, middle-click, and the link's menu keep it. */\n action?: () => void;\n })\n | (DropdownActionBase & {\n disabled: true;\n action?: never;\n href?: never;\n external?: never;\n });\n\n/** A second, smaller action at the end of a row, such as \"Only\" beside a checkbox; it keeps the menu open. */\nexport type DropdownSecondaryAction = {\n label: string;\n /** Accessible name when the visible label alone does not say what it acts on, such as \"Only Team Logistik\". */\n ariaLabel?: string;\n action: () => void;\n};\n\n/** Declarative radio or checkbox row for compact action menus. */\nexport type DropdownChoice = DropdownActionBase & {\n action: () => void;\n checked: boolean | (() => boolean);\n choice: \"checkbox\" | \"radio\";\n href?: string;\n closeOnSelect?: boolean;\n color?: string;\n /**\n * A second action at the end of the row. It shows while the row is hovered or focused, always on a touch screen,\n * and keeps its place when hidden, so the row never changes width. Right and Left move between the two.\n */\n secondary?: DropdownSecondaryAction;\n};\n\nexport type DropdownSection = {\n sectionLabel?: string;\n /**\n * `row` sets a few short radio choices, such as a sort direction, side by side as one segmented row. Give it a\n * `sectionLabel`: the label names the choice above the row and for screen readers.\n */\n layout?: \"row\";\n /** A quiet action at the end of the section label, such as \"All\"; it needs a `sectionLabel` and keeps the menu open. */\n labelAction?: DropdownSecondaryAction;\n items: readonly (DropdownAction | DropdownChoice)[];\n};\n\nexport type DropdownItem = DropdownAction | DropdownChoice | DropdownSection;\n\nexport type DropdownProps = {\n items: readonly DropdownItem[];\n children: JSX.Element;\n position?: DropdownPosition | (() => DropdownPosition);\n /** Larger menu rows and typography for touch. Defaults to `default`. */\n variant?: \"default\" | \"touch\";\n /**\n * Exact menu width as a CSS length. Without it the menu sizes to its longest\n * entry: at least `12rem` (`18rem` for touch), at most the viewport width\n * less `1rem` per side, where longer entries wrap.\n */\n width?: string;\n class?: string;\n menuClass?: string;\n onClose?: () => void;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n disabled?: boolean;\n label?: string;\n align?: \"start\" | \"end\";\n /**\n * `sheet` opens the same items as a bottom sheet on phones (below 48rem) instead of a menu beside the trigger.\n * Defaults to `menu`. A controlled menu (`open`) always stays a menu.\n */\n phone?: \"menu\" | \"sheet\";\n /** Content above the phone sheet's menu. `close` dismisses it with normal history and focus restoration. */\n sheetTop?: (close: () => void) => JSX.Element;\n /**\n * Renders the entries only once the menu first opens, for a menu repeated on every row of a long list: the page\n * then carries each row's trigger, not each row's entries. Fixed for the menu's lifetime.\n */\n lazy?: boolean;\n /**\n * Receives `open`, which shows the menu without its trigger beside `anchor`, as for a context menu, a key or a\n * grip. Focus returns to `returnFocus` when the menu or sheet closes; pass a function when an entry can move the\n * place focus belongs to. Phones get the sheet as from the trigger.\n */\n openAt?: (open: (anchor: DropdownAnchor, returnFocus?: DropdownReturnFocus) => void) => void;\n /** Receives `close`, which closes the menu or sheet and returns focus. */\n closeWith?: (close: () => void) => void;\n};\n\nexport type DropdownTriggerProps = Omit<\n ButtonProps,\n \"aria-controls\" | \"aria-expanded\" | \"aria-haspopup\" | \"children\" | \"disabled\" | \"onClick\" | \"onKeyDown\"\n> & {\n children: JSX.Element;\n /** Use `plain` when a specialized component class owns the complete visual treatment. */\n appearance?: \"button\" | \"plain\";\n disabled?: boolean;\n iconOnly?: boolean;\n label?: string;\n size?: ButtonSize;\n tooltip?: JSX.Element | false;\n tooltipDelay?: number;\n tooltipPlacement?: TooltipPlacement;\n variant?: ButtonVariant;\n};\n\nexport type DropdownItemProps = {\n children: JSX.Element;\n closeOnSelect?: boolean;\n ariaLabel?: string;\n icon?: string;\n image?: string;\n description?: string;\n /** Quiet trailing information, such as a count. */\n trailing?: JSX.Element;\n disabled?: boolean;\n danger?: boolean;\n variant?: \"danger\";\n href?: string;\n external?: boolean;\n /** Runs when the item is chosen. With `href`, a plain click runs it instead of following the link. */\n onSelect?: () => void;\n class?: string;\n};\n\ntype MenuContextValue = {\n close: (restoreFocus?: boolean) => void;\n};\n\ntype DropdownContextValue = {\n disabled: () => boolean;\n menuId: string;\n open: () => boolean;\n registerTrigger: (element: HTMLButtonElement) => void;\n toggle: () => void;\n triggerKeyDown: JSX.EventHandlerUnion<HTMLButtonElement, KeyboardEvent>;\n};\n\nconst MenuContext = createContext<MenuContextValue>();\nconst DropdownContext = createContext<DropdownContextValue>();\n\nconst actionableItems = (menu: HTMLElement | undefined): HTMLElement[] =>\n menu\n ? Array.from(\n menu.querySelectorAll<HTMLElement>(\n [\n \"[role='menuitem']:not([aria-disabled='true'])\",\n \"[role='menuitemcheckbox']:not([aria-disabled='true'])\",\n \"[role='menuitemradio']:not([aria-disabled='true'])\",\n ].join(\", \"),\n ),\n )\n : [];\n\nconst focusMenuItem = (menu: HTMLElement | undefined, index: number): void => {\n const items = actionableItems(menu).filter((item) => !item.classList.contains(\"k2b-dropdown__secondary\"));\n if (items.length === 0) return;\n items[(index + items.length) % items.length]?.focus();\n};\n\nexport const dropdownPosition = (\n trigger: Pick<DOMRect, \"left\" | \"top\" | \"right\" | \"bottom\">,\n menu: Pick<DOMRect, \"width\" | \"height\">,\n position: DropdownPosition,\n viewport: { width: number; height: number },\n gap = 4,\n): { left: number; top: number } => {\n let left = trigger.left;\n let top = trigger.bottom + gap;\n\n if (position === \"bottom-left\" || position === \"top-left\") left = trigger.right - menu.width;\n if (position === \"top-right\" || position === \"top-left\") top = trigger.top - menu.height - gap;\n if (position === \"right-start\") {\n left = trigger.right + gap;\n top = trigger.top;\n }\n\n return {\n left: Math.max(8, Math.min(left, viewport.width - menu.width - 8)),\n top: Math.max(8, Math.min(top, viewport.height - menu.height - 8)),\n };\n};\n\nconst itemContent = (props: {\n description?: string;\n icon?: string;\n image?: string;\n trailing?: JSX.Element;\n children: JSX.Element;\n}): JSX.Element => (\n <>\n <Show when={props.image} fallback={<Show when={props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>}>\n {(image) => <img class=\"k2b-dropdown__image\" src={image()} alt=\"\" />}\n </Show>\n <span class=\"k2b-dropdown__copy\">\n <span>{props.children}</span>\n <Show when={props.description}>{(description) => <small>{description()}</small>}</Show>\n </span>\n {props.trailing}\n </>\n);\n\nexport function DropdownItem(props: DropdownItemProps): JSX.Element {\n const menu = useContext(MenuContext);\n const danger = () => props.danger || props.variant === \"danger\";\n const content = itemContent(props);\n\n return (\n <Show\n when={!props.disabled ? props.href : undefined}\n fallback={\n <button\n type=\"button\"\n role=\"menuitem\"\n aria-label={props.ariaLabel}\n tabIndex={-1}\n class={`k2b-dropdown__item ${props.class ?? \"\"}`}\n data-danger={danger() ? \"true\" : undefined}\n disabled={props.disabled}\n aria-disabled={props.disabled ? \"true\" : undefined}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (props.closeOnSelect !== false) menu?.close();\n props.onSelect?.();\n }}\n >\n {content}\n </button>\n }\n >\n {(href) => (\n <a\n href={href()}\n target={props.external ? \"_blank\" : undefined}\n rel={props.external ? \"noopener noreferrer\" : undefined}\n role=\"menuitem\"\n aria-label={props.ariaLabel}\n tabIndex={-1}\n class={`k2b-dropdown__item ${props.class ?? \"\"}`}\n data-danger={danger() ? \"true\" : undefined}\n onClick={(event) => {\n // With `onSelect`, a plain click runs it in place of the link; a modified click keeps its browser meaning.\n if (props.onSelect && !(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {\n event.preventDefault();\n menu?.close();\n props.onSelect();\n return;\n }\n menu?.close(false);\n }}\n >\n {content}\n </a>\n )}\n </Show>\n );\n}\n\nfunction DropdownChoiceItem(props: DropdownChoice): JSX.Element {\n return (\n <Show when={props.secondary} fallback={<DropdownChoiceRow {...props} />}>\n {(secondary) => (\n <div class=\"k2b-dropdown__pair\">\n <DropdownChoiceRow {...props} />\n <DropdownSecondaryButton {...secondary()} class=\"k2b-dropdown__secondary\" />\n </div>\n )}\n </Show>\n );\n}\n\nfunction DropdownSecondaryButton(props: DropdownSecondaryAction & { class: string }): JSX.Element {\n return (\n <button\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n class={props.class}\n aria-label={props.ariaLabel}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n props.action();\n }}\n >\n {props.label}\n </button>\n );\n}\n\nfunction DropdownChoiceRow(props: DropdownChoice): JSX.Element {\n const menu = useContext(MenuContext);\n const checked = () => (typeof props.checked === \"function\" ? props.checked() : props.checked);\n let element: HTMLElement | undefined;\n return (\n <Dynamic\n ref={(node: HTMLAnchorElement | HTMLButtonElement) => {\n element = node;\n }}\n component={!props.disabled && props.href ? \"a\" : \"button\"}\n href={!props.disabled ? props.href : undefined}\n type={!props.disabled && props.href ? undefined : \"button\"}\n role={props.choice === \"checkbox\" ? \"menuitemcheckbox\" : \"menuitemradio\"}\n aria-label={props.ariaLabel}\n aria-checked={checked()}\n aria-disabled={props.disabled ? \"true\" : undefined}\n tabIndex={-1}\n class={`k2b-dropdown__item ${props.class ?? \"\"}`}\n data-selected={checked() ? \"true\" : undefined}\n disabled={props.disabled}\n onClick={(event: MouseEvent) => {\n if (props.href && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {\n menu?.close(false);\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n if (props.closeOnSelect !== false) menu?.close();\n props.action();\n }}\n onKeyDown={(event: KeyboardEvent) => {\n // A link answers only Enter; as a menu choice it also answers Space, like the button form.\n if (event.key !== \" \" || props.disabled || !props.href) return;\n event.preventDefault();\n element?.click();\n }}\n >\n <Show when={props.choice === \"checkbox\"}>\n <span class=\"k2b-dropdown__checkbox\" aria-hidden=\"true\">\n <Show when={checked()}>\n <i class=\"ti ti-check\" />\n </Show>\n </span>\n </Show>\n <Show when={props.image} fallback={<Show when={props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>}>\n {(image) => <img class=\"k2b-dropdown__image\" src={image()} alt=\"\" />}\n </Show>\n <Show when={props.color}>\n {(color) => <span class=\"k2b-dropdown__color\" style={{ \"--k2b-dropdown-color\": color() }} aria-hidden=\"true\" />}\n </Show>\n <span class=\"k2b-dropdown__copy\">\n <span>{props.label}</span>\n <Show when={props.description}>{(description) => <small>{description()}</small>}</Show>\n </span>\n {props.trailing}\n {/* Always present for radios, so selecting the widest entry cannot widen a content-sized menu. */}\n <Show when={props.choice === \"radio\"}>\n <i class=\"ti ti-check k2b-dropdown__check\" data-hidden={checked() ? undefined : \"true\"} aria-hidden=\"true\" />\n </Show>\n </Dynamic>\n );\n}\n\nexport function DropdownItems(props: { items: readonly DropdownItem[]; close: (restoreFocus?: boolean) => void }): JSX.Element {\n const messages = useUiMessages();\n // Rows read their current item: a host that rebuilds equal items while the menu is open keeps each row element (#2140).\n const renderItem = (item: () => DropdownAction | DropdownChoice): JSX.Element => {\n const initial = untrack(item);\n if (\"choice\" in initial) return <DropdownChoiceItem {...mergeProps(() => item() as DropdownChoice)} />;\n const action = () => item() as DropdownAction;\n return (\n <DropdownItem\n ariaLabel={action().ariaLabel}\n closeOnSelect={closeOnSelectOf(action())}\n icon={action().icon}\n image={action().image}\n description={action().description}\n trailing={action().trailing}\n variant={action().variant}\n disabled={action().disabled}\n class={action().class}\n href={hrefOf(action())}\n external={externalOf(action())}\n onSelect={selectAction(action())}\n >\n {action().label}\n </DropdownItem>\n );\n };\n\n return (\n <MenuContext.Provider value={{ close: props.close }}>\n <KeyedFor each={props.items} by={(item) => (\"items\" in item ? `section:${item.sectionLabel ?? \"\"}` : `item:${item.label}`)}>\n {(current, index) => {\n const item = current();\n return (\n <Show when={\"items\" in item} fallback={renderItem(current as () => DropdownAction | DropdownChoice)}>\n <div\n class=\"k2b-dropdown__section\"\n data-divided={index() > 0 ? \"true\" : undefined}\n role=\"group\"\n // A row of choices is no set of actions: without a label it stays unnamed rather than misnamed.\n aria-label={\n (current() as DropdownSection).sectionLabel ??\n ((current() as DropdownSection).layout === \"row\" ? undefined : messages().actions)\n }\n >\n <Show when={(current() as DropdownSection).sectionLabel}>\n {(label) => (\n <Show when={(current() as DropdownSection).labelAction} fallback={<div class=\"k2b-dropdown__label\">{label()}</div>}>\n {(action) => (\n <div class=\"k2b-dropdown__label k2b-dropdown__label--action\">\n <span>{label()}</span>\n <DropdownSecondaryButton {...action()} class=\"k2b-dropdown__label-action\" />\n </div>\n )}\n </Show>\n )}\n </Show>\n <Show\n when={(current() as DropdownSection).layout === \"row\"}\n fallback={\n <KeyedFor each={(current() as DropdownSection).items} by={(row) => row.label}>\n {renderItem}\n </KeyedFor>\n }\n >\n <div class=\"k2b-dropdown__row\">\n <KeyedFor each={(current() as DropdownSection).items} by={(row) => row.label}>\n {renderItem}\n </KeyedFor>\n </div>\n </Show>\n </div>\n </Show>\n );\n }}\n </KeyedFor>\n </MenuContext.Provider>\n );\n}\n\nfunction DropdownTrigger(props: DropdownTriggerProps): JSX.Element {\n const context = useContext(DropdownContext);\n if (!context) throw new Error(\"Dropdown.Trigger must be used inside Dropdown.Root\");\n const [local, rest] = splitProps(props, [\n \"appearance\",\n \"children\",\n \"class\",\n \"disabled\",\n \"iconOnly\",\n \"label\",\n \"ref\",\n \"size\",\n \"tabIndex\",\n \"title\",\n \"tooltip\",\n \"tooltipDelay\",\n \"tooltipPlacement\",\n \"type\",\n \"variant\",\n ]);\n let target: HTMLButtonElement | undefined;\n const disabled = () => Boolean(context.disabled() || local.disabled);\n // An icon-only trigger shows its label as a hint, like IconButton.\n const tooltip = useLabelTooltip(\n () => local.tooltip,\n () => (local.iconOnly ? (local.title ?? local.label) : undefined),\n );\n const register = (element: HTMLButtonElement) => {\n target = element;\n context.registerTrigger(element);\n if (typeof local.ref === \"function\") local.ref(element);\n };\n const click: JSX.EventHandlerUnion<HTMLButtonElement, MouseEvent> = (event) => {\n event.stopPropagation();\n context.toggle();\n };\n\n if (local.appearance !== \"plain\") {\n return (\n <Button\n {...rest}\n ref={register}\n aria-controls={context.menuId}\n aria-expanded={context.open()}\n aria-haspopup=\"menu\"\n aria-label={local.label}\n disabled={disabled()}\n tabIndex={disabled() ? -1 : local.tabIndex}\n onClick={click}\n onKeyDown={context.triggerKeyDown}\n type={local.type ?? \"button\"}\n class={`${local.iconOnly ? \"k2b-icon-button\" : \"\"} k2b-dropdown__trigger ${local.class ?? \"\"}`}\n size={local.size}\n variant={local.variant ?? (local.iconOnly ? \"ghost\" : undefined)}\n title={iconTitle(local.title, tooltip())}\n tooltip={tooltip()}\n tooltipDelay={local.tooltipDelay}\n tooltipPlacement={local.tooltipPlacement}\n >\n {local.children}\n </Button>\n );\n }\n\n return (\n <>\n <button\n {...rest}\n ref={register}\n aria-controls={context.menuId}\n aria-expanded={context.open()}\n aria-haspopup=\"menu\"\n aria-label={local.label}\n disabled={disabled()}\n tabIndex={disabled() ? -1 : local.tabIndex}\n onClick={click}\n onKeyDown={context.triggerKeyDown}\n type={local.type ?? \"button\"}\n class={`k2b-dropdown__trigger ${local.class ?? \"\"}`}\n title={iconTitle(local.title, tooltip())}\n >\n {local.children}\n </button>\n <Show when={tooltip() !== false && tooltip() !== undefined}>\n <Tooltip\n content={tooltip() as JSX.Element}\n target={() => target}\n delay={local.tooltipDelay}\n disabled={disabled()}\n placement={local.tooltipPlacement}\n />\n </Show>\n </>\n );\n}\n\n/** Accessible top-layer menu with explicit trigger ownership. */\nfunction DropdownRoot(props: DropdownProps): JSX.Element {\n const messages = useUiMessages();\n const locale = useLocale();\n /** The open phone sheet's cancel switch: it closes when the menu goes or is disabled, as the popover does. */\n let sheet: AbortController | undefined;\n const id = createUniqueId().replace(/[^a-zA-Z0-9_-]/g, \"-\");\n const menuId = `k2b-dropdown-${id}`;\n const [internalOpen, setInternalOpen] = createSignal(false);\n const [entriesShown, setEntriesShown] = createSignal(!props.lazy);\n let triggerRef: HTMLButtonElement | undefined;\n /** Set while the menu is open from `openAt`: it appears beside `anchor`, and focus returns to `origin`. */\n let anchor: DropdownAnchor | undefined;\n let origin: DropdownReturnFocus | undefined;\n const originElement = () => (typeof origin === \"function\" ? origin() : origin);\n let menuRef: HTMLDivElement | undefined;\n let triggerRing = true;\n let mounted = false;\n /** Where a key on the trigger asked the focus to go; a controlled menu opens later, in its owner's update. */\n let keyFocus: \"first\" | \"last\" | false = false;\n let viewportListenersAttached = false;\n let resizeObserver: ResizeObserver | undefined;\n\n const isOpen = () => props.open ?? internalOpen();\n const position = (): DropdownPosition =>\n typeof props.position === \"function\" ? props.position() : (props.position ?? (props.align === \"end\" ? \"bottom-left\" : \"bottom-right\"));\n\n const place = () => {\n const at = anchor ?? triggerRef;\n if (!at || !menuRef) return;\n const rect = dropdownPosition(at.getBoundingClientRect(), menuRef.getBoundingClientRect(), position(), {\n width: window.innerWidth,\n height: window.innerHeight,\n });\n menuRef.style.left = `${rect.left}px`;\n menuRef.style.top = `${rect.top}px`;\n };\n const reposition = () => {\n if (isOpen()) place();\n };\n const attachViewportListeners = () => {\n if (viewportListenersAttached) return;\n viewportListenersAttached = true;\n window.addEventListener(\"resize\", reposition);\n window.addEventListener(\"scroll\", reposition, true);\n // A content-sized menu changes size when its items change while it is open.\n if (menuRef && typeof ResizeObserver !== \"undefined\") {\n resizeObserver ??= new ResizeObserver(reposition);\n resizeObserver.observe(menuRef);\n }\n };\n const detachViewportListeners = () => {\n if (!viewportListenersAttached) return;\n viewportListenersAttached = false;\n window.removeEventListener(\"resize\", reposition);\n window.removeEventListener(\"scroll\", reposition, true);\n resizeObserver?.disconnect();\n };\n const close = (restoreFocus = true) => {\n // Before hiding, so the popover does not return focus on its own.\n if (restoreFocus) returnFocus(originElement() ?? triggerRef, triggerRing);\n if (menuRef?.matches(\":popover-open\")) menuRef.hidePopover();\n // Like `open`, expose the closed state now: the toggle event can arrive after the next key press, and a trigger\n // that still reads as open would ignore Enter (Escape, then Enter at once, must reopen).\n setInternalOpen(false);\n detachViewportListeners();\n };\n const open = (focus: \"first\" | \"last\" | false = \"first\") => {\n if (props.disabled || !menuRef || menuRef.matches(\":popover-open\")) return;\n triggerRing = ringOnReturn(originElement() ?? triggerRef);\n // A lazy menu's entries exist before it shows, so it places and focuses them as any other.\n setEntriesShown(true);\n menuRef.showPopover();\n // The toggle event arrives a task later; expose the open state before focus moves into the menu.\n setInternalOpen(true);\n attachViewportListeners();\n place();\n queueMicrotask(() => {\n if (focus) focusMenuItem(menuRef, focus === \"first\" ? 0 : -1);\n });\n };\n const requestOpen = (next: boolean, focus: \"first\" | \"last\" | false = \"first\") => {\n if (props.disabled && next) return;\n if (props.open !== undefined) {\n props.onOpenChange?.(next);\n return;\n }\n if (next && props.phone === \"sheet\" && prefersMenuSheet()) {\n if (sheet) return;\n const current = new AbortController();\n sheet = current;\n // A sheet opened without its trigger returns focus to its own target, which an entry may have moved,\n // rather than to whatever had focus as it opened.\n const anchored = origin !== undefined;\n const ring = anchored && ringOnReturn(originElement());\n if (anchored && document.activeElement instanceof HTMLElement) document.activeElement.blur();\n // The sheet is this menu's open state: the trigger reports it and the owner hears both ends.\n setInternalOpen(true);\n props.onOpenChange?.(true);\n void openMenuSheet({\n Items: DropdownItems,\n items: props.items,\n label: props.label ?? messages().dropdownMenu,\n locale: locale(),\n top: props.sheetTop,\n signal: current.signal,\n }).finally(() => {\n sheet = undefined;\n // An entry that moved focus elsewhere, such as into a field, keeps it.\n const target = anchored ? originElement() : undefined;\n const focused = document.activeElement;\n if (target?.isConnected && (!focused || focused === document.body)) returnFocus(target, ring);\n setInternalOpen(false);\n props.onOpenChange?.(false);\n props.onClose?.();\n });\n return;\n }\n if (next) open(focus);\n else close(false);\n };\n const handleMenuKeyDown = (event: KeyboardEvent) => {\n const items = actionableItems(menuRef);\n if (focusMenuRow(items, event.key) || focusRowSegment(items, event.key)) {\n event.preventDefault();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n returnFocus(originElement() ?? triggerRef, triggerRing);\n requestOpen(false);\n } else if (event.key === \"Tab\") {\n requestOpen(false);\n }\n };\n\n const context: DropdownContextValue = {\n disabled: () => Boolean(props.disabled),\n menuId,\n open: isOpen,\n registerTrigger: (element) => {\n triggerRef = element;\n },\n toggle: () => {\n if (!isOpen()) anchor = origin = undefined;\n requestOpen(!isOpen());\n },\n triggerKeyDown: (event) => {\n if (![\"Enter\", \" \", \"ArrowDown\", \"ArrowUp\"].includes(event.key)) return;\n event.preventDefault();\n event.stopPropagation();\n if (isOpen()) {\n focusMenuItem(menuRef, event.key === \"ArrowUp\" ? -1 : 0);\n return;\n }\n anchor = origin = undefined;\n keyFocus = event.key === \"ArrowUp\" ? \"last\" : \"first\";\n requestOpen(true, keyFocus);\n keyFocus = false;\n },\n };\n\n createEffect(() => {\n const controlled = props.open;\n if (!mounted || controlled === undefined || !menuRef) return;\n if (controlled && !menuRef.matches(\":popover-open\")) open(keyFocus);\n if (!controlled && menuRef.matches(\":popover-open\")) close(false);\n });\n createEffect(() => {\n if (!props.disabled) return;\n sheet?.abort();\n if (mounted) close(false);\n });\n props.openAt?.((at, focus) => {\n if (isOpen()) return;\n anchor = at;\n origin = focus;\n requestOpen(true);\n });\n props.closeWith?.(() => {\n sheet?.abort();\n if (isOpen()) close();\n });\n onMount(() => {\n mounted = true;\n if (props.open) open(false);\n onCleanup(detachViewportListeners);\n });\n onCleanup(() => sheet?.abort());\n\n return (\n <DropdownContext.Provider value={context}>\n <span class={`k2b-dropdown ${props.class ?? \"\"}`}>\n {props.children}\n <div\n ref={menuRef}\n id={menuId}\n popover=\"auto\"\n role=\"menu\"\n aria-label={props.label ?? messages().dropdownMenu}\n class={`k2b-dropdown__menu ${props.menuClass ?? \"\"}`}\n style={props.width ? { \"--k2b-dropdown-width\": props.width } : undefined}\n data-width={props.width ? \"fixed\" : undefined}\n data-variant={props.variant ?? \"default\"}\n data-position={position()}\n onKeyDown={handleMenuKeyDown}\n onToggle={(event) => {\n const nextOpen = (event as ToggleEvent).newState === \"open\";\n const wasOpen = (event as ToggleEvent).oldState === \"open\";\n setInternalOpen(nextOpen);\n if (nextOpen) setEntriesShown(true);\n if (nextOpen) attachViewportListeners();\n else detachViewportListeners();\n if (props.open === undefined || props.open !== nextOpen) props.onOpenChange?.(nextOpen);\n // A light dismiss hides the menu with focus inside it; an opener without a trigger takes it back.\n const focused = document.activeElement;\n const target = wasOpen && !nextOpen ? originElement() : undefined;\n if (target?.isConnected && (!focused || focused === document.body || menuRef?.contains(focused)))\n returnFocus(target, triggerRing);\n if (wasOpen && !nextOpen) props.onClose?.();\n if (!nextOpen && props.open === true) queueMicrotask(() => props.open === true && open(false));\n }}\n >\n <Show when={entriesShown()}>\n <DropdownItems items={props.items} close={close} />\n </Show>\n </div>\n </span>\n </DropdownContext.Provider>\n );\n}\n\ntype DropdownComponent = ((props: DropdownProps) => JSX.Element) & {\n Root: (props: DropdownProps) => JSX.Element;\n Trigger: (props: DropdownTriggerProps) => JSX.Element;\n Item: (props: DropdownItemProps) => JSX.Element;\n};\n\nexport const Dropdown = DropdownRoot as DropdownComponent;\nDropdown.Root = DropdownRoot;\nDropdown.Trigger = DropdownTrigger;\nDropdown.Item = DropdownItem;\n\nexport default Dropdown;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SACE,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,GAAG,EAEH,UAAU,EACV,SAAS,EACT,OAAO,EACP,IAAI,EACJ,UAAU,EACV,OAAO,EACP,UAAU,QACL,UAAU;AACjB,SAAS,OAAO,QAAQ,cAAc;AACtC,SAAS,OAAO,EAAyB,eAAe,QAAQ,qBAAqB;AACrF,SAAS,WAAW,EAAE,YAAY,QAAQ,0BAA0B;AACpE,SAAS,QAAQ,QAAQ,uBAAuB;AAChD,SAAS,SAAS,QAAQ,gBAAgB;AAC1C,SAAS,aAAa,QAAQ,kBAAkB;AAChD,SAAS,MAAM,EAAyD,SAAS,QAAQ,UAAU;AACnG,SAAS,YAAY,EAAE,eAAe,QAAQ,aAAa;AAC3D,SAAS,aAAa,EAAE,gBAAgB,QAAQ,cAAc;;AAE9D;AACA,MAAM,YAAY,GAAI,IAA6B,IAAK,IAAI,CAAC,MAAM;AACnE,MAAM,eAAe,GAAI,IAAoB,IAAM,eAAe,IAAI,IAAI,GAAG,IAAI,CAAC,aAAa,GAAG,SAAU;AAC5G,MAAM,MAAM,GAAI,IAAoB,IAAM,MAAM,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,SAAU;AACjF,MAAM,UAAU,GAAI,IAAoB,IAAM,UAAU,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,GAAG,SAAU;;AAG7F;;AAEA;;AAkDA;;AAQA;;AAwHA,MAAM,WAAW,GAAG,aAAa,CAAmB,CAAC;AACrD,MAAM,eAAe,GAAG,aAAa,CAAuB,CAAC;AAE7D,MAAM,eAAe,GAAI,IAA6B,IACpD,IAAI,GACA,KAAK,CAAC,IAAI,CACR,IAAI,CAAC,gBAAgB,CACnB,CACE,+CAA+C,EAC/C,uDAAuD,EACvD,oDAAoD,CACrD,CAAC,IAAI,CAAC,IAAI,CACb,CACF,CAAC,GACD,EAAE;AAER,MAAM,aAAa,GAAG,CAAC,IAA6B,EAAE,KAAa,KAAW;EAC5E,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,CAAE,IAAI,IAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;EACzG,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;EACxB,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC;AAED,OAAO,MAAM,gBAAgB,GAAG,CAC9B,OAA2D,EAC3D,IAAuC,EACvC,QAA0B,EAC1B,QAA2C,EAC3C,GAAG,GAAG,CAAC,KAC2B;EAClC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI;EACvB,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,GAAG;EAE9B,IAAI,QAAQ,KAAK,aAAa,IAAI,QAAQ,KAAK,UAAU,EAAE,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;EAC5F,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,UAAU,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG;EAC9F,IAAI,QAAQ,KAAK,aAAa,EAAE;IAC9B,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,GAAG;IAC1B,GAAG,GAAG,OAAO,CAAC,GAAG;EACnB;EAEA,OAAO;IACL,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAClE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;EACnE,CAAC;AACH,CAAC;AAED,MAAM,WAAW,GAAI,KAMpB,uBAEI,IAAI;EAAA,IAAC,IAAI;IAAA,OAAE,KAAK,CAAC,KAAK;EAAA;EAAA,IAAE,QAAQ;IAAA,yBAAG,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,IAAI;MAAA;MAAA,UAAI,IAAI,oDAAe,IAAI,CAAC,CAAC;IAAuB;EAAA;EAAA,UACzG,KAAK,kDAA2C,KAAK,CAAC,CAAC;AAAW,2BAG7D,KAAK,CAAC,QAAQ,8BACpB,IAAI;EAAA,IAAC,IAAI;IAAA,OAAE,KAAK,CAAC,WAAW;EAAA;EAAA,UAAI,WAAW,4BAAa,WAAW,CAAC,CAAC;AAAS,MAEhF,KAAK,CAAC,QAAQ,CAElB;AAED,OAAO,SAAS,YAAY,CAAC,KAAwB,EAAe;EAClE,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC;EACpC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,KAAK,QAAQ;EAC/D,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC;EAElC,yBACG,IAAI;IAAA,IACH,IAAI;MAAA,OAAE,gBAAC,KAAK,CAAC,QAAQ,MAAG,KAAK,CAAC,IAAI,GAAG,SAAS;IAAA;IAAA,IAC9C,QAAQ;MAAA,4DAIQ,KAAK,CAAC,SAAS,iBAEpB,+BAAsB,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,gCACnC,MAAM,CAAC,CAAC,GAAG,MAAM,YAAG,SAAS,4CAChC,KAAK,CAAC,QAAQ,0CACT,KAAK,CAAC,QAAQ,GAAG,MAAM,YAAG,SAAS,0BAQjD,OAAO;IAAA;IAAA,UAIV,IAAI,mDAEI,IAAI,CAAC,CAAC,2CACJ,KAAK,CAAC,QAAQ,GAAG,QAAQ,YAAG,SAAS,wCACxC,KAAK,CAAC,QAAQ,GAAG,qBAAqB,YAAG,SAAS,uDAE3C,KAAK,CAAC,SAAS,iBAEpB,+BAAsB,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,gCACnC,MAAM,CAAC,CAAC,GAAG,MAAM,YAAG,SAAS,0BAYzC,OAAO;EAEX;AAGP;AAEA,SAAS,kBAAkB,CAAC,KAAqB,EAAe;EAC9D,yBACG,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,KAAK,CAAC,SAAS;IAAA;IAAA,IAAE,QAAQ;MAAA,yBAAG,iBAAiB,EAAK,KAAK;IAAA;IAAA,UAC/D,SAAS,8CAEN,iBAAiB,EAAK,KAAK,+BAC3B,uBAAuB,eAAK,SAAS;MAAA;IAAA;EAEzC;AAGP;AAEA,SAAS,uBAAuB,CAAC,KAAkD,EAAe;EAChG,uDAKW,KAAK,CAAC,KAAK,wDACN,KAAK,CAAC,SAAS,0BAO1B,KAAK,CAAC,KAAK;AAGlB;AAEA,SAAS,iBAAiB,CAAC,KAAqB,EAAe;EAC7D,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC;EACpC,MAAM,OAAO,GAAG,MAAO,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,OAAQ;EAC7F,IAAI,OAAgC;EACpC,yBACG,OAAO;IAAA,IAIN,SAAS;MAAA,OAAE,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,GAAG,GAAG,GAAG,QAAQ;IAAA;IAAA,IACzD,IAAI;MAAA,OAAE,gBAAC,KAAK,CAAC,QAAQ,MAAG,KAAK,CAAC,IAAI,GAAG,SAAS;IAAA;IAAA,IAC9C,IAAI;MAAA,OAAE,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,GAAG,SAAS,GAAG,QAAQ;IAAA;IAAA,IAC1D,IAAI;MAAA,OAAE,KAAK,CAAC,MAAM,KAAK,UAAU,GAAG,kBAAkB,GAAG,eAAe;IAAA;IAAA;MAAA,OAC5D,KAAK,CAAC,SAAS;IAAA;IAAA;MAAA,OACb,OAAO,CAAC,CAAC;IAAA;IAAA;MAAA,OACR,KAAK,CAAC,QAAQ,GAAG,MAAM,GAAG,SAAS;IAAA;IAClD,QAAQ,EAAE,CAAC,CAAC;IAAA;MAAA,OACL,sBAAsB,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;IAAA;IAAA;MAAA,OACjC,OAAO,CAAC,CAAC,GAAG,MAAM,GAAG,SAAS;IAAA;IAAA,IAC7C,QAAQ;MAAA,OAAE,KAAK,CAAC,QAAQ;IAAA;IACxB,OAAO,EAAG,KAAiB,IAAK;MAC9B,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE;QACpF,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC;QAClB;MACF;MACA,KAAK,CAAC,cAAc,CAAC,CAAC;MACtB,KAAK,CAAC,eAAe,CAAC,CAAC;MACvB,IAAI,KAAK,CAAC,aAAa,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;MAChD,KAAK,CAAC,MAAM,CAAC,CAAC;IAChB,CAAC;IACD,SAAS,EAAG,KAAoB,IAAK;MACnC;MACA,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;MACxD,KAAK,CAAC,cAAc,CAAC,CAAC;MACtB,OAAO,EAAE,KAAK,CAAC,CAAC;IAClB,CAAC;IAAA;MAAA,0BAEA,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,MAAM,KAAK,UAAU;QAAA;QAAA;UAAA,iDAElC,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,OAAO,CAAC,CAAC;YAAA;YAAA;cAAA;YAAA;UAAA;QAAA;MAAA,sBAKxB,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,KAAK;QAAA;QAAA,IAAE,QAAQ;UAAA,yBAAG,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,KAAK,CAAC,IAAI;YAAA;YAAA,UAAI,IAAI,oDAAe,IAAI,CAAC,CAAC;UAAuB;QAAA;QAAA,UACzG,KAAK,kDAA2C,KAAK,CAAC,CAAC;MAAW,sBAErE,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,KAAK;QAAA;QAAA,UACnB,KAAK,yEAAwE,KAAK,CAAC,CAAC;MAAyB,2BAGxG,KAAK,CAAC,KAAK,8BACjB,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,WAAW;QAAA;QAAA,UAAI,WAAW,4BAAa,WAAW,CAAC,CAAC;MAAS,MAEhF,KAAK,CAAC,QAAQ,oBAEd,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,MAAM,KAAK,OAAO;QAAA;QAAA;UAAA,oDACsB,OAAO,CAAC,CAAC,YAAG,SAAS,UAAG,MAAM;QAAA;MAAA;IAAA;EAAA;AAI9F;AAEA,OAAO,SAAS,aAAa,CAAC,KAAkF,EAAe;EAC7H,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC;EACA,MAAM,UAAU,GAAI,IAA2C,IAAkB;IAC/E,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAC7B,IAAI,QAAQ,IAAI,OAAO,EAAE,yBAAQ,kBAAkB,qBAAK,UAAU,CAAC,MAAM,IAAI,CAAC,CAAmB,CAAC;IAClG,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,CAAmB;IAC7C,yBACG,YAAY;MAAA,IACX,SAAS;QAAA,OAAE,MAAM,CAAC,CAAC,CAAC,SAAS;MAAA;MAAA,IAC7B,aAAa;QAAA,OAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;MAAA;MAAA,IACxC,IAAI;QAAA,OAAE,MAAM,CAAC,CAAC,CAAC,IAAI;MAAA;MAAA,IACnB,KAAK;QAAA,OAAE,MAAM,CAAC,CAAC,CAAC,KAAK;MAAA;MAAA,IACrB,WAAW;QAAA,OAAE,MAAM,CAAC,CAAC,CAAC,WAAW;MAAA;MAAA,IACjC,QAAQ;QAAA,OAAE,MAAM,CAAC,CAAC,CAAC,QAAQ;MAAA;MAAA,IAC3B,OAAO;QAAA,OAAE,MAAM,CAAC,CAAC,CAAC,OAAO;MAAA;MAAA,IACzB,QAAQ;QAAA,OAAE,MAAM,CAAC,CAAC,CAAC,QAAQ;MAAA;MAAA;QAAA,OACpB,MAAM,CAAC,CAAC,CAAC,KAAK;MAAA;MAAA,IACrB,IAAI;QAAA,OAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;MAAA;MAAA,IACtB,QAAQ;QAAA,OAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;MAAA;MAAA,IAC9B,QAAQ;QAAA,OAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;MAAA;MAAA;QAAA,OAE/B,MAAM,CAAC,CAAC,CAAC,KAAK;MAAA;IAAA;EAGrB,CAAC;EAED,yBACG,WAAW,CAAC,QAAQ;IAAA,IAAC,KAAK;MAAA,OAAE;QAAE,KAAK,EAAE,KAAK,CAAC;MAAM,CAAC;IAAA;IAAA;MAAA,yBAChD,QAAQ;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,KAAK;QAAA;QAAE,EAAE,EAAG,IAAI,IAAM,OAAO,IAAI,IAAI,GAAG,WAAW,IAAI,CAAC,YAAY,IAAI,EAAE,EAAE,GAAG,QAAQ,IAAI,CAAC,KAAK,EAAG;QAAA,UACvH,CAAC,OAAO,EAAE,KAAK,KAAK;UACnB,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC;UACtB,yBACG,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,OAAO,IAAI,IAAI;YAAA;YAAA,IAAE,QAAQ;cAAA,OAAE,UAAU,CAAC,OAAgD,CAAC;YAAA;YAAA;cAAA,sDAGjF,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,YAAG,SAAS,uDAI3C,OAAO,CAAC,CAAC,CAAqB,YAAY,KACzC,OAAO,CAAC,CAAC,CAAqB,MAAM,KAAK,KAAK,GAAG,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,4CAGnF,IAAI;gBAAA,IAAC,IAAI;kBAAA,OAAG,OAAO,CAAC,CAAC,CAAqB,YAAY;gBAAA;gBAAA,UACnD,KAAK,sBACJ,IAAI;kBAAA,IAAC,IAAI;oBAAA,OAAG,OAAO,CAAC,CAAC,CAAqB,WAAW;kBAAA;kBAAA,IAAE,QAAQ;oBAAA,gCAAoC,KAAK,CAAC,CAAC;kBAAA;kBAAA,UACvG,MAAM,6BAEG,KAAK,CAAC,CAAC,8BACb,uBAAuB,eAAK,MAAM;oBAAA;kBAAA;gBAEtC;cAEJ,gCAEF,IAAI;gBAAA,IACH,IAAI;kBAAA,OAAG,OAAO,CAAC,CAAC,CAAqB,MAAM,KAAK,KAAK;gBAAA;gBAAA,IACrD,QAAQ;kBAAA,yBACL,QAAQ;oBAAA,IAAC,IAAI;sBAAA,OAAG,OAAO,CAAC,CAAC,CAAqB,KAAK;oBAAA;oBAAE,EAAE,EAAG,GAAG,IAAK,GAAG,CAAC,KAAK;oBAAA,UACzE;kBAAU;gBAAA;gBAAA;kBAAA,kDAKZ,QAAQ;oBAAA,IAAC,IAAI;sBAAA,OAAG,OAAO,CAAC,CAAC,CAAqB,KAAK;oBAAA;oBAAE,EAAE,EAAG,GAAG,IAAK,GAAG,CAAC,KAAK;oBAAA,UACzE;kBAAU;gBAAA;cAAA;YAAA;UAAA;QAOzB;MAAC;IAAA;EAAA;AAIT;AAEA,SAAS,eAAe,CAAC,KAA2B,EAAe;EACjE,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC;EAC3C,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC;EACnF,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CACtC,YAAY,EACZ,UAAU,EACV,OAAO,EACP,UAAU,EACV,UAAU,EACV,OAAO,EACP,KAAK,EACL,MAAM,EACN,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,MAAM,EACN,SAAS,CACV,CAAC;EACF,IAAI,MAAqC;EACzC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC;EACpE;EACA,MAAM,OAAO,GAAG,eAAe,CAC7B,MAAM,KAAK,CAAC,OAAO,EACnB,MAAO,KAAK,CAAC,QAAQ,GAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,GAAI,SACzD,CAAC;EACD,MAAM,QAAQ,GAAI,OAA0B,IAAK;IAC/C,MAAM,GAAG,OAAO;IAChB,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC;IAChC,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;EACzD,CAAC;EACD,MAAM,KAA2D,GAAI,KAAK,IAAK;IAC7E,KAAK,CAAC,eAAe,CAAC,CAAC;IACvB,OAAO,CAAC,MAAM,CAAC,CAAC;EAClB,CAAC;EAED,IAAI,KAAK,CAAC,UAAU,KAAK,OAAO,EAAE;IAChC,yBACG,MAAM,eACD,IAAI;MAAA;QAAA,OAEO,OAAO,CAAC,MAAM;MAAA;MAAA;QAAA,OACd,OAAO,CAAC,IAAI,CAAC,CAAC;MAAA;MAAA;MAAA;QAAA,OAEjB,KAAK,CAAC,KAAK;MAAA;MAAA,IACvB,QAAQ;QAAA,OAAE,QAAQ,CAAC,CAAC;MAAA;MAAA,IACpB,QAAQ;QAAA,OAAE,uBAAQ,CAAC,CAAC,MAAG,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ;MAAA;MAC1C,OAAO,EAAE,KAAK;MAAA,IACd,SAAS;QAAA,OAAE,OAAO,CAAC,cAAc;MAAA;MAAA,IACjC,IAAI;QAAA,OAAE,KAAK,CAAC,IAAI,IAAI,QAAQ;MAAA;MAAA;QAAA,OACrB,GAAG,KAAK,CAAC,QAAQ,GAAG,iBAAiB,GAAG,EAAE,0BAA0B,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;MAAA;MAAA,IAC9F,IAAI;QAAA,OAAE,KAAK,CAAC,IAAI;MAAA;MAAA,IAChB,OAAO;QAAA,OAAE,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;MAAA;MAAA,IAChE,KAAK;QAAA,OAAE,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;MAAA;MAAA,IACxC,OAAO;QAAA,OAAE,OAAO,CAAC,CAAC;MAAA;MAAA,IAClB,YAAY;QAAA,OAAE,KAAK,CAAC,YAAY;MAAA;MAAA,IAChC,gBAAgB;QAAA,OAAE,KAAK,CAAC,gBAAgB;MAAA;MAAA;QAAA,OAEvC,KAAK,CAAC,QAAQ;MAAA;IAAA;EAGrB;EAEA,4CAGU,IAAI;IAAA;MAAA,OAEO,OAAO,CAAC,MAAM;IAAA;IAAA;MAAA,OACd,OAAO,CAAC,IAAI,CAAC,CAAC;IAAA;IAAA,iBACf,MAAM;IAAA;MAAA,OACR,KAAK,CAAC,KAAK;IAAA;IAAA,IACvB,QAAQ;MAAA,OAAE,QAAQ,CAAC,CAAC;IAAA;IAAA,IACpB,QAAQ;MAAA,OAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ;IAAA;IAAA,IAG1C,IAAI;MAAA,OAAE,KAAK,CAAC,IAAI,IAAI,QAAQ;IAAA;IAAA;MAAA,OACrB,yBAAyB,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;IAAA;IAAA,IACnD,KAAK;MAAA,OAAE,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA;EAAA,aAEvC,KAAK,CAAC,QAAQ,6BAEhB,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,oBAAO,CAAC,CAAC,KAAK,KAAK,OAAI,OAAO,CAAC,CAAC,KAAK,SAAS;IAAA;IAAA;MAAA,yBACvD,OAAO;QAAA,IACN,OAAO;UAAA,OAAE,OAAO,CAAC,CAAC;QAAA;QAClB,MAAM,EAAE,MAAM,MAAM;QAAA,IACpB,KAAK;UAAA,OAAE,KAAK,CAAC,YAAY;QAAA;QAAA,IACzB,QAAQ;UAAA,OAAE,QAAQ,CAAC,CAAC;QAAA;QAAA,IACpB,SAAS;UAAA,OAAE,KAAK,CAAC,gBAAgB;QAAA;MAAA;IAAA;EAAA;AAK3C;;AAEA;AACA,SAAS,YAAY,CAAC,KAAoB,EAAe;EACvD,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;EAC1B;EACA,IAAI,KAAkC;EACtC,MAAM,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC;EAC3D,MAAM,MAAM,GAAG,gBAAgB,EAAE,EAAE;EACnC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC;EAC3D,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,YAAY,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;EACjE,IAAI,UAAyC;EAC7C;EACA,IAAI,MAAkC;EACtC,IAAI,MAAuC;EAC3C,MAAM,aAAa,GAAG,MAAO,OAAO,MAAM,KAAK,UAAU,GAAG,MAAM,CAAC,CAAC,GAAG,MAAO;EAC9E,IAAI,OAAmC;EACvC,IAAI,WAAW,GAAG,IAAI;EACtB,IAAI,OAAO,GAAG,KAAK;EACnB;EACA,IAAI,QAAkC,GAAG,KAAK;EAC9C,IAAI,yBAAyB,GAAG,KAAK;EACrC,IAAI,cAA0C;EAE9C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC;EACjD,MAAM,QAAQ,GAAG,MACf,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,KAAK,KAAK,KAAK,GAAG,aAAa,GAAG,cAAc,CAAE;EAExI,MAAM,KAAK,GAAG,MAAM;IAClB,MAAM,EAAE,GAAG,MAAM,IAAI,UAAU;IAC/B,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE;IACrB,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE;MACrG,KAAK,EAAE,MAAM,CAAC,UAAU;MACxB,MAAM,EAAE,MAAM,CAAC;IACjB,CAAC,CAAC;IACF,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI;IACrC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI;EACrC,CAAC;EACD,MAAM,UAAU,GAAG,MAAM;IACvB,IAAI,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;EACvB,CAAC;EACD,MAAM,uBAAuB,GAAG,MAAM;IACpC,IAAI,yBAAyB,EAAE;IAC/B,yBAAyB,GAAG,IAAI;IAChC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC7C,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC;IACnD;IACA,IAAI,OAAO,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE;MACpD,cAAc,KAAK,IAAI,cAAc,CAAC,UAAU,CAAC;MACjD,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC;IACjC;EACF,CAAC;EACD,MAAM,uBAAuB,GAAG,MAAM;IACpC,IAAI,CAAC,yBAAyB,EAAE;IAChC,yBAAyB,GAAG,KAAK;IACjC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,UAAU,CAAC;IAChD,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC;IACtD,cAAc,EAAE,UAAU,CAAC,CAAC;EAC9B,CAAC;EACD,MAAM,KAAK,GAAG,CAAC,YAAY,GAAG,IAAI,KAAK;IACrC;IACA,IAAI,YAAY,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC,IAAI,UAAU,EAAE,WAAW,CAAC;IACzE,IAAI,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5D;IACA;IACA,eAAe,CAAC,KAAK,CAAC;IACtB,uBAAuB,CAAC,CAAC;EAC3B,CAAC;EACD,MAAM,IAAI,GAAG,CAAC,KAA+B,GAAG,OAAO,KAAK;IAC1D,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE;IACpE,WAAW,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC,IAAI,UAAU,CAAC;IACzD;IACA,eAAe,CAAC,IAAI,CAAC;IACrB,OAAO,CAAC,WAAW,CAAC,CAAC;IACrB;IACA,eAAe,CAAC,IAAI,CAAC;IACrB,uBAAuB,CAAC,CAAC;IACzB,KAAK,CAAC,CAAC;IACP,cAAc,CAAC,MAAM;MACnB,IAAI,KAAK,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,KAAK,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC;EACJ,CAAC;EACD,MAAM,WAAW,GAAG,CAAC,IAAa,EAAE,KAA+B,GAAG,OAAO,KAAK;IAChF,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE;IAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE;MAC5B,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;MAC1B;IACF;IACA,IAAI,IAAI,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,gBAAgB,CAAC,CAAC,EAAE;MACzD,IAAI,KAAK,EAAE;MACX,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,CAAC;MACrC,KAAK,GAAG,OAAO;MACf;MACA;MACA,MAAM,QAAQ,GAAG,MAAM,KAAK,SAAS;MACrC,MAAM,IAAI,GAAG,QAAQ,IAAI,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC;MACtD,IAAI,QAAQ,IAAI,QAAQ,CAAC,aAAa,YAAY,WAAW,EAAE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;MAC5F;MACA,eAAe,CAAC,IAAI,CAAC;MACrB,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;MAC1B,KAAK,aAAa,CAAC;QACjB,KAAK,EAAE,aAAa;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,YAAY;QAC7C,MAAM,EAAE,MAAM,CAAC,CAAC;QAChB,GAAG,EAAE,KAAK,CAAC,QAAQ;QACnB,MAAM,EAAE,OAAO,CAAC;MAClB,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM;QACf,KAAK,GAAG,SAAS;QACjB;QACA,MAAM,MAAM,GAAG,QAAQ,GAAG,aAAa,CAAC,CAAC,GAAG,SAAS;QACrD,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa;QACtC,IAAI,MAAM,EAAE,WAAW,KAAK,CAAC,OAAO,IAAI,OAAO,KAAK,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC;QAC7F,eAAe,CAAC,KAAK,CAAC;QACtB,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;QAC3B,KAAK,CAAC,OAAO,GAAG,CAAC;MACnB,CAAC,CAAC;MACF;IACF;IACA,IAAI,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KACjB,KAAK,CAAC,KAAK,CAAC;EACnB,CAAC;EACD,MAAM,iBAAiB,GAAI,KAAoB,IAAK;IAClD,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC;IACtC,IAAI,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE;MACvE,KAAK,CAAC,cAAc,CAAC,CAAC;IACxB,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;MACjC,KAAK,CAAC,cAAc,CAAC,CAAC;MACtB,WAAW,CAAC,aAAa,CAAC,CAAC,IAAI,UAAU,EAAE,WAAW,CAAC;MACvD,WAAW,CAAC,KAAK,CAAC;IACpB,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE;MAC9B,WAAW,CAAC,KAAK,CAAC;IACpB;EACF,CAAC;EAED,MAAM,OAA6B,GAAG;IACpC,QAAQ,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;IACvC,MAAM;IACN,IAAI,EAAE,MAAM;IACZ,eAAe,EAAG,OAAO,IAAK;MAC5B,UAAU,GAAG,OAAO;IACtB,CAAC;IACD,MAAM,EAAE,MAAM;MACZ,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;MAC1C,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,cAAc,EAAG,KAAK,IAAK;MACzB,IAAI,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;MACjE,KAAK,CAAC,cAAc,CAAC,CAAC;MACtB,KAAK,CAAC,eAAe,CAAC,CAAC;MACvB,IAAI,MAAM,CAAC,CAAC,EAAE;QACZ,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,KAAK,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACxD;MACF;MACA,MAAM,GAAG,MAAM,GAAG,SAAS;MAC3B,QAAQ,GAAG,KAAK,CAAC,GAAG,KAAK,SAAS,GAAG,MAAM,GAAG,OAAO;MACrD,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC;MAC3B,QAAQ,GAAG,KAAK;IAClB;EACF,CAAC;EAED,YAAY,CAAC,MAAM;IACjB,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI;IAC7B,IAAI,CAAC,OAAO,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,OAAO,EAAE;IACtD,IAAI,UAAU,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC;IACnE,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;EACnE,CAAC,CAAC;EACF,YAAY,CAAC,MAAM;IACjB,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;IACrB,KAAK,EAAE,KAAK,CAAC,CAAC;IACd,IAAI,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;EAC3B,CAAC,CAAC;EACF,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,KAAK,KAAK;IAC5B,IAAI,MAAM,CAAC,CAAC,EAAE;IACd,MAAM,GAAG,EAAE;IACX,MAAM,GAAG,KAAK;IACd,WAAW,CAAC,IAAI,CAAC;EACnB,CAAC,CAAC;EACF,KAAK,CAAC,SAAS,GAAG,MAAM;IACtB,KAAK,EAAE,KAAK,CAAC,CAAC;IACd,IAAI,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;EACvB,CAAC,CAAC;EACF,OAAO,CAAC,MAAM;IACZ,OAAO,GAAG,IAAI;IACd,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC;IAC3B,SAAS,CAAC,uBAAuB,CAAC;EACpC,CAAC,CAAC;EACF,SAAS,CAAC,MAAM,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;EAE/B,yBACG,eAAe,CAAC,QAAQ;IAAC,KAAK,EAAE,OAAO;IAAA;MAAA,uBACzB,yBAAgB,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,WAC7C,KAAK,CAAC,QAAQ,iCAGT,MAAM,uDAGE,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,YAAY,iBAC3C,+BAAsB,KAAK,CAAC,SAAS,IAAI,EAAE,SAAE,aAC7C,KAAK,CAAC,KAAK,GAAG;QAAE,sBAAsB,EAAE,KAAK,CAAC;MAAM,CAAC,GAAG,SAAS,gCAC5D,KAAK,CAAC,KAAK,GAAG,OAAO,YAAG,SAAS,0DAC/B,KAAK,CAAC,OAAO,IAAI,SAAS,2DACzB,QAAQ,CAAC,CAAC,4CAmBxB,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,YAAY,CAAC,CAAC;QAAA;QAAA;UAAA,yBACvB,aAAa;YAAA,IAAC,KAAK;cAAA,OAAE,KAAK,CAAC,KAAK;YAAA;YAAE,KAAK,EAAE;UAAK;QAAA;MAAA;IAAA;EAAA;AAM3D;AAQA,OAAO,MAAM,QAAQ,GAAG,YAAiC;AACzD,QAAQ,CAAC,IAAI,GAAG,YAAY;AAC5B,QAAQ,CAAC,OAAO,GAAG,eAAe;AAClC,QAAQ,CAAC,IAAI,GAAG,YAAY;AAE5B,eAAe,QAAQ","ignoreList":[]}
|
|
@@ -4,7 +4,7 @@ import { escape as _$escape } from "solid-js/web";
|
|
|
4
4
|
var _tmpl$ = ["<div popover=\"manual\" class=\"", "\">", "</div>"];
|
|
5
5
|
import { createEffect, onCleanup } from "solid-js";
|
|
6
6
|
import { isServer } from "solid-js/web";
|
|
7
|
-
import { Toolbar } from "./Toolbar";
|
|
7
|
+
import { Toolbar, ToolbarHintsContext } from "./Toolbar";
|
|
8
8
|
const GAP = 8;
|
|
9
9
|
const EDGE = 8;
|
|
10
10
|
|
|
@@ -91,12 +91,17 @@ export function SelectionToolbar(props) {
|
|
|
91
91
|
});
|
|
92
92
|
});
|
|
93
93
|
return (// biome-ignore lint/a11y/noStaticElementInteractions: the toolbar inside is the keyboard target; the frame only keeps the selection on press and forwards Escape.
|
|
94
|
-
_$ssr(_tmpl$, `k2b-selection-toolbar ${_$escape(props.class ?? "", true)}`, _$escape(_$createComponent(
|
|
95
|
-
|
|
96
|
-
return props.label;
|
|
97
|
-
},
|
|
94
|
+
_$ssr(_tmpl$, `k2b-selection-toolbar ${_$escape(props.class ?? "", true)}`, _$escape(_$createComponent(ToolbarHintsContext.Provider, {
|
|
95
|
+
value: false,
|
|
98
96
|
get children() {
|
|
99
|
-
return
|
|
97
|
+
return _$createComponent(Toolbar, {
|
|
98
|
+
get label() {
|
|
99
|
+
return props.label;
|
|
100
|
+
},
|
|
101
|
+
get children() {
|
|
102
|
+
return props.children;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
100
105
|
}
|
|
101
106
|
})))
|
|
102
107
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["actions/SelectionToolbar.tsx"],"sourcesContent":["import { createEffect, type JSX, onCleanup } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { Toolbar } from \"./Toolbar\";\n\nexport type SelectionToolbarProps = {\n /**\n * The selection's box in viewport coordinates, or nothing while the toolbar is closed. It is read again on every\n * scroll and resize while the toolbar is open, so a function that measures the selection keeps it attached.\n */\n anchor: () => DOMRect | null | undefined;\n label: string;\n /**\n * `above` (default) places the toolbar over the selection and below it when the space above is too small. `below`\n * always places it below, for touch, where the system's own selection menu sits above.\n */\n placement?: \"above\" | \"below\";\n /** The area the toolbar stays in, such as the editor's scroll area under its toolbar: it goes below the selection when the space above inside this area is too small. */\n boundary?: () => HTMLElement | null | undefined;\n /** Escape inside the toolbar; the application closes it and returns focus to the text. */\n onEscape?: () => void;\n children: JSX.Element;\n class?: string;\n};\n\nconst GAP = 8;\nconst EDGE = 8;\n\n/** Where the toolbar goes for a selection box: centered on its first line, inside the viewport. */\nexport const selectionToolbarPosition = (\n anchor: Pick<DOMRect, \"top\" | \"bottom\" | \"left\" | \"width\">,\n toolbar: { width: number; height: number },\n viewport: { width: number; height: number; top?: number },\n placement: \"above\" | \"below\" = \"above\",\n): { left: number; top: number; side: \"above\" | \"below\" } => {\n const left = Math.max(EDGE, Math.min(anchor.left + anchor.width / 2 - toolbar.width / 2, viewport.width - toolbar.width - EDGE));\n // A boundary scrolled above the window still leaves the window's top edge as the limit.\n const upper = Math.max(0, viewport.top ?? 0) + EDGE;\n const above = anchor.top - toolbar.height - GAP;\n const below = anchor.bottom + GAP;\n const fitsAbove = above >= upper;\n const fitsBelow = below + toolbar.height <= viewport.height - EDGE;\n // The preferred side when it fits, the other side when only that fits; never on the selected text otherwise.\n const side = placement === \"below\" ? (fitsBelow || !fitsAbove ? \"below\" : \"above\") : fitsAbove || !fitsBelow ? \"above\" : \"below\";\n if (side === \"above\") return { left, top: fitsAbove ? above : upper, side };\n return { left, top: fitsBelow ? below : Math.max(upper, viewport.height - EDGE - toolbar.height), side };\n};\n\nconst keepsFocus = (target: EventTarget | null) =>\n target instanceof Element && !!target.closest(\"input, textarea, select, [contenteditable='true']\");\n\n/**\n * A toolbar that floats at a text selection, such as formatting and comment actions over selected text. It lies in\n * the top layer, so no scroll container clips it, and pressing its buttons keeps the selection.\n */\nexport function SelectionToolbar(props: SelectionToolbarProps): JSX.Element {\n let root!: HTMLDivElement;\n const place = () => {\n const anchor = props.anchor();\n if (!anchor) return false;\n const boundary = props.boundary?.()?.getBoundingClientRect();\n const size = root.getBoundingClientRect();\n const { left, top, side } = selectionToolbarPosition(\n anchor,\n size,\n { width: document.documentElement.clientWidth, height: window.innerHeight, top: boundary?.top },\n props.placement,\n );\n root.style.left = `${Math.round(left)}px`;\n root.style.top = `${Math.round(top)}px`;\n root.dataset.side = side;\n return true;\n };\n\n if (!isServer)\n createEffect(() => {\n const open = !!props.anchor();\n if (!open) {\n if (root.matches(\":popover-open\")) root.hidePopover();\n return;\n }\n if (!root.matches(\":popover-open\")) root.showPopover();\n place();\n let frame = 0;\n const follow = () => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n if (!place() && root.matches(\":popover-open\")) root.hidePopover();\n });\n };\n window.addEventListener(\"scroll\", follow, { capture: true, passive: true });\n window.addEventListener(\"resize\", follow, { passive: true });\n const observer = new ResizeObserver(follow);\n observer.observe(root);\n onCleanup(() => {\n cancelAnimationFrame(frame);\n window.removeEventListener(\"scroll\", follow, { capture: true });\n window.removeEventListener(\"resize\", follow);\n observer.disconnect();\n });\n });\n\n return (\n // biome-ignore lint/a11y/noStaticElementInteractions: the toolbar inside is the keyboard target; the frame only keeps the selection on press and forwards Escape.\n <div\n ref={root}\n popover=\"manual\"\n class={`k2b-selection-toolbar ${props.class ?? \"\"}`}\n onPointerDown={(event) => {\n // A press on a button would otherwise move focus and clear the selection the actions apply to.\n if (!keepsFocus(event.target)) event.preventDefault();\n }}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\" || !props.onEscape) return;\n event.preventDefault();\n event.stopPropagation();\n props.onEscape();\n }}\n >\n <Toolbar label={props.label}>{props.children}</Toolbar>\n </div>\n );\n}\n"],"mappings":";;;;AAAA,SAAS,YAAY,EAAY,SAAS,QAAQ,UAAU;AAC5D,SAAS,QAAQ,QAAQ,cAAc;AACvC,SAAS,OAAO,QAAQ,WAAW;
|
|
1
|
+
{"version":3,"names":[],"sources":["actions/SelectionToolbar.tsx"],"sourcesContent":["import { createEffect, type JSX, onCleanup } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { Toolbar, ToolbarHintsContext } from \"./Toolbar\";\n\nexport type SelectionToolbarProps = {\n /**\n * The selection's box in viewport coordinates, or nothing while the toolbar is closed. It is read again on every\n * scroll and resize while the toolbar is open, so a function that measures the selection keeps it attached.\n */\n anchor: () => DOMRect | null | undefined;\n label: string;\n /**\n * `above` (default) places the toolbar over the selection and below it when the space above is too small. `below`\n * always places it below, for touch, where the system's own selection menu sits above.\n */\n placement?: \"above\" | \"below\";\n /** The area the toolbar stays in, such as the editor's scroll area under its toolbar: it goes below the selection when the space above inside this area is too small. */\n boundary?: () => HTMLElement | null | undefined;\n /** Escape inside the toolbar; the application closes it and returns focus to the text. */\n onEscape?: () => void;\n children: JSX.Element;\n class?: string;\n};\n\nconst GAP = 8;\nconst EDGE = 8;\n\n/** Where the toolbar goes for a selection box: centered on its first line, inside the viewport. */\nexport const selectionToolbarPosition = (\n anchor: Pick<DOMRect, \"top\" | \"bottom\" | \"left\" | \"width\">,\n toolbar: { width: number; height: number },\n viewport: { width: number; height: number; top?: number },\n placement: \"above\" | \"below\" = \"above\",\n): { left: number; top: number; side: \"above\" | \"below\" } => {\n const left = Math.max(EDGE, Math.min(anchor.left + anchor.width / 2 - toolbar.width / 2, viewport.width - toolbar.width - EDGE));\n // A boundary scrolled above the window still leaves the window's top edge as the limit.\n const upper = Math.max(0, viewport.top ?? 0) + EDGE;\n const above = anchor.top - toolbar.height - GAP;\n const below = anchor.bottom + GAP;\n const fitsAbove = above >= upper;\n const fitsBelow = below + toolbar.height <= viewport.height - EDGE;\n // The preferred side when it fits, the other side when only that fits; never on the selected text otherwise.\n const side = placement === \"below\" ? (fitsBelow || !fitsAbove ? \"below\" : \"above\") : fitsAbove || !fitsBelow ? \"above\" : \"below\";\n if (side === \"above\") return { left, top: fitsAbove ? above : upper, side };\n return { left, top: fitsBelow ? below : Math.max(upper, viewport.height - EDGE - toolbar.height), side };\n};\n\nconst keepsFocus = (target: EventTarget | null) =>\n target instanceof Element && !!target.closest(\"input, textarea, select, [contenteditable='true']\");\n\n/**\n * A toolbar that floats at a text selection, such as formatting and comment actions over selected text. It lies in\n * the top layer, so no scroll container clips it, and pressing its buttons keeps the selection.\n */\nexport function SelectionToolbar(props: SelectionToolbarProps): JSX.Element {\n let root!: HTMLDivElement;\n const place = () => {\n const anchor = props.anchor();\n if (!anchor) return false;\n const boundary = props.boundary?.()?.getBoundingClientRect();\n const size = root.getBoundingClientRect();\n const { left, top, side } = selectionToolbarPosition(\n anchor,\n size,\n { width: document.documentElement.clientWidth, height: window.innerHeight, top: boundary?.top },\n props.placement,\n );\n root.style.left = `${Math.round(left)}px`;\n root.style.top = `${Math.round(top)}px`;\n root.dataset.side = side;\n return true;\n };\n\n if (!isServer)\n createEffect(() => {\n const open = !!props.anchor();\n if (!open) {\n if (root.matches(\":popover-open\")) root.hidePopover();\n return;\n }\n if (!root.matches(\":popover-open\")) root.showPopover();\n place();\n let frame = 0;\n const follow = () => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n if (!place() && root.matches(\":popover-open\")) root.hidePopover();\n });\n };\n window.addEventListener(\"scroll\", follow, { capture: true, passive: true });\n window.addEventListener(\"resize\", follow, { passive: true });\n const observer = new ResizeObserver(follow);\n observer.observe(root);\n onCleanup(() => {\n cancelAnimationFrame(frame);\n window.removeEventListener(\"scroll\", follow, { capture: true });\n window.removeEventListener(\"resize\", follow);\n observer.disconnect();\n });\n });\n\n return (\n // biome-ignore lint/a11y/noStaticElementInteractions: the toolbar inside is the keyboard target; the frame only keeps the selection on press and forwards Escape.\n <div\n ref={root}\n popover=\"manual\"\n class={`k2b-selection-toolbar ${props.class ?? \"\"}`}\n onPointerDown={(event) => {\n // A press on a button would otherwise move focus and clear the selection the actions apply to.\n if (!keepsFocus(event.target)) event.preventDefault();\n }}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\" || !props.onEscape) return;\n event.preventDefault();\n event.stopPropagation();\n props.onEscape();\n }}\n >\n <ToolbarHintsContext.Provider value={false}>\n <Toolbar label={props.label}>{props.children}</Toolbar>\n </ToolbarHintsContext.Provider>\n </div>\n );\n}\n"],"mappings":";;;;AAAA,SAAS,YAAY,EAAY,SAAS,QAAQ,UAAU;AAC5D,SAAS,QAAQ,QAAQ,cAAc;AACvC,SAAS,OAAO,EAAE,mBAAmB,QAAQ,WAAW;AAsBxD,MAAM,GAAG,GAAG,CAAC;AACb,MAAM,IAAI,GAAG,CAAC;;AAEd;AACA,OAAO,MAAM,wBAAwB,GAAG,CACtC,MAA0D,EAC1D,OAA0C,EAC1C,QAAyD,EACzD,SAA4B,GAAG,OAAO,KACqB;EAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;EAChI;EACA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI;EACnD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,GAAG;EAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG;EACjC,MAAM,SAAS,GAAG,KAAK,IAAI,KAAK;EAChC,MAAM,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI;EAClE;EACA,MAAM,IAAI,GAAG,SAAS,KAAK,OAAO,GAAI,SAAS,IAAI,CAAC,SAAS,GAAG,OAAO,GAAG,OAAO,GAAI,SAAS,IAAI,CAAC,SAAS,GAAG,OAAO,GAAG,OAAO;EAChI,IAAI,IAAI,KAAK,OAAO,EAAE,OAAO;IAAE,IAAI;IAAE,GAAG,EAAE,SAAS,GAAG,KAAK,GAAG,KAAK;IAAE;EAAK,CAAC;EAC3E,OAAO;IAAE,IAAI;IAAE,GAAG,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAAE;EAAK,CAAC;AAC1G,CAAC;AAED,MAAM,UAAU,GAAI,MAA0B,IAC5C,MAAM,YAAY,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,mDAAmD,CAAC;;AAEpG;AACA;AACA;AACA;AACA,OAAO,SAAS,gBAAgB,CAAC,KAA4B,EAAe;EAC1E,IAAI,IAAqB;EACzB,MAAM,KAAK,GAAG,MAAM;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,EAAE,OAAO,KAAK;IACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,qBAAqB,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACzC,MAAM;MAAE,IAAI;MAAE,GAAG;MAAE;IAAK,CAAC,GAAG,wBAAwB,CAClD,MAAM,EACN,IAAI,EACJ;MAAE,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,WAAW;MAAE,MAAM,EAAE,MAAM,CAAC,WAAW;MAAE,GAAG,EAAE,QAAQ,EAAE;IAAI,CAAC,EAC/F,KAAK,CAAC,SACR,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI;IACzC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI;IACvC,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI;IACxB,OAAO,IAAI;EACb,CAAC;EAED,IAAI,CAAC,QAAQ,EACX,YAAY,CAAC,MAAM;IACjB,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,CAAC,IAAI,EAAE;MACT,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;MACrD;IACF;IACA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACtD,KAAK,CAAC,CAAC;IACP,IAAI,KAAK,GAAG,CAAC;IACb,MAAM,MAAM,GAAG,MAAM;MACnB,oBAAoB,CAAC,KAAK,CAAC;MAC3B,KAAK,GAAG,qBAAqB,CAAC,MAAM;QAClC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;MACnE,CAAC,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE;MAAE,OAAO,EAAE,IAAI;MAAE,OAAO,EAAE;IAAK,CAAC,CAAC;IAC3E,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE;MAAE,OAAO,EAAE;IAAK,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;IACtB,SAAS,CAAC,MAAM;MACd,oBAAoB,CAAC,KAAK,CAAC;MAC3B,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE;QAAE,OAAO,EAAE;MAAK,CAAC,CAAC;MAC/D,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC;MAC5C,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvB,CAAC,CAAC;EACJ,CAAC,CAAC;EAEJ,QACE;IAAA,cAIS,kCAAyB,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,6BAYlD,mBAAmB,CAAC,QAAQ;MAAC,KAAK,EAAE,KAAK;MAAA;QAAA,yBACvC,OAAO;UAAA,IAAC,KAAK;YAAA,OAAE,KAAK,CAAC,KAAK;UAAA;UAAA;YAAA,OAAG,KAAK,CAAC,QAAQ;UAAA;QAAA;MAAA;IAAA;EAAA;AAIpD","ignoreList":[]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createComponent as _$createComponent } from "solid-js/web";
|
|
2
|
+
import { memo as _$memo } from "solid-js/web";
|
|
2
3
|
import { ssr as _$ssr } from "solid-js/web";
|
|
3
4
|
import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
|
|
4
5
|
import { escape as _$escape } from "solid-js/web";
|
|
@@ -21,6 +22,8 @@ import { Dropdown } from "./Dropdown";
|
|
|
21
22
|
import { useToolbarMessages } from "./toolbar-messages";
|
|
22
23
|
const defaultToolbarOrientation = () => "horizontal";
|
|
23
24
|
const ToolbarOrientationContext = createContext(defaultToolbarOrientation);
|
|
25
|
+
/** False where actions are icon-sized, such as SelectionToolbar: no room below the icon for a hint. Package-internal. */
|
|
26
|
+
export const ToolbarHintsContext = createContext(true);
|
|
24
27
|
|
|
25
28
|
// `item` is created once per action: the More menu keys its rows by identity, so a remeasure keeps a focused row.
|
|
26
29
|
|
|
@@ -69,6 +72,7 @@ const ariaShortcut = (keys, platform) => {
|
|
|
69
72
|
};
|
|
70
73
|
const ToolbarAction = props => {
|
|
71
74
|
const register = useContext(ToolbarActionsContext);
|
|
75
|
+
const hints = useContext(ToolbarHintsContext);
|
|
72
76
|
const locale = useLocale();
|
|
73
77
|
const [platform, setPlatform] = createSignal(isServer || sharedConfig.context ? "other" : keyboardPlatform());
|
|
74
78
|
onMount(() => setPlatform(keyboardPlatform()));
|
|
@@ -101,7 +105,7 @@ const ToolbarAction = props => {
|
|
|
101
105
|
get children() {
|
|
102
106
|
return [_$ssr(_tmpl$, _$ssrAttribute("class", _$escape(props.icon, true), false)), _$createComponent(Show, {
|
|
103
107
|
get when() {
|
|
104
|
-
return props.keys;
|
|
108
|
+
return hints && props.keys;
|
|
105
109
|
},
|
|
106
110
|
children: keys => _$createComponent(Kbd, {
|
|
107
111
|
get keys() {
|