@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
|
@@ -78,10 +78,10 @@ export function update(state, msg) {
|
|
|
78
78
|
return [{ ...state, disabled: msg.disabled }, []];
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
export function connect(
|
|
81
|
+
export function connect(state, send, opts = {}) {
|
|
82
82
|
const locale = useContext(LocaleContext);
|
|
83
|
-
const incrementLabel = opts.incrementLabel ??
|
|
84
|
-
const decrementLabel = opts.decrementLabel ??
|
|
83
|
+
const incrementLabel = opts.incrementLabel ?? locale.numberInput.increment;
|
|
84
|
+
const decrementLabel = opts.decrementLabel ?? locale.numberInput.decrement;
|
|
85
85
|
const validate = opts.validate;
|
|
86
86
|
const trySetValue = (value) => {
|
|
87
87
|
if (validate) {
|
|
@@ -95,20 +95,20 @@ export function connect(get, send, opts = {}) {
|
|
|
95
95
|
root: {
|
|
96
96
|
'data-scope': 'number-input',
|
|
97
97
|
'data-part': 'root',
|
|
98
|
-
'data-disabled': (
|
|
98
|
+
'data-disabled': state.map((st) => (st.disabled ? '' : undefined)),
|
|
99
99
|
},
|
|
100
100
|
input: {
|
|
101
101
|
type: 'text',
|
|
102
102
|
role: 'spinbutton',
|
|
103
103
|
inputMode: 'decimal',
|
|
104
|
-
'aria-valuemin': (
|
|
105
|
-
'aria-valuemax': (
|
|
106
|
-
'aria-valuenow': (
|
|
107
|
-
'aria-disabled': (
|
|
108
|
-
'aria-readonly': (
|
|
109
|
-
disabled: (
|
|
110
|
-
readOnly: (
|
|
111
|
-
value: (
|
|
104
|
+
'aria-valuemin': state.map((st) => (isFinite(st.min) ? st.min : undefined)),
|
|
105
|
+
'aria-valuemax': state.map((st) => (isFinite(st.max) ? st.max : undefined)),
|
|
106
|
+
'aria-valuenow': state.map((st) => st.value ?? undefined),
|
|
107
|
+
'aria-disabled': state.map((st) => (st.disabled ? 'true' : undefined)),
|
|
108
|
+
'aria-readonly': state.map((st) => (st.readOnly ? 'true' : undefined)),
|
|
109
|
+
disabled: state.map((st) => st.disabled),
|
|
110
|
+
readOnly: state.map((st) => st.readOnly),
|
|
111
|
+
value: state.map((st) => st.rawText),
|
|
112
112
|
'data-scope': 'number-input',
|
|
113
113
|
'data-part': 'input',
|
|
114
114
|
onInput: tagSend(send, ['setRawText'], (e) => {
|
|
@@ -155,10 +155,8 @@ export function connect(get, send, opts = {}) {
|
|
|
155
155
|
increment: {
|
|
156
156
|
type: 'button',
|
|
157
157
|
'aria-label': incrementLabel,
|
|
158
|
-
'aria-disabled': (
|
|
159
|
-
|
|
160
|
-
: undefined,
|
|
161
|
-
disabled: (s) => get(s).disabled || get(s).readOnly || (get(s).value ?? 0) >= get(s).max,
|
|
158
|
+
'aria-disabled': state.map((st) => st.disabled || st.readOnly || (st.value ?? 0) >= st.max ? 'true' : undefined),
|
|
159
|
+
disabled: state.map((st) => st.disabled || st.readOnly || (st.value ?? 0) >= st.max),
|
|
162
160
|
'data-scope': 'number-input',
|
|
163
161
|
'data-part': 'increment',
|
|
164
162
|
tabIndex: -1,
|
|
@@ -167,10 +165,8 @@ export function connect(get, send, opts = {}) {
|
|
|
167
165
|
decrement: {
|
|
168
166
|
type: 'button',
|
|
169
167
|
'aria-label': decrementLabel,
|
|
170
|
-
'aria-disabled': (
|
|
171
|
-
|
|
172
|
-
: undefined,
|
|
173
|
-
disabled: (s) => get(s).disabled || get(s).readOnly || (get(s).value ?? 0) <= get(s).min,
|
|
168
|
+
'aria-disabled': state.map((st) => st.disabled || st.readOnly || (st.value ?? 0) <= st.min ? 'true' : undefined),
|
|
169
|
+
disabled: state.map((st) => st.disabled || st.readOnly || (st.value ?? 0) <= st.min),
|
|
174
170
|
'data-scope': 'number-input',
|
|
175
171
|
'data-part': 'decrement',
|
|
176
172
|
tabIndex: -1,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"number-input.js","sourceRoot":"","sources":["../../src/components/number-input.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 * Number input — numeric field with increment/decrement buttons. Clamps\n * to min/max and snaps to step. Keyboard: Arrow Up/Down, PageUp/PageDown,\n * Home/End.\n */\n\nexport interface NumberInputState {\n value: number | null\n min: number\n max: number\n step: number\n disabled: boolean\n readOnly: boolean\n /** Allow a free-text input value while the user is typing. */\n rawText: string\n}\n\nexport type NumberInputMsg =\n /** @intent(\"Set the numeric value (clamped to min/max, snapped to step)\") */\n | { type: 'setValue'; value: number | null }\n /** @humanOnly */\n | { type: 'setRawText'; text: string }\n /** @intent(\"Commit the in-progress text input — parse, clamp, snap, and update value\") */\n | { type: 'commit' }\n /** @intent(\"Increase value by step (or step × multiplier)\") */\n | { type: 'increment'; multiplier?: number }\n /** @intent(\"Decrease value by step (or step × multiplier)\") */\n | { type: 'decrement'; multiplier?: number }\n /** @intent(\"Snap value to the configured minimum\") */\n | { type: 'toMin' }\n /** @intent(\"Snap value to the configured maximum\") */\n | { type: 'toMax' }\n /** @humanOnly */\n | { type: 'setDisabled'; disabled: boolean }\n\nexport interface NumberInputInit {\n value?: number | null\n min?: number\n max?: number\n step?: number\n disabled?: boolean\n readOnly?: boolean\n}\n\nexport function init(opts: NumberInputInit = {}): NumberInputState {\n const value = opts.value ?? null\n return {\n value,\n min: opts.min ?? -Infinity,\n max: opts.max ?? Infinity,\n step: opts.step ?? 1,\n disabled: opts.disabled ?? false,\n readOnly: opts.readOnly ?? false,\n rawText: value === null ? '' : String(value),\n }\n}\n\nfunction clamp(n: number, min: number, max: number): number {\n if (n < min) return min\n if (n > max) return max\n return n\n}\n\nfunction snap(n: number, step: number, anchor = 0): number {\n if (step <= 0) return n\n const origin = isFinite(anchor) ? anchor : 0\n const decimals = decimalPlaces(step)\n const steps = Math.round((n - origin) / step)\n const snapped = origin + steps * step\n return Number(snapped.toFixed(decimals))\n}\n\nfunction decimalPlaces(n: number): number {\n if (Math.floor(n) === n) return 0\n const str = n.toString()\n const dot = str.indexOf('.')\n return dot === -1 ? 0 : str.length - dot - 1\n}\n\nexport function update(state: NumberInputState, msg: NumberInputMsg): [NumberInputState, never[]] {\n if (msg.type !== 'setDisabled' && (state.disabled || state.readOnly)) {\n // Allow setRawText for controlled typing? No — disabled means no interaction.\n return [state, []]\n }\n switch (msg.type) {\n case 'setValue': {\n const v =\n msg.value === null\n ? null\n : clamp(snap(msg.value, state.step, state.min), state.min, state.max)\n return [{ ...state, value: v, rawText: v === null ? '' : String(v) }, []]\n }\n case 'setRawText':\n return [{ ...state, rawText: msg.text }, []]\n case 'commit': {\n const parsed = parseFloat(state.rawText)\n if (isNaN(parsed))\n return [{ ...state, rawText: state.value === null ? '' : String(state.value) }, []]\n const v = clamp(snap(parsed, state.step, state.min), state.min, state.max)\n return [{ ...state, value: v, rawText: String(v) }, []]\n }\n case 'increment': {\n const base = state.value ?? 0\n const raw = base + state.step * (msg.multiplier ?? 1)\n const decimals = decimalPlaces(state.step)\n const v = clamp(Number(raw.toFixed(decimals)), state.min, state.max)\n return [{ ...state, value: v, rawText: String(v) }, []]\n }\n case 'decrement': {\n const base = state.value ?? 0\n const raw = base - state.step * (msg.multiplier ?? 1)\n const decimals = decimalPlaces(state.step)\n const v = clamp(Number(raw.toFixed(decimals)), state.min, state.max)\n return [{ ...state, value: v, rawText: String(v) }, []]\n }\n case 'toMin':\n return [{ ...state, value: state.min, rawText: String(state.min) }, []]\n case 'toMax':\n return [{ ...state, value: state.max, rawText: String(state.max) }, []]\n case 'setDisabled':\n return [{ ...state, disabled: msg.disabled }, []]\n }\n}\n\nexport interface NumberInputParts<S> {\n root: {\n 'data-scope': 'number-input'\n 'data-part': 'root'\n 'data-disabled': (s: S) => '' | undefined\n }\n input: {\n type: 'text'\n role: 'spinbutton'\n inputMode: 'decimal'\n 'aria-valuemin': (s: S) => number | undefined\n 'aria-valuemax': (s: S) => number | undefined\n 'aria-valuenow': (s: S) => number | undefined\n 'aria-disabled': (s: S) => 'true' | undefined\n 'aria-readonly': (s: S) => 'true' | undefined\n disabled: (s: S) => boolean\n readOnly: (s: S) => boolean\n value: (s: S) => string\n 'data-scope': 'number-input'\n 'data-part': 'input'\n onInput: (e: Event) => void\n onBlur: (e: FocusEvent) => void\n onKeyDown: (e: KeyboardEvent) => void\n }\n increment: {\n type: 'button'\n 'aria-label': string | ((s: S) => string)\n 'aria-disabled': (s: S) => 'true' | undefined\n disabled: (s: S) => boolean\n 'data-scope': 'number-input'\n 'data-part': 'increment'\n tabIndex: -1\n onClick: (e: MouseEvent) => void\n }\n decrement: {\n type: 'button'\n 'aria-label': string | ((s: S) => string)\n 'aria-disabled': (s: S) => 'true' | undefined\n disabled: (s: S) => boolean\n 'data-scope': 'number-input'\n 'data-part': 'decrement'\n tabIndex: -1\n onClick: (e: MouseEvent) => void\n }\n}\n\nexport interface ConnectOptions {\n incrementLabel?: string\n decrementLabel?: string\n /** Validate the numeric value before committing. Non-empty array blocks setValue. */\n validate?: (value: number) => string[] | null\n}\n\nexport function connect<S>(\n get: (s: S) => NumberInputState,\n send: Send<NumberInputMsg>,\n opts: ConnectOptions = {},\n): NumberInputParts<S> {\n const locale = useContext<S, Locale>(LocaleContext)\n const incrementLabel: string | ((s: S) => string) =\n opts.incrementLabel ?? ((s: S) => locale(s).numberInput.increment)\n const decrementLabel: string | ((s: S) => string) =\n opts.decrementLabel ?? ((s: S) => locale(s).numberInput.decrement)\n const validate = opts.validate\n\n const trySetValue = (value: number) => {\n if (validate) {\n const errors = validate(value)\n if (errors && errors.length > 0) return\n }\n send({ type: 'setValue', value })\n }\n\n return {\n root: {\n 'data-scope': 'number-input',\n 'data-part': 'root',\n 'data-disabled': (s) => (get(s).disabled ? '' : undefined),\n },\n input: {\n type: 'text',\n role: 'spinbutton',\n inputMode: 'decimal',\n 'aria-valuemin': (s) => (isFinite(get(s).min) ? get(s).min : undefined),\n 'aria-valuemax': (s) => (isFinite(get(s).max) ? get(s).max : undefined),\n 'aria-valuenow': (s) => get(s).value ?? undefined,\n 'aria-disabled': (s) => (get(s).disabled ? 'true' : undefined),\n 'aria-readonly': (s) => (get(s).readOnly ? 'true' : undefined),\n disabled: (s) => get(s).disabled,\n readOnly: (s) => get(s).readOnly,\n value: (s) => get(s).rawText,\n 'data-scope': 'number-input',\n 'data-part': 'input',\n onInput: tagSend(send, ['setRawText'], (e) => {\n const text = (e.target as HTMLInputElement).value\n send({ type: 'setRawText', text })\n const parsed = parseFloat(text)\n if (!isNaN(parsed)) trySetValue(parsed)\n }),\n onBlur: tagSend(send, ['commit'], () => send({ type: 'commit' })),\n onKeyDown: tagSend(send, ['increment', 'decrement', 'toMin', 'toMax', 'commit'], (e) => {\n switch (e.key) {\n case 'ArrowUp':\n e.preventDefault()\n send({ type: 'increment' })\n return\n case 'ArrowDown':\n e.preventDefault()\n send({ type: 'decrement' })\n return\n case 'PageUp':\n e.preventDefault()\n send({ type: 'increment', multiplier: 10 })\n return\n case 'PageDown':\n e.preventDefault()\n send({ type: 'decrement', multiplier: 10 })\n return\n case 'Home':\n e.preventDefault()\n send({ type: 'toMin' })\n return\n case 'End':\n e.preventDefault()\n send({ type: 'toMax' })\n return\n case 'Enter':\n e.preventDefault()\n send({ type: 'commit' })\n return\n }\n }),\n },\n increment: {\n type: 'button',\n 'aria-label': incrementLabel,\n 'aria-disabled': (s) =>\n get(s).disabled || get(s).readOnly || (get(s).value ?? 0) >= get(s).max\n ? 'true'\n : undefined,\n disabled: (s) => get(s).disabled || get(s).readOnly || (get(s).value ?? 0) >= get(s).max,\n 'data-scope': 'number-input',\n 'data-part': 'increment',\n tabIndex: -1,\n onClick: tagSend(send, ['increment'], () => send({ type: 'increment' })),\n },\n decrement: {\n type: 'button',\n 'aria-label': decrementLabel,\n 'aria-disabled': (s) =>\n get(s).disabled || get(s).readOnly || (get(s).value ?? 0) <= get(s).min\n ? 'true'\n : undefined,\n disabled: (s) => get(s).disabled || get(s).readOnly || (get(s).value ?? 0) <= get(s).min,\n 'data-scope': 'number-input',\n 'data-part': 'decrement',\n tabIndex: -1,\n onClick: tagSend(send, ['decrement'], () => send({ type: 'decrement' })),\n },\n }\n}\n\nexport const numberInput = { init, update, connect }\n"]}
|
|
1
|
+
{"version":3,"file":"number-input.js","sourceRoot":"","sources":["../../src/components/number-input.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 * Number input — numeric field with increment/decrement buttons. Clamps\n * to min/max and snaps to step. Keyboard: Arrow Up/Down, PageUp/PageDown,\n * Home/End.\n */\n\nexport interface NumberInputState {\n value: number | null\n min: number\n max: number\n step: number\n disabled: boolean\n readOnly: boolean\n /** Allow a free-text input value while the user is typing. */\n rawText: string\n}\n\nexport type NumberInputMsg =\n /** @intent(\"Set the numeric value (clamped to min/max, snapped to step)\") */\n | { type: 'setValue'; value: number | null }\n /** @humanOnly */\n | { type: 'setRawText'; text: string }\n /** @intent(\"Commit the in-progress text input — parse, clamp, snap, and update value\") */\n | { type: 'commit' }\n /** @intent(\"Increase value by step (or step × multiplier)\") */\n | { type: 'increment'; multiplier?: number }\n /** @intent(\"Decrease value by step (or step × multiplier)\") */\n | { type: 'decrement'; multiplier?: number }\n /** @intent(\"Snap value to the configured minimum\") */\n | { type: 'toMin' }\n /** @intent(\"Snap value to the configured maximum\") */\n | { type: 'toMax' }\n /** @humanOnly */\n | { type: 'setDisabled'; disabled: boolean }\n\nexport interface NumberInputInit {\n value?: number | null\n min?: number\n max?: number\n step?: number\n disabled?: boolean\n readOnly?: boolean\n}\n\nexport function init(opts: NumberInputInit = {}): NumberInputState {\n const value = opts.value ?? null\n return {\n value,\n min: opts.min ?? -Infinity,\n max: opts.max ?? Infinity,\n step: opts.step ?? 1,\n disabled: opts.disabled ?? false,\n readOnly: opts.readOnly ?? false,\n rawText: value === null ? '' : String(value),\n }\n}\n\nfunction clamp(n: number, min: number, max: number): number {\n if (n < min) return min\n if (n > max) return max\n return n\n}\n\nfunction snap(n: number, step: number, anchor = 0): number {\n if (step <= 0) return n\n const origin = isFinite(anchor) ? anchor : 0\n const decimals = decimalPlaces(step)\n const steps = Math.round((n - origin) / step)\n const snapped = origin + steps * step\n return Number(snapped.toFixed(decimals))\n}\n\nfunction decimalPlaces(n: number): number {\n if (Math.floor(n) === n) return 0\n const str = n.toString()\n const dot = str.indexOf('.')\n return dot === -1 ? 0 : str.length - dot - 1\n}\n\nexport function update(state: NumberInputState, msg: NumberInputMsg): [NumberInputState, never[]] {\n if (msg.type !== 'setDisabled' && (state.disabled || state.readOnly)) {\n // Allow setRawText for controlled typing? No — disabled means no interaction.\n return [state, []]\n }\n switch (msg.type) {\n case 'setValue': {\n const v =\n msg.value === null\n ? null\n : clamp(snap(msg.value, state.step, state.min), state.min, state.max)\n return [{ ...state, value: v, rawText: v === null ? '' : String(v) }, []]\n }\n case 'setRawText':\n return [{ ...state, rawText: msg.text }, []]\n case 'commit': {\n const parsed = parseFloat(state.rawText)\n if (isNaN(parsed))\n return [{ ...state, rawText: state.value === null ? '' : String(state.value) }, []]\n const v = clamp(snap(parsed, state.step, state.min), state.min, state.max)\n return [{ ...state, value: v, rawText: String(v) }, []]\n }\n case 'increment': {\n const base = state.value ?? 0\n const raw = base + state.step * (msg.multiplier ?? 1)\n const decimals = decimalPlaces(state.step)\n const v = clamp(Number(raw.toFixed(decimals)), state.min, state.max)\n return [{ ...state, value: v, rawText: String(v) }, []]\n }\n case 'decrement': {\n const base = state.value ?? 0\n const raw = base - state.step * (msg.multiplier ?? 1)\n const decimals = decimalPlaces(state.step)\n const v = clamp(Number(raw.toFixed(decimals)), state.min, state.max)\n return [{ ...state, value: v, rawText: String(v) }, []]\n }\n case 'toMin':\n return [{ ...state, value: state.min, rawText: String(state.min) }, []]\n case 'toMax':\n return [{ ...state, value: state.max, rawText: String(state.max) }, []]\n case 'setDisabled':\n return [{ ...state, disabled: msg.disabled }, []]\n }\n}\n\nexport interface NumberInputParts {\n root: {\n 'data-scope': 'number-input'\n 'data-part': 'root'\n 'data-disabled': Signal<'' | undefined>\n }\n input: {\n type: 'text'\n role: 'spinbutton'\n inputMode: 'decimal'\n 'aria-valuemin': Signal<number | undefined>\n 'aria-valuemax': Signal<number | undefined>\n 'aria-valuenow': Signal<number | undefined>\n 'aria-disabled': Signal<'true' | undefined>\n 'aria-readonly': Signal<'true' | undefined>\n disabled: Signal<boolean>\n readOnly: Signal<boolean>\n value: Signal<string>\n 'data-scope': 'number-input'\n 'data-part': 'input'\n onInput: (e: Event) => void\n onBlur: (e: FocusEvent) => void\n onKeyDown: (e: KeyboardEvent) => void\n }\n increment: {\n type: 'button'\n 'aria-label': string\n 'aria-disabled': Signal<'true' | undefined>\n disabled: Signal<boolean>\n 'data-scope': 'number-input'\n 'data-part': 'increment'\n tabIndex: -1\n onClick: (e: MouseEvent) => void\n }\n decrement: {\n type: 'button'\n 'aria-label': string\n 'aria-disabled': Signal<'true' | undefined>\n disabled: Signal<boolean>\n 'data-scope': 'number-input'\n 'data-part': 'decrement'\n tabIndex: -1\n onClick: (e: MouseEvent) => void\n }\n}\n\nexport interface ConnectOptions {\n incrementLabel?: string\n decrementLabel?: string\n /** Validate the numeric value before committing. Non-empty array blocks setValue. */\n validate?: (value: number) => string[] | null\n}\n\nexport function connect(\n state: Signal<NumberInputState>,\n send: Send<NumberInputMsg>,\n opts: ConnectOptions = {},\n): NumberInputParts {\n const locale = useContext(LocaleContext)\n const incrementLabel = opts.incrementLabel ?? locale.numberInput.increment\n const decrementLabel = opts.decrementLabel ?? locale.numberInput.decrement\n const validate = opts.validate\n\n const trySetValue = (value: number) => {\n if (validate) {\n const errors = validate(value)\n if (errors && errors.length > 0) return\n }\n send({ type: 'setValue', value })\n }\n\n return {\n root: {\n 'data-scope': 'number-input',\n 'data-part': 'root',\n 'data-disabled': state.map((st) => (st.disabled ? '' : undefined)),\n },\n input: {\n type: 'text',\n role: 'spinbutton',\n inputMode: 'decimal',\n 'aria-valuemin': state.map((st) => (isFinite(st.min) ? st.min : undefined)),\n 'aria-valuemax': state.map((st) => (isFinite(st.max) ? st.max : undefined)),\n 'aria-valuenow': state.map((st) => st.value ?? undefined),\n 'aria-disabled': state.map((st) => (st.disabled ? 'true' : undefined)),\n 'aria-readonly': state.map((st) => (st.readOnly ? 'true' : undefined)),\n disabled: state.map((st) => st.disabled),\n readOnly: state.map((st) => st.readOnly),\n value: state.map((st) => st.rawText),\n 'data-scope': 'number-input',\n 'data-part': 'input',\n onInput: tagSend(send, ['setRawText'], (e) => {\n const text = (e.target as HTMLInputElement).value\n send({ type: 'setRawText', text })\n const parsed = parseFloat(text)\n if (!isNaN(parsed)) trySetValue(parsed)\n }),\n onBlur: tagSend(send, ['commit'], () => send({ type: 'commit' })),\n onKeyDown: tagSend(send, ['increment', 'decrement', 'toMin', 'toMax', 'commit'], (e) => {\n switch (e.key) {\n case 'ArrowUp':\n e.preventDefault()\n send({ type: 'increment' })\n return\n case 'ArrowDown':\n e.preventDefault()\n send({ type: 'decrement' })\n return\n case 'PageUp':\n e.preventDefault()\n send({ type: 'increment', multiplier: 10 })\n return\n case 'PageDown':\n e.preventDefault()\n send({ type: 'decrement', multiplier: 10 })\n return\n case 'Home':\n e.preventDefault()\n send({ type: 'toMin' })\n return\n case 'End':\n e.preventDefault()\n send({ type: 'toMax' })\n return\n case 'Enter':\n e.preventDefault()\n send({ type: 'commit' })\n return\n }\n }),\n },\n increment: {\n type: 'button',\n 'aria-label': incrementLabel,\n 'aria-disabled': state.map((st) =>\n st.disabled || st.readOnly || (st.value ?? 0) >= st.max ? 'true' : undefined,\n ),\n disabled: state.map((st) => st.disabled || st.readOnly || (st.value ?? 0) >= st.max),\n 'data-scope': 'number-input',\n 'data-part': 'increment',\n tabIndex: -1,\n onClick: tagSend(send, ['increment'], () => send({ type: 'increment' })),\n },\n decrement: {\n type: 'button',\n 'aria-label': decrementLabel,\n 'aria-disabled': state.map((st) =>\n st.disabled || st.readOnly || (st.value ?? 0) <= st.min ? 'true' : undefined,\n ),\n disabled: state.map((st) => st.disabled || st.readOnly || (st.value ?? 0) <= st.min),\n 'data-scope': 'number-input',\n 'data-part': 'decrement',\n tabIndex: -1,\n onClick: tagSend(send, ['decrement'], () => send({ type: 'decrement' })),\n },\n }\n}\n\nexport const numberInput = { init, update, connect }\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Send } from '@llui/dom';
|
|
1
|
+
import type { Send, Signal } from '@llui/dom';
|
|
2
2
|
/**
|
|
3
3
|
* Pagination — page navigation with ellipses for large ranges.
|
|
4
4
|
* `page` is 1-based. Siblings are the count of pages shown on each side
|
|
@@ -67,28 +67,28 @@ export type PageItem = {
|
|
|
67
67
|
* `[first ..boundaries] … [siblings around current] … [boundaries ..last]`.
|
|
68
68
|
*/
|
|
69
69
|
export declare function pageItems(state: PaginationState): PageItem[];
|
|
70
|
-
export interface PaginationParts
|
|
70
|
+
export interface PaginationParts {
|
|
71
71
|
root: {
|
|
72
72
|
role: 'navigation';
|
|
73
|
-
'aria-label': string
|
|
73
|
+
'aria-label': string;
|
|
74
74
|
'data-scope': 'pagination';
|
|
75
75
|
'data-part': 'root';
|
|
76
|
-
'data-disabled':
|
|
76
|
+
'data-disabled': Signal<'' | undefined>;
|
|
77
77
|
};
|
|
78
78
|
prevTrigger: {
|
|
79
79
|
type: 'button';
|
|
80
|
-
'aria-label': string
|
|
81
|
-
'aria-disabled':
|
|
82
|
-
disabled:
|
|
80
|
+
'aria-label': string;
|
|
81
|
+
'aria-disabled': Signal<'true' | undefined>;
|
|
82
|
+
disabled: Signal<boolean>;
|
|
83
83
|
'data-scope': 'pagination';
|
|
84
84
|
'data-part': 'prev-trigger';
|
|
85
85
|
onClick: (e: MouseEvent) => void;
|
|
86
86
|
};
|
|
87
87
|
nextTrigger: {
|
|
88
88
|
type: 'button';
|
|
89
|
-
'aria-label': string
|
|
90
|
-
'aria-disabled':
|
|
91
|
-
disabled:
|
|
89
|
+
'aria-label': string;
|
|
90
|
+
'aria-disabled': Signal<'true' | undefined>;
|
|
91
|
+
disabled: Signal<boolean>;
|
|
92
92
|
'data-scope': 'pagination';
|
|
93
93
|
'data-part': 'next-trigger';
|
|
94
94
|
onClick: (e: MouseEvent) => void;
|
|
@@ -96,8 +96,8 @@ export interface PaginationParts<S> {
|
|
|
96
96
|
item: (page: number) => {
|
|
97
97
|
type: 'button';
|
|
98
98
|
'aria-label': string;
|
|
99
|
-
'aria-current':
|
|
100
|
-
'data-selected':
|
|
99
|
+
'aria-current': Signal<'page' | undefined>;
|
|
100
|
+
'data-selected': Signal<'' | undefined>;
|
|
101
101
|
'data-scope': 'pagination';
|
|
102
102
|
'data-part': 'item';
|
|
103
103
|
'data-value': string;
|
|
@@ -116,7 +116,7 @@ export interface ConnectOptions {
|
|
|
116
116
|
nextLabel?: string;
|
|
117
117
|
pageLabel?: (page: number) => string;
|
|
118
118
|
}
|
|
119
|
-
export declare function connect
|
|
119
|
+
export declare function connect(state: Signal<PaginationState>, send: Send<PaginationMsg>, opts?: ConnectOptions): PaginationParts;
|
|
120
120
|
export declare const pagination: {
|
|
121
121
|
init: typeof init;
|
|
122
122
|
update: typeof update;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/components/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/components/pagination.ts"],"names":[],"mappings":"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"}
|
|
@@ -79,11 +79,11 @@ export function pageItems(state) {
|
|
|
79
79
|
}
|
|
80
80
|
return items;
|
|
81
81
|
}
|
|
82
|
-
export function connect(
|
|
82
|
+
export function connect(state, send, opts = {}) {
|
|
83
83
|
const locale = useContext(LocaleContext);
|
|
84
|
-
const label = opts.label ??
|
|
85
|
-
const prevLabel = opts.prevLabel ??
|
|
86
|
-
const nextLabel = opts.nextLabel ??
|
|
84
|
+
const label = opts.label ?? locale.pagination.label;
|
|
85
|
+
const prevLabel = opts.prevLabel ?? locale.pagination.prev;
|
|
86
|
+
const nextLabel = opts.nextLabel ?? locale.pagination.next;
|
|
87
87
|
const pageLabel = opts.pageLabel ?? en.pagination.page;
|
|
88
88
|
return {
|
|
89
89
|
root: {
|
|
@@ -91,13 +91,13 @@ export function connect(get, send, opts = {}) {
|
|
|
91
91
|
'aria-label': label,
|
|
92
92
|
'data-scope': 'pagination',
|
|
93
93
|
'data-part': 'root',
|
|
94
|
-
'data-disabled': (
|
|
94
|
+
'data-disabled': state.map((st) => (st.disabled ? '' : undefined)),
|
|
95
95
|
},
|
|
96
96
|
prevTrigger: {
|
|
97
97
|
type: 'button',
|
|
98
98
|
'aria-label': prevLabel,
|
|
99
|
-
'aria-disabled': (
|
|
100
|
-
disabled: (
|
|
99
|
+
'aria-disabled': state.map((st) => (st.page <= 1 || st.disabled ? 'true' : undefined)),
|
|
100
|
+
disabled: state.map((st) => st.page <= 1 || st.disabled),
|
|
101
101
|
'data-scope': 'pagination',
|
|
102
102
|
'data-part': 'prev-trigger',
|
|
103
103
|
onClick: tagSend(send, ['prev'], () => send({ type: 'prev' })),
|
|
@@ -105,14 +105,8 @@ export function connect(get, send, opts = {}) {
|
|
|
105
105
|
nextTrigger: {
|
|
106
106
|
type: 'button',
|
|
107
107
|
'aria-label': nextLabel,
|
|
108
|
-
'aria-disabled': (
|
|
109
|
-
|
|
110
|
-
return st.page >= totalPages(st) || st.disabled ? 'true' : undefined;
|
|
111
|
-
},
|
|
112
|
-
disabled: (s) => {
|
|
113
|
-
const st = get(s);
|
|
114
|
-
return st.page >= totalPages(st) || st.disabled;
|
|
115
|
-
},
|
|
108
|
+
'aria-disabled': state.map((st) => st.page >= totalPages(st) || st.disabled ? 'true' : undefined),
|
|
109
|
+
disabled: state.map((st) => st.page >= totalPages(st) || st.disabled),
|
|
116
110
|
'data-scope': 'pagination',
|
|
117
111
|
'data-part': 'next-trigger',
|
|
118
112
|
onClick: tagSend(send, ['next'], () => send({ type: 'next' })),
|
|
@@ -120,8 +114,8 @@ export function connect(get, send, opts = {}) {
|
|
|
120
114
|
item: (page) => ({
|
|
121
115
|
type: 'button',
|
|
122
116
|
'aria-label': pageLabel(page),
|
|
123
|
-
'aria-current': (
|
|
124
|
-
'data-selected': (
|
|
117
|
+
'aria-current': state.map((st) => (st.page === page ? 'page' : undefined)),
|
|
118
|
+
'data-selected': state.map((st) => (st.page === page ? '' : undefined)),
|
|
125
119
|
'data-scope': 'pagination',
|
|
126
120
|
'data-part': 'item',
|
|
127
121
|
'data-value': String(page),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/components/pagination.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send } from '@llui/dom'\nimport { useContext, tagSend } from '@llui/dom'\nimport { LocaleContext, en } from '../locale.js'\nimport type { Locale } from '../locale.js'\n\n/**\n * Pagination — page navigation with ellipses for large ranges.\n * `page` is 1-based. Siblings are the count of pages shown on each side\n * of the current page. Boundaries are shown at the start/end.\n */\n\nexport interface PaginationState {\n page: number\n pageSize: number\n total: number\n siblings: number\n boundaries: number\n disabled: boolean\n}\n\nexport type PaginationMsg =\n /** @intent(\"Jump to a specific 1-based page number\") */\n | { type: 'goTo'; page: number }\n /** @intent(\"Advance to the next page\") */\n | { type: 'next' }\n /** @intent(\"Go back to the previous page\") */\n | { type: 'prev' }\n /** @intent(\"Jump to the first page\") */\n | { type: 'first' }\n /** @intent(\"Jump to the last page\") */\n | { type: 'last' }\n /** @intent(\"Change how many items each page contains\") */\n | { type: 'setPageSize'; pageSize: number }\n /** @humanOnly */\n | { type: 'setTotal'; total: number }\n\nexport interface PaginationInit {\n page?: number\n pageSize?: number\n total?: number\n siblings?: number\n boundaries?: number\n disabled?: boolean\n}\n\nexport function init(opts: PaginationInit = {}): PaginationState {\n return {\n page: opts.page ?? 1,\n pageSize: opts.pageSize ?? 10,\n total: opts.total ?? 0,\n siblings: opts.siblings ?? 1,\n boundaries: opts.boundaries ?? 1,\n disabled: opts.disabled ?? false,\n }\n}\n\nexport function totalPages(state: PaginationState): number {\n if (state.pageSize <= 0 || state.total <= 0) return 0\n return Math.max(1, Math.ceil(state.total / state.pageSize))\n}\n\nfunction clampPage(page: number, total: number): number {\n if (total === 0) return 1\n return Math.max(1, Math.min(page, total))\n}\n\nexport function update(state: PaginationState, msg: PaginationMsg): [PaginationState, never[]] {\n if (state.disabled) return [state, []]\n const pages = totalPages(state)\n switch (msg.type) {\n case 'goTo':\n return [{ ...state, page: clampPage(msg.page, pages) }, []]\n case 'next':\n return [{ ...state, page: clampPage(state.page + 1, pages) }, []]\n case 'prev':\n return [{ ...state, page: clampPage(state.page - 1, pages) }, []]\n case 'first':\n return [{ ...state, page: 1 }, []]\n case 'last':\n return [{ ...state, page: pages }, []]\n case 'setPageSize': {\n // Preserve first visible item when pageSize changes\n const firstItem = (state.page - 1) * state.pageSize\n const nextPage = Math.floor(firstItem / msg.pageSize) + 1\n const nextPages = Math.max(1, Math.ceil(state.total / msg.pageSize))\n return [{ ...state, pageSize: msg.pageSize, page: Math.min(nextPage, nextPages) }, []]\n }\n case 'setTotal': {\n const nextPages = Math.max(1, Math.ceil(msg.total / state.pageSize))\n return [{ ...state, total: msg.total, page: Math.min(state.page, nextPages) }, []]\n }\n }\n}\n\nexport type PageItem =\n | { type: 'page'; page: number }\n | { type: 'ellipsis'; position: 'start' | 'end' }\n\n/**\n * Compute the visible page buttons with ellipses:\n * `[first ..boundaries] … [siblings around current] … [boundaries ..last]`.\n */\nexport function pageItems(state: PaginationState): PageItem[] {\n const pages = totalPages(state)\n if (pages === 0) return []\n\n // Build the set of pages we want to show: first boundary, last boundary,\n // and current ± siblings.\n const pageSet = new Set<number>()\n for (let i = 1; i <= Math.min(state.boundaries, pages); i++) pageSet.add(i)\n for (let i = Math.max(pages - state.boundaries + 1, 1); i <= pages; i++) pageSet.add(i)\n const start = Math.max(1, state.page - state.siblings)\n const end = Math.min(pages, state.page + state.siblings)\n for (let i = start; i <= end; i++) pageSet.add(i)\n\n // Emit items in order, inserting ellipses for gaps > 1.\n const sorted = [...pageSet].sort((a, b) => a - b)\n const items: PageItem[] = []\n for (let i = 0; i < sorted.length; i++) {\n const page = sorted[i]!\n items.push({ type: 'page', page })\n if (i < sorted.length - 1 && sorted[i + 1]! - page > 1) {\n items.push({ type: 'ellipsis', position: page < state.page ? 'start' : 'end' })\n }\n }\n return items\n}\n\nexport interface PaginationParts<S> {\n root: {\n role: 'navigation'\n 'aria-label': string | ((s: S) => string)\n 'data-scope': 'pagination'\n 'data-part': 'root'\n 'data-disabled': (s: S) => '' | undefined\n }\n prevTrigger: {\n type: 'button'\n 'aria-label': string | ((s: S) => string)\n 'aria-disabled': (s: S) => 'true' | undefined\n disabled: (s: S) => boolean\n 'data-scope': 'pagination'\n 'data-part': 'prev-trigger'\n onClick: (e: MouseEvent) => void\n }\n nextTrigger: {\n type: 'button'\n 'aria-label': string | ((s: S) => string)\n 'aria-disabled': (s: S) => 'true' | undefined\n disabled: (s: S) => boolean\n 'data-scope': 'pagination'\n 'data-part': 'next-trigger'\n onClick: (e: MouseEvent) => void\n }\n item: (page: number) => {\n type: 'button'\n 'aria-label': string\n 'aria-current': (s: S) => 'page' | undefined\n 'data-selected': (s: S) => '' | undefined\n 'data-scope': 'pagination'\n 'data-part': 'item'\n 'data-value': string\n onClick: (e: MouseEvent) => void\n }\n ellipsis: (position: 'start' | 'end') => {\n 'aria-hidden': 'true'\n 'data-scope': 'pagination'\n 'data-part': 'ellipsis'\n 'data-position': 'start' | 'end'\n }\n}\n\nexport interface ConnectOptions {\n label?: string\n prevLabel?: string\n nextLabel?: string\n pageLabel?: (page: number) => string\n}\n\nexport function connect<S>(\n get: (s: S) => PaginationState,\n send: Send<PaginationMsg>,\n opts: ConnectOptions = {},\n): PaginationParts<S> {\n const locale = useContext<S, Locale>(LocaleContext)\n const label: string | ((s: S) => string) = opts.label ?? ((s: S) => locale(s).pagination.label)\n const prevLabel: string | ((s: S) => string) =\n opts.prevLabel ?? ((s: S) => locale(s).pagination.prev)\n const nextLabel: string | ((s: S) => string) =\n opts.nextLabel ?? ((s: S) => locale(s).pagination.next)\n const pageLabel = opts.pageLabel ?? en.pagination.page\n\n return {\n root: {\n role: 'navigation',\n 'aria-label': label,\n 'data-scope': 'pagination',\n 'data-part': 'root',\n 'data-disabled': (s) => (get(s).disabled ? '' : undefined),\n },\n prevTrigger: {\n type: 'button',\n 'aria-label': prevLabel,\n 'aria-disabled': (s) => (get(s).page <= 1 || get(s).disabled ? 'true' : undefined),\n disabled: (s) => get(s).page <= 1 || get(s).disabled,\n 'data-scope': 'pagination',\n 'data-part': 'prev-trigger',\n onClick: tagSend(send, ['prev'], () => send({ type: 'prev' })),\n },\n nextTrigger: {\n type: 'button',\n 'aria-label': nextLabel,\n 'aria-disabled': (s) => {\n const st = get(s)\n return st.page >= totalPages(st) || st.disabled ? 'true' : undefined\n },\n disabled: (s) => {\n const st = get(s)\n return st.page >= totalPages(st) || st.disabled\n },\n 'data-scope': 'pagination',\n 'data-part': 'next-trigger',\n onClick: tagSend(send, ['next'], () => send({ type: 'next' })),\n },\n item: (page: number) => ({\n type: 'button',\n 'aria-label': pageLabel(page),\n 'aria-current': (s) => (get(s).page === page ? 'page' : undefined),\n 'data-selected': (s) => (get(s).page === page ? '' : undefined),\n 'data-scope': 'pagination',\n 'data-part': 'item',\n 'data-value': String(page),\n onClick: tagSend(send, ['goTo'], () => send({ type: 'goTo', page })),\n }),\n ellipsis: (position: 'start' | 'end') => ({\n 'aria-hidden': 'true',\n 'data-scope': 'pagination',\n 'data-part': 'ellipsis',\n 'data-position': position,\n }),\n }\n}\n\nexport const pagination = { init, update, connect, totalPages, pageItems }\n"]}
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/components/pagination.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send, Signal } from '@llui/dom'\nimport { useContext, tagSend } from '@llui/dom'\nimport { LocaleContext, en } from '../locale.js'\n\n/**\n * Pagination — page navigation with ellipses for large ranges.\n * `page` is 1-based. Siblings are the count of pages shown on each side\n * of the current page. Boundaries are shown at the start/end.\n */\n\nexport interface PaginationState {\n page: number\n pageSize: number\n total: number\n siblings: number\n boundaries: number\n disabled: boolean\n}\n\nexport type PaginationMsg =\n /** @intent(\"Jump to a specific 1-based page number\") */\n | { type: 'goTo'; page: number }\n /** @intent(\"Advance to the next page\") */\n | { type: 'next' }\n /** @intent(\"Go back to the previous page\") */\n | { type: 'prev' }\n /** @intent(\"Jump to the first page\") */\n | { type: 'first' }\n /** @intent(\"Jump to the last page\") */\n | { type: 'last' }\n /** @intent(\"Change how many items each page contains\") */\n | { type: 'setPageSize'; pageSize: number }\n /** @humanOnly */\n | { type: 'setTotal'; total: number }\n\nexport interface PaginationInit {\n page?: number\n pageSize?: number\n total?: number\n siblings?: number\n boundaries?: number\n disabled?: boolean\n}\n\nexport function init(opts: PaginationInit = {}): PaginationState {\n return {\n page: opts.page ?? 1,\n pageSize: opts.pageSize ?? 10,\n total: opts.total ?? 0,\n siblings: opts.siblings ?? 1,\n boundaries: opts.boundaries ?? 1,\n disabled: opts.disabled ?? false,\n }\n}\n\nexport function totalPages(state: PaginationState): number {\n if (state.pageSize <= 0 || state.total <= 0) return 0\n return Math.max(1, Math.ceil(state.total / state.pageSize))\n}\n\nfunction clampPage(page: number, total: number): number {\n if (total === 0) return 1\n return Math.max(1, Math.min(page, total))\n}\n\nexport function update(state: PaginationState, msg: PaginationMsg): [PaginationState, never[]] {\n if (state.disabled) return [state, []]\n const pages = totalPages(state)\n switch (msg.type) {\n case 'goTo':\n return [{ ...state, page: clampPage(msg.page, pages) }, []]\n case 'next':\n return [{ ...state, page: clampPage(state.page + 1, pages) }, []]\n case 'prev':\n return [{ ...state, page: clampPage(state.page - 1, pages) }, []]\n case 'first':\n return [{ ...state, page: 1 }, []]\n case 'last':\n return [{ ...state, page: pages }, []]\n case 'setPageSize': {\n // Preserve first visible item when pageSize changes\n const firstItem = (state.page - 1) * state.pageSize\n const nextPage = Math.floor(firstItem / msg.pageSize) + 1\n const nextPages = Math.max(1, Math.ceil(state.total / msg.pageSize))\n return [{ ...state, pageSize: msg.pageSize, page: Math.min(nextPage, nextPages) }, []]\n }\n case 'setTotal': {\n const nextPages = Math.max(1, Math.ceil(msg.total / state.pageSize))\n return [{ ...state, total: msg.total, page: Math.min(state.page, nextPages) }, []]\n }\n }\n}\n\nexport type PageItem =\n | { type: 'page'; page: number }\n | { type: 'ellipsis'; position: 'start' | 'end' }\n\n/**\n * Compute the visible page buttons with ellipses:\n * `[first ..boundaries] … [siblings around current] … [boundaries ..last]`.\n */\nexport function pageItems(state: PaginationState): PageItem[] {\n const pages = totalPages(state)\n if (pages === 0) return []\n\n // Build the set of pages we want to show: first boundary, last boundary,\n // and current ± siblings.\n const pageSet = new Set<number>()\n for (let i = 1; i <= Math.min(state.boundaries, pages); i++) pageSet.add(i)\n for (let i = Math.max(pages - state.boundaries + 1, 1); i <= pages; i++) pageSet.add(i)\n const start = Math.max(1, state.page - state.siblings)\n const end = Math.min(pages, state.page + state.siblings)\n for (let i = start; i <= end; i++) pageSet.add(i)\n\n // Emit items in order, inserting ellipses for gaps > 1.\n const sorted = [...pageSet].sort((a, b) => a - b)\n const items: PageItem[] = []\n for (let i = 0; i < sorted.length; i++) {\n const page = sorted[i]!\n items.push({ type: 'page', page })\n if (i < sorted.length - 1 && sorted[i + 1]! - page > 1) {\n items.push({ type: 'ellipsis', position: page < state.page ? 'start' : 'end' })\n }\n }\n return items\n}\n\nexport interface PaginationParts {\n root: {\n role: 'navigation'\n 'aria-label': string\n 'data-scope': 'pagination'\n 'data-part': 'root'\n 'data-disabled': Signal<'' | undefined>\n }\n prevTrigger: {\n type: 'button'\n 'aria-label': string\n 'aria-disabled': Signal<'true' | undefined>\n disabled: Signal<boolean>\n 'data-scope': 'pagination'\n 'data-part': 'prev-trigger'\n onClick: (e: MouseEvent) => void\n }\n nextTrigger: {\n type: 'button'\n 'aria-label': string\n 'aria-disabled': Signal<'true' | undefined>\n disabled: Signal<boolean>\n 'data-scope': 'pagination'\n 'data-part': 'next-trigger'\n onClick: (e: MouseEvent) => void\n }\n item: (page: number) => {\n type: 'button'\n 'aria-label': string\n 'aria-current': Signal<'page' | undefined>\n 'data-selected': Signal<'' | undefined>\n 'data-scope': 'pagination'\n 'data-part': 'item'\n 'data-value': string\n onClick: (e: MouseEvent) => void\n }\n ellipsis: (position: 'start' | 'end') => {\n 'aria-hidden': 'true'\n 'data-scope': 'pagination'\n 'data-part': 'ellipsis'\n 'data-position': 'start' | 'end'\n }\n}\n\nexport interface ConnectOptions {\n label?: string\n prevLabel?: string\n nextLabel?: string\n pageLabel?: (page: number) => string\n}\n\nexport function connect(\n state: Signal<PaginationState>,\n send: Send<PaginationMsg>,\n opts: ConnectOptions = {},\n): PaginationParts {\n const locale = useContext(LocaleContext)\n const label = opts.label ?? locale.pagination.label\n const prevLabel = opts.prevLabel ?? locale.pagination.prev\n const nextLabel = opts.nextLabel ?? locale.pagination.next\n const pageLabel = opts.pageLabel ?? en.pagination.page\n\n return {\n root: {\n role: 'navigation',\n 'aria-label': label,\n 'data-scope': 'pagination',\n 'data-part': 'root',\n 'data-disabled': state.map((st) => (st.disabled ? '' : undefined)),\n },\n prevTrigger: {\n type: 'button',\n 'aria-label': prevLabel,\n 'aria-disabled': state.map((st) => (st.page <= 1 || st.disabled ? 'true' : undefined)),\n disabled: state.map((st) => st.page <= 1 || st.disabled),\n 'data-scope': 'pagination',\n 'data-part': 'prev-trigger',\n onClick: tagSend(send, ['prev'], () => send({ type: 'prev' })),\n },\n nextTrigger: {\n type: 'button',\n 'aria-label': nextLabel,\n 'aria-disabled': state.map((st) =>\n st.page >= totalPages(st) || st.disabled ? 'true' : undefined,\n ),\n disabled: state.map((st) => st.page >= totalPages(st) || st.disabled),\n 'data-scope': 'pagination',\n 'data-part': 'next-trigger',\n onClick: tagSend(send, ['next'], () => send({ type: 'next' })),\n },\n item: (page: number) => ({\n type: 'button',\n 'aria-label': pageLabel(page),\n 'aria-current': state.map((st) => (st.page === page ? 'page' : undefined)),\n 'data-selected': state.map((st) => (st.page === page ? '' : undefined)),\n 'data-scope': 'pagination',\n 'data-part': 'item',\n 'data-value': String(page),\n onClick: tagSend(send, ['goTo'], () => send({ type: 'goTo', page })),\n }),\n ellipsis: (position: 'start' | 'end') => ({\n 'aria-hidden': 'true',\n 'data-scope': 'pagination',\n 'data-part': 'ellipsis',\n 'data-position': position,\n }),\n }\n}\n\nexport const pagination = { init, update, connect, totalPages, pageItems }\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Send } from '@llui/dom';
|
|
1
|
+
import type { Send, Signal } from '@llui/dom';
|
|
2
2
|
/**
|
|
3
3
|
* Password input — text input with show/hide visibility toggle.
|
|
4
4
|
*/
|
|
@@ -29,27 +29,27 @@ export interface PasswordInputInit {
|
|
|
29
29
|
}
|
|
30
30
|
export declare function init(opts?: PasswordInputInit): PasswordInputState;
|
|
31
31
|
export declare function update(state: PasswordInputState, msg: PasswordInputMsg): [PasswordInputState, never[]];
|
|
32
|
-
export interface PasswordInputParts
|
|
32
|
+
export interface PasswordInputParts {
|
|
33
33
|
root: {
|
|
34
34
|
'data-scope': 'password-input';
|
|
35
35
|
'data-part': 'root';
|
|
36
|
-
'data-visible':
|
|
37
|
-
'data-disabled':
|
|
36
|
+
'data-visible': Signal<'' | undefined>;
|
|
37
|
+
'data-disabled': Signal<'' | undefined>;
|
|
38
38
|
};
|
|
39
39
|
input: {
|
|
40
|
-
type:
|
|
40
|
+
type: Signal<'text' | 'password'>;
|
|
41
41
|
autoComplete: string;
|
|
42
|
-
disabled:
|
|
43
|
-
value:
|
|
42
|
+
disabled: Signal<boolean>;
|
|
43
|
+
value: Signal<string>;
|
|
44
44
|
'data-scope': 'password-input';
|
|
45
45
|
'data-part': 'input';
|
|
46
46
|
onInput: (e: Event) => void;
|
|
47
47
|
};
|
|
48
48
|
visibilityTrigger: {
|
|
49
49
|
type: 'button';
|
|
50
|
-
'aria-label':
|
|
51
|
-
'aria-pressed':
|
|
52
|
-
disabled:
|
|
50
|
+
'aria-label': Signal<string>;
|
|
51
|
+
'aria-pressed': Signal<boolean>;
|
|
52
|
+
disabled: Signal<boolean>;
|
|
53
53
|
tabIndex: -1;
|
|
54
54
|
'data-scope': 'password-input';
|
|
55
55
|
'data-part': 'visibility-trigger';
|
|
@@ -61,7 +61,7 @@ export interface ConnectOptions {
|
|
|
61
61
|
showLabel?: string;
|
|
62
62
|
hideLabel?: string;
|
|
63
63
|
}
|
|
64
|
-
export declare function connect
|
|
64
|
+
export declare function connect(state: Signal<PasswordInputState>, send: Send<PasswordInputMsg>, opts?: ConnectOptions): PasswordInputParts;
|
|
65
65
|
export declare const passwordInput: {
|
|
66
66
|
init: typeof init;
|
|
67
67
|
update: typeof update;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password-input.d.ts","sourceRoot":"","sources":["../../src/components/password-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"password-input.d.ts","sourceRoot":"","sources":["../../src/components/password-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAI7C;;GAEG;AAEH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,MAAM,gBAAgB;AAC1B,6DAA6D;AAC3D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACrC,qDAAqD;GACnD;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE;AAC9B,sEAAsE;GACpE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAA;AAE5C,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,IAAI,CAAC,IAAI,GAAE,iBAAsB,GAAG,kBAAkB,CAMrE;AAED,wBAAgB,MAAM,CACpB,KAAK,EAAE,kBAAkB,EACzB,GAAG,EAAE,gBAAgB,GACpB,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,CAU/B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE;QACJ,YAAY,EAAE,gBAAgB,CAAA;QAC9B,WAAW,EAAE,MAAM,CAAA;QACnB,cAAc,EAAE,MAAM,CAAC,EAAE,GAAG,SAAS,CAAC,CAAA;QACtC,eAAe,EAAE,MAAM,CAAC,EAAE,GAAG,SAAS,CAAC,CAAA;KACxC,CAAA;IACD,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC,CAAA;QACjC,YAAY,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;QACzB,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QACrB,YAAY,EAAE,gBAAgB,CAAA;QAC9B,WAAW,EAAE,OAAO,CAAA;QACpB,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;KAC5B,CAAA;IACD,iBAAiB,EAAE;QACjB,IAAI,EAAE,QAAQ,CAAA;QACd,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QAC5B,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;QAC/B,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;QACzB,QAAQ,EAAE,CAAC,CAAC,CAAA;QACZ,YAAY,EAAE,gBAAgB,CAAA;QAC9B,WAAW,EAAE,oBAAoB,CAAA;QACjC,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAA;KACjC,CAAA;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,OAAO,CACrB,KAAK,EAAE,MAAM,CAAC,kBAAkB,CAAC,EACjC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAC5B,IAAI,GAAE,cAAmB,GACxB,kBAAkB,CAuCpB;AAED,eAAO,MAAM,aAAa;;;;CAA4B,CAAA"}
|
|
@@ -19,7 +19,7 @@ export function update(state, msg) {
|
|
|
19
19
|
return [{ ...state, visible: msg.visible }, []];
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
export function connect(
|
|
22
|
+
export function connect(state, send, opts = {}) {
|
|
23
23
|
const locale = useContext(LocaleContext);
|
|
24
24
|
const autoComplete = opts.autoComplete ?? 'current-password';
|
|
25
25
|
const showLabel = opts.showLabel;
|
|
@@ -28,25 +28,25 @@ export function connect(get, send, opts = {}) {
|
|
|
28
28
|
root: {
|
|
29
29
|
'data-scope': 'password-input',
|
|
30
30
|
'data-part': 'root',
|
|
31
|
-
'data-visible': (
|
|
32
|
-
'data-disabled': (
|
|
31
|
+
'data-visible': state.map((st) => (st.visible ? '' : undefined)),
|
|
32
|
+
'data-disabled': state.map((st) => (st.disabled ? '' : undefined)),
|
|
33
33
|
},
|
|
34
34
|
input: {
|
|
35
|
-
type: (
|
|
35
|
+
type: state.map((st) => (st.visible ? 'text' : 'password')),
|
|
36
36
|
autoComplete,
|
|
37
|
-
disabled: (
|
|
38
|
-
value: (
|
|
37
|
+
disabled: state.map((st) => st.disabled),
|
|
38
|
+
value: state.map((st) => st.value),
|
|
39
39
|
'data-scope': 'password-input',
|
|
40
40
|
'data-part': 'input',
|
|
41
41
|
onInput: tagSend(send, ['setValue'], (e) => send({ type: 'setValue', value: e.target.value })),
|
|
42
42
|
},
|
|
43
43
|
visibilityTrigger: {
|
|
44
44
|
type: 'button',
|
|
45
|
-
'aria-label': (
|
|
46
|
-
? (hideLabel ?? locale
|
|
47
|
-
: (showLabel ?? locale
|
|
48
|
-
'aria-pressed': (
|
|
49
|
-
disabled: (
|
|
45
|
+
'aria-label': state.map((st) => st.visible
|
|
46
|
+
? (hideLabel ?? locale.passwordInput.hide)
|
|
47
|
+
: (showLabel ?? locale.passwordInput.show)),
|
|
48
|
+
'aria-pressed': state.map((st) => st.visible),
|
|
49
|
+
disabled: state.map((st) => st.disabled),
|
|
50
50
|
tabIndex: -1,
|
|
51
51
|
'data-scope': 'password-input',
|
|
52
52
|
'data-part': 'visibility-trigger',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password-input.js","sourceRoot":"","sources":["../../src/components/password-input.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"password-input.js","sourceRoot":"","sources":["../../src/components/password-input.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 * Password input — text input with show/hide visibility toggle.\n */\n\nexport interface PasswordInputState {\n value: string\n visible: boolean\n disabled: boolean\n}\n\nexport type PasswordInputMsg =\n /** @intent(\"Update the password value as the user types\") */\n | { type: 'setValue'; value: string }\n /** @intent(\"Toggle the show/hide-password state\") */\n | { type: 'toggleVisibility' }\n /** @intent(\"Set the show/hide-password state to a specific value\") */\n | { type: 'setVisible'; visible: boolean }\n\nexport interface PasswordInputInit {\n value?: string\n visible?: boolean\n disabled?: boolean\n}\n\nexport function init(opts: PasswordInputInit = {}): PasswordInputState {\n return {\n value: opts.value ?? '',\n visible: opts.visible ?? false,\n disabled: opts.disabled ?? false,\n }\n}\n\nexport function update(\n state: PasswordInputState,\n msg: PasswordInputMsg,\n): [PasswordInputState, never[]] {\n if (state.disabled && msg.type !== 'setValue') return [state, []]\n switch (msg.type) {\n case 'setValue':\n return [{ ...state, value: msg.value }, []]\n case 'toggleVisibility':\n return [{ ...state, visible: !state.visible }, []]\n case 'setVisible':\n return [{ ...state, visible: msg.visible }, []]\n }\n}\n\nexport interface PasswordInputParts {\n root: {\n 'data-scope': 'password-input'\n 'data-part': 'root'\n 'data-visible': Signal<'' | undefined>\n 'data-disabled': Signal<'' | undefined>\n }\n input: {\n type: Signal<'text' | 'password'>\n autoComplete: string\n disabled: Signal<boolean>\n value: Signal<string>\n 'data-scope': 'password-input'\n 'data-part': 'input'\n onInput: (e: Event) => void\n }\n visibilityTrigger: {\n type: 'button'\n 'aria-label': Signal<string>\n 'aria-pressed': Signal<boolean>\n disabled: Signal<boolean>\n tabIndex: -1\n 'data-scope': 'password-input'\n 'data-part': 'visibility-trigger'\n onClick: (e: MouseEvent) => void\n }\n}\n\nexport interface ConnectOptions {\n autoComplete?: string\n showLabel?: string\n hideLabel?: string\n}\n\nexport function connect(\n state: Signal<PasswordInputState>,\n send: Send<PasswordInputMsg>,\n opts: ConnectOptions = {},\n): PasswordInputParts {\n const locale = useContext(LocaleContext)\n const autoComplete = opts.autoComplete ?? 'current-password'\n const showLabel = opts.showLabel\n const hideLabel = opts.hideLabel\n\n return {\n root: {\n 'data-scope': 'password-input',\n 'data-part': 'root',\n 'data-visible': state.map((st) => (st.visible ? '' : undefined)),\n 'data-disabled': state.map((st) => (st.disabled ? '' : undefined)),\n },\n input: {\n type: state.map((st) => (st.visible ? 'text' : 'password')),\n autoComplete,\n disabled: state.map((st) => st.disabled),\n value: state.map((st) => st.value),\n 'data-scope': 'password-input',\n 'data-part': 'input',\n onInput: tagSend(send, ['setValue'], (e) =>\n send({ type: 'setValue', value: (e.target as HTMLInputElement).value }),\n ),\n },\n visibilityTrigger: {\n type: 'button',\n 'aria-label': state.map((st) =>\n st.visible\n ? (hideLabel ?? locale.passwordInput.hide)\n : (showLabel ?? locale.passwordInput.show),\n ),\n 'aria-pressed': state.map((st) => st.visible),\n disabled: state.map((st) => st.disabled),\n tabIndex: -1,\n 'data-scope': 'password-input',\n 'data-part': 'visibility-trigger',\n onClick: tagSend(send, ['toggleVisibility'], () => send({ type: 'toggleVisibility' })),\n },\n }\n}\n\nexport const passwordInput = { init, update, connect }\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Send } from '@llui/dom';
|
|
1
|
+
import type { Send, Signal } from '@llui/dom';
|
|
2
2
|
/**
|
|
3
3
|
* Pin input — a sequence of single-character fields for OTP codes, etc.
|
|
4
4
|
* Auto-advances on input, handles backspace to previous field, supports
|
|
@@ -50,13 +50,13 @@ export declare function init(opts?: PinInputInit): PinInputState;
|
|
|
50
50
|
export declare function update(state: PinInputState, msg: PinInputMsg): [PinInputState, never[]];
|
|
51
51
|
export declare function isComplete(state: PinInputState): boolean;
|
|
52
52
|
export declare function getValue(state: PinInputState): string;
|
|
53
|
-
export interface PinInputParts
|
|
53
|
+
export interface PinInputParts {
|
|
54
54
|
root: {
|
|
55
55
|
role: 'group';
|
|
56
56
|
'aria-labelledby': string;
|
|
57
57
|
'data-scope': 'pin-input';
|
|
58
58
|
'data-part': 'root';
|
|
59
|
-
'data-disabled':
|
|
59
|
+
'data-disabled': Signal<'' | undefined>;
|
|
60
60
|
};
|
|
61
61
|
label: {
|
|
62
62
|
id: string;
|
|
@@ -65,14 +65,14 @@ export interface PinInputParts<S> {
|
|
|
65
65
|
};
|
|
66
66
|
/** Props for the input at a given index. */
|
|
67
67
|
input: (index: number) => {
|
|
68
|
-
type:
|
|
69
|
-
inputMode:
|
|
70
|
-
pattern:
|
|
68
|
+
type: Signal<'text' | 'password'>;
|
|
69
|
+
inputMode: Signal<'numeric' | 'text'>;
|
|
70
|
+
pattern: Signal<string>;
|
|
71
71
|
maxLength: 1;
|
|
72
72
|
autoComplete: 'off';
|
|
73
73
|
'aria-label': string;
|
|
74
|
-
disabled:
|
|
75
|
-
value:
|
|
74
|
+
disabled: Signal<boolean>;
|
|
75
|
+
value: Signal<string>;
|
|
76
76
|
'data-scope': 'pin-input';
|
|
77
77
|
'data-part': 'input';
|
|
78
78
|
'data-index': string;
|
|
@@ -88,7 +88,7 @@ export interface ConnectOptions {
|
|
|
88
88
|
/** Validate each character before setting. Non-empty array blocks setDigit. */
|
|
89
89
|
validate?: (value: string) => string[] | null;
|
|
90
90
|
}
|
|
91
|
-
export declare function connect
|
|
91
|
+
export declare function connect(state: Signal<PinInputState>, send: Send<PinInputMsg>, opts: ConnectOptions): PinInputParts;
|
|
92
92
|
export declare const pinInput: {
|
|
93
93
|
init: typeof init;
|
|
94
94
|
update: typeof update;
|