@llui/components 0.4.10 → 0.5.1
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/components/accordion.d.ts +13 -13
- package/dist/components/accordion.d.ts.map +1 -1
- package/dist/components/accordion.js +9 -9
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/alert-dialog.d.ts +8 -8
- package/dist/components/alert-dialog.d.ts.map +1 -1
- package/dist/components/alert-dialog.js +2 -2
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/angle-slider.d.ts +13 -13
- package/dist/components/angle-slider.d.ts.map +1 -1
- package/dist/components/angle-slider.js +11 -11
- package/dist/components/angle-slider.js.map +1 -1
- package/dist/components/async-list.d.ts +7 -7
- package/dist/components/async-list.d.ts.map +1 -1
- package/dist/components/async-list.js +5 -8
- package/dist/components/async-list.js.map +1 -1
- package/dist/components/avatar.d.ts +9 -9
- package/dist/components/avatar.d.ts.map +1 -1
- package/dist/components/avatar.js +7 -7
- package/dist/components/avatar.js.map +1 -1
- package/dist/components/carousel.d.ts +18 -18
- package/dist/components/carousel.d.ts.map +1 -1
- package/dist/components/carousel.js +12 -12
- package/dist/components/carousel.js.map +1 -1
- package/dist/components/cascade-select.d.ts +12 -12
- package/dist/components/cascade-select.d.ts.map +1 -1
- package/dist/components/cascade-select.js +8 -8
- package/dist/components/cascade-select.js.map +1 -1
- package/dist/components/checkbox.d.ts +14 -14
- package/dist/components/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox.js +12 -12
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/clipboard.d.ts +8 -8
- package/dist/components/clipboard.d.ts.map +1 -1
- package/dist/components/clipboard.js +6 -6
- package/dist/components/clipboard.js.map +1 -1
- package/dist/components/collapsible.d.ts +11 -11
- package/dist/components/collapsible.d.ts.map +1 -1
- package/dist/components/collapsible.js +9 -9
- package/dist/components/collapsible.js.map +1 -1
- package/dist/components/color-picker.d.ts +19 -19
- package/dist/components/color-picker.d.ts.map +1 -1
- package/dist/components/color-picker.js +21 -21
- package/dist/components/color-picker.js.map +1 -1
- package/dist/components/combobox.d.ts +25 -25
- package/dist/components/combobox.d.ts.map +1 -1
- package/dist/components/combobox.js +54 -59
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/context-menu.d.ts +14 -14
- package/dist/components/context-menu.d.ts.map +1 -1
- package/dist/components/context-menu.js +15 -19
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/date-input.d.ts +13 -13
- package/dist/components/date-input.d.ts.map +1 -1
- package/dist/components/date-input.js +11 -11
- package/dist/components/date-input.js.map +1 -1
- package/dist/components/date-picker.d.ts +11 -11
- package/dist/components/date-picker.d.ts.map +1 -1
- package/dist/components/date-picker.js +7 -7
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/dialog.d.ts +15 -15
- package/dist/components/dialog.d.ts.map +1 -1
- package/dist/components/dialog.js +45 -50
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/drawer.d.ts +13 -13
- package/dist/components/drawer.d.ts.map +1 -1
- package/dist/components/drawer.js +44 -49
- package/dist/components/drawer.js.map +1 -1
- package/dist/components/editable.d.ts +11 -11
- package/dist/components/editable.d.ts.map +1 -1
- package/dist/components/editable.js +9 -9
- package/dist/components/editable.js.map +1 -1
- package/dist/components/file-upload.d.ts +19 -19
- package/dist/components/file-upload.d.ts.map +1 -1
- package/dist/components/file-upload.js +14 -14
- package/dist/components/file-upload.js.map +1 -1
- package/dist/components/floating-panel.d.ts +14 -14
- package/dist/components/floating-panel.d.ts.map +1 -1
- package/dist/components/floating-panel.js +13 -14
- package/dist/components/floating-panel.js.map +1 -1
- package/dist/components/form.d.ts +9 -9
- package/dist/components/form.d.ts.map +1 -1
- package/dist/components/form.js +7 -7
- package/dist/components/form.js.map +1 -1
- package/dist/components/hover-card.d.ts +9 -9
- package/dist/components/hover-card.d.ts.map +1 -1
- package/dist/components/hover-card.js +12 -13
- package/dist/components/hover-card.js.map +1 -1
- package/dist/components/image-cropper.d.ts +8 -8
- package/dist/components/image-cropper.d.ts.map +1 -1
- package/dist/components/image-cropper.js +7 -8
- package/dist/components/image-cropper.js.map +1 -1
- package/dist/components/in-view.d.ts +6 -6
- package/dist/components/in-view.d.ts.map +1 -1
- package/dist/components/in-view.js +2 -2
- package/dist/components/in-view.js.map +1 -1
- package/dist/components/listbox.d.ts +16 -16
- package/dist/components/listbox.d.ts.map +1 -1
- package/dist/components/listbox.js +16 -16
- package/dist/components/listbox.js.map +1 -1
- package/dist/components/marquee.d.ts +8 -8
- package/dist/components/marquee.d.ts.map +1 -1
- package/dist/components/marquee.js +8 -11
- package/dist/components/marquee.js.map +1 -1
- package/dist/components/menu.d.ts +15 -15
- package/dist/components/menu.d.ts.map +1 -1
- package/dist/components/menu.js +16 -17
- package/dist/components/menu.js.map +1 -1
- package/dist/components/navigation-menu.d.ts +12 -12
- package/dist/components/navigation-menu.d.ts.map +1 -1
- package/dist/components/navigation-menu.js +8 -8
- package/dist/components/navigation-menu.js.map +1 -1
- package/dist/components/number-input.d.ts +18 -18
- package/dist/components/number-input.d.ts.map +1 -1
- package/dist/components/number-input.js +16 -20
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/pagination.d.ts +13 -13
- package/dist/components/pagination.d.ts.map +1 -1
- package/dist/components/pagination.js +11 -17
- package/dist/components/pagination.js.map +1 -1
- package/dist/components/password-input.d.ts +11 -11
- package/dist/components/password-input.d.ts.map +1 -1
- package/dist/components/password-input.js +11 -11
- package/dist/components/password-input.js.map +1 -1
- package/dist/components/pin-input.d.ts +9 -9
- package/dist/components/pin-input.d.ts.map +1 -1
- package/dist/components/pin-input.js +9 -9
- package/dist/components/pin-input.js.map +1 -1
- package/dist/components/popover.d.ts +11 -11
- package/dist/components/popover.d.ts.map +1 -1
- package/dist/components/popover.js +61 -60
- package/dist/components/popover.js.map +1 -1
- package/dist/components/presence.d.ts +7 -5
- package/dist/components/presence.d.ts.map +1 -1
- package/dist/components/presence.js +5 -3
- package/dist/components/presence.js.map +1 -1
- package/dist/components/progress.d.ts +14 -14
- package/dist/components/progress.d.ts.map +1 -1
- package/dist/components/progress.js +12 -12
- package/dist/components/progress.js.map +1 -1
- package/dist/components/qr-code.d.ts +7 -7
- package/dist/components/qr-code.d.ts.map +1 -1
- package/dist/components/qr-code.js +7 -7
- package/dist/components/qr-code.js.map +1 -1
- package/dist/components/radio-group.d.ts +15 -15
- package/dist/components/radio-group.d.ts.map +1 -1
- package/dist/components/radio-group.js +12 -13
- package/dist/components/radio-group.js.map +1 -1
- package/dist/components/rating-group.d.ts +13 -13
- package/dist/components/rating-group.d.ts.map +1 -1
- package/dist/components/rating-group.js +10 -11
- package/dist/components/rating-group.js.map +1 -1
- package/dist/components/scroll-area.d.ts +10 -10
- package/dist/components/scroll-area.d.ts.map +1 -1
- package/dist/components/scroll-area.js +10 -15
- package/dist/components/scroll-area.js.map +1 -1
- package/dist/components/select.d.ts +26 -26
- package/dist/components/select.d.ts.map +1 -1
- package/dist/components/select.js +29 -33
- package/dist/components/select.js.map +1 -1
- package/dist/components/signature-pad.d.ts +12 -12
- package/dist/components/signature-pad.d.ts.map +1 -1
- package/dist/components/signature-pad.js +10 -10
- package/dist/components/signature-pad.js.map +1 -1
- package/dist/components/slider.d.ts +22 -22
- package/dist/components/slider.d.ts.map +1 -1
- package/dist/components/slider.js +17 -17
- package/dist/components/slider.js.map +1 -1
- package/dist/components/sortable.d.ts +11 -11
- package/dist/components/sortable.d.ts.map +1 -1
- package/dist/components/sortable.js +20 -20
- package/dist/components/sortable.js.map +1 -1
- package/dist/components/splitter.d.ts +15 -15
- package/dist/components/splitter.d.ts.map +1 -1
- package/dist/components/splitter.js +15 -15
- package/dist/components/splitter.js.map +1 -1
- package/dist/components/steps.d.ts +14 -14
- package/dist/components/steps.d.ts.map +1 -1
- package/dist/components/steps.js +10 -16
- package/dist/components/steps.js.map +1 -1
- package/dist/components/switch.d.ts +12 -12
- package/dist/components/switch.d.ts.map +1 -1
- package/dist/components/switch.js +10 -10
- package/dist/components/switch.js.map +1 -1
- package/dist/components/tabs.d.ts +15 -15
- package/dist/components/tabs.d.ts.map +1 -1
- package/dist/components/tabs.js +11 -11
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tags-input.d.ts +14 -14
- package/dist/components/tags-input.d.ts.map +1 -1
- package/dist/components/tags-input.js +10 -10
- package/dist/components/tags-input.js.map +1 -1
- package/dist/components/theme-switch.d.ts +5 -5
- package/dist/components/theme-switch.d.ts.map +1 -1
- package/dist/components/theme-switch.js +3 -3
- package/dist/components/theme-switch.js.map +1 -1
- package/dist/components/time-picker.d.ts +19 -19
- package/dist/components/time-picker.d.ts.map +1 -1
- package/dist/components/time-picker.js +17 -17
- package/dist/components/time-picker.js.map +1 -1
- package/dist/components/timer.d.ts +10 -10
- package/dist/components/timer.d.ts.map +1 -1
- package/dist/components/timer.js +8 -8
- package/dist/components/timer.js.map +1 -1
- package/dist/components/toast.d.ts +8 -8
- package/dist/components/toast.d.ts.map +1 -1
- package/dist/components/toast.js +4 -4
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toc.d.ts +12 -12
- package/dist/components/toc.d.ts.map +1 -1
- package/dist/components/toc.js +8 -8
- package/dist/components/toc.js.map +1 -1
- package/dist/components/toggle-group.d.ts +13 -13
- package/dist/components/toggle-group.d.ts.map +1 -1
- package/dist/components/toggle-group.js +9 -9
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.d.ts +8 -8
- package/dist/components/toggle.d.ts.map +1 -1
- package/dist/components/toggle.js +6 -6
- package/dist/components/toggle.js.map +1 -1
- package/dist/components/tooltip.d.ts +10 -10
- package/dist/components/tooltip.d.ts.map +1 -1
- package/dist/components/tooltip.js +13 -14
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/tour.d.ts +7 -7
- package/dist/components/tour.d.ts.map +1 -1
- package/dist/components/tour.js +5 -5
- package/dist/components/tour.js.map +1 -1
- package/dist/components/tree-view.d.ts +19 -19
- package/dist/components/tree-view.d.ts.map +1 -1
- package/dist/components/tree-view.js +23 -23
- package/dist/components/tree-view.js.map +1 -1
- package/dist/patterns/confirm-dialog.d.ts +4 -4
- package/dist/patterns/confirm-dialog.d.ts.map +1 -1
- package/dist/patterns/confirm-dialog.js +7 -9
- package/dist/patterns/confirm-dialog.js.map +1 -1
- package/package.json +3 -3
- package/dist/components/enter-view.d.ts +0 -73
- package/dist/components/enter-view.d.ts.map +0 -1
- package/dist/components/enter-view.js +0 -51
- package/dist/utils/validators.d.ts +0 -34
- package/dist/utils/validators.d.ts.map +0 -1
- package/dist/utils/validators.js +0 -83
|
@@ -15,7 +15,7 @@ export function update(state, msg) {
|
|
|
15
15
|
return [{ ...state, open: msg.open }, []];
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
export function connect(
|
|
18
|
+
export function connect(state, send, opts) {
|
|
19
19
|
const base = opts.id;
|
|
20
20
|
const triggerId = `${base}:trigger`;
|
|
21
21
|
const contentId = `${base}:content`;
|
|
@@ -59,8 +59,8 @@ export function connect(get, send, opts) {
|
|
|
59
59
|
return {
|
|
60
60
|
trigger: {
|
|
61
61
|
id: triggerId,
|
|
62
|
-
'aria-describedby': (s) => (
|
|
63
|
-
'data-state': (s) => (
|
|
62
|
+
'aria-describedby': state.map((s) => (s.open ? contentId : undefined)),
|
|
63
|
+
'data-state': state.map((s) => (s.open ? 'open' : 'closed')),
|
|
64
64
|
'data-scope': 'tooltip',
|
|
65
65
|
'data-part': 'trigger',
|
|
66
66
|
onPointerEnter: () => scheduleShow(delayOpen),
|
|
@@ -85,7 +85,7 @@ export function connect(get, send, opts) {
|
|
|
85
85
|
content: {
|
|
86
86
|
role: 'tooltip',
|
|
87
87
|
id: contentId,
|
|
88
|
-
'data-state': (s) => (
|
|
88
|
+
'data-state': state.map((s) => (s.open ? 'open' : 'closed')),
|
|
89
89
|
'data-scope': 'tooltip',
|
|
90
90
|
'data-part': 'content',
|
|
91
91
|
// Allow pointer to enter content without closing (for interactive tooltips)
|
|
@@ -104,7 +104,7 @@ export function connect(get, send, opts) {
|
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
106
|
export function overlay(opts) {
|
|
107
|
-
const
|
|
107
|
+
const rawTarget = opts.target ?? 'body';
|
|
108
108
|
const placement = opts.placement ?? 'top';
|
|
109
109
|
const offset = opts.offset ?? 6;
|
|
110
110
|
const flip = opts.flip !== false;
|
|
@@ -112,11 +112,12 @@ export function overlay(opts) {
|
|
|
112
112
|
const parts = opts.parts;
|
|
113
113
|
const contentId = parts.content.id;
|
|
114
114
|
const triggerId = parts.trigger.id;
|
|
115
|
-
return show({
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
return show(opts.state.map((s) => s.open), () => {
|
|
116
|
+
const targetEl = typeof rawTarget === 'string'
|
|
117
|
+
? (document.querySelector(rawTarget) ?? document.body)
|
|
118
|
+
: rawTarget;
|
|
119
|
+
return [
|
|
120
|
+
portal(() => {
|
|
120
121
|
onMount(() => {
|
|
121
122
|
const contentEl = document.getElementById(contentId);
|
|
122
123
|
const triggerEl = document.getElementById(triggerId);
|
|
@@ -138,10 +139,8 @@ export function overlay(opts) {
|
|
|
138
139
|
});
|
|
139
140
|
});
|
|
140
141
|
return [div(parts.positioner, opts.content())];
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
enter: opts.transition?.enter,
|
|
144
|
-
leave: opts.transition?.leave,
|
|
142
|
+
}, targetEl),
|
|
143
|
+
];
|
|
145
144
|
});
|
|
146
145
|
}
|
|
147
146
|
export const tooltip = { init, update, connect, overlay };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip.js","sourceRoot":"","sources":["../../src/components/tooltip.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send, TransitionOptions } from '@llui/dom'\nimport { show, portal, onMount, div, tagSend } from '@llui/dom'\nimport { attachFloating, type Placement } from '../utils/floating.js'\n\n/**\n * Tooltip — hover / focus-triggered, positioned. Opens after a short delay\n * to avoid flicker from passing pointers, closes immediately on blur or\n * after a grace period on pointer leave.\n *\n * Pure reducer handles only the boolean `open` state; timing (delays,\n * debouncing) lives in the event handlers returned from `connect()`, which\n * close over per-instance timers.\n */\n\nexport interface TooltipState {\n open: boolean\n}\n\nexport type TooltipMsg =\n /** @intent(\"Show the tooltip\") */\n | { type: 'show' }\n /** @intent(\"Hide the tooltip\") */\n | { type: 'hide' }\n /** @intent(\"Toggle the tooltip's visibility\") */\n | { type: 'toggle' }\n /** @intent(\"Set the tooltip's open state to a specific value\") */\n | { type: 'setOpen'; open: boolean }\n\nexport interface TooltipInit {\n open?: boolean\n}\n\nexport function init(opts: TooltipInit = {}): TooltipState {\n return { open: opts.open ?? false }\n}\n\nexport function update(state: TooltipState, msg: TooltipMsg): [TooltipState, never[]] {\n switch (msg.type) {\n case 'show':\n return [{ ...state, open: true }, []]\n case 'hide':\n return [{ ...state, open: false }, []]\n case 'toggle':\n return [{ ...state, open: !state.open }, []]\n case 'setOpen':\n return [{ ...state, open: msg.open }, []]\n }\n}\n\nexport interface TooltipParts<S> {\n trigger: {\n id: string\n 'aria-describedby': (s: S) => string | undefined\n 'data-state': (s: S) => 'open' | 'closed'\n 'data-scope': 'tooltip'\n 'data-part': 'trigger'\n onPointerEnter: (e: PointerEvent) => void\n onPointerLeave: (e: PointerEvent) => void\n onFocus: (e: FocusEvent) => void\n onBlur: (e: FocusEvent) => void\n onKeyDown: (e: KeyboardEvent) => void\n }\n positioner: {\n 'data-scope': 'tooltip'\n 'data-part': 'positioner'\n style: string\n }\n content: {\n role: 'tooltip'\n id: string\n 'data-state': (s: S) => 'open' | 'closed'\n 'data-scope': 'tooltip'\n 'data-part': 'content'\n onPointerEnter: (e: PointerEvent) => void\n onPointerLeave: (e: PointerEvent) => void\n }\n arrow: {\n 'data-scope': 'tooltip'\n 'data-part': 'arrow'\n }\n}\n\nexport interface ConnectOptions {\n id: string\n /** ms to wait before opening (default: 300). */\n delayOpen?: number\n /** ms to wait before closing after pointer leaves (default: 100). */\n delayClose?: number\n /** Open immediately on focus without delay (default: true). */\n openOnFocus?: boolean\n}\n\nexport function connect<S>(\n get: (s: S) => TooltipState,\n send: Send<TooltipMsg>,\n opts: ConnectOptions,\n): TooltipParts<S> {\n const base = opts.id\n const triggerId = `${base}:trigger`\n const contentId = `${base}:content`\n const delayOpen = opts.delayOpen ?? 300\n const delayClose = opts.delayClose ?? 100\n const openOnFocus = opts.openOnFocus !== false\n\n let openTimer: ReturnType<typeof setTimeout> | null = null\n let closeTimer: ReturnType<typeof setTimeout> | null = null\n\n const clearTimers = (): void => {\n if (openTimer) {\n clearTimeout(openTimer)\n openTimer = null\n }\n if (closeTimer) {\n clearTimeout(closeTimer)\n closeTimer = null\n }\n }\n\n const scheduleShow = (delay: number): void => {\n clearTimers()\n if (delay <= 0) {\n send({ type: 'show' })\n return\n }\n openTimer = setTimeout(() => {\n openTimer = null\n send({ type: 'show' })\n }, delay)\n }\n\n const scheduleHide = (delay: number): void => {\n clearTimers()\n if (delay <= 0) {\n send({ type: 'hide' })\n return\n }\n closeTimer = setTimeout(() => {\n closeTimer = null\n send({ type: 'hide' })\n }, delay)\n }\n\n return {\n trigger: {\n id: triggerId,\n 'aria-describedby': (s) => (get(s).open ? contentId : undefined),\n 'data-state': (s) => (get(s).open ? 'open' : 'closed'),\n 'data-scope': 'tooltip',\n 'data-part': 'trigger',\n onPointerEnter: () => scheduleShow(delayOpen),\n onPointerLeave: () => scheduleHide(delayClose),\n onFocus: () => {\n if (openOnFocus) scheduleShow(0)\n },\n onBlur: () => scheduleHide(0),\n onKeyDown: tagSend(send, ['hide'], (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n clearTimers()\n send({ type: 'hide' })\n }\n }),\n },\n positioner: {\n 'data-scope': 'tooltip',\n 'data-part': 'positioner',\n style: 'position:absolute;top:0;left:0;pointer-events:none;',\n },\n content: {\n role: 'tooltip',\n id: contentId,\n 'data-state': (s) => (get(s).open ? 'open' : 'closed'),\n 'data-scope': 'tooltip',\n 'data-part': 'content',\n // Allow pointer to enter content without closing (for interactive tooltips)\n onPointerEnter: () => {\n if (closeTimer) {\n clearTimeout(closeTimer)\n closeTimer = null\n }\n },\n onPointerLeave: () => scheduleHide(delayClose),\n },\n arrow: {\n 'data-scope': 'tooltip',\n 'data-part': 'arrow',\n },\n }\n}\n\nexport interface OverlayOptions<S> {\n get: (s: S) => TooltipState\n send: Send<TooltipMsg>\n parts: TooltipParts<S>\n content: () => Node[]\n placement?: Placement\n offset?: number\n flip?: boolean\n shift?: boolean\n transition?: TransitionOptions\n target?: string | HTMLElement\n arrowSelector?: string\n}\n\nexport function overlay<S>(opts: OverlayOptions<S>): Node[] {\n const target = opts.target ?? 'body'\n const placement = opts.placement ?? 'top'\n const offset = opts.offset ?? 6\n const flip = opts.flip !== false\n const shift = opts.shift !== false\n const parts = opts.parts\n const contentId = parts.content.id\n const triggerId = parts.trigger.id\n\n return show<S, TooltipMsg>({\n when: (s) => opts.get(s).open,\n render: () =>\n portal({\n target,\n render: () => {\n onMount(() => {\n const contentEl = document.getElementById(contentId)\n const triggerEl = document.getElementById(triggerId)\n if (!contentEl || !triggerEl) return\n\n const positioner = contentEl.closest('[data-part=\"positioner\"]') as HTMLElement | null\n const floatingEl = positioner ?? contentEl\n const arrow = opts.arrowSelector\n ? (contentEl.querySelector(opts.arrowSelector) as HTMLElement | null)\n : null\n return attachFloating({\n anchor: triggerEl,\n floating: floatingEl,\n placement,\n offset,\n flip,\n shift,\n arrow: arrow ?? undefined,\n })\n })\n return [div(parts.positioner, opts.content())]\n },\n }),\n enter: opts.transition?.enter,\n leave: opts.transition?.leave,\n })\n}\n\nexport const tooltip = { init, update, connect, overlay }\n"]}
|
|
1
|
+
{"version":3,"file":"tooltip.js","sourceRoot":"","sources":["../../src/components/tooltip.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send, Signal, TransitionOptions } from '@llui/dom'\nimport { show, portal, onMount, div, tagSend } from '@llui/dom'\nimport { attachFloating, type Placement } from '../utils/floating.js'\n\n/**\n * Tooltip — hover / focus-triggered, positioned. Opens after a short delay\n * to avoid flicker from passing pointers, closes immediately on blur or\n * after a grace period on pointer leave.\n *\n * Pure reducer handles only the boolean `open` state; timing (delays,\n * debouncing) lives in the event handlers returned from `connect()`, which\n * close over per-instance timers.\n */\n\nexport interface TooltipState {\n open: boolean\n}\n\nexport type TooltipMsg =\n /** @intent(\"Show the tooltip\") */\n | { type: 'show' }\n /** @intent(\"Hide the tooltip\") */\n | { type: 'hide' }\n /** @intent(\"Toggle the tooltip's visibility\") */\n | { type: 'toggle' }\n /** @intent(\"Set the tooltip's open state to a specific value\") */\n | { type: 'setOpen'; open: boolean }\n\nexport interface TooltipInit {\n open?: boolean\n}\n\nexport function init(opts: TooltipInit = {}): TooltipState {\n return { open: opts.open ?? false }\n}\n\nexport function update(state: TooltipState, msg: TooltipMsg): [TooltipState, never[]] {\n switch (msg.type) {\n case 'show':\n return [{ ...state, open: true }, []]\n case 'hide':\n return [{ ...state, open: false }, []]\n case 'toggle':\n return [{ ...state, open: !state.open }, []]\n case 'setOpen':\n return [{ ...state, open: msg.open }, []]\n }\n}\n\nexport interface TooltipParts {\n trigger: {\n id: string\n 'aria-describedby': Signal<string | undefined>\n 'data-state': Signal<'open' | 'closed'>\n 'data-scope': 'tooltip'\n 'data-part': 'trigger'\n onPointerEnter: (e: PointerEvent) => void\n onPointerLeave: (e: PointerEvent) => void\n onFocus: (e: FocusEvent) => void\n onBlur: (e: FocusEvent) => void\n onKeyDown: (e: KeyboardEvent) => void\n }\n positioner: {\n 'data-scope': 'tooltip'\n 'data-part': 'positioner'\n style: string\n }\n content: {\n role: 'tooltip'\n id: string\n 'data-state': Signal<'open' | 'closed'>\n 'data-scope': 'tooltip'\n 'data-part': 'content'\n onPointerEnter: (e: PointerEvent) => void\n onPointerLeave: (e: PointerEvent) => void\n }\n arrow: {\n 'data-scope': 'tooltip'\n 'data-part': 'arrow'\n }\n}\n\nexport interface ConnectOptions {\n id: string\n /** ms to wait before opening (default: 300). */\n delayOpen?: number\n /** ms to wait before closing after pointer leaves (default: 100). */\n delayClose?: number\n /** Open immediately on focus without delay (default: true). */\n openOnFocus?: boolean\n}\n\nexport function connect(\n state: Signal<TooltipState>,\n send: Send<TooltipMsg>,\n opts: ConnectOptions,\n): TooltipParts {\n const base = opts.id\n const triggerId = `${base}:trigger`\n const contentId = `${base}:content`\n const delayOpen = opts.delayOpen ?? 300\n const delayClose = opts.delayClose ?? 100\n const openOnFocus = opts.openOnFocus !== false\n\n let openTimer: ReturnType<typeof setTimeout> | null = null\n let closeTimer: ReturnType<typeof setTimeout> | null = null\n\n const clearTimers = (): void => {\n if (openTimer) {\n clearTimeout(openTimer)\n openTimer = null\n }\n if (closeTimer) {\n clearTimeout(closeTimer)\n closeTimer = null\n }\n }\n\n const scheduleShow = (delay: number): void => {\n clearTimers()\n if (delay <= 0) {\n send({ type: 'show' })\n return\n }\n openTimer = setTimeout(() => {\n openTimer = null\n send({ type: 'show' })\n }, delay)\n }\n\n const scheduleHide = (delay: number): void => {\n clearTimers()\n if (delay <= 0) {\n send({ type: 'hide' })\n return\n }\n closeTimer = setTimeout(() => {\n closeTimer = null\n send({ type: 'hide' })\n }, delay)\n }\n\n return {\n trigger: {\n id: triggerId,\n 'aria-describedby': state.map((s) => (s.open ? contentId : undefined)),\n 'data-state': state.map((s) => (s.open ? 'open' : 'closed')),\n 'data-scope': 'tooltip',\n 'data-part': 'trigger',\n onPointerEnter: () => scheduleShow(delayOpen),\n onPointerLeave: () => scheduleHide(delayClose),\n onFocus: () => {\n if (openOnFocus) scheduleShow(0)\n },\n onBlur: () => scheduleHide(0),\n onKeyDown: tagSend(send, ['hide'], (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n clearTimers()\n send({ type: 'hide' })\n }\n }),\n },\n positioner: {\n 'data-scope': 'tooltip',\n 'data-part': 'positioner',\n style: 'position:absolute;top:0;left:0;pointer-events:none;',\n },\n content: {\n role: 'tooltip',\n id: contentId,\n 'data-state': state.map((s) => (s.open ? 'open' : 'closed')),\n 'data-scope': 'tooltip',\n 'data-part': 'content',\n // Allow pointer to enter content without closing (for interactive tooltips)\n onPointerEnter: () => {\n if (closeTimer) {\n clearTimeout(closeTimer)\n closeTimer = null\n }\n },\n onPointerLeave: () => scheduleHide(delayClose),\n },\n arrow: {\n 'data-scope': 'tooltip',\n 'data-part': 'arrow',\n },\n }\n}\n\nexport interface OverlayOptions {\n state: Signal<TooltipState>\n send: Send<TooltipMsg>\n parts: TooltipParts\n content: () => Node[]\n placement?: Placement\n offset?: number\n flip?: boolean\n shift?: boolean\n transition?: TransitionOptions\n target?: string | HTMLElement\n arrowSelector?: string\n}\n\nexport function overlay(opts: OverlayOptions): Node {\n const rawTarget = opts.target ?? 'body'\n const placement = opts.placement ?? 'top'\n const offset = opts.offset ?? 6\n const flip = opts.flip !== false\n const shift = opts.shift !== false\n const parts = opts.parts\n const contentId = parts.content.id\n const triggerId = parts.trigger.id\n\n return show(\n opts.state.map((s) => s.open),\n () => {\n const targetEl =\n typeof rawTarget === 'string'\n ? (document.querySelector(rawTarget) ?? document.body)\n : rawTarget\n return [\n portal(() => {\n onMount(() => {\n const contentEl = document.getElementById(contentId)\n const triggerEl = document.getElementById(triggerId)\n if (!contentEl || !triggerEl) return\n\n const positioner = contentEl.closest('[data-part=\"positioner\"]') as HTMLElement | null\n const floatingEl = positioner ?? contentEl\n const arrow = opts.arrowSelector\n ? (contentEl.querySelector(opts.arrowSelector) as HTMLElement | null)\n : null\n return attachFloating({\n anchor: triggerEl,\n floating: floatingEl,\n placement,\n offset,\n flip,\n shift,\n arrow: arrow ?? undefined,\n })\n })\n return [div(parts.positioner, opts.content())]\n }, targetEl),\n ]\n },\n )\n}\n\nexport const tooltip = { init, update, connect, overlay }\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Send } from '@llui/dom';
|
|
1
|
+
import type { Send, Signal } from '@llui/dom';
|
|
2
2
|
/**
|
|
3
3
|
* Tour — guided walkthrough over a sequence of steps, each targeting
|
|
4
4
|
* an element on the page with a pop-up explanation. The state machine
|
|
@@ -80,7 +80,7 @@ export declare function progress(state: TourState): {
|
|
|
80
80
|
current: number;
|
|
81
81
|
total: number;
|
|
82
82
|
};
|
|
83
|
-
export interface TourParts
|
|
83
|
+
export interface TourParts {
|
|
84
84
|
root: {
|
|
85
85
|
role: 'dialog';
|
|
86
86
|
'aria-modal': 'false';
|
|
@@ -88,7 +88,7 @@ export interface TourParts<S> {
|
|
|
88
88
|
'aria-describedby': string;
|
|
89
89
|
'data-scope': 'tour';
|
|
90
90
|
'data-part': 'root';
|
|
91
|
-
hidden:
|
|
91
|
+
hidden: Signal<boolean>;
|
|
92
92
|
};
|
|
93
93
|
backdrop: {
|
|
94
94
|
'data-scope': 'tour';
|
|
@@ -117,7 +117,7 @@ export interface TourParts<S> {
|
|
|
117
117
|
};
|
|
118
118
|
prevTrigger: {
|
|
119
119
|
type: 'button';
|
|
120
|
-
disabled:
|
|
120
|
+
disabled: Signal<boolean>;
|
|
121
121
|
'data-scope': 'tour';
|
|
122
122
|
'data-part': 'prev-trigger';
|
|
123
123
|
onClick: (e: MouseEvent) => void;
|
|
@@ -126,12 +126,12 @@ export interface TourParts<S> {
|
|
|
126
126
|
type: 'button';
|
|
127
127
|
'data-scope': 'tour';
|
|
128
128
|
'data-part': 'next-trigger';
|
|
129
|
-
'data-last':
|
|
129
|
+
'data-last': Signal<'' | undefined>;
|
|
130
130
|
onClick: (e: MouseEvent) => void;
|
|
131
131
|
};
|
|
132
132
|
closeTrigger: {
|
|
133
133
|
type: 'button';
|
|
134
|
-
'aria-label': string
|
|
134
|
+
'aria-label': string;
|
|
135
135
|
'data-scope': 'tour';
|
|
136
136
|
'data-part': 'close-trigger';
|
|
137
137
|
onClick: (e: MouseEvent) => void;
|
|
@@ -144,7 +144,7 @@ export interface ConnectOptions {
|
|
|
144
144
|
* typically require an explicit dismiss. */
|
|
145
145
|
closeOnBackdropClick?: boolean;
|
|
146
146
|
}
|
|
147
|
-
export declare function connect
|
|
147
|
+
export declare function connect(state: Signal<TourState>, send: Send<TourMsg>, opts: ConnectOptions): TourParts;
|
|
148
148
|
export declare const tour: {
|
|
149
149
|
init: typeof init;
|
|
150
150
|
update: typeof update;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tour.d.ts","sourceRoot":"","sources":["../../src/components/tour.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"tour.d.ts","sourceRoot":"","sources":["../../src/components/tour.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAI7C;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAA;IACd,qCAAqC;IACrC,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;IAC/C,4DAA4D;IAC5D,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,oCAAoC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,MAAM,MAAM,OAAO;AACjB,iFAAiF;AAC/E;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE;AACnB,4EAA4E;GAC1E;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,gFAAgF;GAC9E;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,8CAA8C;GAC5C;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,6DAA6D;GAC3D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACjC,iBAAiB;GACf;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,QAAQ,EAAE,CAAA;CAAE,CAAA;AAE3C,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,IAAI,CAAC,IAAI,GAAE,QAAa,GAAG,SAAS,CASnD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAgC3E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,IAAI,CAE7D;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEjD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEhD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAE7E;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ,CAAA;QACd,YAAY,EAAE,OAAO,CAAA;QACrB,iBAAiB,EAAE,MAAM,CAAA;QACzB,kBAAkB,EAAE,MAAM,CAAA;QAC1B,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,MAAM,CAAA;QACnB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;KACxB,CAAA;IACD,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,UAAU,CAAA;QACvB,aAAa,EAAE,MAAM,CAAA;QACrB,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAA;KACjC,CAAA;IACD,SAAS,EAAE;QACT,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,WAAW,CAAA;QACxB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAA;QACV,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,OAAO,CAAA;KACrB,CAAA;IACD,WAAW,EAAE;QACX,EAAE,EAAE,MAAM,CAAA;QACV,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,aAAa,CAAA;KAC3B,CAAA;IACD,YAAY,EAAE;QACZ,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,eAAe,CAAA;KAC7B,CAAA;IACD,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAA;QACd,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;QACzB,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,cAAc,CAAA;QAC3B,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAA;KACjC,CAAA;IACD,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAA;QACd,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,cAAc,CAAA;QAC3B,WAAW,EAAE,MAAM,CAAC,EAAE,GAAG,SAAS,CAAC,CAAA;QACnC,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAA;KACjC,CAAA;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,QAAQ,CAAA;QACd,YAAY,EAAE,MAAM,CAAA;QACpB,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,eAAe,CAAA;QAC5B,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAA;KACjC,CAAA;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;iDAC6C;IAC7C,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,wBAAgB,OAAO,CACrB,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,EACxB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EACnB,IAAI,EAAE,cAAc,GACnB,SAAS,CAiEX;AAED,eAAO,MAAM,IAAI;;;;;;;;CAQhB,CAAA"}
|
package/dist/components/tour.js
CHANGED
|
@@ -59,7 +59,7 @@ export function isLast(state) {
|
|
|
59
59
|
export function progress(state) {
|
|
60
60
|
return { current: state.index + 1, total: state.steps.length };
|
|
61
61
|
}
|
|
62
|
-
export function connect(
|
|
62
|
+
export function connect(state, send, opts) {
|
|
63
63
|
const locale = useContext(LocaleContext);
|
|
64
64
|
const titleId = `${opts.id}:title`;
|
|
65
65
|
const descId = `${opts.id}:description`;
|
|
@@ -72,7 +72,7 @@ export function connect(get, send, opts) {
|
|
|
72
72
|
'aria-describedby': descId,
|
|
73
73
|
'data-scope': 'tour',
|
|
74
74
|
'data-part': 'root',
|
|
75
|
-
hidden: (s) => !
|
|
75
|
+
hidden: state.map((s) => !s.open),
|
|
76
76
|
},
|
|
77
77
|
backdrop: {
|
|
78
78
|
'data-scope': 'tour',
|
|
@@ -104,7 +104,7 @@ export function connect(get, send, opts) {
|
|
|
104
104
|
},
|
|
105
105
|
prevTrigger: {
|
|
106
106
|
type: 'button',
|
|
107
|
-
disabled: (s) => isFirst(
|
|
107
|
+
disabled: state.map((s) => isFirst(s)),
|
|
108
108
|
'data-scope': 'tour',
|
|
109
109
|
'data-part': 'prev-trigger',
|
|
110
110
|
onClick: tagSend(send, ['prev'], () => send({ type: 'prev' })),
|
|
@@ -113,12 +113,12 @@ export function connect(get, send, opts) {
|
|
|
113
113
|
type: 'button',
|
|
114
114
|
'data-scope': 'tour',
|
|
115
115
|
'data-part': 'next-trigger',
|
|
116
|
-
'data-last': (s) => (isLast(
|
|
116
|
+
'data-last': state.map((s) => (isLast(s) ? '' : undefined)),
|
|
117
117
|
onClick: tagSend(send, ['next'], () => send({ type: 'next' })),
|
|
118
118
|
},
|
|
119
119
|
closeTrigger: {
|
|
120
120
|
type: 'button',
|
|
121
|
-
'aria-label': opts.closeLabel ??
|
|
121
|
+
'aria-label': opts.closeLabel ?? locale.tour.close,
|
|
122
122
|
'data-scope': 'tour',
|
|
123
123
|
'data-part': 'close-trigger',
|
|
124
124
|
onClick: tagSend(send, ['stop'], () => send({ type: 'stop' })),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tour.js","sourceRoot":"","sources":["../../src/components/tour.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send } from '@llui/dom'\nimport { useContext, tagSend } from '@llui/dom'\nimport { LocaleContext } from '../locale.js'\nimport type { Locale } from '../locale.js'\n\n/**\n * Tour — guided walkthrough over a sequence of steps, each targeting\n * an element on the page with a pop-up explanation. The state machine\n * tracks the current step index and open/closed; positioning of the\n * pop-up relative to the target selector is done in the view layer\n * (typically via onMount + attachFloating).\n *\n * Typical shape:\n *\n * const t = tour.connect<State>(s => s.tour, m => send({type:'tour', msg:m}))\n * ...tour.overlay<State>({\n * get: s => s.tour,\n * send: m => send({type:'tour', msg:m}),\n * parts: t,\n * content: (step) => [\n * h3({ ...t.title }, [text(step.title)]),\n * p({ ...t.description }, [text(step.description)]),\n * button({ ...t.prevTrigger }, [text('Back')]),\n * button({ ...t.nextTrigger }, [text('Next')]),\n * ],\n * })\n */\n\nexport interface TourStep {\n id: string\n title: string\n description: string\n /** CSS selector or element ref for the tour target. */\n target: string\n /** Placement hint for the pop-up. */\n placement?: 'top' | 'bottom' | 'left' | 'right'\n /** Whether to show the highlight ring around the target. */\n spotlight?: boolean\n}\n\nexport interface TourState {\n steps: TourStep[]\n open: boolean\n index: number\n /** Ids of steps already visited. */\n visited: string[]\n}\n\nexport type TourMsg =\n /** @intent(\"Begin the tour at the first step (or current index if resuming)\") */\n | { type: 'start' }\n /** @intent(\"Close the tour without finishing (does not reset progress)\") */\n | { type: 'stop' }\n /** @intent(\"Advance to the next step (closes the tour after the last step)\") */\n | { type: 'next' }\n /** @intent(\"Go back to the previous step\") */\n | { type: 'prev' }\n /** @intent(\"Jump to a specific step by zero-based index\") */\n | { type: 'goto'; index: number }\n /** @humanOnly */\n | { type: 'setSteps'; steps: TourStep[] }\n\nexport interface TourInit {\n steps?: TourStep[]\n open?: boolean\n index?: number\n}\n\nexport function init(opts: TourInit = {}): TourState {\n const steps = opts.steps ?? []\n const index = Math.max(0, Math.min(opts.index ?? 0, Math.max(0, steps.length - 1)))\n return {\n steps,\n open: opts.open ?? false,\n index,\n visited: opts.open && steps[index] ? [steps[index].id] : [],\n }\n}\n\nexport function update(state: TourState, msg: TourMsg): [TourState, never[]] {\n switch (msg.type) {\n case 'start': {\n if (state.steps.length === 0) return [state, []]\n const first = state.steps[0]!\n return [{ ...state, open: true, index: 0, visited: [first.id] }, []]\n }\n case 'stop':\n return [{ ...state, open: false }, []]\n case 'next': {\n const last = state.steps.length - 1\n if (state.index >= last) return [{ ...state, open: false }, []]\n const nextIdx = state.index + 1\n const nextStep = state.steps[nextIdx]!\n const visited = state.visited.includes(nextStep.id)\n ? state.visited\n : [...state.visited, nextStep.id]\n return [{ ...state, index: nextIdx, visited }, []]\n }\n case 'prev': {\n if (state.index <= 0) return [state, []]\n return [{ ...state, index: state.index - 1 }, []]\n }\n case 'goto': {\n if (msg.index < 0 || msg.index >= state.steps.length) return [state, []]\n const step = state.steps[msg.index]!\n const visited = state.visited.includes(step.id) ? state.visited : [...state.visited, step.id]\n return [{ ...state, open: true, index: msg.index, visited }, []]\n }\n case 'setSteps':\n return [{ ...state, steps: msg.steps, index: 0 }, []]\n }\n}\n\nexport function currentStep(state: TourState): TourStep | null {\n return state.steps[state.index] ?? null\n}\n\nexport function isFirst(state: TourState): boolean {\n return state.index === 0\n}\n\nexport function isLast(state: TourState): boolean {\n return state.index === state.steps.length - 1\n}\n\nexport function progress(state: TourState): { current: number; total: number } {\n return { current: state.index + 1, total: state.steps.length }\n}\n\nexport interface TourParts<S> {\n root: {\n role: 'dialog'\n 'aria-modal': 'false'\n 'aria-labelledby': string\n 'aria-describedby': string\n 'data-scope': 'tour'\n 'data-part': 'root'\n hidden: (s: S) => boolean\n }\n backdrop: {\n 'data-scope': 'tour'\n 'data-part': 'backdrop'\n 'aria-hidden': 'true'\n onClick: (e: MouseEvent) => void\n }\n spotlight: {\n 'data-scope': 'tour'\n 'data-part': 'spotlight'\n 'aria-hidden': 'true'\n }\n title: {\n id: string\n 'data-scope': 'tour'\n 'data-part': 'title'\n }\n description: {\n id: string\n 'data-scope': 'tour'\n 'data-part': 'description'\n }\n progressText: {\n 'data-scope': 'tour'\n 'data-part': 'progress-text'\n }\n prevTrigger: {\n type: 'button'\n disabled: (s: S) => boolean\n 'data-scope': 'tour'\n 'data-part': 'prev-trigger'\n onClick: (e: MouseEvent) => void\n }\n nextTrigger: {\n type: 'button'\n 'data-scope': 'tour'\n 'data-part': 'next-trigger'\n 'data-last': (s: S) => '' | undefined\n onClick: (e: MouseEvent) => void\n }\n closeTrigger: {\n type: 'button'\n 'aria-label': string | ((s: S) => string)\n 'data-scope': 'tour'\n 'data-part': 'close-trigger'\n onClick: (e: MouseEvent) => void\n }\n}\n\nexport interface ConnectOptions {\n id: string\n closeLabel?: string\n /** Whether clicking the backdrop stops the tour. Default: false — tours\n * typically require an explicit dismiss. */\n closeOnBackdropClick?: boolean\n}\n\nexport function connect<S>(\n get: (s: S) => TourState,\n send: Send<TourMsg>,\n opts: ConnectOptions,\n): TourParts<S> {\n const locale = useContext<S, Locale>(LocaleContext)\n const titleId = `${opts.id}:title`\n const descId = `${opts.id}:description`\n const closeOnBackdrop = opts.closeOnBackdropClick === true\n\n return {\n root: {\n role: 'dialog',\n 'aria-modal': 'false',\n 'aria-labelledby': titleId,\n 'aria-describedby': descId,\n 'data-scope': 'tour',\n 'data-part': 'root',\n hidden: (s) => !get(s).open,\n },\n backdrop: {\n 'data-scope': 'tour',\n 'data-part': 'backdrop',\n 'aria-hidden': 'true',\n onClick: tagSend(send, ['stop'], () => {\n if (closeOnBackdrop) send({ type: 'stop' })\n }),\n },\n spotlight: {\n 'data-scope': 'tour',\n 'data-part': 'spotlight',\n 'aria-hidden': 'true',\n },\n title: {\n id: titleId,\n 'data-scope': 'tour',\n 'data-part': 'title',\n },\n description: {\n id: descId,\n 'data-scope': 'tour',\n 'data-part': 'description',\n },\n progressText: {\n 'data-scope': 'tour',\n 'data-part': 'progress-text',\n },\n prevTrigger: {\n type: 'button',\n disabled: (s) => isFirst(get(s)),\n 'data-scope': 'tour',\n 'data-part': 'prev-trigger',\n onClick: tagSend(send, ['prev'], () => send({ type: 'prev' })),\n },\n nextTrigger: {\n type: 'button',\n 'data-scope': 'tour',\n 'data-part': 'next-trigger',\n 'data-last': (s) => (isLast(get(s)) ? '' : undefined),\n onClick: tagSend(send, ['next'], () => send({ type: 'next' })),\n },\n closeTrigger: {\n type: 'button',\n 'aria-label': opts.closeLabel ?? ((s: S) => locale(s).tour.close),\n 'data-scope': 'tour',\n 'data-part': 'close-trigger',\n onClick: tagSend(send, ['stop'], () => send({ type: 'stop' })),\n },\n }\n}\n\nexport const tour = {\n init,\n update,\n connect,\n currentStep,\n isFirst,\n isLast,\n progress,\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tour.js","sourceRoot":"","sources":["../../src/components/tour.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send, Signal } from '@llui/dom'\nimport { useContext, tagSend } from '@llui/dom'\nimport { LocaleContext } from '../locale.js'\n\n/**\n * Tour — guided walkthrough over a sequence of steps, each targeting\n * an element on the page with a pop-up explanation. The state machine\n * tracks the current step index and open/closed; positioning of the\n * pop-up relative to the target selector is done in the view layer\n * (typically via onMount + attachFloating).\n *\n * Typical shape:\n *\n * const t = tour.connect<State>(s => s.tour, m => send({type:'tour', msg:m}))\n * ...tour.overlay<State>({\n * get: s => s.tour,\n * send: m => send({type:'tour', msg:m}),\n * parts: t,\n * content: (step) => [\n * h3({ ...t.title }, [text(step.title)]),\n * p({ ...t.description }, [text(step.description)]),\n * button({ ...t.prevTrigger }, [text('Back')]),\n * button({ ...t.nextTrigger }, [text('Next')]),\n * ],\n * })\n */\n\nexport interface TourStep {\n id: string\n title: string\n description: string\n /** CSS selector or element ref for the tour target. */\n target: string\n /** Placement hint for the pop-up. */\n placement?: 'top' | 'bottom' | 'left' | 'right'\n /** Whether to show the highlight ring around the target. */\n spotlight?: boolean\n}\n\nexport interface TourState {\n steps: TourStep[]\n open: boolean\n index: number\n /** Ids of steps already visited. */\n visited: string[]\n}\n\nexport type TourMsg =\n /** @intent(\"Begin the tour at the first step (or current index if resuming)\") */\n | { type: 'start' }\n /** @intent(\"Close the tour without finishing (does not reset progress)\") */\n | { type: 'stop' }\n /** @intent(\"Advance to the next step (closes the tour after the last step)\") */\n | { type: 'next' }\n /** @intent(\"Go back to the previous step\") */\n | { type: 'prev' }\n /** @intent(\"Jump to a specific step by zero-based index\") */\n | { type: 'goto'; index: number }\n /** @humanOnly */\n | { type: 'setSteps'; steps: TourStep[] }\n\nexport interface TourInit {\n steps?: TourStep[]\n open?: boolean\n index?: number\n}\n\nexport function init(opts: TourInit = {}): TourState {\n const steps = opts.steps ?? []\n const index = Math.max(0, Math.min(opts.index ?? 0, Math.max(0, steps.length - 1)))\n return {\n steps,\n open: opts.open ?? false,\n index,\n visited: opts.open && steps[index] ? [steps[index].id] : [],\n }\n}\n\nexport function update(state: TourState, msg: TourMsg): [TourState, never[]] {\n switch (msg.type) {\n case 'start': {\n if (state.steps.length === 0) return [state, []]\n const first = state.steps[0]!\n return [{ ...state, open: true, index: 0, visited: [first.id] }, []]\n }\n case 'stop':\n return [{ ...state, open: false }, []]\n case 'next': {\n const last = state.steps.length - 1\n if (state.index >= last) return [{ ...state, open: false }, []]\n const nextIdx = state.index + 1\n const nextStep = state.steps[nextIdx]!\n const visited = state.visited.includes(nextStep.id)\n ? state.visited\n : [...state.visited, nextStep.id]\n return [{ ...state, index: nextIdx, visited }, []]\n }\n case 'prev': {\n if (state.index <= 0) return [state, []]\n return [{ ...state, index: state.index - 1 }, []]\n }\n case 'goto': {\n if (msg.index < 0 || msg.index >= state.steps.length) return [state, []]\n const step = state.steps[msg.index]!\n const visited = state.visited.includes(step.id) ? state.visited : [...state.visited, step.id]\n return [{ ...state, open: true, index: msg.index, visited }, []]\n }\n case 'setSteps':\n return [{ ...state, steps: msg.steps, index: 0 }, []]\n }\n}\n\nexport function currentStep(state: TourState): TourStep | null {\n return state.steps[state.index] ?? null\n}\n\nexport function isFirst(state: TourState): boolean {\n return state.index === 0\n}\n\nexport function isLast(state: TourState): boolean {\n return state.index === state.steps.length - 1\n}\n\nexport function progress(state: TourState): { current: number; total: number } {\n return { current: state.index + 1, total: state.steps.length }\n}\n\nexport interface TourParts {\n root: {\n role: 'dialog'\n 'aria-modal': 'false'\n 'aria-labelledby': string\n 'aria-describedby': string\n 'data-scope': 'tour'\n 'data-part': 'root'\n hidden: Signal<boolean>\n }\n backdrop: {\n 'data-scope': 'tour'\n 'data-part': 'backdrop'\n 'aria-hidden': 'true'\n onClick: (e: MouseEvent) => void\n }\n spotlight: {\n 'data-scope': 'tour'\n 'data-part': 'spotlight'\n 'aria-hidden': 'true'\n }\n title: {\n id: string\n 'data-scope': 'tour'\n 'data-part': 'title'\n }\n description: {\n id: string\n 'data-scope': 'tour'\n 'data-part': 'description'\n }\n progressText: {\n 'data-scope': 'tour'\n 'data-part': 'progress-text'\n }\n prevTrigger: {\n type: 'button'\n disabled: Signal<boolean>\n 'data-scope': 'tour'\n 'data-part': 'prev-trigger'\n onClick: (e: MouseEvent) => void\n }\n nextTrigger: {\n type: 'button'\n 'data-scope': 'tour'\n 'data-part': 'next-trigger'\n 'data-last': Signal<'' | undefined>\n onClick: (e: MouseEvent) => void\n }\n closeTrigger: {\n type: 'button'\n 'aria-label': string\n 'data-scope': 'tour'\n 'data-part': 'close-trigger'\n onClick: (e: MouseEvent) => void\n }\n}\n\nexport interface ConnectOptions {\n id: string\n closeLabel?: string\n /** Whether clicking the backdrop stops the tour. Default: false — tours\n * typically require an explicit dismiss. */\n closeOnBackdropClick?: boolean\n}\n\nexport function connect(\n state: Signal<TourState>,\n send: Send<TourMsg>,\n opts: ConnectOptions,\n): TourParts {\n const locale = useContext(LocaleContext)\n const titleId = `${opts.id}:title`\n const descId = `${opts.id}:description`\n const closeOnBackdrop = opts.closeOnBackdropClick === true\n\n return {\n root: {\n role: 'dialog',\n 'aria-modal': 'false',\n 'aria-labelledby': titleId,\n 'aria-describedby': descId,\n 'data-scope': 'tour',\n 'data-part': 'root',\n hidden: state.map((s) => !s.open),\n },\n backdrop: {\n 'data-scope': 'tour',\n 'data-part': 'backdrop',\n 'aria-hidden': 'true',\n onClick: tagSend(send, ['stop'], () => {\n if (closeOnBackdrop) send({ type: 'stop' })\n }),\n },\n spotlight: {\n 'data-scope': 'tour',\n 'data-part': 'spotlight',\n 'aria-hidden': 'true',\n },\n title: {\n id: titleId,\n 'data-scope': 'tour',\n 'data-part': 'title',\n },\n description: {\n id: descId,\n 'data-scope': 'tour',\n 'data-part': 'description',\n },\n progressText: {\n 'data-scope': 'tour',\n 'data-part': 'progress-text',\n },\n prevTrigger: {\n type: 'button',\n disabled: state.map((s) => isFirst(s)),\n 'data-scope': 'tour',\n 'data-part': 'prev-trigger',\n onClick: tagSend(send, ['prev'], () => send({ type: 'prev' })),\n },\n nextTrigger: {\n type: 'button',\n 'data-scope': 'tour',\n 'data-part': 'next-trigger',\n 'data-last': state.map((s) => (isLast(s) ? '' : undefined)),\n onClick: tagSend(send, ['next'], () => send({ type: 'next' })),\n },\n closeTrigger: {\n type: 'button',\n 'aria-label': opts.closeLabel ?? locale.tour.close,\n 'data-scope': 'tour',\n 'data-part': 'close-trigger',\n onClick: tagSend(send, ['stop'], () => send({ type: 'stop' })),\n },\n }\n}\n\nexport const tour = {\n init,\n update,\n connect,\n currentStep,\n isFirst,\n isLast,\n progress,\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Send } from '@llui/dom';
|
|
1
|
+
import type { Send, Signal } from '@llui/dom';
|
|
2
2
|
/**
|
|
3
3
|
* Tree view — hierarchical list with expand/collapse. Items are identified
|
|
4
4
|
* by opaque string ids; the tree structure (children relationship) is
|
|
@@ -188,22 +188,22 @@ export declare function isChecked(state: TreeViewState, id: string): boolean;
|
|
|
188
188
|
export declare function isIndeterminate(state: TreeViewState, id: string): boolean;
|
|
189
189
|
export declare function isRenaming(state: TreeViewState, id: string): boolean;
|
|
190
190
|
export declare function isLoading(state: TreeViewState, id: string): boolean;
|
|
191
|
-
export interface TreeItemParts
|
|
191
|
+
export interface TreeItemParts {
|
|
192
192
|
item: {
|
|
193
193
|
role: 'treeitem';
|
|
194
194
|
id: string;
|
|
195
|
-
'aria-expanded':
|
|
196
|
-
'aria-selected':
|
|
195
|
+
'aria-expanded': Signal<boolean | undefined>;
|
|
196
|
+
'aria-selected': Signal<boolean | undefined>;
|
|
197
197
|
'aria-level': number;
|
|
198
|
-
'aria-busy':
|
|
199
|
-
tabIndex:
|
|
198
|
+
'aria-busy': Signal<'true' | undefined>;
|
|
199
|
+
tabIndex: Signal<number>;
|
|
200
200
|
'data-scope': 'tree-view';
|
|
201
201
|
'data-part': 'item';
|
|
202
202
|
'data-value': string;
|
|
203
203
|
'data-depth': string;
|
|
204
|
-
'data-selected':
|
|
205
|
-
'data-focused':
|
|
206
|
-
'data-loading':
|
|
204
|
+
'data-selected': Signal<'' | undefined>;
|
|
205
|
+
'data-focused': Signal<'' | undefined>;
|
|
206
|
+
'data-loading': Signal<'' | undefined>;
|
|
207
207
|
onClick: (e: MouseEvent) => void;
|
|
208
208
|
onKeyDown: (e: KeyboardEvent) => void;
|
|
209
209
|
onFocus: (e: FocusEvent) => void;
|
|
@@ -212,7 +212,7 @@ export interface TreeItemParts<S> {
|
|
|
212
212
|
branchTrigger: {
|
|
213
213
|
'data-scope': 'tree-view';
|
|
214
214
|
'data-part': 'branch-trigger';
|
|
215
|
-
'data-state':
|
|
215
|
+
'data-state': Signal<'open' | 'closed'>;
|
|
216
216
|
onClick: (e: MouseEvent) => void;
|
|
217
217
|
};
|
|
218
218
|
/**
|
|
@@ -225,23 +225,23 @@ export interface TreeItemParts<S> {
|
|
|
225
225
|
*/
|
|
226
226
|
checkbox: {
|
|
227
227
|
role: 'checkbox';
|
|
228
|
-
'aria-checked':
|
|
228
|
+
'aria-checked': Signal<'true' | 'false' | 'mixed'>;
|
|
229
229
|
'data-scope': 'tree-view';
|
|
230
230
|
'data-part': 'checkbox';
|
|
231
|
-
'data-state':
|
|
231
|
+
'data-state': Signal<'checked' | 'unchecked' | 'indeterminate'>;
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
|
-
export interface TreeViewParts
|
|
234
|
+
export interface TreeViewParts {
|
|
235
235
|
root: {
|
|
236
236
|
role: 'tree';
|
|
237
|
-
'aria-owns':
|
|
238
|
-
'aria-multiselectable':
|
|
239
|
-
'aria-disabled':
|
|
237
|
+
'aria-owns': Signal<string | undefined>;
|
|
238
|
+
'aria-multiselectable': Signal<'true' | undefined>;
|
|
239
|
+
'aria-disabled': Signal<'true' | undefined>;
|
|
240
240
|
'data-scope': 'tree-view';
|
|
241
241
|
'data-part': 'root';
|
|
242
|
-
'data-disabled':
|
|
242
|
+
'data-disabled': Signal<'' | undefined>;
|
|
243
243
|
};
|
|
244
|
-
item: (id: string, depth: number, isBranch: boolean, parentId?: string | null) => TreeItemParts
|
|
244
|
+
item: (id: string, depth: number, isBranch: boolean, parentId?: string | null) => TreeItemParts;
|
|
245
245
|
}
|
|
246
246
|
export interface ConnectOptions {
|
|
247
247
|
id: string;
|
|
@@ -252,7 +252,7 @@ export interface ConnectOptions {
|
|
|
252
252
|
*/
|
|
253
253
|
expandOnClick?: boolean;
|
|
254
254
|
}
|
|
255
|
-
export declare function connect
|
|
255
|
+
export declare function connect(state: Signal<TreeViewState>, send: Send<TreeViewMsg>, opts: ConnectOptions): TreeViewParts;
|
|
256
256
|
export declare const treeView: {
|
|
257
257
|
init: typeof init;
|
|
258
258
|
update: typeof update;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-view.d.ts","sourceRoot":"","sources":["../../src/components/tree-view.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"tree-view.d.ts","sourceRoot":"","sources":["../../src/components/tree-view.ts"],"names":[],"mappings":"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"}
|
|
@@ -174,40 +174,40 @@ export function isRenaming(state, id) {
|
|
|
174
174
|
export function isLoading(state, id) {
|
|
175
175
|
return state.loading.includes(id);
|
|
176
176
|
}
|
|
177
|
-
export function connect(
|
|
177
|
+
export function connect(state, send, opts) {
|
|
178
178
|
const itemId = (v) => `${opts.id}:item:${v}`;
|
|
179
179
|
const expandOnClick = opts.expandOnClick === true;
|
|
180
180
|
return {
|
|
181
181
|
root: {
|
|
182
182
|
role: 'tree',
|
|
183
|
-
'aria-owns': (s) => {
|
|
184
|
-
const items =
|
|
183
|
+
'aria-owns': state.map((s) => {
|
|
184
|
+
const items = s.visibleItems;
|
|
185
185
|
if (items.length === 0)
|
|
186
186
|
return undefined;
|
|
187
187
|
return items.map((id) => itemId(id)).join(' ');
|
|
188
|
-
},
|
|
189
|
-
'aria-multiselectable': (s) =>
|
|
190
|
-
'aria-disabled': (s) => (
|
|
188
|
+
}),
|
|
189
|
+
'aria-multiselectable': state.map((s) => s.selectionMode === 'multiple' ? 'true' : undefined),
|
|
190
|
+
'aria-disabled': state.map((s) => (s.disabled ? 'true' : undefined)),
|
|
191
191
|
'data-scope': 'tree-view',
|
|
192
192
|
'data-part': 'root',
|
|
193
|
-
'data-disabled': (s) => (
|
|
193
|
+
'data-disabled': state.map((s) => (s.disabled ? '' : undefined)),
|
|
194
194
|
},
|
|
195
195
|
item: (id, depth, isBranch, parentId = null) => ({
|
|
196
196
|
item: {
|
|
197
197
|
role: 'treeitem',
|
|
198
198
|
id: itemId(id),
|
|
199
|
-
'aria-expanded': (s) => (isBranch ? isExpanded(
|
|
200
|
-
'aria-selected': (s) =>
|
|
199
|
+
'aria-expanded': state.map((s) => (isBranch ? isExpanded(s, id) : undefined)),
|
|
200
|
+
'aria-selected': state.map((s) => s.selectionMode === 'single' ? isSelected(s, id) : undefined),
|
|
201
201
|
'aria-level': depth + 1,
|
|
202
|
-
'aria-busy': (s) => (isLoading(
|
|
203
|
-
tabIndex: (s) => (
|
|
202
|
+
'aria-busy': state.map((s) => (isLoading(s, id) ? 'true' : undefined)),
|
|
203
|
+
tabIndex: state.map((s) => (s.focused === id ? 0 : -1)),
|
|
204
204
|
'data-scope': 'tree-view',
|
|
205
205
|
'data-part': 'item',
|
|
206
206
|
'data-value': id,
|
|
207
207
|
'data-depth': String(depth),
|
|
208
|
-
'data-selected': (s) => (isSelected(
|
|
209
|
-
'data-focused': (s) => (
|
|
210
|
-
'data-loading': (s) => (isLoading(
|
|
208
|
+
'data-selected': state.map((s) => (isSelected(s, id) ? '' : undefined)),
|
|
209
|
+
'data-focused': state.map((s) => (s.focused === id ? '' : undefined)),
|
|
210
|
+
'data-loading': state.map((s) => (isLoading(s, id) ? '' : undefined)),
|
|
211
211
|
onClick: tagSend(send, ['select', 'toggleBranch'], (e) => {
|
|
212
212
|
send({ type: 'select', id, additive: e.metaKey || e.ctrlKey });
|
|
213
213
|
if (expandOnClick && isBranch)
|
|
@@ -275,7 +275,7 @@ export function connect(get, send, opts) {
|
|
|
275
275
|
branchTrigger: {
|
|
276
276
|
'data-scope': 'tree-view',
|
|
277
277
|
'data-part': 'branch-trigger',
|
|
278
|
-
'data-state': (s) => (isExpanded(
|
|
278
|
+
'data-state': state.map((s) => (isExpanded(s, id) ? 'open' : 'closed')),
|
|
279
279
|
onClick: tagSend(send, ['toggleBranch'], (e) => {
|
|
280
280
|
e.stopPropagation();
|
|
281
281
|
send({ type: 'toggleBranch', id });
|
|
@@ -283,18 +283,18 @@ export function connect(get, send, opts) {
|
|
|
283
283
|
},
|
|
284
284
|
checkbox: {
|
|
285
285
|
role: 'checkbox',
|
|
286
|
-
'aria-checked': (s) => {
|
|
287
|
-
if (isIndeterminate(
|
|
286
|
+
'aria-checked': state.map((s) => {
|
|
287
|
+
if (isIndeterminate(s, id))
|
|
288
288
|
return 'mixed';
|
|
289
|
-
return isChecked(
|
|
290
|
-
},
|
|
289
|
+
return isChecked(s, id) ? 'true' : 'false';
|
|
290
|
+
}),
|
|
291
291
|
'data-scope': 'tree-view',
|
|
292
292
|
'data-part': 'checkbox',
|
|
293
|
-
'data-state': (s) => {
|
|
294
|
-
if (isIndeterminate(
|
|
293
|
+
'data-state': state.map((s) => {
|
|
294
|
+
if (isIndeterminate(s, id))
|
|
295
295
|
return 'indeterminate';
|
|
296
|
-
return isChecked(
|
|
297
|
-
},
|
|
296
|
+
return isChecked(s, id) ? 'checked' : 'unchecked';
|
|
297
|
+
}),
|
|
298
298
|
},
|
|
299
299
|
}),
|
|
300
300
|
};
|