@k2b/ui 0.25.0 → 0.26.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/GestureMenu.js +2 -2
- package/dist/browser/actions/GestureMenu.js.map +1 -1
- package/dist/browser/content/Calendar.js +8 -7
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/CalendarDayView.js +4 -3
- package/dist/browser/content/CalendarDayView.js.map +1 -1
- package/dist/browser/content/CalendarWeekView.js +4 -3
- package/dist/browser/content/CalendarWeekView.js.map +1 -1
- package/dist/browser/content/Timeline.js +3 -3
- package/dist/browser/content/Timeline.js.map +1 -1
- package/dist/browser/content/calendar-time-view.js +0 -1
- package/dist/browser/content/calendar-time-view.js.map +1 -1
- package/dist/browser/index.js +1 -0
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/inputs/Combobox.js +22 -3
- package/dist/browser/inputs/Combobox.js.map +1 -1
- package/dist/browser/inputs/QrScanner.js +2 -1
- package/dist/browser/inputs/QrScanner.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +12 -13
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +4 -4
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/scroll-fade.js +14 -9
- package/dist/browser/layout/scroll-fade.js.map +1 -1
- package/dist/browser/layout/sidebar-scroll-memory.js +38 -0
- package/dist/browser/layout/sidebar-scroll-memory.js.map +1 -0
- package/dist/browser/motion.js +7 -0
- package/dist/browser/motion.js.map +1 -0
- package/dist/ssr/actions/GestureMenu.js +2 -2
- package/dist/ssr/actions/GestureMenu.js.map +1 -1
- package/dist/ssr/content/Calendar.js +8 -7
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/CalendarDayView.js +4 -3
- package/dist/ssr/content/CalendarDayView.js.map +1 -1
- package/dist/ssr/content/CalendarWeekView.js +4 -3
- package/dist/ssr/content/CalendarWeekView.js.map +1 -1
- package/dist/ssr/content/Timeline.js +3 -3
- package/dist/ssr/content/Timeline.js.map +1 -1
- package/dist/ssr/content/calendar-time-view.js +0 -1
- package/dist/ssr/content/calendar-time-view.js.map +1 -1
- package/dist/ssr/index.js +1 -0
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/inputs/Combobox.js +18 -3
- package/dist/ssr/inputs/Combobox.js.map +1 -1
- package/dist/ssr/inputs/QrScanner.js +2 -1
- package/dist/ssr/inputs/QrScanner.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +12 -13
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +4 -4
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/scroll-fade.js +14 -9
- package/dist/ssr/layout/scroll-fade.js.map +1 -1
- package/dist/ssr/layout/sidebar-scroll-memory.js +38 -0
- package/dist/ssr/layout/sidebar-scroll-memory.js.map +1 -0
- package/dist/ssr/motion.js +7 -0
- package/dist/ssr/motion.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/types/content/calendar-time-view.d.ts +0 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/inputs/Combobox.d.ts +1 -0
- package/dist/types/layout/scroll-fade.d.ts +2 -0
- package/dist/types/layout/sidebar-scroll-memory.d.ts +6 -0
- package/dist/types/motion.d.ts +6 -0
- package/package.json +1 -1
|
@@ -18,6 +18,7 @@ import { createSignal, onCleanup, onMount, Show } from "solid-js";
|
|
|
18
18
|
import { dialogCore } from "../feedback/dialog-core";
|
|
19
19
|
import { LocaleProvider, useLocale } from "../intl/locale";
|
|
20
20
|
import BottomSheet, { bottomSheetOptions } from "../layout/BottomSheet";
|
|
21
|
+
import { prefersReducedMotion } from "../motion";
|
|
21
22
|
import { ContextMenu } from "./ContextMenu";
|
|
22
23
|
import { DropdownItems, focusRowSegment } from "./Dropdown";
|
|
23
24
|
|
|
@@ -74,7 +75,6 @@ const afterClose = (items, run) => {
|
|
|
74
75
|
items: item.items.map(entry)
|
|
75
76
|
} : entry(item));
|
|
76
77
|
};
|
|
77
|
-
const reducedMotion = () => typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
78
78
|
const menuItems = menu => Array.from(menu.querySelectorAll("[role^='menuitem']:not([aria-disabled='true'])"));
|
|
79
79
|
|
|
80
80
|
/**
|
|
@@ -285,7 +285,7 @@ export function GestureMenu(props) {
|
|
|
285
285
|
const direction = dx > 0 ? "right" : "left";
|
|
286
286
|
if (!action(swipeKind(direction))) return;
|
|
287
287
|
clearTimeout(settleTimer);
|
|
288
|
-
reduced =
|
|
288
|
+
reduced = prefersReducedMotion();
|
|
289
289
|
moveSwipe(current, direction, dx);
|
|
290
290
|
};
|
|
291
291
|
const onPointerUp = event => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["actions/GestureMenu.tsx"],"sourcesContent":["import { createSignal, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { LocaleProvider, useLocale } from \"../intl/locale\";\nimport BottomSheet, { bottomSheetOptions } from \"../layout/BottomSheet\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport {\n type DropdownAction,\n type DropdownActionBase,\n type DropdownChoice,\n DropdownItems,\n type DropdownSection,\n focusRowSegment,\n} from \"./Dropdown\";\n\n/** A finger held this long without moving opens the menu, as the platforms' own long press does. */\nconst LONG_PRESS_MS = 500;\n/** A second tap that starts this soon after the first ended makes a double tap. */\nconst DOUBLE_TAP_MS = 300;\n/** The second tap lands at most this far from the first. */\nconst DOUBLE_TAP_DISTANCE = 32;\n/** Movement up to this is still a tap or a long press. */\nconst SLOP = 10;\n/** A swipe must be this many times wider than tall; anything steeper belongs to the page's scrolling. */\nconst SWIPE_RATIO = 1.5;\n/** Travel at which a released swipe runs its action. */\nconst SWIPE_THRESHOLD = 64;\n/** The content follows the finger up to the threshold, then at a quarter of its travel, up to this. */\nconst SWIPE_MAX = 96;\nconst SWIPE_RESISTANCE = 0.25;\n/** Swipes do not start this close to the screen's side edges, where the system's back and forward gestures are. */\nconst EDGE = 20;\n/** Duration of the snap back in `.k2b-gesture-menu[data-settling]`. */\nconst SETTLE_MS = 160;\n\n/**\n * Gestures never start on these elements: links, controls, fields, code blocks, and anything marked\n * `data-gesture-ignore` keep their own touch and mouse behavior.\n */\nconst IGNORE = [\n \"a[href]\",\n \"button\",\n \"input\",\n \"textarea\",\n \"select\",\n \"summary\",\n \"label\",\n \"audio\",\n \"video\",\n \"pre\",\n \"[contenteditable]:not([contenteditable='false'])\",\n \"[role='button']\",\n \"[role='link']\",\n \"[role='checkbox']\",\n \"[role='switch']\",\n \"[role='slider']\",\n \"[role='tab']\",\n \"[role^='menuitem']\",\n \"[data-gesture-ignore]\",\n].join(\", \");\n\nexport type GestureKind = \"swipe-right\" | \"swipe-left\" | \"double-tap\";\n\n/** A menu action that a gesture runs as well. */\nexport type GestureMenuAction = DropdownActionBase & {\n action: () => void;\n /** The gesture that runs this action. Give each gesture to at most one item; a disabled item disables its gesture. */\n gesture?: GestureKind;\n};\n\nexport type GestureMenuSection = Omit<DropdownSection, \"items\"> & {\n items: readonly (GestureMenuAction | DropdownAction | DropdownChoice)[];\n};\n\nexport type GestureMenuItem = GestureMenuAction | DropdownAction | DropdownChoice | GestureMenuSection;\n\nexport type GestureMenuProps = {\n /**\n * The menu. A long press opens it as a bottom sheet, a right-click, the Context Menu key, or Shift+F10 as a menu.\n * An item with `gesture` is also run by that gesture, so every gesture has its entry here.\n */\n items: readonly GestureMenuItem[];\n /** Names the element and its menu, for example \"Message from Nora, 10:42\". */\n label: string;\n children: JSX.Element;\n /** Shown above the menu in the long-press sheet, for example a row of quick reactions. `close` closes the sheet. */\n sheetTop?: (close: () => void) => JSX.Element;\n /** Tab order of the element. A list that moves focus between its rows itself passes -1. */\n tabIndex?: number;\n /** Runs before the menu or the sheet shows its items, for example to select what was pressed. */\n onOpen?: () => void;\n class?: string;\n};\n\ntype SwipeDirection = \"right\" | \"left\";\n\ntype Swipe = {\n direction: SwipeDirection;\n icon?: string;\n /** How far the content is moved, in pixels; always 0 with reduced motion. */\n offset: number;\n /** Travel relative to the threshold, from 0 to 1. */\n progress: number;\n armed: boolean;\n settling: boolean;\n};\n\ntype Press = {\n id: number;\n x: number;\n y: number;\n timer?: ReturnType<typeof setTimeout>;\n /** The finger left the slop: no tap or long press any more. */\n moved: boolean;\n /** The long press opened the sheet. */\n long: boolean;\n /** The press started soon after a tap nearby. */\n second: boolean;\n /** The press started at a side edge of the screen. */\n edge: boolean;\n direction?: SwipeDirection;\n};\n\ntype Entry = GestureMenuAction | DropdownAction | DropdownChoice;\n\nconst gestureAction = (items: readonly GestureMenuItem[], kind: GestureKind): GestureMenuAction | undefined => {\n for (const item of items)\n for (const entry of \"items\" in item ? item.items : [item])\n if (\"gesture\" in entry && entry.gesture === kind) return entry.disabled ? undefined : entry;\n return undefined;\n};\n\nconst swipeKind = (direction: SwipeDirection): GestureKind => (direction === \"right\" ? \"swipe-right\" : \"swipe-left\");\n\n/**\n * The sheet's items hand their action to `run` instead of running it while the sheet closes: `dialogCore` settles the\n * sheet after it left the history, and only then may an action navigate or open the next dialog.\n * A choice or action that keeps the menu open runs at once.\n */\nconst afterClose = (items: readonly GestureMenuItem[], run: (action: () => void) => void): GestureMenuItem[] => {\n const entry = (item: Entry): Entry => {\n const action = item.action;\n if (!action || (\"closeOnSelect\" in item && item.closeOnSelect === false)) return item;\n return { ...item, action: () => run(action) };\n };\n return items.map((item) => (\"items\" in item ? { ...item, items: item.items.map(entry) } : entry(item)));\n};\n\nconst reducedMotion = () => typeof matchMedia === \"function\" && matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n\nconst menuItems = (menu: HTMLElement): HTMLElement[] =>\n Array.from(menu.querySelectorAll<HTMLElement>(\"[role^='menuitem']:not([aria-disabled='true'])\"));\n\n/**\n * The menu inside the long-press sheet: the same items, at touch size, with arrow keys for a connected keyboard. Focus\n * starts on the sheet itself, which shows no ring on a phone; the first arrow key moves it into the menu.\n */\nfunction SheetMenu(props: { items: readonly GestureMenuItem[]; label: string; close: () => void; dialog: HTMLDialogElement }): JSX.Element {\n let menu!: HTMLDivElement;\n const focus = (index: number) => {\n const items = menuItems(menu);\n items[(index + items.length) % items.length]?.focus();\n };\n const onKeyDown = (event: KeyboardEvent) => {\n const items = menuItems(menu);\n const current = items.indexOf(document.activeElement as HTMLElement);\n if (event.key === \"ArrowDown\") focus(current + 1);\n else if (event.key === \"ArrowUp\") focus(current < 0 ? -1 : current - 1);\n else if (event.key === \"Home\" || event.key === \"End\") focus(event.key === \"Home\" ? 0 : -1);\n else if (!focusRowSegment(items, event.key)) return;\n event.preventDefault();\n };\n // Keys pressed on the sheet itself, while it is the top level of the shared dialog.\n const onSheetKeyDown = (event: KeyboardEvent) => {\n if (event.target === props.dialog && props.dialog.lastElementChild?.contains(menu)) onKeyDown(event);\n };\n onMount(() => {\n props.dialog.addEventListener(\"keydown\", onSheetKeyDown);\n onCleanup(() => props.dialog.removeEventListener(\"keydown\", onSheetKeyDown));\n });\n return (\n <div ref={menu} class=\"k2b-gesture-menu__sheet-menu\" role=\"menu\" aria-label={props.label} onKeyDown={onKeyDown}>\n <DropdownItems items={props.items} close={() => props.close()} />\n </div>\n );\n}\n\n/**\n * Touch gestures for an element, each the shortcut of an entry in its menu: a horizontal swipe, a double tap, and a\n * long press that opens the whole menu as a `BottomSheet`. A mouse double-click runs the double-tap action; a\n * right-click and the keyboard open the menu beside the element. Vertical scrolling never turns into a swipe.\n */\nexport function GestureMenu(props: GestureMenuProps): JSX.Element {\n const locale = useLocale();\n const [swipe, setSwipe] = createSignal<Swipe>();\n let surface!: HTMLDivElement;\n let press: Press | undefined;\n let lastTap: { x: number; y: number; at: number } | undefined;\n let lastPointer = \"mouse\";\n /**\n * The touch or pen press that just ended did something: its `touchend` is cancelled, so no click or mouse events\n * follow, and a pen's click, which comes without touch events, is cancelled itself.\n */\n let consumed = false;\n let sheetOpen = false;\n /** Closes an open sheet when the element goes, for example when its message is deleted. */\n const disposed = new AbortController();\n let reduced = false;\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n\n const active = () => props.items.length > 0;\n const action = (kind: GestureKind) => gestureAction(props.items, kind);\n const touchAction = () => (action(\"swipe-right\") || action(\"swipe-left\") ? \"swipe\" : action(\"double-tap\") ? \"tap\" : undefined);\n\n /** Whether the event started on something with a meaning of its own, inside this element. */\n const ignored = (target: EventTarget | null) => {\n const found = target instanceof Element ? target.closest(IGNORE) : null;\n return found !== null && found !== surface && surface.contains(found);\n };\n\n const openSheet = () => {\n if (sheetOpen || !active()) return;\n sheetOpen = true;\n props.onOpen?.();\n const current = locale();\n let chosen: (() => void) | undefined;\n const choose = (action: () => void) => {\n chosen = action;\n };\n void dialogCore\n .open<void>(\n (close, context) => (\n <LocaleProvider locale={current}>\n <BottomSheet onDismiss={context.requestDismiss}>\n <BottomSheet.Body>\n {props.sheetTop?.(() => close())}\n <SheetMenu items={afterClose(props.items, choose)} label={props.label} close={() => close()} dialog={context.dialog} />\n </BottomSheet.Body>\n </BottomSheet>\n </LocaleProvider>\n ),\n { ...bottomSheetOptions, ariaLabel: props.label, history: true, signal: disposed.signal },\n )\n .then(() => chosen?.())\n .finally(() => {\n sheetOpen = false;\n });\n };\n\n /** Another pointer that goes down anywhere while a finger presses, as in a pinch, ends the gesture. */\n const onOtherPointer = (event: PointerEvent) => {\n if (!press || event.pointerId === press.id) return;\n if (press.direction) settle();\n endPress();\n };\n\n const endPress = () => {\n clearTimeout(press?.timer);\n press = undefined;\n document.removeEventListener(\"pointerdown\", onOtherPointer, true);\n delete surface.dataset.pressing;\n };\n\n const settle = () => {\n const current = swipe();\n if (!current) return;\n clearTimeout(settleTimer);\n if (reduced || current.offset === 0) {\n setSwipe(undefined);\n return;\n }\n setSwipe({ ...current, offset: 0, progress: 0, armed: false, settling: true });\n settleTimer = setTimeout(() => setSwipe(undefined), SETTLE_MS);\n };\n\n const moveSwipe = (current: Press, direction: SwipeDirection, dx: number) => {\n const travel = Math.max(0, direction === \"right\" ? dx : -dx);\n const moved = travel <= SWIPE_THRESHOLD ? travel : SWIPE_THRESHOLD + (travel - SWIPE_THRESHOLD) * SWIPE_RESISTANCE;\n const offset = reduced ? 0 : Math.min(SWIPE_MAX, moved) * (direction === \"right\" ? 1 : -1);\n current.direction = direction;\n setSwipe({\n direction,\n icon: action(swipeKind(direction))?.icon,\n offset,\n progress: Math.min(1, travel / SWIPE_THRESHOLD),\n armed: travel >= SWIPE_THRESHOLD,\n settling: false,\n });\n };\n\n const longPress = () => {\n if (!press) return;\n press.long = true;\n lastTap = undefined;\n openSheet();\n };\n\n const onPointerDown = (event: PointerEvent) => {\n lastPointer = event.pointerType;\n consumed = false;\n // Any press in between, on a link, with a mouse, or with another finger, ends a pending double tap.\n const previous = lastTap;\n lastTap = undefined;\n // Another finger ends the gesture through `onOtherPointer` and starts none.\n if (event.pointerType === \"mouse\" || !event.isPrimary) return;\n endPress();\n if (!active() || ignored(event.target)) return;\n const second =\n previous !== undefined &&\n performance.now() - previous.at <= DOUBLE_TAP_MS &&\n Math.hypot(event.clientX - previous.x, event.clientY - previous.y) <= DOUBLE_TAP_DISTANCE;\n press = {\n id: event.pointerId,\n x: event.clientX,\n y: event.clientY,\n moved: false,\n long: false,\n second,\n edge: event.clientX < EDGE || event.clientX > window.innerWidth - EDGE,\n timer: setTimeout(longPress, LONG_PRESS_MS),\n };\n document.addEventListener(\"pointerdown\", onOtherPointer, true);\n // Hybrid devices keep text selection for the mouse; a finger on the element selects nothing.\n surface.dataset.pressing = \"\";\n };\n\n const onPointerMove = (event: PointerEvent) => {\n const current = press;\n if (!current || event.pointerId !== current.id || current.long) return;\n const dx = event.clientX - current.x;\n const dy = event.clientY - current.y;\n if (current.direction) {\n moveSwipe(current, current.direction, dx);\n return;\n }\n if (current.moved || Math.hypot(dx, dy) < SLOP) return;\n current.moved = true;\n clearTimeout(current.timer);\n if (current.edge || Math.abs(dx) < Math.abs(dy) * SWIPE_RATIO) return;\n const direction: SwipeDirection = dx > 0 ? \"right\" : \"left\";\n if (!action(swipeKind(direction))) return;\n clearTimeout(settleTimer);\n reduced = reducedMotion();\n moveSwipe(current, direction, dx);\n };\n\n const onPointerUp = (event: PointerEvent) => {\n const current = press;\n if (!current || event.pointerId !== current.id) return;\n endPress();\n if (current.long) {\n consumed = true;\n return;\n }\n if (current.direction) {\n // Where the finger lifts decides, and the item as it is now.\n moveSwipe(current, current.direction, event.clientX - current.x);\n const swipeAction = swipe()?.armed ? action(swipeKind(current.direction)) : undefined;\n settle();\n if (swipeAction) {\n consumed = true;\n swipeAction.action();\n }\n return;\n }\n if (current.moved) return;\n const doubleTap = action(\"double-tap\");\n if (!doubleTap) return;\n if (current.second) {\n consumed = true;\n doubleTap.action();\n return;\n }\n lastTap = { x: event.clientX, y: event.clientY, at: performance.now() };\n };\n\n // The browser took the touch, for example to scroll the page.\n const onPointerCancel = (event: PointerEvent) => {\n if (!press || event.pointerId !== press.id) return;\n if (press.direction) settle();\n endPress();\n lastTap = undefined;\n };\n\n const onTouchEnd = (event: TouchEvent) => {\n if (!consumed) return;\n consumed = false;\n if (event.cancelable) event.preventDefault();\n };\n\n // A pen sends no touch events; the click after its gesture is cancelled here. A keyboard's click has no detail.\n const onClick = (event: MouseEvent) => {\n if (!consumed || event.detail === 0) return;\n consumed = false;\n event.preventDefault();\n event.stopPropagation();\n };\n\n const onContextMenu = (event: MouseEvent) => {\n // Without items the element has no menu, and the browser keeps its own.\n if (!active()) return;\n // Links, fields, and code keep the browser's own menu.\n if (ignored(event.target)) {\n event.stopPropagation();\n return;\n }\n // A mouse or the keyboard opens the menu beside the element through ContextMenu.\n if (!press && !(\"pointerType\" in event && (event.pointerType === \"touch\" || event.pointerType === \"pen\"))) return;\n // Android and touch screens report a long press as a context-menu event, sometimes before the timer.\n event.preventDefault();\n event.stopPropagation();\n if (press && !press.long && !press.moved) {\n clearTimeout(press.timer);\n longPress();\n }\n };\n\n // The second press of a mouse double-click would select a word; in this element it runs the double-tap action.\n const onMouseDown = (event: MouseEvent) => {\n if (event.button === 0 && event.detail >= 2 && lastPointer === \"mouse\" && action(\"double-tap\") && !ignored(event.target))\n event.preventDefault();\n };\n\n const onDoubleClick = (event: MouseEvent) => {\n if (lastPointer !== \"mouse\" || ignored(event.target)) return;\n const doubleTap = action(\"double-tap\");\n if (!doubleTap) return;\n event.preventDefault();\n doubleTap.action();\n };\n\n onMount(() => {\n surface.addEventListener(\"pointerdown\", onPointerDown);\n surface.addEventListener(\"pointermove\", onPointerMove);\n surface.addEventListener(\"pointerup\", onPointerUp);\n surface.addEventListener(\"pointercancel\", onPointerCancel);\n surface.addEventListener(\"touchend\", onTouchEnd, { passive: false });\n surface.addEventListener(\"click\", onClick, true);\n surface.addEventListener(\"contextmenu\", onContextMenu);\n surface.addEventListener(\"mousedown\", onMouseDown);\n surface.addEventListener(\"dblclick\", onDoubleClick);\n onCleanup(() => {\n disposed.abort();\n endPress();\n clearTimeout(settleTimer);\n surface.removeEventListener(\"pointerdown\", onPointerDown);\n surface.removeEventListener(\"pointermove\", onPointerMove);\n surface.removeEventListener(\"pointerup\", onPointerUp);\n surface.removeEventListener(\"pointercancel\", onPointerCancel);\n surface.removeEventListener(\"touchend\", onTouchEnd);\n surface.removeEventListener(\"click\", onClick, true);\n surface.removeEventListener(\"contextmenu\", onContextMenu);\n surface.removeEventListener(\"mousedown\", onMouseDown);\n surface.removeEventListener(\"dblclick\", onDoubleClick);\n });\n });\n\n return (\n <ContextMenu\n items={props.items}\n label={props.label}\n tabIndex={props.tabIndex}\n disabled={!active()}\n onOpen={props.onOpen}\n class={props.class}\n >\n <div\n ref={surface}\n class=\"k2b-gesture-menu\"\n data-active={active() ? \"\" : undefined}\n data-touch={touchAction()}\n data-swipe={swipe()?.direction}\n data-armed={swipe()?.armed ? \"\" : undefined}\n data-settling={swipe()?.settling ? \"\" : undefined}\n style={{\n \"--k2b-gesture-menu-offset\": `${swipe()?.offset ?? 0}px`,\n \"--k2b-gesture-menu-progress\": String(swipe()?.progress ?? 0),\n }}\n >\n <Show when={swipe()}>\n {(current) => (\n <span class=\"k2b-gesture-menu__swipe\" aria-hidden=\"true\">\n <i class={current().icon ?? (current().direction === \"right\" ? \"ti ti-arrow-right\" : \"ti ti-arrow-left\")} />\n </span>\n )}\n </Show>\n <div class=\"k2b-gesture-menu__content\">{props.children}</div>\n </div>\n </ContextMenu>\n );\n}\n\nexport default GestureMenu;\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,YAAY,EAAY,SAAS,EAAE,OAAO,EAAE,IAAI,QAAQ,UAAU;AAC3E,SAAS,UAAU,QAAQ,yBAAyB;AACpD,SAAS,cAAc,EAAE,SAAS,QAAQ,gBAAgB;AAC1D,OAAO,WAAW,IAAI,kBAAkB,QAAQ,uBAAuB;AACvE,SAAS,WAAW,QAAQ,eAAe;AAC3C,SAIE,aAAa,EAEb,eAAe,QACV,YAAY;;AAEnB;AACA,MAAM,aAAa,GAAG,GAAG;AACzB;AACA,MAAM,aAAa,GAAG,GAAG;AACzB;AACA,MAAM,mBAAmB,GAAG,EAAE;AAC9B;AACA,MAAM,IAAI,GAAG,EAAE;AACf;AACA,MAAM,WAAW,GAAG,GAAG;AACvB;AACA,MAAM,eAAe,GAAG,EAAE;AAC1B;AACA,MAAM,SAAS,GAAG,EAAE;AACpB,MAAM,gBAAgB,GAAG,IAAI;AAC7B;AACA,MAAM,IAAI,GAAG,EAAE;AACf;AACA,MAAM,SAAS,GAAG,GAAG;;AAErB;AACA;AACA;AACA;AACA,MAAM,MAAM,GAAG,CACb,SAAS,EACT,QAAQ,EACR,OAAO,EACP,UAAU,EACV,QAAQ,EACR,SAAS,EACT,OAAO,EACP,OAAO,EACP,OAAO,EACP,KAAK,EACL,kDAAkD,EAClD,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,uBAAuB,CACxB,CAAC,IAAI,CAAC,IAAI,CAAC;;AAIZ;;AA8DA,MAAM,aAAa,GAAG,CAAC,KAAiC,EAAE,IAAiB,KAAoC;EAC7G,KAAK,MAAM,IAAI,IAAI,KAAK,EACtB,KAAK,MAAM,KAAK,IAAI,OAAO,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,EACvD,IAAI,SAAS,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,OAAO,KAAK,CAAC,QAAQ,GAAG,SAAS,GAAG,KAAK;EAC/F,OAAO,SAAS;AAClB,CAAC;AAED,MAAM,SAAS,GAAI,SAAyB,IAAmB,SAAS,KAAK,OAAO,GAAG,aAAa,GAAG,YAAa;;AAEpH;AACA;AACA;AACA;AACA;AACA,MAAM,UAAU,GAAG,CAAC,KAAiC,EAAE,GAAiC,KAAwB;EAC9G,MAAM,KAAK,GAAI,IAAW,IAAY;IACpC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;IAC1B,IAAI,CAAC,MAAM,IAAK,eAAe,IAAI,IAAI,IAAI,IAAI,CAAC,aAAa,KAAK,KAAM,EAAE,OAAO,IAAI;IACrF,OAAO;MAAE,GAAG,IAAI;MAAE,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM;IAAE,CAAC;EAC/C,CAAC;EACD,OAAO,KAAK,CAAC,GAAG,CAAE,IAAI,IAAM,OAAO,IAAI,IAAI,GAAG;IAAE,GAAG,IAAI;IAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK;EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAE,CAAC;AACzG,CAAC;AAED,MAAM,aAAa,GAAG,MAAM,OAAO,UAAU,KAAK,UAAU,IAAI,UAAU,CAAC,kCAAkC,CAAC,CAAC,OAAO;AAEtH,MAAM,SAAS,GAAI,IAAiB,IAClC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAc,gDAAgD,CAAC,CAAC;;AAElG;AACA;AACA;AACA;AACA,SAAS,SAAS,CAAC,KAAyG,EAAe;EACzI,IAAI,IAAqB;EACzB,MAAM,KAAK,GAAI,KAAa,IAAK;IAC/B,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC;IAC7B,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;EACvD,CAAC;EACD,MAAM,SAAS,GAAI,KAAoB,IAAK;IAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC;IAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAA4B,CAAC;IACpE,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,KAC7C,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,KACnE,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KACtF,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE;IAC7C,KAAK,CAAC,cAAc,CAAC,CAAC;EACxB,CAAC;EACD;EACA,MAAM,cAAc,GAAI,KAAoB,IAAK;IAC/C,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC;EACtG,CAAC;EACD,OAAO,CAAC,MAAM;IACZ,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,CAAC;IACxD,SAAS,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;EAC9E,CAAC,CAAC;EACF;IAAA;IAAA,iBACuG,SAAS;IAAA,YAApG,IAAI;IAAA,mDAAJ,IAAI;IAAA,iCACX,aAAa;MAAA,IAAC,KAAK;QAAA,OAAE,KAAK,CAAC,KAAK;MAAA;MAAE,KAAK,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC;IAAC;IAAA,kDADc,KAAK,CAAC,KAAK;IAAA;IAAA;EAAA;AAI5F;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS,WAAW,CAAC,KAAuB,EAAe;EAChE,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;EAC1B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAQ,CAAC;EAC/C,IAAI,OAAwB;EAC5B,IAAI,KAAwB;EAC5B,IAAI,OAAyD;EAC7D,IAAI,WAAW,GAAG,OAAO;EACzB;AACF;AACA;AACA;EACE,IAAI,QAAQ,GAAG,KAAK;EACpB,IAAI,SAAS,GAAG,KAAK;EACrB;EACA,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,CAAC;EACtC,IAAI,OAAO,GAAG,KAAK;EACnB,IAAI,WAAsD;EAE1D,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;EAC3C,MAAM,MAAM,GAAI,IAAiB,IAAK,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC;EACtE,MAAM,WAAW,GAAG,MAAO,MAAM,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,GAAG,SAAU;;EAE9H;EACA,MAAM,OAAO,GAAI,MAA0B,IAAK;IAC9C,MAAM,KAAK,GAAG,MAAM,YAAY,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IACvE,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;EACvE,CAAC;EAED,MAAM,SAAS,GAAG,MAAM;IACtB,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE;IAC5B,SAAS,GAAG,IAAI;IAChB,KAAK,CAAC,MAAM,GAAG,CAAC;IAChB,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC;IACxB,IAAI,MAAgC;IACpC,MAAM,MAAM,GAAI,MAAkB,IAAK;MACrC,MAAM,GAAG,MAAM;IACjB,CAAC;IACD,KAAK,UAAU,CACZ,IAAI,CACH,CAAC,KAAK,EAAE,OAAO,uBACZ,cAAc;MAAC,MAAM,EAAE,OAAO;MAAA;QAAA,yBAC5B,WAAW;UAAA,IAAC,SAAS;YAAA,OAAE,OAAO,CAAC,cAAc;UAAA;UAAA;YAAA,yBAC3C,WAAW,CAAC,IAAI;cAAA;gBAAA,qBACd,KAAK,CAAC,QAAQ,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,qBAC/B,SAAS;kBAAA,IAAC,KAAK;oBAAA,OAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;kBAAA;kBAAA,IAAE,KAAK;oBAAA,OAAE,KAAK,CAAC,KAAK;kBAAA;kBAAE,KAAK,EAAE,MAAM,KAAK,CAAC,CAAC;kBAAA,IAAE,MAAM;oBAAA,OAAE,OAAO,CAAC,MAAM;kBAAA;gBAAA;cAAA;YAAA;UAAA;QAAA;MAAA;IAAA,EAI1H,EACD;MAAE,GAAG,kBAAkB;MAAE,SAAS,EAAE,KAAK,CAAC,KAAK;MAAE,OAAO,EAAE,IAAI;MAAE,MAAM,EAAE,QAAQ,CAAC;IAAO,CAC1F,CAAC,CACA,IAAI,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC,CACtB,OAAO,CAAC,MAAM;MACb,SAAS,GAAG,KAAK;IACnB,CAAC,CAAC;EACN,CAAC;;EAED;EACA,MAAM,cAAc,GAAI,KAAmB,IAAK;IAC9C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,EAAE;IAC5C,IAAI,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,CAAC,CAAC;EACZ,CAAC;EAED,MAAM,QAAQ,GAAG,MAAM;IACrB,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;IAC1B,KAAK,GAAG,SAAS;IACjB,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC;IACjE,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ;EACjC,CAAC;EAED,MAAM,MAAM,GAAG,MAAM;IACnB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC;IACvB,IAAI,CAAC,OAAO,EAAE;IACd,YAAY,CAAC,WAAW,CAAC;IACzB,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;MACnC,QAAQ,CAAC,SAAS,CAAC;MACnB;IACF;IACA,QAAQ,CAAC;MAAE,GAAG,OAAO;MAAE,MAAM,EAAE,CAAC;MAAE,QAAQ,EAAE,CAAC;MAAE,KAAK,EAAE,KAAK;MAAE,QAAQ,EAAE;IAAK,CAAC,CAAC;IAC9E,WAAW,GAAG,UAAU,CAAC,MAAM,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;EAChE,CAAC;EAED,MAAM,SAAS,GAAG,CAAC,OAAc,EAAE,SAAyB,EAAE,EAAU,KAAK;IAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,KAAK,OAAO,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,IAAI,eAAe,GAAG,MAAM,GAAG,eAAe,GAAG,CAAC,MAAM,GAAG,eAAe,IAAI,gBAAgB;IAClH,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,SAAS,KAAK,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1F,OAAO,CAAC,SAAS,GAAG,SAAS;IAC7B,QAAQ,CAAC;MACP,SAAS;MACT,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI;MACxC,MAAM;MACN,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC;MAC/C,KAAK,EAAE,MAAM,IAAI,eAAe;MAChC,QAAQ,EAAE;IACZ,CAAC,CAAC;EACJ,CAAC;EAED,MAAM,SAAS,GAAG,MAAM;IACtB,IAAI,CAAC,KAAK,EAAE;IACZ,KAAK,CAAC,IAAI,GAAG,IAAI;IACjB,OAAO,GAAG,SAAS;IACnB,SAAS,CAAC,CAAC;EACb,CAAC;EAED,MAAM,aAAa,GAAI,KAAmB,IAAK;IAC7C,WAAW,GAAG,KAAK,CAAC,WAAW;IAC/B,QAAQ,GAAG,KAAK;IAChB;IACA,MAAM,QAAQ,GAAG,OAAO;IACxB,OAAO,GAAG,SAAS;IACnB;IACA,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;IACvD,QAAQ,CAAC,CAAC;IACV,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;IACxC,MAAM,MAAM,GACV,QAAQ,KAAK,SAAS,IACtB,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,EAAE,IAAI,aAAa,IAChD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,mBAAmB;IAC3F,KAAK,GAAG;MACN,EAAE,EAAE,KAAK,CAAC,SAAS;MACnB,CAAC,EAAE,KAAK,CAAC,OAAO;MAChB,CAAC,EAAE,KAAK,CAAC,OAAO;MAChB,KAAK,EAAE,KAAK;MACZ,IAAI,EAAE,KAAK;MACX,MAAM;MACN,IAAI,EAAE,KAAK,CAAC,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI;MACtE,KAAK,EAAE,UAAU,CAAC,SAAS,EAAE,aAAa;IAC5C,CAAC;IACD,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC;IAC9D;IACA,OAAO,CAAC,OAAO,CAAC,QAAQ,GAAG,EAAE;EAC/B,CAAC;EAED,MAAM,aAAa,GAAI,KAAmB,IAAK;IAC7C,MAAM,OAAO,GAAG,KAAK;IACrB,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE;IAChE,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC;IACpC,IAAI,OAAO,CAAC,SAAS,EAAE;MACrB,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;MACzC;IACF;IACA,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE;IAChD,OAAO,CAAC,KAAK,GAAG,IAAI;IACpB,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3B,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE;IAC/D,MAAM,SAAyB,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,GAAG,MAAM;IAC3D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE;IACnC,YAAY,CAAC,WAAW,CAAC;IACzB,OAAO,GAAG,aAAa,CAAC,CAAC;IACzB,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC;EACnC,CAAC;EAED,MAAM,WAAW,GAAI,KAAmB,IAAK;IAC3C,MAAM,OAAO,GAAG,KAAK;IACrB,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,EAAE;IAChD,QAAQ,CAAC,CAAC;IACV,IAAI,OAAO,CAAC,IAAI,EAAE;MAChB,QAAQ,GAAG,IAAI;MACf;IACF;IACA,IAAI,OAAO,CAAC,SAAS,EAAE;MACrB;MACA,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;MAChE,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,SAAS;MACrF,MAAM,CAAC,CAAC;MACR,IAAI,WAAW,EAAE;QACf,QAAQ,GAAG,IAAI;QACf,WAAW,CAAC,MAAM,CAAC,CAAC;MACtB;MACA;IACF;IACA,IAAI,OAAO,CAAC,KAAK,EAAE;IACnB,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC;IACtC,IAAI,CAAC,SAAS,EAAE;IAChB,IAAI,OAAO,CAAC,MAAM,EAAE;MAClB,QAAQ,GAAG,IAAI;MACf,SAAS,CAAC,MAAM,CAAC,CAAC;MAClB;IACF;IACA,OAAO,GAAG;MAAE,CAAC,EAAE,KAAK,CAAC,OAAO;MAAE,CAAC,EAAE,KAAK,CAAC,OAAO;MAAE,EAAE,EAAE,WAAW,CAAC,GAAG,CAAC;IAAE,CAAC;EACzE,CAAC;;EAED;EACA,MAAM,eAAe,GAAI,KAAmB,IAAK;IAC/C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,EAAE;IAC5C,IAAI,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,CAAC,CAAC;IACV,OAAO,GAAG,SAAS;EACrB,CAAC;EAED,MAAM,UAAU,GAAI,KAAiB,IAAK;IACxC,IAAI,CAAC,QAAQ,EAAE;IACf,QAAQ,GAAG,KAAK;IAChB,IAAI,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;EAC9C,CAAC;;EAED;EACA,MAAM,OAAO,GAAI,KAAiB,IAAK;IACrC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;IACrC,QAAQ,GAAG,KAAK;IAChB,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,KAAK,CAAC,eAAe,CAAC,CAAC;EACzB,CAAC;EAED,MAAM,aAAa,GAAI,KAAiB,IAAK;IAC3C;IACA,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE;IACf;IACA,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;MACzB,KAAK,CAAC,eAAe,CAAC,CAAC;MACvB;IACF;IACA;IACA,IAAI,CAAC,KAAK,IAAI,EAAE,aAAa,IAAI,KAAK,KAAK,KAAK,CAAC,WAAW,KAAK,OAAO,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,CAAC,EAAE;IAC3G;IACA,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,KAAK,CAAC,eAAe,CAAC,CAAC;IACvB,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;MACxC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC;MACzB,SAAS,CAAC,CAAC;IACb;EACF,CAAC;;EAED;EACA,MAAM,WAAW,GAAI,KAAiB,IAAK;IACzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,WAAW,KAAK,OAAO,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EACtH,KAAK,CAAC,cAAc,CAAC,CAAC;EAC1B,CAAC;EAED,MAAM,aAAa,GAAI,KAAiB,IAAK;IAC3C,IAAI,WAAW,KAAK,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;IACtD,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC;IACtC,IAAI,CAAC,SAAS,EAAE;IAChB,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,SAAS,CAAC,MAAM,CAAC,CAAC;EACpB,CAAC;EAED,OAAO,CAAC,MAAM;IACZ,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC;IACtD,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC;IACtD,OAAO,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC;IAClD,OAAO,CAAC,gBAAgB,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1D,OAAO,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE;MAAE,OAAO,EAAE;IAAM,CAAC,CAAC;IACpE,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;IAChD,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC;IACtD,OAAO,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC;IAClD,OAAO,CAAC,gBAAgB,CAAC,UAAU,EAAE,aAAa,CAAC;IACnD,SAAS,CAAC,MAAM;MACd,QAAQ,CAAC,KAAK,CAAC,CAAC;MAChB,QAAQ,CAAC,CAAC;MACV,YAAY,CAAC,WAAW,CAAC;MACzB,OAAO,CAAC,mBAAmB,CAAC,aAAa,EAAE,aAAa,CAAC;MACzD,OAAO,CAAC,mBAAmB,CAAC,aAAa,EAAE,aAAa,CAAC;MACzD,OAAO,CAAC,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC;MACrD,OAAO,CAAC,mBAAmB,CAAC,eAAe,EAAE,eAAe,CAAC;MAC7D,OAAO,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC;MACnD,OAAO,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;MACnD,OAAO,CAAC,mBAAmB,CAAC,aAAa,EAAE,aAAa,CAAC;MACzD,OAAO,CAAC,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC;MACrD,OAAO,CAAC,mBAAmB,CAAC,UAAU,EAAE,aAAa,CAAC;IACxD,CAAC,CAAC;EACJ,CAAC,CAAC;EAEF,yBACG,WAAW;IAAA,IACV,KAAK;MAAA,OAAE,KAAK,CAAC,KAAK;IAAA;IAAA,IAClB,KAAK;MAAA,OAAE,KAAK,CAAC,KAAK;IAAA;IAAA,IAClB,QAAQ;MAAA,OAAE,KAAK,CAAC,QAAQ;IAAA;IAAA,IACxB,QAAQ;MAAA,OAAE,CAAC,MAAM,CAAC,CAAC;IAAA;IAAA,IACnB,MAAM;MAAA,OAAE,KAAK,CAAC,MAAM;IAAA;IAAA;MAAA,OACb,KAAK,CAAC,KAAK;IAAA;IAAA;MAAA;QAAA;QAAA;QAAA;MAAA,aAGX,OAAO;MAAA,sDAAP,OAAO;MAAA,kCAYX,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,CAAC;QAAA;QAAA,UACf,OAAO;UAAA;YAAA;UAAA,kCAEK,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;UAAA;QAAA;MAE3G;MAAA,sBAEqC,KAAK,CAAC,QAAQ;MAAA;QAAA,UAjBzC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,SAAS;UAAA,OAC1B,WAAW,CAAC,CAAC;UAAA,OACb,KAAK,CAAC,CAAC,EAAE,SAAS;UAAA,OAClB,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,EAAE,GAAG,SAAS;UAAA,OAC5B,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,EAAE,GAAG,SAAS;UAAA,OAElB,GAAG,KAAK,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,IAAI;UAAA,OACzB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;MAAA;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;MAAA;MAAA;IAAA;EAAA;AAcvE;AAEA,eAAe,WAAW;AAAC","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["actions/GestureMenu.tsx"],"sourcesContent":["import { createSignal, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { LocaleProvider, useLocale } from \"../intl/locale\";\nimport BottomSheet, { bottomSheetOptions } from \"../layout/BottomSheet\";\nimport { prefersReducedMotion } from \"../motion\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport {\n type DropdownAction,\n type DropdownActionBase,\n type DropdownChoice,\n DropdownItems,\n type DropdownSection,\n focusRowSegment,\n} from \"./Dropdown\";\n\n/** A finger held this long without moving opens the menu, as the platforms' own long press does. */\nconst LONG_PRESS_MS = 500;\n/** A second tap that starts this soon after the first ended makes a double tap. */\nconst DOUBLE_TAP_MS = 300;\n/** The second tap lands at most this far from the first. */\nconst DOUBLE_TAP_DISTANCE = 32;\n/** Movement up to this is still a tap or a long press. */\nconst SLOP = 10;\n/** A swipe must be this many times wider than tall; anything steeper belongs to the page's scrolling. */\nconst SWIPE_RATIO = 1.5;\n/** Travel at which a released swipe runs its action. */\nconst SWIPE_THRESHOLD = 64;\n/** The content follows the finger up to the threshold, then at a quarter of its travel, up to this. */\nconst SWIPE_MAX = 96;\nconst SWIPE_RESISTANCE = 0.25;\n/** Swipes do not start this close to the screen's side edges, where the system's back and forward gestures are. */\nconst EDGE = 20;\n/** Duration of the snap back in `.k2b-gesture-menu[data-settling]`. */\nconst SETTLE_MS = 160;\n\n/**\n * Gestures never start on these elements: links, controls, fields, code blocks, and anything marked\n * `data-gesture-ignore` keep their own touch and mouse behavior.\n */\nconst IGNORE = [\n \"a[href]\",\n \"button\",\n \"input\",\n \"textarea\",\n \"select\",\n \"summary\",\n \"label\",\n \"audio\",\n \"video\",\n \"pre\",\n \"[contenteditable]:not([contenteditable='false'])\",\n \"[role='button']\",\n \"[role='link']\",\n \"[role='checkbox']\",\n \"[role='switch']\",\n \"[role='slider']\",\n \"[role='tab']\",\n \"[role^='menuitem']\",\n \"[data-gesture-ignore]\",\n].join(\", \");\n\nexport type GestureKind = \"swipe-right\" | \"swipe-left\" | \"double-tap\";\n\n/** A menu action that a gesture runs as well. */\nexport type GestureMenuAction = DropdownActionBase & {\n action: () => void;\n /** The gesture that runs this action. Give each gesture to at most one item; a disabled item disables its gesture. */\n gesture?: GestureKind;\n};\n\nexport type GestureMenuSection = Omit<DropdownSection, \"items\"> & {\n items: readonly (GestureMenuAction | DropdownAction | DropdownChoice)[];\n};\n\nexport type GestureMenuItem = GestureMenuAction | DropdownAction | DropdownChoice | GestureMenuSection;\n\nexport type GestureMenuProps = {\n /**\n * The menu. A long press opens it as a bottom sheet, a right-click, the Context Menu key, or Shift+F10 as a menu.\n * An item with `gesture` is also run by that gesture, so every gesture has its entry here.\n */\n items: readonly GestureMenuItem[];\n /** Names the element and its menu, for example \"Message from Nora, 10:42\". */\n label: string;\n children: JSX.Element;\n /** Shown above the menu in the long-press sheet, for example a row of quick reactions. `close` closes the sheet. */\n sheetTop?: (close: () => void) => JSX.Element;\n /** Tab order of the element. A list that moves focus between its rows itself passes -1. */\n tabIndex?: number;\n /** Runs before the menu or the sheet shows its items, for example to select what was pressed. */\n onOpen?: () => void;\n class?: string;\n};\n\ntype SwipeDirection = \"right\" | \"left\";\n\ntype Swipe = {\n direction: SwipeDirection;\n icon?: string;\n /** How far the content is moved, in pixels; always 0 with reduced motion. */\n offset: number;\n /** Travel relative to the threshold, from 0 to 1. */\n progress: number;\n armed: boolean;\n settling: boolean;\n};\n\ntype Press = {\n id: number;\n x: number;\n y: number;\n timer?: ReturnType<typeof setTimeout>;\n /** The finger left the slop: no tap or long press any more. */\n moved: boolean;\n /** The long press opened the sheet. */\n long: boolean;\n /** The press started soon after a tap nearby. */\n second: boolean;\n /** The press started at a side edge of the screen. */\n edge: boolean;\n direction?: SwipeDirection;\n};\n\ntype Entry = GestureMenuAction | DropdownAction | DropdownChoice;\n\nconst gestureAction = (items: readonly GestureMenuItem[], kind: GestureKind): GestureMenuAction | undefined => {\n for (const item of items)\n for (const entry of \"items\" in item ? item.items : [item])\n if (\"gesture\" in entry && entry.gesture === kind) return entry.disabled ? undefined : entry;\n return undefined;\n};\n\nconst swipeKind = (direction: SwipeDirection): GestureKind => (direction === \"right\" ? \"swipe-right\" : \"swipe-left\");\n\n/**\n * The sheet's items hand their action to `run` instead of running it while the sheet closes: `dialogCore` settles the\n * sheet after it left the history, and only then may an action navigate or open the next dialog.\n * A choice or action that keeps the menu open runs at once.\n */\nconst afterClose = (items: readonly GestureMenuItem[], run: (action: () => void) => void): GestureMenuItem[] => {\n const entry = (item: Entry): Entry => {\n const action = item.action;\n if (!action || (\"closeOnSelect\" in item && item.closeOnSelect === false)) return item;\n return { ...item, action: () => run(action) };\n };\n return items.map((item) => (\"items\" in item ? { ...item, items: item.items.map(entry) } : entry(item)));\n};\n\nconst menuItems = (menu: HTMLElement): HTMLElement[] =>\n Array.from(menu.querySelectorAll<HTMLElement>(\"[role^='menuitem']:not([aria-disabled='true'])\"));\n\n/**\n * The menu inside the long-press sheet: the same items, at touch size, with arrow keys for a connected keyboard. Focus\n * starts on the sheet itself, which shows no ring on a phone; the first arrow key moves it into the menu.\n */\nfunction SheetMenu(props: { items: readonly GestureMenuItem[]; label: string; close: () => void; dialog: HTMLDialogElement }): JSX.Element {\n let menu!: HTMLDivElement;\n const focus = (index: number) => {\n const items = menuItems(menu);\n items[(index + items.length) % items.length]?.focus();\n };\n const onKeyDown = (event: KeyboardEvent) => {\n const items = menuItems(menu);\n const current = items.indexOf(document.activeElement as HTMLElement);\n if (event.key === \"ArrowDown\") focus(current + 1);\n else if (event.key === \"ArrowUp\") focus(current < 0 ? -1 : current - 1);\n else if (event.key === \"Home\" || event.key === \"End\") focus(event.key === \"Home\" ? 0 : -1);\n else if (!focusRowSegment(items, event.key)) return;\n event.preventDefault();\n };\n // Keys pressed on the sheet itself, while it is the top level of the shared dialog.\n const onSheetKeyDown = (event: KeyboardEvent) => {\n if (event.target === props.dialog && props.dialog.lastElementChild?.contains(menu)) onKeyDown(event);\n };\n onMount(() => {\n props.dialog.addEventListener(\"keydown\", onSheetKeyDown);\n onCleanup(() => props.dialog.removeEventListener(\"keydown\", onSheetKeyDown));\n });\n return (\n <div ref={menu} class=\"k2b-gesture-menu__sheet-menu\" role=\"menu\" aria-label={props.label} onKeyDown={onKeyDown}>\n <DropdownItems items={props.items} close={() => props.close()} />\n </div>\n );\n}\n\n/**\n * Touch gestures for an element, each the shortcut of an entry in its menu: a horizontal swipe, a double tap, and a\n * long press that opens the whole menu as a `BottomSheet`. A mouse double-click runs the double-tap action; a\n * right-click and the keyboard open the menu beside the element. Vertical scrolling never turns into a swipe.\n */\nexport function GestureMenu(props: GestureMenuProps): JSX.Element {\n const locale = useLocale();\n const [swipe, setSwipe] = createSignal<Swipe>();\n let surface!: HTMLDivElement;\n let press: Press | undefined;\n let lastTap: { x: number; y: number; at: number } | undefined;\n let lastPointer = \"mouse\";\n /**\n * The touch or pen press that just ended did something: its `touchend` is cancelled, so no click or mouse events\n * follow, and a pen's click, which comes without touch events, is cancelled itself.\n */\n let consumed = false;\n let sheetOpen = false;\n /** Closes an open sheet when the element goes, for example when its message is deleted. */\n const disposed = new AbortController();\n let reduced = false;\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n\n const active = () => props.items.length > 0;\n const action = (kind: GestureKind) => gestureAction(props.items, kind);\n const touchAction = () => (action(\"swipe-right\") || action(\"swipe-left\") ? \"swipe\" : action(\"double-tap\") ? \"tap\" : undefined);\n\n /** Whether the event started on something with a meaning of its own, inside this element. */\n const ignored = (target: EventTarget | null) => {\n const found = target instanceof Element ? target.closest(IGNORE) : null;\n return found !== null && found !== surface && surface.contains(found);\n };\n\n const openSheet = () => {\n if (sheetOpen || !active()) return;\n sheetOpen = true;\n props.onOpen?.();\n const current = locale();\n let chosen: (() => void) | undefined;\n const choose = (action: () => void) => {\n chosen = action;\n };\n void dialogCore\n .open<void>(\n (close, context) => (\n <LocaleProvider locale={current}>\n <BottomSheet onDismiss={context.requestDismiss}>\n <BottomSheet.Body>\n {props.sheetTop?.(() => close())}\n <SheetMenu items={afterClose(props.items, choose)} label={props.label} close={() => close()} dialog={context.dialog} />\n </BottomSheet.Body>\n </BottomSheet>\n </LocaleProvider>\n ),\n { ...bottomSheetOptions, ariaLabel: props.label, history: true, signal: disposed.signal },\n )\n .then(() => chosen?.())\n .finally(() => {\n sheetOpen = false;\n });\n };\n\n /** Another pointer that goes down anywhere while a finger presses, as in a pinch, ends the gesture. */\n const onOtherPointer = (event: PointerEvent) => {\n if (!press || event.pointerId === press.id) return;\n if (press.direction) settle();\n endPress();\n };\n\n const endPress = () => {\n clearTimeout(press?.timer);\n press = undefined;\n document.removeEventListener(\"pointerdown\", onOtherPointer, true);\n delete surface.dataset.pressing;\n };\n\n const settle = () => {\n const current = swipe();\n if (!current) return;\n clearTimeout(settleTimer);\n if (reduced || current.offset === 0) {\n setSwipe(undefined);\n return;\n }\n setSwipe({ ...current, offset: 0, progress: 0, armed: false, settling: true });\n settleTimer = setTimeout(() => setSwipe(undefined), SETTLE_MS);\n };\n\n const moveSwipe = (current: Press, direction: SwipeDirection, dx: number) => {\n const travel = Math.max(0, direction === \"right\" ? dx : -dx);\n const moved = travel <= SWIPE_THRESHOLD ? travel : SWIPE_THRESHOLD + (travel - SWIPE_THRESHOLD) * SWIPE_RESISTANCE;\n const offset = reduced ? 0 : Math.min(SWIPE_MAX, moved) * (direction === \"right\" ? 1 : -1);\n current.direction = direction;\n setSwipe({\n direction,\n icon: action(swipeKind(direction))?.icon,\n offset,\n progress: Math.min(1, travel / SWIPE_THRESHOLD),\n armed: travel >= SWIPE_THRESHOLD,\n settling: false,\n });\n };\n\n const longPress = () => {\n if (!press) return;\n press.long = true;\n lastTap = undefined;\n openSheet();\n };\n\n const onPointerDown = (event: PointerEvent) => {\n lastPointer = event.pointerType;\n consumed = false;\n // Any press in between, on a link, with a mouse, or with another finger, ends a pending double tap.\n const previous = lastTap;\n lastTap = undefined;\n // Another finger ends the gesture through `onOtherPointer` and starts none.\n if (event.pointerType === \"mouse\" || !event.isPrimary) return;\n endPress();\n if (!active() || ignored(event.target)) return;\n const second =\n previous !== undefined &&\n performance.now() - previous.at <= DOUBLE_TAP_MS &&\n Math.hypot(event.clientX - previous.x, event.clientY - previous.y) <= DOUBLE_TAP_DISTANCE;\n press = {\n id: event.pointerId,\n x: event.clientX,\n y: event.clientY,\n moved: false,\n long: false,\n second,\n edge: event.clientX < EDGE || event.clientX > window.innerWidth - EDGE,\n timer: setTimeout(longPress, LONG_PRESS_MS),\n };\n document.addEventListener(\"pointerdown\", onOtherPointer, true);\n // Hybrid devices keep text selection for the mouse; a finger on the element selects nothing.\n surface.dataset.pressing = \"\";\n };\n\n const onPointerMove = (event: PointerEvent) => {\n const current = press;\n if (!current || event.pointerId !== current.id || current.long) return;\n const dx = event.clientX - current.x;\n const dy = event.clientY - current.y;\n if (current.direction) {\n moveSwipe(current, current.direction, dx);\n return;\n }\n if (current.moved || Math.hypot(dx, dy) < SLOP) return;\n current.moved = true;\n clearTimeout(current.timer);\n if (current.edge || Math.abs(dx) < Math.abs(dy) * SWIPE_RATIO) return;\n const direction: SwipeDirection = dx > 0 ? \"right\" : \"left\";\n if (!action(swipeKind(direction))) return;\n clearTimeout(settleTimer);\n reduced = prefersReducedMotion();\n moveSwipe(current, direction, dx);\n };\n\n const onPointerUp = (event: PointerEvent) => {\n const current = press;\n if (!current || event.pointerId !== current.id) return;\n endPress();\n if (current.long) {\n consumed = true;\n return;\n }\n if (current.direction) {\n // Where the finger lifts decides, and the item as it is now.\n moveSwipe(current, current.direction, event.clientX - current.x);\n const swipeAction = swipe()?.armed ? action(swipeKind(current.direction)) : undefined;\n settle();\n if (swipeAction) {\n consumed = true;\n swipeAction.action();\n }\n return;\n }\n if (current.moved) return;\n const doubleTap = action(\"double-tap\");\n if (!doubleTap) return;\n if (current.second) {\n consumed = true;\n doubleTap.action();\n return;\n }\n lastTap = { x: event.clientX, y: event.clientY, at: performance.now() };\n };\n\n // The browser took the touch, for example to scroll the page.\n const onPointerCancel = (event: PointerEvent) => {\n if (!press || event.pointerId !== press.id) return;\n if (press.direction) settle();\n endPress();\n lastTap = undefined;\n };\n\n const onTouchEnd = (event: TouchEvent) => {\n if (!consumed) return;\n consumed = false;\n if (event.cancelable) event.preventDefault();\n };\n\n // A pen sends no touch events; the click after its gesture is cancelled here. A keyboard's click has no detail.\n const onClick = (event: MouseEvent) => {\n if (!consumed || event.detail === 0) return;\n consumed = false;\n event.preventDefault();\n event.stopPropagation();\n };\n\n const onContextMenu = (event: MouseEvent) => {\n // Without items the element has no menu, and the browser keeps its own.\n if (!active()) return;\n // Links, fields, and code keep the browser's own menu.\n if (ignored(event.target)) {\n event.stopPropagation();\n return;\n }\n // A mouse or the keyboard opens the menu beside the element through ContextMenu.\n if (!press && !(\"pointerType\" in event && (event.pointerType === \"touch\" || event.pointerType === \"pen\"))) return;\n // Android and touch screens report a long press as a context-menu event, sometimes before the timer.\n event.preventDefault();\n event.stopPropagation();\n if (press && !press.long && !press.moved) {\n clearTimeout(press.timer);\n longPress();\n }\n };\n\n // The second press of a mouse double-click would select a word; in this element it runs the double-tap action.\n const onMouseDown = (event: MouseEvent) => {\n if (event.button === 0 && event.detail >= 2 && lastPointer === \"mouse\" && action(\"double-tap\") && !ignored(event.target))\n event.preventDefault();\n };\n\n const onDoubleClick = (event: MouseEvent) => {\n if (lastPointer !== \"mouse\" || ignored(event.target)) return;\n const doubleTap = action(\"double-tap\");\n if (!doubleTap) return;\n event.preventDefault();\n doubleTap.action();\n };\n\n onMount(() => {\n surface.addEventListener(\"pointerdown\", onPointerDown);\n surface.addEventListener(\"pointermove\", onPointerMove);\n surface.addEventListener(\"pointerup\", onPointerUp);\n surface.addEventListener(\"pointercancel\", onPointerCancel);\n surface.addEventListener(\"touchend\", onTouchEnd, { passive: false });\n surface.addEventListener(\"click\", onClick, true);\n surface.addEventListener(\"contextmenu\", onContextMenu);\n surface.addEventListener(\"mousedown\", onMouseDown);\n surface.addEventListener(\"dblclick\", onDoubleClick);\n onCleanup(() => {\n disposed.abort();\n endPress();\n clearTimeout(settleTimer);\n surface.removeEventListener(\"pointerdown\", onPointerDown);\n surface.removeEventListener(\"pointermove\", onPointerMove);\n surface.removeEventListener(\"pointerup\", onPointerUp);\n surface.removeEventListener(\"pointercancel\", onPointerCancel);\n surface.removeEventListener(\"touchend\", onTouchEnd);\n surface.removeEventListener(\"click\", onClick, true);\n surface.removeEventListener(\"contextmenu\", onContextMenu);\n surface.removeEventListener(\"mousedown\", onMouseDown);\n surface.removeEventListener(\"dblclick\", onDoubleClick);\n });\n });\n\n return (\n <ContextMenu\n items={props.items}\n label={props.label}\n tabIndex={props.tabIndex}\n disabled={!active()}\n onOpen={props.onOpen}\n class={props.class}\n >\n <div\n ref={surface}\n class=\"k2b-gesture-menu\"\n data-active={active() ? \"\" : undefined}\n data-touch={touchAction()}\n data-swipe={swipe()?.direction}\n data-armed={swipe()?.armed ? \"\" : undefined}\n data-settling={swipe()?.settling ? \"\" : undefined}\n style={{\n \"--k2b-gesture-menu-offset\": `${swipe()?.offset ?? 0}px`,\n \"--k2b-gesture-menu-progress\": String(swipe()?.progress ?? 0),\n }}\n >\n <Show when={swipe()}>\n {(current) => (\n <span class=\"k2b-gesture-menu__swipe\" aria-hidden=\"true\">\n <i class={current().icon ?? (current().direction === \"right\" ? \"ti ti-arrow-right\" : \"ti ti-arrow-left\")} />\n </span>\n )}\n </Show>\n <div class=\"k2b-gesture-menu__content\">{props.children}</div>\n </div>\n </ContextMenu>\n );\n}\n\nexport default GestureMenu;\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,YAAY,EAAY,SAAS,EAAE,OAAO,EAAE,IAAI,QAAQ,UAAU;AAC3E,SAAS,UAAU,QAAQ,yBAAyB;AACpD,SAAS,cAAc,EAAE,SAAS,QAAQ,gBAAgB;AAC1D,OAAO,WAAW,IAAI,kBAAkB,QAAQ,uBAAuB;AACvE,SAAS,oBAAoB,QAAQ,WAAW;AAChD,SAAS,WAAW,QAAQ,eAAe;AAC3C,SAIE,aAAa,EAEb,eAAe,QACV,YAAY;;AAEnB;AACA,MAAM,aAAa,GAAG,GAAG;AACzB;AACA,MAAM,aAAa,GAAG,GAAG;AACzB;AACA,MAAM,mBAAmB,GAAG,EAAE;AAC9B;AACA,MAAM,IAAI,GAAG,EAAE;AACf;AACA,MAAM,WAAW,GAAG,GAAG;AACvB;AACA,MAAM,eAAe,GAAG,EAAE;AAC1B;AACA,MAAM,SAAS,GAAG,EAAE;AACpB,MAAM,gBAAgB,GAAG,IAAI;AAC7B;AACA,MAAM,IAAI,GAAG,EAAE;AACf;AACA,MAAM,SAAS,GAAG,GAAG;;AAErB;AACA;AACA;AACA;AACA,MAAM,MAAM,GAAG,CACb,SAAS,EACT,QAAQ,EACR,OAAO,EACP,UAAU,EACV,QAAQ,EACR,SAAS,EACT,OAAO,EACP,OAAO,EACP,OAAO,EACP,KAAK,EACL,kDAAkD,EAClD,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,uBAAuB,CACxB,CAAC,IAAI,CAAC,IAAI,CAAC;;AAIZ;;AA8DA,MAAM,aAAa,GAAG,CAAC,KAAiC,EAAE,IAAiB,KAAoC;EAC7G,KAAK,MAAM,IAAI,IAAI,KAAK,EACtB,KAAK,MAAM,KAAK,IAAI,OAAO,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,EACvD,IAAI,SAAS,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,OAAO,KAAK,CAAC,QAAQ,GAAG,SAAS,GAAG,KAAK;EAC/F,OAAO,SAAS;AAClB,CAAC;AAED,MAAM,SAAS,GAAI,SAAyB,IAAmB,SAAS,KAAK,OAAO,GAAG,aAAa,GAAG,YAAa;;AAEpH;AACA;AACA;AACA;AACA;AACA,MAAM,UAAU,GAAG,CAAC,KAAiC,EAAE,GAAiC,KAAwB;EAC9G,MAAM,KAAK,GAAI,IAAW,IAAY;IACpC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;IAC1B,IAAI,CAAC,MAAM,IAAK,eAAe,IAAI,IAAI,IAAI,IAAI,CAAC,aAAa,KAAK,KAAM,EAAE,OAAO,IAAI;IACrF,OAAO;MAAE,GAAG,IAAI;MAAE,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM;IAAE,CAAC;EAC/C,CAAC;EACD,OAAO,KAAK,CAAC,GAAG,CAAE,IAAI,IAAM,OAAO,IAAI,IAAI,GAAG;IAAE,GAAG,IAAI;IAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK;EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAE,CAAC;AACzG,CAAC;AAED,MAAM,SAAS,GAAI,IAAiB,IAClC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAc,gDAAgD,CAAC,CAAC;;AAElG;AACA;AACA;AACA;AACA,SAAS,SAAS,CAAC,KAAyG,EAAe;EACzI,IAAI,IAAqB;EACzB,MAAM,KAAK,GAAI,KAAa,IAAK;IAC/B,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC;IAC7B,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;EACvD,CAAC;EACD,MAAM,SAAS,GAAI,KAAoB,IAAK;IAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC;IAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAA4B,CAAC;IACpE,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,KAC7C,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,KACnE,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KACtF,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE;IAC7C,KAAK,CAAC,cAAc,CAAC,CAAC;EACxB,CAAC;EACD;EACA,MAAM,cAAc,GAAI,KAAoB,IAAK;IAC/C,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC;EACtG,CAAC;EACD,OAAO,CAAC,MAAM;IACZ,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,CAAC;IACxD,SAAS,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;EAC9E,CAAC,CAAC;EACF;IAAA;IAAA,iBACuG,SAAS;IAAA,YAApG,IAAI;IAAA,mDAAJ,IAAI;IAAA,iCACX,aAAa;MAAA,IAAC,KAAK;QAAA,OAAE,KAAK,CAAC,KAAK;MAAA;MAAE,KAAK,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC;IAAC;IAAA,kDADc,KAAK,CAAC,KAAK;IAAA;IAAA;EAAA;AAI5F;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS,WAAW,CAAC,KAAuB,EAAe;EAChE,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;EAC1B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAQ,CAAC;EAC/C,IAAI,OAAwB;EAC5B,IAAI,KAAwB;EAC5B,IAAI,OAAyD;EAC7D,IAAI,WAAW,GAAG,OAAO;EACzB;AACF;AACA;AACA;EACE,IAAI,QAAQ,GAAG,KAAK;EACpB,IAAI,SAAS,GAAG,KAAK;EACrB;EACA,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,CAAC;EACtC,IAAI,OAAO,GAAG,KAAK;EACnB,IAAI,WAAsD;EAE1D,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;EAC3C,MAAM,MAAM,GAAI,IAAiB,IAAK,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC;EACtE,MAAM,WAAW,GAAG,MAAO,MAAM,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,GAAG,SAAU;;EAE9H;EACA,MAAM,OAAO,GAAI,MAA0B,IAAK;IAC9C,MAAM,KAAK,GAAG,MAAM,YAAY,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IACvE,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;EACvE,CAAC;EAED,MAAM,SAAS,GAAG,MAAM;IACtB,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE;IAC5B,SAAS,GAAG,IAAI;IAChB,KAAK,CAAC,MAAM,GAAG,CAAC;IAChB,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC;IACxB,IAAI,MAAgC;IACpC,MAAM,MAAM,GAAI,MAAkB,IAAK;MACrC,MAAM,GAAG,MAAM;IACjB,CAAC;IACD,KAAK,UAAU,CACZ,IAAI,CACH,CAAC,KAAK,EAAE,OAAO,uBACZ,cAAc;MAAC,MAAM,EAAE,OAAO;MAAA;QAAA,yBAC5B,WAAW;UAAA,IAAC,SAAS;YAAA,OAAE,OAAO,CAAC,cAAc;UAAA;UAAA;YAAA,yBAC3C,WAAW,CAAC,IAAI;cAAA;gBAAA,qBACd,KAAK,CAAC,QAAQ,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,qBAC/B,SAAS;kBAAA,IAAC,KAAK;oBAAA,OAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;kBAAA;kBAAA,IAAE,KAAK;oBAAA,OAAE,KAAK,CAAC,KAAK;kBAAA;kBAAE,KAAK,EAAE,MAAM,KAAK,CAAC,CAAC;kBAAA,IAAE,MAAM;oBAAA,OAAE,OAAO,CAAC,MAAM;kBAAA;gBAAA;cAAA;YAAA;UAAA;QAAA;MAAA;IAAA,EAI1H,EACD;MAAE,GAAG,kBAAkB;MAAE,SAAS,EAAE,KAAK,CAAC,KAAK;MAAE,OAAO,EAAE,IAAI;MAAE,MAAM,EAAE,QAAQ,CAAC;IAAO,CAC1F,CAAC,CACA,IAAI,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC,CACtB,OAAO,CAAC,MAAM;MACb,SAAS,GAAG,KAAK;IACnB,CAAC,CAAC;EACN,CAAC;;EAED;EACA,MAAM,cAAc,GAAI,KAAmB,IAAK;IAC9C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,EAAE;IAC5C,IAAI,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,CAAC,CAAC;EACZ,CAAC;EAED,MAAM,QAAQ,GAAG,MAAM;IACrB,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;IAC1B,KAAK,GAAG,SAAS;IACjB,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC;IACjE,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ;EACjC,CAAC;EAED,MAAM,MAAM,GAAG,MAAM;IACnB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC;IACvB,IAAI,CAAC,OAAO,EAAE;IACd,YAAY,CAAC,WAAW,CAAC;IACzB,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;MACnC,QAAQ,CAAC,SAAS,CAAC;MACnB;IACF;IACA,QAAQ,CAAC;MAAE,GAAG,OAAO;MAAE,MAAM,EAAE,CAAC;MAAE,QAAQ,EAAE,CAAC;MAAE,KAAK,EAAE,KAAK;MAAE,QAAQ,EAAE;IAAK,CAAC,CAAC;IAC9E,WAAW,GAAG,UAAU,CAAC,MAAM,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;EAChE,CAAC;EAED,MAAM,SAAS,GAAG,CAAC,OAAc,EAAE,SAAyB,EAAE,EAAU,KAAK;IAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,KAAK,OAAO,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,IAAI,eAAe,GAAG,MAAM,GAAG,eAAe,GAAG,CAAC,MAAM,GAAG,eAAe,IAAI,gBAAgB;IAClH,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,SAAS,KAAK,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1F,OAAO,CAAC,SAAS,GAAG,SAAS;IAC7B,QAAQ,CAAC;MACP,SAAS;MACT,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI;MACxC,MAAM;MACN,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC;MAC/C,KAAK,EAAE,MAAM,IAAI,eAAe;MAChC,QAAQ,EAAE;IACZ,CAAC,CAAC;EACJ,CAAC;EAED,MAAM,SAAS,GAAG,MAAM;IACtB,IAAI,CAAC,KAAK,EAAE;IACZ,KAAK,CAAC,IAAI,GAAG,IAAI;IACjB,OAAO,GAAG,SAAS;IACnB,SAAS,CAAC,CAAC;EACb,CAAC;EAED,MAAM,aAAa,GAAI,KAAmB,IAAK;IAC7C,WAAW,GAAG,KAAK,CAAC,WAAW;IAC/B,QAAQ,GAAG,KAAK;IAChB;IACA,MAAM,QAAQ,GAAG,OAAO;IACxB,OAAO,GAAG,SAAS;IACnB;IACA,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;IACvD,QAAQ,CAAC,CAAC;IACV,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;IACxC,MAAM,MAAM,GACV,QAAQ,KAAK,SAAS,IACtB,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,EAAE,IAAI,aAAa,IAChD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,mBAAmB;IAC3F,KAAK,GAAG;MACN,EAAE,EAAE,KAAK,CAAC,SAAS;MACnB,CAAC,EAAE,KAAK,CAAC,OAAO;MAChB,CAAC,EAAE,KAAK,CAAC,OAAO;MAChB,KAAK,EAAE,KAAK;MACZ,IAAI,EAAE,KAAK;MACX,MAAM;MACN,IAAI,EAAE,KAAK,CAAC,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI;MACtE,KAAK,EAAE,UAAU,CAAC,SAAS,EAAE,aAAa;IAC5C,CAAC;IACD,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC;IAC9D;IACA,OAAO,CAAC,OAAO,CAAC,QAAQ,GAAG,EAAE;EAC/B,CAAC;EAED,MAAM,aAAa,GAAI,KAAmB,IAAK;IAC7C,MAAM,OAAO,GAAG,KAAK;IACrB,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE;IAChE,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC;IACpC,IAAI,OAAO,CAAC,SAAS,EAAE;MACrB,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;MACzC;IACF;IACA,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE;IAChD,OAAO,CAAC,KAAK,GAAG,IAAI;IACpB,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3B,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE;IAC/D,MAAM,SAAyB,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,GAAG,MAAM;IAC3D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE;IACnC,YAAY,CAAC,WAAW,CAAC;IACzB,OAAO,GAAG,oBAAoB,CAAC,CAAC;IAChC,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC;EACnC,CAAC;EAED,MAAM,WAAW,GAAI,KAAmB,IAAK;IAC3C,MAAM,OAAO,GAAG,KAAK;IACrB,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,EAAE;IAChD,QAAQ,CAAC,CAAC;IACV,IAAI,OAAO,CAAC,IAAI,EAAE;MAChB,QAAQ,GAAG,IAAI;MACf;IACF;IACA,IAAI,OAAO,CAAC,SAAS,EAAE;MACrB;MACA,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;MAChE,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,SAAS;MACrF,MAAM,CAAC,CAAC;MACR,IAAI,WAAW,EAAE;QACf,QAAQ,GAAG,IAAI;QACf,WAAW,CAAC,MAAM,CAAC,CAAC;MACtB;MACA;IACF;IACA,IAAI,OAAO,CAAC,KAAK,EAAE;IACnB,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC;IACtC,IAAI,CAAC,SAAS,EAAE;IAChB,IAAI,OAAO,CAAC,MAAM,EAAE;MAClB,QAAQ,GAAG,IAAI;MACf,SAAS,CAAC,MAAM,CAAC,CAAC;MAClB;IACF;IACA,OAAO,GAAG;MAAE,CAAC,EAAE,KAAK,CAAC,OAAO;MAAE,CAAC,EAAE,KAAK,CAAC,OAAO;MAAE,EAAE,EAAE,WAAW,CAAC,GAAG,CAAC;IAAE,CAAC;EACzE,CAAC;;EAED;EACA,MAAM,eAAe,GAAI,KAAmB,IAAK;IAC/C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,EAAE;IAC5C,IAAI,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,CAAC,CAAC;IACV,OAAO,GAAG,SAAS;EACrB,CAAC;EAED,MAAM,UAAU,GAAI,KAAiB,IAAK;IACxC,IAAI,CAAC,QAAQ,EAAE;IACf,QAAQ,GAAG,KAAK;IAChB,IAAI,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;EAC9C,CAAC;;EAED;EACA,MAAM,OAAO,GAAI,KAAiB,IAAK;IACrC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;IACrC,QAAQ,GAAG,KAAK;IAChB,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,KAAK,CAAC,eAAe,CAAC,CAAC;EACzB,CAAC;EAED,MAAM,aAAa,GAAI,KAAiB,IAAK;IAC3C;IACA,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE;IACf;IACA,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;MACzB,KAAK,CAAC,eAAe,CAAC,CAAC;MACvB;IACF;IACA;IACA,IAAI,CAAC,KAAK,IAAI,EAAE,aAAa,IAAI,KAAK,KAAK,KAAK,CAAC,WAAW,KAAK,OAAO,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,CAAC,EAAE;IAC3G;IACA,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,KAAK,CAAC,eAAe,CAAC,CAAC;IACvB,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;MACxC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC;MACzB,SAAS,CAAC,CAAC;IACb;EACF,CAAC;;EAED;EACA,MAAM,WAAW,GAAI,KAAiB,IAAK;IACzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,WAAW,KAAK,OAAO,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EACtH,KAAK,CAAC,cAAc,CAAC,CAAC;EAC1B,CAAC;EAED,MAAM,aAAa,GAAI,KAAiB,IAAK;IAC3C,IAAI,WAAW,KAAK,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;IACtD,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC;IACtC,IAAI,CAAC,SAAS,EAAE;IAChB,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,SAAS,CAAC,MAAM,CAAC,CAAC;EACpB,CAAC;EAED,OAAO,CAAC,MAAM;IACZ,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC;IACtD,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC;IACtD,OAAO,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC;IAClD,OAAO,CAAC,gBAAgB,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1D,OAAO,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE;MAAE,OAAO,EAAE;IAAM,CAAC,CAAC;IACpE,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;IAChD,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC;IACtD,OAAO,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC;IAClD,OAAO,CAAC,gBAAgB,CAAC,UAAU,EAAE,aAAa,CAAC;IACnD,SAAS,CAAC,MAAM;MACd,QAAQ,CAAC,KAAK,CAAC,CAAC;MAChB,QAAQ,CAAC,CAAC;MACV,YAAY,CAAC,WAAW,CAAC;MACzB,OAAO,CAAC,mBAAmB,CAAC,aAAa,EAAE,aAAa,CAAC;MACzD,OAAO,CAAC,mBAAmB,CAAC,aAAa,EAAE,aAAa,CAAC;MACzD,OAAO,CAAC,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC;MACrD,OAAO,CAAC,mBAAmB,CAAC,eAAe,EAAE,eAAe,CAAC;MAC7D,OAAO,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC;MACnD,OAAO,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;MACnD,OAAO,CAAC,mBAAmB,CAAC,aAAa,EAAE,aAAa,CAAC;MACzD,OAAO,CAAC,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC;MACrD,OAAO,CAAC,mBAAmB,CAAC,UAAU,EAAE,aAAa,CAAC;IACxD,CAAC,CAAC;EACJ,CAAC,CAAC;EAEF,yBACG,WAAW;IAAA,IACV,KAAK;MAAA,OAAE,KAAK,CAAC,KAAK;IAAA;IAAA,IAClB,KAAK;MAAA,OAAE,KAAK,CAAC,KAAK;IAAA;IAAA,IAClB,QAAQ;MAAA,OAAE,KAAK,CAAC,QAAQ;IAAA;IAAA,IACxB,QAAQ;MAAA,OAAE,CAAC,MAAM,CAAC,CAAC;IAAA;IAAA,IACnB,MAAM;MAAA,OAAE,KAAK,CAAC,MAAM;IAAA;IAAA;MAAA,OACb,KAAK,CAAC,KAAK;IAAA;IAAA;MAAA;QAAA;QAAA;QAAA;MAAA,aAGX,OAAO;MAAA,sDAAP,OAAO;MAAA,kCAYX,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,CAAC;QAAA;QAAA,UACf,OAAO;UAAA;YAAA;UAAA,kCAEK,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;UAAA;QAAA;MAE3G;MAAA,sBAEqC,KAAK,CAAC,QAAQ;MAAA;QAAA,UAjBzC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,SAAS;UAAA,OAC1B,WAAW,CAAC,CAAC;UAAA,OACb,KAAK,CAAC,CAAC,EAAE,SAAS;UAAA,OAClB,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,EAAE,GAAG,SAAS;UAAA,OAC5B,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,EAAE,GAAG,SAAS;UAAA,OAElB,GAAG,KAAK,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,IAAI;UAAA,OACzB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;MAAA;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;MAAA;MAAA;IAAA;EAAA;AAcvE;AAEA,eAAe,WAAW;AAAC","ignoreList":[]}
|
|
@@ -85,6 +85,7 @@ import { GestureMenu } from "../actions/GestureMenu";
|
|
|
85
85
|
import SegmentedControl from "../actions/SegmentedControl";
|
|
86
86
|
import { useDateConfigLocale } from "../intl/locale";
|
|
87
87
|
import { useUiMessages } from "../intl/messages";
|
|
88
|
+
import { prefersReducedMotion } from "../motion";
|
|
88
89
|
import { CalendarDayView } from "./CalendarDayView";
|
|
89
90
|
import { CalendarWeekView } from "./CalendarWeekView";
|
|
90
91
|
import { addDayKeys } from "./calendar-days";
|
|
@@ -95,7 +96,7 @@ import { fitMonthWeek, layoutMonthWeek, monthLaneCapacity } from "./calendar-mon
|
|
|
95
96
|
import { MONTH_ROW_BLOCK, MONTH_ROWS_IN_VIEW, monthFocusRow, monthOfWeek, monthRenderWindow, monthRevealTop, monthRowOf, monthTodayDirection, monthVisibleRows, monthWeekKeys } from "./calendar-month-scroll";
|
|
96
97
|
import { calendarDayIndexAtPoint, calendarMinuteAtPoint, startCalendarPointerSession } from "./calendar-pointer";
|
|
97
98
|
import { EventChip, eventHref, followCalendarHref, formatTime, ownerDateConfig, parseDate, placeCalendarPopover, textWidth, validDate } from "./calendar-shared";
|
|
98
|
-
import { compactGermanDate
|
|
99
|
+
import { compactGermanDate } from "./calendar-time-view";
|
|
99
100
|
|
|
100
101
|
/** The days a host loaded events for, from the first day `from` up to `to`, both `YYYY-MM-DD` or dates. */
|
|
101
102
|
|
|
@@ -1474,7 +1475,7 @@ const MonthView = props => {
|
|
|
1474
1475
|
reportVisible();
|
|
1475
1476
|
};
|
|
1476
1477
|
const pulseToday = () => {
|
|
1477
|
-
if (
|
|
1478
|
+
if (prefersReducedMotion()) return;
|
|
1478
1479
|
setPulseKey(todayKey());
|
|
1479
1480
|
window.clearTimeout(pulseTimer);
|
|
1480
1481
|
pulseTimer = window.setTimeout(() => setPulseKey(""), 1000);
|
|
@@ -1523,16 +1524,16 @@ const MonthView = props => {
|
|
|
1523
1524
|
if (!scroller) return;
|
|
1524
1525
|
const maximum = Math.max(0, scroller.scrollHeight - scroller.clientHeight);
|
|
1525
1526
|
const target = Math.max(0, Math.min(top, maximum));
|
|
1526
|
-
if (smooth && !
|
|
1527
|
+
if (smooth && !prefersReducedMotion() && Math.abs(target - scroller.scrollTop) > viewHeight() * 3) {
|
|
1527
1528
|
scroller.scrollTop = target - Math.sign(target - scroller.scrollTop) * viewHeight();
|
|
1528
1529
|
readScroll();
|
|
1529
1530
|
}
|
|
1530
1531
|
scroller.scrollTo({
|
|
1531
1532
|
top: target,
|
|
1532
|
-
behavior: smooth && !
|
|
1533
|
+
behavior: smooth && !prefersReducedMotion() ? "smooth" : "instant"
|
|
1533
1534
|
});
|
|
1534
1535
|
if (top > maximum + 1) loadMore("later");
|
|
1535
|
-
if (!smooth ||
|
|
1536
|
+
if (!smooth || prefersReducedMotion()) {
|
|
1536
1537
|
readScroll();
|
|
1537
1538
|
finishGlide();
|
|
1538
1539
|
}
|
|
@@ -1597,7 +1598,7 @@ const MonthView = props => {
|
|
|
1597
1598
|
};
|
|
1598
1599
|
const goToday = () => {
|
|
1599
1600
|
if (!continuous() || !loaded(todayKey()) || !scroller) return false;
|
|
1600
|
-
pulseOnArrival = !
|
|
1601
|
+
pulseOnArrival = !prefersReducedMotion();
|
|
1601
1602
|
if (positionMonth(todayKey(), true, true)) return true;
|
|
1602
1603
|
pulseOnArrival = false;
|
|
1603
1604
|
return false;
|
|
@@ -3207,7 +3208,7 @@ const TimeGridView = props => {
|
|
|
3207
3208
|
if (!scrollContainer || !defaultHourMarker) return;
|
|
3208
3209
|
const targetTop = defaultHourMarker.getBoundingClientRect().top - scrollContainer.getBoundingClientRect().top;
|
|
3209
3210
|
// Reduced motion jumps to the business hours instead of gliding there, like every transition of the library.
|
|
3210
|
-
const behavior =
|
|
3211
|
+
const behavior = prefersReducedMotion() ? "auto" : "smooth";
|
|
3211
3212
|
scrollContainer.scrollTo({
|
|
3212
3213
|
top: Math.max(0, scrollContainer.scrollTop + targetTop),
|
|
3213
3214
|
behavior
|