@k2b/ui 0.44.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/actions/Dropdown.js +8 -1
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/FilterChip.js +11 -5
- package/dist/browser/actions/FilterChip.js.map +1 -1
- package/dist/browser/actions/Tabs.js +3 -4
- package/dist/browser/actions/Tabs.js.map +1 -1
- package/dist/browser/actions/ViewTabs.js +225 -93
- package/dist/browser/actions/ViewTabs.js.map +1 -1
- package/dist/browser/actions/menu-sheet.js +2 -3
- package/dist/browser/actions/menu-sheet.js.map +1 -1
- package/dist/browser/actions/phone-sheet.js +4 -0
- package/dist/browser/actions/phone-sheet.js.map +1 -0
- package/dist/browser/content/DataTable.js +47 -51
- package/dist/browser/content/DataTable.js.map +1 -1
- package/dist/browser/content/FileGrid.js +125 -99
- package/dist/browser/content/FileGrid.js.map +1 -1
- package/dist/browser/feedback/dialog-core.js +5 -1
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/feedback/dialog-tone.js +26 -0
- package/dist/browser/feedback/dialog-tone.js.map +1 -0
- package/dist/browser/feedback/index.js.map +1 -1
- package/dist/browser/feedback/prompt-confirm.js +223 -0
- package/dist/browser/feedback/prompt-confirm.js.map +1 -0
- package/dist/browser/feedback/prompts.js +195 -343
- package/dist/browser/feedback/prompts.js.map +1 -1
- package/dist/browser/inputs/ChoiceList.js +45 -17
- package/dist/browser/inputs/ChoiceList.js.map +1 -1
- package/dist/browser/inputs/DatePicker.js +1647 -334
- package/dist/browser/inputs/DatePicker.js.map +1 -1
- package/dist/browser/inputs/TextInput.js +5 -4
- package/dist/browser/inputs/TextInput.js.map +1 -1
- package/dist/browser/inputs/choice.js +36 -9
- package/dist/browser/inputs/choice.js.map +1 -1
- package/dist/browser/inputs/date-input-messages.js +128 -0
- package/dist/browser/inputs/date-input-messages.js.map +1 -0
- package/dist/browser/inputs/date-input-status.js +132 -0
- package/dist/browser/inputs/date-input-status.js.map +1 -0
- package/dist/browser/inputs/date-input.js +334 -0
- package/dist/browser/inputs/date-input.js.map +1 -0
- package/dist/browser/inputs/date-sheet.js +49 -0
- package/dist/browser/inputs/date-sheet.js.map +1 -0
- package/dist/browser/internal/reveal-in-scroller.js +28 -0
- package/dist/browser/internal/reveal-in-scroller.js.map +1 -0
- package/dist/browser/intl/messages.js +6 -0
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +556 -528
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/BottomSheet.js +3 -0
- package/dist/browser/layout/BottomSheet.js.map +1 -1
- package/dist/browser/layout/DetailPanel.js +130 -108
- package/dist/browser/layout/DetailPanel.js.map +1 -1
- package/dist/browser/layout/DetailSections.js +1019 -0
- package/dist/browser/layout/DetailSections.js.map +1 -0
- package/dist/browser/layout/DetailsToggle.js +32 -0
- package/dist/browser/layout/DetailsToggle.js.map +1 -0
- package/dist/browser/layout/Discussion.js +3 -0
- package/dist/browser/layout/Discussion.js.map +1 -1
- package/dist/browser/layout/MobileShell.js +116 -94
- package/dist/browser/layout/MobileShell.js.map +1 -1
- package/dist/browser/layout/PageTitle.js +33 -10
- package/dist/browser/layout/PageTitle.js.map +1 -1
- package/dist/browser/layout/PanelDialog.js +167 -132
- package/dist/browser/layout/PanelDialog.js.map +1 -1
- package/dist/browser/layout/Settings.js +175 -139
- package/dist/browser/layout/Settings.js.map +1 -1
- package/dist/browser/layout/SettingsModal.js +2 -4
- package/dist/browser/layout/SettingsModal.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +12 -0
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/detail-sections-messages.js +123 -0
- package/dist/browser/layout/detail-sections-messages.js.map +1 -0
- package/dist/browser/layout/index.js +2 -0
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/surfaces/Avatar.js +3 -1
- package/dist/browser/surfaces/Avatar.js.map +1 -1
- package/dist/browser/surfaces/AvatarStack.js +95 -61
- package/dist/browser/surfaces/AvatarStack.js.map +1 -1
- package/dist/browser/surfaces/ChangeList.js +77 -0
- package/dist/browser/surfaces/ChangeList.js.map +1 -0
- package/dist/browser/surfaces/StatusBadge.js +47 -14
- package/dist/browser/surfaces/StatusBadge.js.map +1 -1
- package/dist/browser/surfaces/index.js +2 -1
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/browser/text-editor/TextEditor.js +26 -8
- package/dist/browser/text-editor/TextEditor.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +6 -0
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/FilterChip.js +1 -1
- package/dist/ssr/actions/FilterChip.js.map +1 -1
- package/dist/ssr/actions/Tabs.js +3 -4
- package/dist/ssr/actions/Tabs.js.map +1 -1
- package/dist/ssr/actions/ViewTabs.js +144 -37
- package/dist/ssr/actions/ViewTabs.js.map +1 -1
- package/dist/ssr/actions/menu-sheet.js +2 -3
- package/dist/ssr/actions/menu-sheet.js.map +1 -1
- package/dist/ssr/actions/phone-sheet.js +4 -0
- package/dist/ssr/actions/phone-sheet.js.map +1 -0
- package/dist/ssr/content/DataTable.js +1 -2
- package/dist/ssr/content/DataTable.js.map +1 -1
- package/dist/ssr/content/FileGrid.js +36 -22
- package/dist/ssr/content/FileGrid.js.map +1 -1
- package/dist/ssr/feedback/dialog-core.js +5 -1
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/feedback/dialog-tone.js +26 -0
- package/dist/ssr/feedback/dialog-tone.js.map +1 -0
- package/dist/ssr/feedback/index.js.map +1 -1
- package/dist/ssr/feedback/prompt-confirm.js +123 -0
- package/dist/ssr/feedback/prompt-confirm.js.map +1 -0
- package/dist/ssr/feedback/prompts.js +60 -132
- package/dist/ssr/feedback/prompts.js.map +1 -1
- package/dist/ssr/inputs/ChoiceList.js +29 -9
- package/dist/ssr/inputs/ChoiceList.js.map +1 -1
- package/dist/ssr/inputs/DatePicker.js +1183 -166
- package/dist/ssr/inputs/DatePicker.js.map +1 -1
- package/dist/ssr/inputs/TextInput.js +5 -4
- package/dist/ssr/inputs/TextInput.js.map +1 -1
- package/dist/ssr/inputs/choice.js +36 -9
- package/dist/ssr/inputs/choice.js.map +1 -1
- package/dist/ssr/inputs/date-input-messages.js +128 -0
- package/dist/ssr/inputs/date-input-messages.js.map +1 -0
- package/dist/ssr/inputs/date-input-status.js +132 -0
- package/dist/ssr/inputs/date-input-status.js.map +1 -0
- package/dist/ssr/inputs/date-input.js +334 -0
- package/dist/ssr/inputs/date-input.js.map +1 -0
- package/dist/ssr/inputs/date-sheet.js +44 -0
- package/dist/ssr/inputs/date-sheet.js.map +1 -0
- package/dist/ssr/internal/reveal-in-scroller.js +28 -0
- package/dist/ssr/internal/reveal-in-scroller.js.map +1 -0
- package/dist/ssr/intl/messages.js +6 -0
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +71 -50
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/BottomSheet.js +3 -0
- package/dist/ssr/layout/BottomSheet.js.map +1 -1
- package/dist/ssr/layout/DetailPanel.js +17 -0
- package/dist/ssr/layout/DetailPanel.js.map +1 -1
- package/dist/ssr/layout/DetailSections.js +762 -0
- package/dist/ssr/layout/DetailSections.js.map +1 -0
- package/dist/ssr/layout/DetailsToggle.js +29 -0
- package/dist/ssr/layout/DetailsToggle.js.map +1 -0
- package/dist/ssr/layout/Discussion.js +3 -0
- package/dist/ssr/layout/Discussion.js.map +1 -1
- package/dist/ssr/layout/MobileShell.js +45 -28
- package/dist/ssr/layout/MobileShell.js.map +1 -1
- package/dist/ssr/layout/PageTitle.js +29 -6
- package/dist/ssr/layout/PageTitle.js.map +1 -1
- package/dist/ssr/layout/PanelDialog.js +48 -30
- package/dist/ssr/layout/PanelDialog.js.map +1 -1
- package/dist/ssr/layout/Settings.js +34 -18
- package/dist/ssr/layout/Settings.js.map +1 -1
- package/dist/ssr/layout/SettingsModal.js +2 -4
- package/dist/ssr/layout/SettingsModal.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +12 -0
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/detail-sections-messages.js +123 -0
- package/dist/ssr/layout/detail-sections-messages.js.map +1 -0
- package/dist/ssr/layout/index.js +2 -0
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/surfaces/Avatar.js +3 -1
- package/dist/ssr/surfaces/Avatar.js.map +1 -1
- package/dist/ssr/surfaces/AvatarStack.js +61 -32
- package/dist/ssr/surfaces/AvatarStack.js.map +1 -1
- package/dist/ssr/surfaces/ChangeList.js +37 -0
- package/dist/ssr/surfaces/ChangeList.js.map +1 -0
- package/dist/ssr/surfaces/StatusBadge.js +26 -8
- package/dist/ssr/surfaces/StatusBadge.js.map +1 -1
- package/dist/ssr/surfaces/index.js +2 -1
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/ssr/text-editor/TextEditor.js +26 -8
- package/dist/ssr/text-editor/TextEditor.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/FilterChip.d.ts +4 -0
- package/dist/types/actions/ViewTabs.d.ts +11 -1
- package/dist/types/actions/menu-sheet.d.ts +1 -3
- package/dist/types/actions/phone-sheet.d.ts +3 -0
- package/dist/types/content/FileGrid.d.ts +6 -0
- package/dist/types/feedback/dialog-tone.d.ts +10 -0
- package/dist/types/feedback/index.d.ts +1 -0
- package/dist/types/feedback/prompt-confirm.d.ts +19 -0
- package/dist/types/feedback/prompts.d.ts +4 -8
- package/dist/types/inputs/ChoiceList.d.ts +7 -3
- package/dist/types/inputs/DatePicker.d.ts +13 -3
- package/dist/types/inputs/TextInput.d.ts +1 -1
- package/dist/types/inputs/choice.d.ts +9 -3
- package/dist/types/inputs/date-input-messages.d.ts +64 -0
- package/dist/types/inputs/date-input-status.d.ts +35 -0
- package/dist/types/inputs/date-input.d.ts +90 -0
- package/dist/types/inputs/date-sheet.d.ts +14 -0
- package/dist/types/internal/reveal-in-scroller.d.ts +6 -0
- package/dist/types/intl/messages.d.ts +3 -0
- package/dist/types/layout/AppWorkspace.d.ts +14 -0
- package/dist/types/layout/BottomSheet.d.ts +3 -0
- package/dist/types/layout/DetailPanel.d.ts +9 -0
- package/dist/types/layout/DetailSections.d.ts +156 -0
- package/dist/types/layout/DetailsToggle.d.ts +13 -0
- package/dist/types/layout/PageTitle.d.ts +7 -0
- package/dist/types/layout/PanelDialog.d.ts +3 -0
- package/dist/types/layout/Settings.d.ts +17 -1
- package/dist/types/layout/detail-sections-messages.d.ts +59 -0
- package/dist/types/layout/index.d.ts +5 -2
- package/dist/types/surfaces/Avatar.d.ts +3 -0
- package/dist/types/surfaces/AvatarStack.d.ts +20 -1
- package/dist/types/surfaces/ChangeList.d.ts +20 -0
- package/dist/types/surfaces/StatusBadge.d.ts +5 -0
- package/dist/types/surfaces/index.d.ts +5 -3
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["inputs/TextInput.tsx"],"sourcesContent":["import { createSignal, type JSX, Show, splitProps } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { createFieldMeta, Field, fieldControlAria } from \"../internal/field\";\nimport { useUiMessages } from \"../intl/messages\";\nimport type { Completion } from \"./completion\";\nimport type { ValueFieldProps } from \"./field-contract\";\nimport { commitFieldValue, resolveMaybeAccessor } from \"./field-contract\";\nimport { useInputMessages } from \"./input-messages\";\nimport { MarkdownEditor } from \"./markdown/MarkdownEditor\";\n\nexport type TextInputProps = Omit<\n JSX.InputHTMLAttributes<HTMLInputElement>,\n \"onChange\" | \"onInput\" | \"onKeyDown\" | \"prefix\" | \"suffix\" | \"type\" | \"value\" | keyof ValueFieldProps<string>\n> &\n ValueFieldProps<string> & {\n minLength?: number;\n maxLength?: number;\n type?: \"text\" | \"search\" | \"email\" | \"url\" | \"tel\";\n variant?: \"default\" | \"ai\" | \"compact\";\n /** Set false for a plain field without a leading icon. */\n icon?: string | false;\n activeIcon?: string;\n /** ID of a consumer-owned visible error; caller owns its announcement. Native controls only. */\n externalErrorId?: string;\n prefix?: JSX.Element;\n suffix?: JSX.Element;\n clearable?: boolean;\n onClear?: () => void;\n clearLabel?: string;\n multiline?: boolean;\n monospace?: boolean;\n password?: boolean;\n markdown?: boolean;\n onSubmit?: () => void;\n onKeyDown?: JSX.EventHandlerUnion<HTMLInputElement | HTMLTextAreaElement, KeyboardEvent>;\n lines?: number;\n abbreviations?: Record<string, string>;\n completions?: readonly Completion[];\n };\n\nexport function TextInput(props: TextInputProps): JSX.Element {\n const messages = useUiMessages();\n const inputMessages = useInputMessages();\n const [local, rest] = splitProps(props, [\n \"activeIcon\",\n \"aria-describedby\",\n \"aria-label\",\n \"class\",\n \"clearLabel\",\n \"clearable\",\n \"completions\",\n \"description\",\n \"error\",\n \"externalErrorId\",\n \"icon\",\n \"id\",\n \"label\",\n \"lines\",\n \"markdown\",\n \"minLength\",\n \"maxLength\",\n \"onKeyDown\",\n \"monospace\",\n \"multiline\",\n \"onClear\",\n \"onValueCommit\",\n \"onSubmit\",\n \"onValueChange\",\n \"password\",\n \"prefix\",\n \"required\",\n \"suffix\",\n \"type\",\n \"value\",\n \"variant\",\n \"abbreviations\",\n ]);\n const meta = createFieldMeta(local.id);\n const value = () => resolveMaybeAccessor(local.value) ?? \"\";\n const error = () => resolveMaybeAccessor(local.error);\n // HTML IDs are single nonempty tokens; numeric starts and punctuation are valid.\n const externalErrorId = () => {\n const id = local.externalErrorId;\n return id && !/[\\t\\n\\f\\r ]/.test(id) ? id : undefined;\n };\n const controlMeta = {\n ...meta,\n get errorId() {\n return externalErrorId() ?? meta.errorId;\n },\n };\n const [passwordVisible, setPasswordVisible] = createSignal(false);\n const multiline = () => Boolean(local.multiline || local.markdown);\n const compact = () => local.variant === \"compact\";\n const icon = () =>\n local.icon === false\n ? \"\"\n : (local.icon ?? (local.variant === \"ai\" ? \"ti ti-sparkles\" : local.markdown ? \"ti ti-markdown\" : \"ti ti-cursor-text\"));\n // A custom icon stays while typing (a search field keeps its magnifier); only the default icon switches to the pencil.\n const activeIcon = () => local.activeIcon ?? (local.icon || undefined) ?? (local.variant === \"ai\" ? \"ti ti-sparkles\" : \"ti ti-pencil\");\n // Names, addresses and passwords are typed exactly: phone keyboards must not capitalize or \"correct\" them.\n const verbatim = () =>\n local.password || local.type === \"email\" || local.type === \"url\" || /\\b(username|email|url)\\b/.test(String(rest.autocomplete ?? \"\"));\n const input = (next: string) => local.onValueChange?.(next);\n const commit = (next: string) => local.onValueCommit?.(next);\n const submitOnEnter = (event: KeyboardEvent) => {\n if (local.onSubmit && event.key === \"Enter\" && !event.shiftKey && !event.metaKey) {\n event.preventDefault();\n local.onSubmit();\n }\n };\n /** The caller's key handler runs first; Enter submits unless it handled the key. */\n const keyDown: JSX.EventHandler<HTMLInputElement | HTMLTextAreaElement, KeyboardEvent> = (event) => {\n const handler = local.onKeyDown;\n if (typeof handler === \"function\") handler(event);\n else if (Array.isArray(handler)) handler[0](handler[1], event);\n if (!event.defaultPrevented) submitOnEnter(event);\n };\n const clear: JSX.EventHandler<HTMLButtonElement, MouseEvent> = (event) => {\n // Clearing removes the button. Return to the field before notifying the caller, whose handler\n // may deliberately navigate or move focus somewhere else.\n event.currentTarget.ownerDocument.getElementById(meta.controlId)?.focus();\n if (local.onClear) {\n local.onClear();\n return;\n }\n commitFieldValue(local, \"\");\n };\n\n return (\n <Show\n when={local.markdown}\n fallback={\n <Field\n class={local.class}\n label={local.label}\n description={local.description}\n error={externalErrorId() ? undefined : error()}\n meta={meta}\n required={local.required}\n disabled={rest.disabled}\n >\n <div\n class=\"k2b-input-shell k2b-text-input\"\n data-variant={compact() ? \"compact\" : undefined}\n data-invalid={error() ? \"true\" : undefined}\n data-ai={local.variant === \"ai\" ? \"true\" : undefined}\n data-multiline={multiline() ? \"true\" : undefined}\n data-monospace={local.monospace ? \"true\" : undefined}\n style={multiline() ? { \"--k2b-editor-lines\": String(local.lines ?? 3) } : undefined}\n >\n <Show when={!compact() && local.icon !== false}>\n <span class=\"k2b-input-shell__icon k2b-text-input__icon\" aria-hidden=\"true\">\n <i class={icon()} />\n <i class={activeIcon()} />\n </span>\n </Show>\n <Show when={local.prefix}>\n <span class=\"k2b-input-shell__affix\">{local.prefix}</span>\n </Show>\n <Show\n when={multiline()}\n fallback={\n <input\n autocapitalize={verbatim() ? \"none\" : undefined}\n autocorrect={verbatim() ? \"off\" : undefined}\n spellcheck={verbatim() ? false : undefined}\n {...rest}\n id={meta.controlId}\n class=\"k2b-input\"\n size={rest.size ?? (compact() ? 9 : undefined)}\n type={local.password && !passwordVisible() ? \"password\" : (local.type ?? \"text\")}\n value={value()}\n minlength={local.minLength}\n maxlength={local.maxLength}\n required={local.required}\n {...fieldControlAria(controlMeta, local)}\n onInput={(event) => {\n input(event.currentTarget.value);\n }}\n onChange={(event) => commit(event.currentTarget.value)}\n onKeyDown={keyDown}\n />\n }\n >\n <textarea\n {...(rest as unknown as JSX.TextareaHTMLAttributes<HTMLTextAreaElement>)}\n id={meta.controlId}\n class=\"k2b-input k2b-text-input__textarea\"\n value={value()}\n rows={local.lines ?? 3}\n required={local.required}\n minlength={local.minLength}\n maxlength={local.maxLength}\n {...fieldControlAria(controlMeta, local)}\n onInput={(event) => {\n input(event.currentTarget.value);\n }}\n onChange={(event) => commit(event.currentTarget.value)}\n onKeyDown={keyDown}\n >\n {/* HTML consumes one leading newline in textarea content. */}\n {isServer ? `\\n${value()}` : undefined}\n </textarea>\n </Show>\n <Show when={local.suffix}>\n <span class=\"k2b-input-shell__affix\">{local.suffix}</span>\n </Show>\n <Show when={local.clearable && value() && !multiline() && !local.password && !rest.disabled && !rest.readOnly}>\n <button\n type=\"button\"\n class=\"k2b-input-shell__clear k2b-input-clear-action\"\n aria-label={local.clearLabel ?? messages().clear}\n onClick={clear}\n >\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </button>\n </Show>\n <Show when={local.password && !multiline()}>\n <button\n type=\"button\"\n class=\"k2b-input-shell__clear\"\n aria-label={passwordVisible() ? inputMessages().hidePassword : inputMessages().showPassword}\n aria-pressed={passwordVisible()}\n disabled={rest.disabled}\n onClick={() => setPasswordVisible((visible) => !visible)}\n >\n <i class={passwordVisible() ? \"ti ti-eye-off\" : \"ti ti-eye\"} aria-hidden=\"true\" />\n </button>\n </Show>\n </div>\n </Field>\n }\n >\n <MarkdownEditor\n class={local.class}\n label={local.label}\n description={local.description}\n error={error()}\n id={meta.controlId}\n name={rest.name}\n value={value()}\n onValueChange={input}\n onValueCommit={local.onValueCommit}\n onSubmit={local.onSubmit}\n placeholder={rest.placeholder}\n disabled={rest.disabled}\n required={local.required}\n lines={local.lines}\n maxLength={local.maxLength}\n spellcheck={rest.spellcheck === undefined ? undefined : rest.spellcheck === true || rest.spellcheck === \"true\"}\n abbreviations={local.abbreviations}\n completions={local.completions}\n aria-label={local[\"aria-label\"]}\n aria-describedby={local[\"aria-describedby\"]}\n />\n </Show>\n );\n}\n\nexport default TextInput;\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAS,YAAY,EAAY,IAAI,EAAE,UAAU,QAAQ,UAAU;AACnE,SAAS,QAAQ,QAAQ,cAAc;AACvC,SAAS,eAAe,EAAE,KAAK,EAAE,gBAAgB,QAAQ,mBAAmB;AAC5E,SAAS,aAAa,QAAQ,kBAAkB;AAGhD,SAAS,gBAAgB,EAAE,oBAAoB,QAAQ,kBAAkB;AACzE,SAAS,gBAAgB,QAAQ,kBAAkB;AACnD,SAAS,cAAc,QAAQ,2BAA2B;AAgC1D,OAAO,SAAS,SAAS,CAAC,KAAqB,EAAe;EAC5D,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC,MAAM,aAAa,GAAG,gBAAgB,CAAC,CAAC;EACxC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CACtC,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,OAAO,EACP,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,EACb,OAAO,EACP,iBAAiB,EACjB,MAAM,EACN,IAAI,EACJ,OAAO,EACP,OAAO,EACP,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAS,EACT,eAAe,EACf,UAAU,EACV,eAAe,EACf,UAAU,EACV,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,MAAM,EACN,OAAO,EACP,SAAS,EACT,eAAe,CAChB,CAAC;EACF,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;EACtC,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE;EAC3D,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC;EACrD;EACA,MAAM,eAAe,GAAG,MAAM;IAC5B,MAAM,EAAE,GAAG,KAAK,CAAC,eAAe;IAChC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,SAAS;EACvD,CAAC;EACD,MAAM,WAAW,GAAG;IAClB,GAAG,IAAI;IACP,IAAI,OAAO,GAAG;MACZ,OAAO,eAAe,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO;IAC1C;EACF,CAAC;EACD,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC;EACjE,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC;EAClE,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,KAAK,SAAS;EACjD,MAAM,IAAI,GAAG,MACX,KAAK,CAAC,IAAI,KAAK,KAAK,GAChB,EAAE,GACD,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,KAAK,IAAI,GAAG,gBAAgB,GAAG,KAAK,CAAC,QAAQ,GAAG,gBAAgB,GAAG,mBAAmB,CAAE;EAC3H;EACA,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,IAAI,IAAI,SAAS,CAAC,KAAK,KAAK,CAAC,OAAO,KAAK,IAAI,GAAG,gBAAgB,GAAG,cAAc,CAAC;EACtI;EACA,MAAM,QAAQ,GAAG,MACf,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;EACtI,MAAM,KAAK,GAAI,IAAY,IAAK,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;EAC3D,MAAM,MAAM,GAAI,IAAY,IAAK,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;EAC5D,MAAM,aAAa,GAAI,KAAoB,IAAK;IAC9C,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;MAChF,KAAK,CAAC,cAAc,CAAC,CAAC;MACtB,KAAK,CAAC,QAAQ,CAAC,CAAC;IAClB;EACF,CAAC;EACD;EACA,MAAM,OAAgF,GAAI,KAAK,IAAK;IAClG,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS;IAC/B,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,KAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;IAC9D,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,aAAa,CAAC,KAAK,CAAC;EACnD,CAAC;EACD,MAAM,KAAsD,GAAI,KAAK,IAAK;IACxE;IACA;IACA,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;IACzE,IAAI,KAAK,CAAC,OAAO,EAAE;MACjB,KAAK,CAAC,OAAO,CAAC,CAAC;MACf;IACF;IACA,gBAAgB,CAAC,KAAK,EAAE,EAAE,CAAC;EAC7B,CAAC;EAED,yBACG,IAAI;IAAA,IACH,IAAI;MAAA,OAAE,KAAK,CAAC,QAAQ;IAAA;IAAA,IACpB,QAAQ;MAAA,yBACL,KAAK;QAAA;UAAA,OACG,KAAK,CAAC,KAAK;QAAA;QAAA,IAClB,KAAK;UAAA,OAAE,KAAK,CAAC,KAAK;QAAA;QAAA,IAClB,WAAW;UAAA,OAAE,KAAK,CAAC,WAAW;QAAA;QAAA,IAC9B,KAAK;UAAA,OAAE,8BAAe,CAAC,CAAC,MAAG,SAAS,GAAG,KAAK,CAAC,CAAC;QAAA;QAC9C,IAAI,EAAE,IAAI;QAAA,IACV,QAAQ;UAAA,OAAE,KAAK,CAAC,QAAQ;QAAA;QAAA,IACxB,QAAQ;UAAA,OAAE,IAAI,CAAC,QAAQ;QAAA;QAAA;UAAA,qDAIP,OAAO,CAAC,CAAC,GAAG,SAAS,YAAG,SAAS,iDACjC,KAAK,CAAC,CAAC,GAAG,MAAM,YAAG,SAAS,4CACjC,KAAK,CAAC,OAAO,KAAK,IAAI,GAAG,MAAM,YAAG,SAAS,mDACpC,SAAS,CAAC,CAAC,GAAG,MAAM,YAAG,SAAS,mDAChC,KAAK,CAAC,SAAS,GAAG,MAAM,YAAG,SAAS,4BAC7C,SAAS,CAAC,CAAC,GAAG;YAAE,oBAAoB,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;UAAE,CAAC,GAAG,SAAS,8BAElF,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,gBAAC,OAAO,CAAC,CAAC,OAAI,KAAK,CAAC,IAAI,KAAK,KAAK;YAAA;YAAA;cAAA,sDAEhC,IAAI,CAAC,CAAC,kDACN,UAAU,CAAC,CAAC;YAAA;UAAA,gCAGzB,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,KAAK,CAAC,MAAM;YAAA;YAAA;cAAA,+BACgB,KAAK,CAAC,MAAM;YAAA;UAAA,gCAEnD,IAAI;YAAA,IACH,IAAI;cAAA,OAAE,SAAS,CAAC,CAAC;YAAA;YAAA,IACjB,QAAQ;cAAA;gBAAA,IAEJ,cAAc;kBAAA,OAAE,QAAQ,CAAC,CAAC,GAAG,MAAM,GAAG,SAAS;gBAAA;gBAAA,IAC/C,WAAW;kBAAA,OAAE,QAAQ,CAAC,CAAC,GAAG,KAAK,GAAG,SAAS;gBAAA;gBAAA,IAC3C,UAAU;kBAAA,OAAE,QAAQ,CAAC,CAAC,GAAG,KAAK,GAAG,SAAS;gBAAA;cAAA,GACtC,IAAI;gBAAA,IACR,EAAE;kBAAA,OAAE,IAAI,CAAC,SAAS;gBAAA;gBAAA,SACZ,WAAW;gBAAA,IACjB,IAAI;kBAAA,OAAE,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;gBAAA;gBAAA,IAC9C,IAAI;kBAAA,OAAE,KAAK,CAAC,QAAQ,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,UAAU,GAAI,KAAK,CAAC,IAAI,IAAI,MAAO;gBAAA;gBAAA,IAChF,KAAK;kBAAA,OAAE,KAAK,CAAC,CAAC;gBAAA;gBAAA,IACd,SAAS;kBAAA,OAAE,KAAK,CAAC,SAAS;gBAAA;gBAAA,IAC1B,SAAS;kBAAA,OAAE,KAAK,CAAC,SAAS;gBAAA;gBAAA,IAC1B,QAAQ;kBAAA,OAAE,KAAK,CAAC,QAAQ;gBAAA;cAAA,SACpB,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC;YAAA;YAAA;cAAA,6CAUrC,IAAI;gBAAA,IACT,EAAE;kBAAA,OAAE,IAAI,CAAC,SAAS;gBAAA;gBAAA,SACZ,oCAAoC;gBAAA,IAC1C,KAAK;kBAAA,OAAE,KAAK,CAAC,CAAC;gBAAA;gBAAA,IACd,IAAI;kBAAA,OAAE,KAAK,CAAC,KAAK,IAAI,CAAC;gBAAA;gBAAA,IACtB,QAAQ;kBAAA,OAAE,KAAK,CAAC,QAAQ;gBAAA;gBAAA,IACxB,SAAS;kBAAA,OAAE,KAAK,CAAC,SAAS;gBAAA;gBAAA,IAC1B,SAAS;kBAAA,OAAE,KAAK,CAAC,SAAS;gBAAA;cAAA,SACtB,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC,GAQvC,QAAQ,GAAG,cAAK,KAAK,CAAC,CAAC,GAAE,YAAG,SAAS;YAAA;UAAA,gCAGzC,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,KAAK,CAAC,MAAM;YAAA;YAAA;cAAA,+BACgB,KAAK,CAAC,MAAM;YAAA;UAAA,gCAEnD,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,qBAAK,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,QAAI,CAAC,IAAI,CAAC,QAAQ;YAAA;YAAA;cAAA,4DAI7F,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK;YAAA;UAAA,gCAMnD,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,oBAAK,CAAC,QAAQ,OAAI,CAAC,SAAS,CAAC,CAAC;YAAA;YAAA;cAAA,mDAI1B,eAAe,CAAC,CAAC,YAAG,aAAa,CAAC,CAAC,CAAC,YAAY,mBAAG,aAAa,CAAC,CAAC,CAAC,YAAY,0DAC7E,eAAe,CAAC,CAAC,4CACrB,IAAI,CAAC,QAAQ,iCAGb,eAAe,CAAC,CAAC,GAAG,eAAe,GAAG,WAAW;YAAA;UAAA;QAAA;MAAA;IAAA;IAAA;MAAA,yBAOpE,cAAc;QAAA;UAAA,OACN,KAAK,CAAC,KAAK;QAAA;QAAA,IAClB,KAAK;UAAA,OAAE,KAAK,CAAC,KAAK;QAAA;QAAA,IAClB,WAAW;UAAA,OAAE,KAAK,CAAC,WAAW;QAAA;QAAA,IAC9B,KAAK;UAAA,OAAE,KAAK,CAAC,CAAC;QAAA;QAAA,IACd,EAAE;UAAA,OAAE,IAAI,CAAC,SAAS;QAAA;QAAA,IAClB,IAAI;UAAA,OAAE,IAAI,CAAC,IAAI;QAAA;QAAA,IACf,KAAK;UAAA,OAAE,KAAK,CAAC,CAAC;QAAA;QACd,aAAa,EAAE,KAAK;QAAA,IACpB,aAAa;UAAA,OAAE,KAAK,CAAC,aAAa;QAAA;QAAA,IAClC,QAAQ;UAAA,OAAE,KAAK,CAAC,QAAQ;QAAA;QAAA,IACxB,WAAW;UAAA,OAAE,IAAI,CAAC,WAAW;QAAA;QAAA,IAC7B,QAAQ;UAAA,OAAE,IAAI,CAAC,QAAQ;QAAA;QAAA,IACvB,QAAQ;UAAA,OAAE,KAAK,CAAC,QAAQ;QAAA;QAAA,IACxB,KAAK;UAAA,OAAE,KAAK,CAAC,KAAK;QAAA;QAAA,IAClB,SAAS;UAAA,OAAE,KAAK,CAAC,SAAS;QAAA;QAAA,IAC1B,UAAU;UAAA,OAAE,iBAAI,CAAC,UAAU,KAAK,SAAS,MAAG,SAAS,GAAG,IAAI,CAAC,UAAU,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,MAAM;QAAA;QAAA,IAC9G,aAAa;UAAA,OAAE,KAAK,CAAC,aAAa;QAAA;QAAA,IAClC,WAAW;UAAA,OAAE,KAAK,CAAC,WAAW;QAAA;QAAA;UAAA,OAClB,KAAK,CAAC,YAAY,CAAC;QAAA;QAAA;UAAA,OACb,KAAK,CAAC,kBAAkB,CAAC;QAAA;MAAA;IAAA;EAAA;AAInD;AAEA,eAAe,SAAS","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/TextInput.tsx"],"sourcesContent":["import { createSignal, type JSX, Show, splitProps } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { createFieldMeta, Field, fieldControlAria } from \"../internal/field\";\nimport { useUiMessages } from \"../intl/messages\";\nimport type { Completion } from \"./completion\";\nimport type { ValueFieldProps } from \"./field-contract\";\nimport { commitFieldValue, resolveMaybeAccessor } from \"./field-contract\";\nimport { useInputMessages } from \"./input-messages\";\nimport { MarkdownEditor } from \"./markdown/MarkdownEditor\";\n\nexport type TextInputProps = Omit<\n JSX.InputHTMLAttributes<HTMLInputElement>,\n \"onChange\" | \"onInput\" | \"onKeyDown\" | \"prefix\" | \"suffix\" | \"type\" | \"value\" | keyof ValueFieldProps<string>\n> &\n ValueFieldProps<string> & {\n minLength?: number;\n maxLength?: number;\n type?: \"text\" | \"search\" | \"email\" | \"url\" | \"tel\";\n variant?: \"default\" | \"ai\" | \"compact\";\n /** A leading icon such as a search magnifier. Plain text fields have none. */\n icon?: string | false;\n activeIcon?: string;\n /** ID of a consumer-owned visible error; caller owns its announcement. Native controls only. */\n externalErrorId?: string;\n prefix?: JSX.Element;\n suffix?: JSX.Element;\n clearable?: boolean;\n onClear?: () => void;\n clearLabel?: string;\n multiline?: boolean;\n monospace?: boolean;\n password?: boolean;\n markdown?: boolean;\n onSubmit?: () => void;\n onKeyDown?: JSX.EventHandlerUnion<HTMLInputElement | HTMLTextAreaElement, KeyboardEvent>;\n lines?: number;\n abbreviations?: Record<string, string>;\n completions?: readonly Completion[];\n };\n\nexport function TextInput(props: TextInputProps): JSX.Element {\n const messages = useUiMessages();\n const inputMessages = useInputMessages();\n const [local, rest] = splitProps(props, [\n \"activeIcon\",\n \"aria-describedby\",\n \"aria-label\",\n \"class\",\n \"clearLabel\",\n \"clearable\",\n \"completions\",\n \"description\",\n \"error\",\n \"externalErrorId\",\n \"icon\",\n \"id\",\n \"label\",\n \"lines\",\n \"markdown\",\n \"minLength\",\n \"maxLength\",\n \"onKeyDown\",\n \"monospace\",\n \"multiline\",\n \"onClear\",\n \"onValueCommit\",\n \"onSubmit\",\n \"onValueChange\",\n \"password\",\n \"prefix\",\n \"required\",\n \"suffix\",\n \"type\",\n \"value\",\n \"variant\",\n \"abbreviations\",\n ]);\n const meta = createFieldMeta(local.id);\n const value = () => resolveMaybeAccessor(local.value) ?? \"\";\n const error = () => resolveMaybeAccessor(local.error);\n // HTML IDs are single nonempty tokens; numeric starts and punctuation are valid.\n const externalErrorId = () => {\n const id = local.externalErrorId;\n return id && !/[\\t\\n\\f\\r ]/.test(id) ? id : undefined;\n };\n const controlMeta = {\n ...meta,\n get errorId() {\n return externalErrorId() ?? meta.errorId;\n },\n };\n const [passwordVisible, setPasswordVisible] = createSignal(false);\n const multiline = () => Boolean(local.multiline || local.markdown);\n const compact = () => local.variant === \"compact\";\n // The field's edge already shows where to type; only a meaningful icon (a search magnifier, the AI mark) leads.\n const icon = () => (local.icon === false ? \"\" : (local.icon ?? (local.variant === \"ai\" ? \"ti ti-sparkles\" : \"\")));\n // An icon stays while typing unless `activeIcon` names a different one.\n const activeIcon = () => local.activeIcon ?? icon();\n // Names, addresses and passwords are typed exactly: phone keyboards must not capitalize or \"correct\" them.\n const verbatim = () =>\n local.password || local.type === \"email\" || local.type === \"url\" || /\\b(username|email|url)\\b/.test(String(rest.autocomplete ?? \"\"));\n const input = (next: string) => local.onValueChange?.(next);\n const commit = (next: string) => local.onValueCommit?.(next);\n const submitOnEnter = (event: KeyboardEvent) => {\n if (local.onSubmit && event.key === \"Enter\" && !event.shiftKey && !event.metaKey) {\n event.preventDefault();\n local.onSubmit();\n }\n };\n /** The caller's key handler runs first; Enter submits unless it handled the key. */\n const keyDown: JSX.EventHandler<HTMLInputElement | HTMLTextAreaElement, KeyboardEvent> = (event) => {\n const handler = local.onKeyDown;\n if (typeof handler === \"function\") handler(event);\n else if (Array.isArray(handler)) handler[0](handler[1], event);\n if (!event.defaultPrevented) submitOnEnter(event);\n };\n const clear: JSX.EventHandler<HTMLButtonElement, MouseEvent> = (event) => {\n // Clearing removes the button. Return to the field before notifying the caller, whose handler\n // may deliberately navigate or move focus somewhere else.\n event.currentTarget.ownerDocument.getElementById(meta.controlId)?.focus();\n if (local.onClear) {\n local.onClear();\n return;\n }\n commitFieldValue(local, \"\");\n };\n\n return (\n <Show\n when={local.markdown}\n fallback={\n <Field\n class={local.class}\n label={local.label}\n description={local.description}\n error={externalErrorId() ? undefined : error()}\n meta={meta}\n required={local.required}\n disabled={rest.disabled}\n >\n <div\n class=\"k2b-input-shell k2b-text-input\"\n data-variant={compact() ? \"compact\" : undefined}\n data-invalid={error() ? \"true\" : undefined}\n data-ai={local.variant === \"ai\" ? \"true\" : undefined}\n data-multiline={multiline() ? \"true\" : undefined}\n data-monospace={local.monospace ? \"true\" : undefined}\n style={multiline() ? { \"--k2b-editor-lines\": String(local.lines ?? 3) } : undefined}\n >\n <Show when={!compact() && icon()}>\n <span class=\"k2b-input-shell__icon k2b-text-input__icon\" aria-hidden=\"true\">\n <i class={icon()} />\n <i class={activeIcon()} />\n </span>\n </Show>\n <Show when={local.prefix}>\n <span class=\"k2b-input-shell__affix\">{local.prefix}</span>\n </Show>\n <Show\n when={multiline()}\n fallback={\n <input\n autocapitalize={verbatim() ? \"none\" : undefined}\n autocorrect={verbatim() ? \"off\" : undefined}\n spellcheck={verbatim() ? false : undefined}\n {...rest}\n id={meta.controlId}\n class=\"k2b-input\"\n size={rest.size ?? (compact() ? 9 : undefined)}\n type={local.password && !passwordVisible() ? \"password\" : (local.type ?? \"text\")}\n value={value()}\n minlength={local.minLength}\n maxlength={local.maxLength}\n required={local.required}\n {...fieldControlAria(controlMeta, local)}\n onInput={(event) => {\n input(event.currentTarget.value);\n }}\n onChange={(event) => commit(event.currentTarget.value)}\n onKeyDown={keyDown}\n />\n }\n >\n <textarea\n {...(rest as unknown as JSX.TextareaHTMLAttributes<HTMLTextAreaElement>)}\n id={meta.controlId}\n class=\"k2b-input k2b-text-input__textarea\"\n value={value()}\n rows={local.lines ?? 3}\n required={local.required}\n minlength={local.minLength}\n maxlength={local.maxLength}\n {...fieldControlAria(controlMeta, local)}\n onInput={(event) => {\n input(event.currentTarget.value);\n }}\n onChange={(event) => commit(event.currentTarget.value)}\n onKeyDown={keyDown}\n >\n {/* HTML consumes one leading newline in textarea content. */}\n {isServer ? `\\n${value()}` : undefined}\n </textarea>\n </Show>\n <Show when={local.suffix}>\n <span class=\"k2b-input-shell__affix\">{local.suffix}</span>\n </Show>\n <Show when={local.clearable && value() && !multiline() && !local.password && !rest.disabled && !rest.readOnly}>\n <button\n type=\"button\"\n class=\"k2b-input-shell__clear k2b-input-clear-action\"\n aria-label={local.clearLabel ?? messages().clear}\n onClick={clear}\n >\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </button>\n </Show>\n <Show when={local.password && !multiline()}>\n <button\n type=\"button\"\n class=\"k2b-input-shell__clear\"\n aria-label={passwordVisible() ? inputMessages().hidePassword : inputMessages().showPassword}\n aria-pressed={passwordVisible()}\n disabled={rest.disabled}\n onClick={() => setPasswordVisible((visible) => !visible)}\n >\n <i class={passwordVisible() ? \"ti ti-eye-off\" : \"ti ti-eye\"} aria-hidden=\"true\" />\n </button>\n </Show>\n </div>\n </Field>\n }\n >\n <MarkdownEditor\n class={local.class}\n label={local.label}\n description={local.description}\n error={error()}\n id={meta.controlId}\n name={rest.name}\n value={value()}\n onValueChange={input}\n onValueCommit={local.onValueCommit}\n onSubmit={local.onSubmit}\n placeholder={rest.placeholder}\n disabled={rest.disabled}\n required={local.required}\n lines={local.lines}\n maxLength={local.maxLength}\n spellcheck={rest.spellcheck === undefined ? undefined : rest.spellcheck === true || rest.spellcheck === \"true\"}\n abbreviations={local.abbreviations}\n completions={local.completions}\n aria-label={local[\"aria-label\"]}\n aria-describedby={local[\"aria-describedby\"]}\n />\n </Show>\n );\n}\n\nexport default TextInput;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -62,10 +62,16 @@ export function createChoiceLoader(loader, debounceMs) {
|
|
|
62
62
|
timer = undefined;
|
|
63
63
|
controller?.abort();
|
|
64
64
|
controller = undefined;
|
|
65
|
+
request++;
|
|
66
|
+
setLoading(false);
|
|
65
67
|
};
|
|
66
68
|
const run = async query => {
|
|
67
69
|
const loadOptions = loader();
|
|
68
|
-
if (!loadOptions)
|
|
70
|
+
if (!loadOptions) {
|
|
71
|
+
// The source went away while its search waited out the debounce.
|
|
72
|
+
setLoading(false);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
69
75
|
controller?.abort();
|
|
70
76
|
controller = new AbortController();
|
|
71
77
|
const currentController = controller;
|
|
@@ -81,13 +87,16 @@ export function createChoiceLoader(loader, debounceMs) {
|
|
|
81
87
|
setError(errorMessage(reason));
|
|
82
88
|
}
|
|
83
89
|
} finally {
|
|
84
|
-
if (currentRequest === request) setLoading(false);
|
|
90
|
+
if (currentRequest === request && !timer) setLoading(false);
|
|
85
91
|
}
|
|
86
92
|
};
|
|
87
93
|
const load = (query, immediate = false) => {
|
|
88
94
|
lastQuery = query;
|
|
89
95
|
if (timer) clearTimeout(timer);
|
|
90
96
|
timer = undefined;
|
|
97
|
+
// A search waiting out its debounce is already loading: the list shows its
|
|
98
|
+
// loading rows, not "no results" for a request that has not run yet.
|
|
99
|
+
if (loader()) setLoading(true);
|
|
91
100
|
if (immediate || debounceMs() <= 0) {
|
|
92
101
|
void run(query);
|
|
93
102
|
return;
|
|
@@ -115,15 +124,23 @@ const popoverIsOpen = popover => {
|
|
|
115
124
|
return false;
|
|
116
125
|
}
|
|
117
126
|
};
|
|
118
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Places the popover under (or above) its trigger. `floor` is the narrowest
|
|
129
|
+
* width it may take, such as the width it already had while open, so filtering
|
|
130
|
+
* the options never makes it narrower.
|
|
131
|
+
*/
|
|
132
|
+
export const placeChoicePopover = (trigger, popover, placement = {}, floor = 0) => {
|
|
119
133
|
const margin = 8;
|
|
120
134
|
const gap = 4;
|
|
121
135
|
const triggerRect = trigger.getBoundingClientRect();
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
136
|
+
// The popover starts at the trigger's left edge and is never narrower than
|
|
137
|
+
// the trigger. Its stylesheet lets it grow to its longest name, as a menu
|
|
138
|
+
// does, so a name stays on one line beside a narrow trigger.
|
|
139
|
+
if (placement.width !== "own") {
|
|
140
|
+
popover.dataset.width = "fit";
|
|
141
|
+
const minWidth = Math.min(Math.max(triggerRect.width, floor), window.innerWidth - margin * 2);
|
|
142
|
+
popover.style.setProperty("--k2b-choice-min-width", `${minWidth}px`);
|
|
143
|
+
}
|
|
127
144
|
|
|
128
145
|
// A stylesheet minimum, such as a popover with filter chips, can make it
|
|
129
146
|
// wider than the trigger, so the clamp below uses the rendered width.
|
|
@@ -142,14 +159,24 @@ export function createChoicePopover(disabled, placement = () => ({})) {
|
|
|
142
159
|
const [trigger, setTrigger] = createSignal();
|
|
143
160
|
const [popover, setPopover] = createSignal();
|
|
144
161
|
let triggerRing = true;
|
|
162
|
+
// The widest the open popover has been: typing a filter never narrows it.
|
|
163
|
+
let widest = 0;
|
|
145
164
|
const place = () => {
|
|
146
165
|
const triggerElement = trigger();
|
|
147
166
|
const popoverElement = popover();
|
|
148
|
-
if (triggerElement
|
|
167
|
+
if (!triggerElement || !popoverElement || !open()) return;
|
|
168
|
+
placeChoicePopover(triggerElement, popoverElement, placement(), widest);
|
|
169
|
+
widest = popoverElement.getBoundingClientRect().width;
|
|
170
|
+
// Hold the width now, while it is the one on screen. Shorter results then
|
|
171
|
+
// keep it without a resize, so the observer below never has to widen the
|
|
172
|
+
// popover again during its own delivery, which WebKit reports as a
|
|
173
|
+
// "ResizeObserver loop" error.
|
|
174
|
+
if (placement().width !== "own") popoverElement.style.setProperty("--k2b-choice-min-width", `${widest}px`);
|
|
149
175
|
};
|
|
150
176
|
const show = () => {
|
|
151
177
|
const popoverElement = popover();
|
|
152
178
|
if (disabled() || !popoverElement || popoverIsOpen(popoverElement)) return;
|
|
179
|
+
widest = 0;
|
|
153
180
|
triggerRing = ringOnReturn(trigger());
|
|
154
181
|
popoverElement.showPopover();
|
|
155
182
|
setOpen(true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["inputs/choice.ts"],"sourcesContent":["import { createEffect, createSignal, onCleanup, type Setter } from \"solid-js\";\nimport { returnFocus, ringOnReturn } from \"../internal/focus-return\";\n\nexport type ChoiceOption<T extends string = string> = {\n value: T;\n label: string;\n description?: string;\n icon?: string;\n color?: string;\n disabled?: boolean;\n /** Optional overlapping groups used by choice controls that expose group filtering. */\n groups?: readonly string[];\n};\n\nexport type ChoiceOptionsLoader<T extends string = string> = (query: string, signal: AbortSignal) => Promise<readonly ChoiceOption<T>[]>;\n\n/** Matches label, description, value, and optional extra keywords. */\nexport const filterChoiceOptions = <\n O extends Pick<ChoiceOption<string>, \"label\" | \"description\" | \"value\"> & { keywords?: readonly string[] },\n>(\n options: readonly O[],\n query: string,\n): readonly O[] => {\n const normalized = query.trim().toLocaleLowerCase();\n if (!normalized) return options;\n return options.filter((option) =>\n [option.label, option.description, option.value, ...(option.keywords ?? [])].some((part) =>\n part?.toLocaleLowerCase().includes(normalized),\n ),\n );\n};\n\n/**\n * Moves through the options and wraps at the ends, skipping `disabled` ones. A\n * RichSelect row that cannot be chosen carries a `disabledReason` instead, so\n * the arrow keys still reach it and its reason can be read.\n */\nexport const nextEnabledChoiceIndex = <O extends { label: string; disabled?: boolean }>(\n options: readonly O[],\n current: number,\n direction: 1 | -1,\n): number => {\n if (options.length === 0 || options.every((option) => option.disabled)) return -1;\n\n let index = current;\n for (let visited = 0; visited < options.length; visited += 1) {\n index = (index + direction + options.length) % options.length;\n if (!options[index]?.disabled) return index;\n }\n return -1;\n};\n\n/**\n * Counts the leading pills that fit into `available` pixels and measures the\n * whole row. When not all of them fit, the rest collapse into a summary pill\n * of width `more`; the first pill always stays and truncates when even it does\n * not fit. Without a measured width (no layout yet) every pill stays. Half a\n * pixel of slack absorbs layout rounding, so a row given exactly its own\n * `rowWidth` always fits.\n */\nexport const fitChoicePills = (\n available: number,\n widths: readonly number[],\n gap: number,\n more: number,\n): { visible: number; rowWidth: number } => {\n const rowWidth = widths.reduce((sum, width) => sum + width, 0) + gap * Math.max(0, widths.length - 1);\n if (available <= 0 || rowWidth <= available + 0.5) return { visible: widths.length, rowWidth };\n let used = more;\n let visible = 0;\n for (const width of widths) {\n used += gap + width;\n if (used > available) break;\n visible += 1;\n }\n return { visible: Math.max(1, visible), rowWidth };\n};\n\nconst errorMessage = (error: unknown): string => (error instanceof Error ? error.message : \"Failed to load options\");\n\nexport function createChoiceLoader<T extends string>(\n loader: () => ChoiceOptionsLoader<T> | undefined,\n debounceMs: () => number,\n): {\n options: () => readonly ChoiceOption<T>[];\n loading: () => boolean;\n error: () => string | undefined;\n load: (query: string, immediate?: boolean) => void;\n retry: () => void;\n cancel: () => void;\n} {\n const [options, setOptions] = createSignal<readonly ChoiceOption<T>[]>([]);\n const [loading, setLoading] = createSignal(false);\n const [error, setError] = createSignal<string>();\n let controller: AbortController | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let request = 0;\n let lastQuery = \"\";\n\n const cancel = () => {\n if (timer) clearTimeout(timer);\n timer = undefined;\n controller?.abort();\n controller = undefined;\n };\n\n const run = async (query: string) => {\n const loadOptions = loader();\n if (!loadOptions) return;\n\n controller?.abort();\n controller = new AbortController();\n const currentController = controller;\n const currentRequest = ++request;\n setLoading(true);\n setError(undefined);\n\n try {\n const next = await loadOptions(query, currentController.signal);\n if (currentRequest === request && !currentController.signal.aborted) setOptions(next);\n } catch (reason) {\n if (currentRequest === request && !currentController.signal.aborted) {\n setOptions([]);\n setError(errorMessage(reason));\n }\n } finally {\n if (currentRequest === request) setLoading(false);\n }\n };\n\n const load = (query: string, immediate = false) => {\n lastQuery = query;\n if (timer) clearTimeout(timer);\n timer = undefined;\n if (immediate || debounceMs() <= 0) {\n void run(query);\n return;\n }\n timer = setTimeout(() => {\n timer = undefined;\n void run(query);\n }, debounceMs());\n };\n\n onCleanup(cancel);\n return { options, loading, error, load, retry: () => load(lastQuery, true), cancel };\n}\n\nconst popoverIsOpen = (popover: HTMLElement | undefined): boolean => {\n if (!popover) return false;\n try {\n return popover.matches(\":popover-open\");\n } catch {\n return false;\n }\n};\n\nexport type ChoicePopoverPlacement = {\n /**\n * `trigger` (default) gives the popover the trigger's width; `own` keeps the\n * width its stylesheet sets, such as a RichSelect with a preview.\n */\n width?: \"trigger\" | \"own\";\n /** The side tried first. The popover flips when the other side has more room. */\n side?: \"below\" | \"above\";\n};\n\nexport const placeChoicePopover = (trigger: HTMLElement, popover: HTMLElement, placement: ChoicePopoverPlacement = {}): void => {\n const margin = 8;\n const gap = 4;\n const triggerRect = trigger.getBoundingClientRect();\n // Cloud sizes its dropdowns to the trigger exactly (`dialog.style.width =\n // rect.width`). Keep that so a narrow toolbar select does not open a wide\n // panel that no longer lines up with the control it belongs to.\n const triggerWidth = Math.min(triggerRect.width, window.innerWidth - margin * 2);\n if (placement.width !== \"own\") popover.style.width = `${triggerWidth}px`;\n\n // A stylesheet minimum, such as a popover with filter chips, can make it\n // wider than the trigger, so the clamp below uses the rendered width.\n const popoverRect = popover.getBoundingClientRect();\n const width = popoverRect.width;\n const left = Math.max(margin, Math.min(triggerRect.left, window.innerWidth - width - margin));\n const roomBelow = window.innerHeight - triggerRect.bottom - gap - margin;\n const roomAbove = triggerRect.top - gap - margin;\n const opensAbove =\n placement.side === \"above\"\n ? popoverRect.height <= roomAbove || roomAbove > roomBelow\n : popoverRect.height > roomBelow && roomAbove > roomBelow;\n const top = opensAbove\n ? Math.max(margin, triggerRect.top - popoverRect.height - gap)\n : Math.min(triggerRect.bottom + gap, window.innerHeight - popoverRect.height - margin);\n\n popover.style.left = `${left}px`;\n popover.style.top = `${Math.max(margin, top)}px`;\n};\n\nexport function createChoicePopover(\n disabled: () => boolean,\n placement: () => ChoicePopoverPlacement = () => ({}),\n): {\n open: () => boolean;\n setTrigger: Setter<HTMLElement | undefined>;\n setPopover: Setter<HTMLElement | undefined>;\n show: () => void;\n hide: (restoreFocus?: boolean) => void;\n toggle: () => void;\n trigger: () => HTMLElement | undefined;\n} {\n const [open, setOpen] = createSignal(false);\n const [trigger, setTrigger] = createSignal<HTMLElement>();\n const [popover, setPopover] = createSignal<HTMLElement>();\n let triggerRing = true;\n\n const place = () => {\n const triggerElement = trigger();\n const popoverElement = popover();\n if (triggerElement && popoverElement && open()) placeChoicePopover(triggerElement, popoverElement, placement());\n };\n\n const show = () => {\n const popoverElement = popover();\n if (disabled() || !popoverElement || popoverIsOpen(popoverElement)) return;\n triggerRing = ringOnReturn(trigger());\n popoverElement.showPopover();\n setOpen(true);\n queueMicrotask(place);\n };\n\n const hide = (restoreFocus = false) => {\n const popoverElement = popover();\n // Before hiding, so the popover does not return focus on its own.\n if (restoreFocus) returnFocus(trigger(), triggerRing);\n if (popoverIsOpen(popoverElement)) popoverElement?.hidePopover();\n setOpen(false);\n };\n\n createEffect(() => {\n const popoverElement = popover();\n if (!popoverElement) return;\n const syncOpenState = () => setOpen(popoverIsOpen(popoverElement));\n const containWheel = (event: WheelEvent) => {\n if (event.ctrlKey) return;\n event.preventDefault();\n\n const target = event.target instanceof Element ? event.target : undefined;\n const groups = target?.closest<HTMLElement>(\".k2b-choice-groups\");\n const horizontalDelta = event.shiftKey && event.deltaX === 0 ? event.deltaY : event.deltaX;\n if (groups && (event.shiftKey || Math.abs(event.deltaX) > Math.abs(event.deltaY)) && groups.scrollWidth > groups.clientWidth) {\n const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? groups.clientWidth : 1;\n groups.scrollLeft += horizontalDelta * unit;\n return;\n }\n\n // A popover with more than one scrolling region, such as a list beside a\n // preview, marks them; the wheel scrolls the one under the pointer.\n const options =\n target?.closest<HTMLElement>(\"[data-choice-scroll]\") ?? popoverElement.querySelector<HTMLElement>(\".k2b-choice-options\");\n if (!options || options.scrollHeight <= options.clientHeight) return;\n const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? options.clientHeight : 1;\n options.scrollTop += event.deltaY * unit;\n };\n popoverElement.addEventListener(\"toggle\", syncOpenState);\n popoverElement.addEventListener(\"wheel\", containWheel, { passive: false });\n onCleanup(() => {\n popoverElement.removeEventListener(\"toggle\", syncOpenState);\n popoverElement.removeEventListener(\"wheel\", containWheel);\n });\n });\n\n createEffect(() => {\n if (!open()) return;\n\n const dismiss = (event: PointerEvent) => {\n const target = event.target;\n if (!(target instanceof Node) || trigger()?.contains(target) || popover()?.contains(target)) return;\n hide();\n };\n const reposition = () => place();\n\n // Async option lists arrive after the popover is already open, so the first\n // placement measures an empty panel. Re-place whenever the panel resizes,\n // otherwise a dropdown that grows past the viewport bottom stays clipped.\n const popoverElement = popover();\n const observer = popoverElement && typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(reposition) : undefined;\n if (popoverElement) observer?.observe(popoverElement);\n\n document.addEventListener(\"pointerdown\", dismiss, true);\n window.addEventListener(\"resize\", reposition);\n window.addEventListener(\"scroll\", reposition, true);\n onCleanup(() => {\n observer?.disconnect();\n document.removeEventListener(\"pointerdown\", dismiss, true);\n window.removeEventListener(\"resize\", reposition);\n window.removeEventListener(\"scroll\", reposition, true);\n });\n });\n\n onCleanup(() => hide());\n return {\n open,\n setTrigger,\n setPopover,\n show,\n hide,\n toggle: () => (open() ? hide() : show()),\n trigger,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/choice.ts"],"sourcesContent":["import { createEffect, createSignal, onCleanup, type Setter } from \"solid-js\";\nimport { returnFocus, ringOnReturn } from \"../internal/focus-return\";\n\nexport type ChoiceOption<T extends string = string> = {\n value: T;\n label: string;\n description?: string;\n icon?: string;\n color?: string;\n disabled?: boolean;\n /** Optional overlapping groups used by choice controls that expose group filtering. */\n groups?: readonly string[];\n};\n\nexport type ChoiceOptionsLoader<T extends string = string> = (query: string, signal: AbortSignal) => Promise<readonly ChoiceOption<T>[]>;\n\n/** Matches label, description, value, and optional extra keywords. */\nexport const filterChoiceOptions = <\n O extends Pick<ChoiceOption<string>, \"label\" | \"description\" | \"value\"> & { keywords?: readonly string[] },\n>(\n options: readonly O[],\n query: string,\n): readonly O[] => {\n const normalized = query.trim().toLocaleLowerCase();\n if (!normalized) return options;\n return options.filter((option) =>\n [option.label, option.description, option.value, ...(option.keywords ?? [])].some((part) =>\n part?.toLocaleLowerCase().includes(normalized),\n ),\n );\n};\n\n/**\n * Moves through the options and wraps at the ends, skipping `disabled` ones. A\n * RichSelect row that cannot be chosen carries a `disabledReason` instead, so\n * the arrow keys still reach it and its reason can be read.\n */\nexport const nextEnabledChoiceIndex = <O extends { label: string; disabled?: boolean }>(\n options: readonly O[],\n current: number,\n direction: 1 | -1,\n): number => {\n if (options.length === 0 || options.every((option) => option.disabled)) return -1;\n\n let index = current;\n for (let visited = 0; visited < options.length; visited += 1) {\n index = (index + direction + options.length) % options.length;\n if (!options[index]?.disabled) return index;\n }\n return -1;\n};\n\n/**\n * Counts the leading pills that fit into `available` pixels and measures the\n * whole row. When not all of them fit, the rest collapse into a summary pill\n * of width `more`; the first pill always stays and truncates when even it does\n * not fit. Without a measured width (no layout yet) every pill stays. Half a\n * pixel of slack absorbs layout rounding, so a row given exactly its own\n * `rowWidth` always fits.\n */\nexport const fitChoicePills = (\n available: number,\n widths: readonly number[],\n gap: number,\n more: number,\n): { visible: number; rowWidth: number } => {\n const rowWidth = widths.reduce((sum, width) => sum + width, 0) + gap * Math.max(0, widths.length - 1);\n if (available <= 0 || rowWidth <= available + 0.5) return { visible: widths.length, rowWidth };\n let used = more;\n let visible = 0;\n for (const width of widths) {\n used += gap + width;\n if (used > available) break;\n visible += 1;\n }\n return { visible: Math.max(1, visible), rowWidth };\n};\n\nconst errorMessage = (error: unknown): string => (error instanceof Error ? error.message : \"Failed to load options\");\n\nexport function createChoiceLoader<T extends string>(\n loader: () => ChoiceOptionsLoader<T> | undefined,\n debounceMs: () => number,\n): {\n options: () => readonly ChoiceOption<T>[];\n loading: () => boolean;\n error: () => string | undefined;\n load: (query: string, immediate?: boolean) => void;\n retry: () => void;\n cancel: () => void;\n} {\n const [options, setOptions] = createSignal<readonly ChoiceOption<T>[]>([]);\n const [loading, setLoading] = createSignal(false);\n const [error, setError] = createSignal<string>();\n let controller: AbortController | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let request = 0;\n let lastQuery = \"\";\n\n const cancel = () => {\n if (timer) clearTimeout(timer);\n timer = undefined;\n controller?.abort();\n controller = undefined;\n request++;\n setLoading(false);\n };\n\n const run = async (query: string) => {\n const loadOptions = loader();\n if (!loadOptions) {\n // The source went away while its search waited out the debounce.\n setLoading(false);\n return;\n }\n\n controller?.abort();\n controller = new AbortController();\n const currentController = controller;\n const currentRequest = ++request;\n setLoading(true);\n setError(undefined);\n\n try {\n const next = await loadOptions(query, currentController.signal);\n if (currentRequest === request && !currentController.signal.aborted) setOptions(next);\n } catch (reason) {\n if (currentRequest === request && !currentController.signal.aborted) {\n setOptions([]);\n setError(errorMessage(reason));\n }\n } finally {\n if (currentRequest === request && !timer) setLoading(false);\n }\n };\n\n const load = (query: string, immediate = false) => {\n lastQuery = query;\n if (timer) clearTimeout(timer);\n timer = undefined;\n // A search waiting out its debounce is already loading: the list shows its\n // loading rows, not \"no results\" for a request that has not run yet.\n if (loader()) setLoading(true);\n if (immediate || debounceMs() <= 0) {\n void run(query);\n return;\n }\n timer = setTimeout(() => {\n timer = undefined;\n void run(query);\n }, debounceMs());\n };\n\n onCleanup(cancel);\n return { options, loading, error, load, retry: () => load(lastQuery, true), cancel };\n}\n\nconst popoverIsOpen = (popover: HTMLElement | undefined): boolean => {\n if (!popover) return false;\n try {\n return popover.matches(\":popover-open\");\n } catch {\n return false;\n }\n};\n\nexport type ChoicePopoverPlacement = {\n /**\n * `trigger` (default) makes the popover at least as wide as the trigger and\n * as wide as its longest name, so names stay on one line; `own` keeps\n * the width its stylesheet sets, such as a RichSelect with a preview.\n */\n width?: \"trigger\" | \"own\";\n /** The side tried first. The popover flips when the other side has more room. */\n side?: \"below\" | \"above\";\n};\n\n/**\n * Places the popover under (or above) its trigger. `floor` is the narrowest\n * width it may take, such as the width it already had while open, so filtering\n * the options never makes it narrower.\n */\nexport const placeChoicePopover = (trigger: HTMLElement, popover: HTMLElement, placement: ChoicePopoverPlacement = {}, floor = 0): void => {\n const margin = 8;\n const gap = 4;\n const triggerRect = trigger.getBoundingClientRect();\n // The popover starts at the trigger's left edge and is never narrower than\n // the trigger. Its stylesheet lets it grow to its longest name, as a menu\n // does, so a name stays on one line beside a narrow trigger.\n if (placement.width !== \"own\") {\n popover.dataset.width = \"fit\";\n const minWidth = Math.min(Math.max(triggerRect.width, floor), window.innerWidth - margin * 2);\n popover.style.setProperty(\"--k2b-choice-min-width\", `${minWidth}px`);\n }\n\n // A stylesheet minimum, such as a popover with filter chips, can make it\n // wider than the trigger, so the clamp below uses the rendered width.\n const popoverRect = popover.getBoundingClientRect();\n const width = popoverRect.width;\n const left = Math.max(margin, Math.min(triggerRect.left, window.innerWidth - width - margin));\n const roomBelow = window.innerHeight - triggerRect.bottom - gap - margin;\n const roomAbove = triggerRect.top - gap - margin;\n const opensAbove =\n placement.side === \"above\"\n ? popoverRect.height <= roomAbove || roomAbove > roomBelow\n : popoverRect.height > roomBelow && roomAbove > roomBelow;\n const top = opensAbove\n ? Math.max(margin, triggerRect.top - popoverRect.height - gap)\n : Math.min(triggerRect.bottom + gap, window.innerHeight - popoverRect.height - margin);\n\n popover.style.left = `${left}px`;\n popover.style.top = `${Math.max(margin, top)}px`;\n};\n\nexport function createChoicePopover(\n disabled: () => boolean,\n placement: () => ChoicePopoverPlacement = () => ({}),\n): {\n open: () => boolean;\n setTrigger: Setter<HTMLElement | undefined>;\n setPopover: Setter<HTMLElement | undefined>;\n show: () => void;\n hide: (restoreFocus?: boolean) => void;\n toggle: () => void;\n trigger: () => HTMLElement | undefined;\n} {\n const [open, setOpen] = createSignal(false);\n const [trigger, setTrigger] = createSignal<HTMLElement>();\n const [popover, setPopover] = createSignal<HTMLElement>();\n let triggerRing = true;\n // The widest the open popover has been: typing a filter never narrows it.\n let widest = 0;\n\n const place = () => {\n const triggerElement = trigger();\n const popoverElement = popover();\n if (!triggerElement || !popoverElement || !open()) return;\n placeChoicePopover(triggerElement, popoverElement, placement(), widest);\n widest = popoverElement.getBoundingClientRect().width;\n // Hold the width now, while it is the one on screen. Shorter results then\n // keep it without a resize, so the observer below never has to widen the\n // popover again during its own delivery, which WebKit reports as a\n // \"ResizeObserver loop\" error.\n if (placement().width !== \"own\") popoverElement.style.setProperty(\"--k2b-choice-min-width\", `${widest}px`);\n };\n\n const show = () => {\n const popoverElement = popover();\n if (disabled() || !popoverElement || popoverIsOpen(popoverElement)) return;\n widest = 0;\n triggerRing = ringOnReturn(trigger());\n popoverElement.showPopover();\n setOpen(true);\n queueMicrotask(place);\n };\n\n const hide = (restoreFocus = false) => {\n const popoverElement = popover();\n // Before hiding, so the popover does not return focus on its own.\n if (restoreFocus) returnFocus(trigger(), triggerRing);\n if (popoverIsOpen(popoverElement)) popoverElement?.hidePopover();\n setOpen(false);\n };\n\n createEffect(() => {\n const popoverElement = popover();\n if (!popoverElement) return;\n const syncOpenState = () => setOpen(popoverIsOpen(popoverElement));\n const containWheel = (event: WheelEvent) => {\n if (event.ctrlKey) return;\n event.preventDefault();\n\n const target = event.target instanceof Element ? event.target : undefined;\n const groups = target?.closest<HTMLElement>(\".k2b-choice-groups\");\n const horizontalDelta = event.shiftKey && event.deltaX === 0 ? event.deltaY : event.deltaX;\n if (groups && (event.shiftKey || Math.abs(event.deltaX) > Math.abs(event.deltaY)) && groups.scrollWidth > groups.clientWidth) {\n const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? groups.clientWidth : 1;\n groups.scrollLeft += horizontalDelta * unit;\n return;\n }\n\n // A popover with more than one scrolling region, such as a list beside a\n // preview, marks them; the wheel scrolls the one under the pointer.\n const options =\n target?.closest<HTMLElement>(\"[data-choice-scroll]\") ?? popoverElement.querySelector<HTMLElement>(\".k2b-choice-options\");\n if (!options || options.scrollHeight <= options.clientHeight) return;\n const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? options.clientHeight : 1;\n options.scrollTop += event.deltaY * unit;\n };\n popoverElement.addEventListener(\"toggle\", syncOpenState);\n popoverElement.addEventListener(\"wheel\", containWheel, { passive: false });\n onCleanup(() => {\n popoverElement.removeEventListener(\"toggle\", syncOpenState);\n popoverElement.removeEventListener(\"wheel\", containWheel);\n });\n });\n\n createEffect(() => {\n if (!open()) return;\n\n const dismiss = (event: PointerEvent) => {\n const target = event.target;\n if (!(target instanceof Node) || trigger()?.contains(target) || popover()?.contains(target)) return;\n hide();\n };\n const reposition = () => place();\n\n // Async option lists arrive after the popover is already open, so the first\n // placement measures an empty panel. Re-place whenever the panel resizes,\n // otherwise a dropdown that grows past the viewport bottom stays clipped.\n const popoverElement = popover();\n const observer = popoverElement && typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(reposition) : undefined;\n if (popoverElement) observer?.observe(popoverElement);\n\n document.addEventListener(\"pointerdown\", dismiss, true);\n window.addEventListener(\"resize\", reposition);\n window.addEventListener(\"scroll\", reposition, true);\n onCleanup(() => {\n observer?.disconnect();\n document.removeEventListener(\"pointerdown\", dismiss, true);\n window.removeEventListener(\"resize\", reposition);\n window.removeEventListener(\"scroll\", reposition, true);\n });\n });\n\n onCleanup(() => hide());\n return {\n open,\n setTrigger,\n setPopover,\n show,\n hide,\n toggle: () => (open() ? hide() : show()),\n trigger,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { i18n } from "@k2b/stdlib";
|
|
2
|
+
|
|
3
|
+
/** Status line and errors of the typed date field; dates, weekdays and distances come from Intl. */
|
|
4
|
+
const dateInputMessages = i18n.define({
|
|
5
|
+
baseLocale: "en",
|
|
6
|
+
messages: {
|
|
7
|
+
en: {
|
|
8
|
+
dayLetters: "DD",
|
|
9
|
+
monthLetters: "MM",
|
|
10
|
+
yearLetters: "YYYY",
|
|
11
|
+
openCalendar: "Open calendar",
|
|
12
|
+
closeCalendar: "Close calendar",
|
|
13
|
+
notADate: ({
|
|
14
|
+
example
|
|
15
|
+
}) => `Not a date. Example: ${example}, wed or +14`,
|
|
16
|
+
notYet: "Not a date yet",
|
|
17
|
+
ambiguous: "Ambiguous. Keep typing.",
|
|
18
|
+
incompleteYear: ({
|
|
19
|
+
year
|
|
20
|
+
}) => `Incomplete year, e.g. ${year}.`,
|
|
21
|
+
unknownUnit: "Unknown unit. Use d, w, m or y.",
|
|
22
|
+
noSuchMonth: ({
|
|
23
|
+
month
|
|
24
|
+
}) => `There is no month ${month}.`,
|
|
25
|
+
shortMonth: ({
|
|
26
|
+
month,
|
|
27
|
+
days
|
|
28
|
+
}) => `${month} has only ${days} days.`,
|
|
29
|
+
earliest: ({
|
|
30
|
+
date
|
|
31
|
+
}) => `${date} at the earliest.`,
|
|
32
|
+
latest: ({
|
|
33
|
+
date
|
|
34
|
+
}) => `${date} at the latest.`,
|
|
35
|
+
outsideRange: "Outside the allowed dates",
|
|
36
|
+
required: "Enter a date.",
|
|
37
|
+
endBeforeStart: "The end is before the start.",
|
|
38
|
+
missingEnd: "Enter an end too.",
|
|
39
|
+
missingStart: "Enter a start too.",
|
|
40
|
+
nextWeekday: ({
|
|
41
|
+
weekday
|
|
42
|
+
}) => `next ${weekday}`,
|
|
43
|
+
nextWeek: "next week",
|
|
44
|
+
notSelectable: ({
|
|
45
|
+
date
|
|
46
|
+
}) => `${date}, not available`,
|
|
47
|
+
limitFrom: ({
|
|
48
|
+
date
|
|
49
|
+
}) => `from ${date}`,
|
|
50
|
+
limitUntil: ({
|
|
51
|
+
date
|
|
52
|
+
}) => `until ${date}`,
|
|
53
|
+
start: "Start",
|
|
54
|
+
end: "End",
|
|
55
|
+
startOf: ({
|
|
56
|
+
label
|
|
57
|
+
}) => `${label}: start`,
|
|
58
|
+
endOf: ({
|
|
59
|
+
label
|
|
60
|
+
}) => `${label}: end`,
|
|
61
|
+
startMissing: "start missing",
|
|
62
|
+
endMissing: "end missing",
|
|
63
|
+
noDate: "No date"
|
|
64
|
+
},
|
|
65
|
+
de: {
|
|
66
|
+
dayLetters: "TT",
|
|
67
|
+
monthLetters: "MM",
|
|
68
|
+
yearLetters: "JJJJ",
|
|
69
|
+
openCalendar: "Kalender öffnen",
|
|
70
|
+
closeCalendar: "Kalender schließen",
|
|
71
|
+
notADate: ({
|
|
72
|
+
example
|
|
73
|
+
}) => `Kein Datum. Beispiel: ${example}, mi oder +14`,
|
|
74
|
+
notYet: "Noch kein Datum",
|
|
75
|
+
ambiguous: "Mehrdeutig. Bitte weiter tippen.",
|
|
76
|
+
incompleteYear: ({
|
|
77
|
+
year
|
|
78
|
+
}) => `Jahr unvollständig, z. B. ${year}.`,
|
|
79
|
+
unknownUnit: "Einheit unbekannt. Möglich: t, w, m, j",
|
|
80
|
+
noSuchMonth: ({
|
|
81
|
+
month
|
|
82
|
+
}) => `Einen ${month}. Monat gibt es nicht.`,
|
|
83
|
+
shortMonth: ({
|
|
84
|
+
month,
|
|
85
|
+
days
|
|
86
|
+
}) => `Der ${month} hat nur ${days} Tage.`,
|
|
87
|
+
earliest: ({
|
|
88
|
+
date
|
|
89
|
+
}) => `Frühestens am ${date}.`,
|
|
90
|
+
latest: ({
|
|
91
|
+
date
|
|
92
|
+
}) => `Spätestens am ${date}.`,
|
|
93
|
+
outsideRange: "Außerhalb der erlaubten Daten",
|
|
94
|
+
required: "Bitte ein Datum eingeben.",
|
|
95
|
+
endBeforeStart: "Das Ende liegt vor dem Start.",
|
|
96
|
+
missingEnd: "Bitte auch ein Ende eingeben.",
|
|
97
|
+
missingStart: "Bitte auch einen Start eingeben.",
|
|
98
|
+
nextWeekday: ({
|
|
99
|
+
weekday
|
|
100
|
+
}) => `nächster ${weekday}`,
|
|
101
|
+
nextWeek: "nächste Woche",
|
|
102
|
+
notSelectable: ({
|
|
103
|
+
date
|
|
104
|
+
}) => `${date}, nicht wählbar`,
|
|
105
|
+
limitFrom: ({
|
|
106
|
+
date
|
|
107
|
+
}) => `ab ${date}`,
|
|
108
|
+
limitUntil: ({
|
|
109
|
+
date
|
|
110
|
+
}) => `bis ${date}`,
|
|
111
|
+
start: "Start",
|
|
112
|
+
end: "Ende",
|
|
113
|
+
startOf: ({
|
|
114
|
+
label
|
|
115
|
+
}) => `${label}: Start`,
|
|
116
|
+
endOf: ({
|
|
117
|
+
label
|
|
118
|
+
}) => `${label}: Ende`,
|
|
119
|
+
startMissing: "Start fehlt",
|
|
120
|
+
endMissing: "Ende fehlt",
|
|
121
|
+
noDate: "Kein Datum"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
/** Resolved from the date locale, so the words join the dates they describe in one language. */
|
|
126
|
+
export const resolveDateInputMessages = locale => dateInputMessages.resolve([locale ?? "en"]).t;
|
|
127
|
+
export const checkDateInputMessages = () => dateInputMessages.check();
|
|
128
|
+
//# sourceMappingURL=date-input-messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/date-input-messages.ts"],"sourcesContent":["import { i18n } from \"@k2b/stdlib\";\n\n/** Status line and errors of the typed date field; dates, weekdays and distances come from Intl. */\nconst dateInputMessages = i18n.define({\n baseLocale: \"en\",\n messages: {\n en: {\n dayLetters: \"DD\",\n monthLetters: \"MM\",\n yearLetters: \"YYYY\",\n openCalendar: \"Open calendar\",\n closeCalendar: \"Close calendar\",\n notADate: ({ example }: { example: string }) => `Not a date. Example: ${example}, wed or +14`,\n notYet: \"Not a date yet\",\n ambiguous: \"Ambiguous. Keep typing.\",\n incompleteYear: ({ year }: { year: string }) => `Incomplete year, e.g. ${year}.`,\n unknownUnit: \"Unknown unit. Use d, w, m or y.\",\n noSuchMonth: ({ month }: { month: number }) => `There is no month ${month}.`,\n shortMonth: ({ month, days }: { month: string; days: number }) => `${month} has only ${days} days.`,\n earliest: ({ date }: { date: string }) => `${date} at the earliest.`,\n latest: ({ date }: { date: string }) => `${date} at the latest.`,\n outsideRange: \"Outside the allowed dates\",\n required: \"Enter a date.\",\n endBeforeStart: \"The end is before the start.\",\n missingEnd: \"Enter an end too.\",\n missingStart: \"Enter a start too.\",\n nextWeekday: ({ weekday }: { weekday: string }) => `next ${weekday}`,\n nextWeek: \"next week\",\n notSelectable: ({ date }: { date: string }) => `${date}, not available`,\n limitFrom: ({ date }: { date: string }) => `from ${date}`,\n limitUntil: ({ date }: { date: string }) => `until ${date}`,\n start: \"Start\",\n end: \"End\",\n startOf: ({ label }: { label: string }) => `${label}: start`,\n endOf: ({ label }: { label: string }) => `${label}: end`,\n startMissing: \"start missing\",\n endMissing: \"end missing\",\n noDate: \"No date\",\n },\n de: {\n dayLetters: \"TT\",\n monthLetters: \"MM\",\n yearLetters: \"JJJJ\",\n openCalendar: \"Kalender öffnen\",\n closeCalendar: \"Kalender schließen\",\n notADate: ({ example }) => `Kein Datum. Beispiel: ${example}, mi oder +14`,\n notYet: \"Noch kein Datum\",\n ambiguous: \"Mehrdeutig. Bitte weiter tippen.\",\n incompleteYear: ({ year }) => `Jahr unvollständig, z. B. ${year}.`,\n unknownUnit: \"Einheit unbekannt. Möglich: t, w, m, j\",\n noSuchMonth: ({ month }) => `Einen ${month}. Monat gibt es nicht.`,\n shortMonth: ({ month, days }) => `Der ${month} hat nur ${days} Tage.`,\n earliest: ({ date }) => `Frühestens am ${date}.`,\n latest: ({ date }) => `Spätestens am ${date}.`,\n outsideRange: \"Außerhalb der erlaubten Daten\",\n required: \"Bitte ein Datum eingeben.\",\n endBeforeStart: \"Das Ende liegt vor dem Start.\",\n missingEnd: \"Bitte auch ein Ende eingeben.\",\n missingStart: \"Bitte auch einen Start eingeben.\",\n nextWeekday: ({ weekday }) => `nächster ${weekday}`,\n nextWeek: \"nächste Woche\",\n notSelectable: ({ date }) => `${date}, nicht wählbar`,\n limitFrom: ({ date }) => `ab ${date}`,\n limitUntil: ({ date }) => `bis ${date}`,\n start: \"Start\",\n end: \"Ende\",\n startOf: ({ label }) => `${label}: Start`,\n endOf: ({ label }) => `${label}: Ende`,\n startMissing: \"Start fehlt\",\n endMissing: \"Ende fehlt\",\n noDate: \"Kein Datum\",\n },\n },\n});\n\nexport type DateInputMessages = ReturnType<(typeof dateInputMessages)[\"resolve\"]>[\"t\"];\n\n/** Resolved from the date locale, so the words join the dates they describe in one language. */\nexport const resolveDateInputMessages = (locale?: string): DateInputMessages => dateInputMessages.resolve([locale ?? \"en\"]).t;\n\nexport const checkDateInputMessages = () => dateInputMessages.check();\n"],"mappings":"AAAA,SAAS,IAAI,QAAQ,aAAa;;AAElC;AACA,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC;EACpC,UAAU,EAAE,IAAI;EAChB,QAAQ,EAAE;IACR,EAAE,EAAE;MACF,UAAU,EAAE,IAAI;MAChB,YAAY,EAAE,IAAI;MAClB,WAAW,EAAE,MAAM;MACnB,YAAY,EAAE,eAAe;MAC7B,aAAa,EAAE,gBAAgB;MAC/B,QAAQ,EAAE,CAAC;QAAE;MAA6B,CAAC,KAAK,wBAAwB,OAAO,cAAc;MAC7F,MAAM,EAAE,gBAAgB;MACxB,SAAS,EAAE,yBAAyB;MACpC,cAAc,EAAE,CAAC;QAAE;MAAuB,CAAC,KAAK,yBAAyB,IAAI,GAAG;MAChF,WAAW,EAAE,iCAAiC;MAC9C,WAAW,EAAE,CAAC;QAAE;MAAyB,CAAC,KAAK,qBAAqB,KAAK,GAAG;MAC5E,UAAU,EAAE,CAAC;QAAE,KAAK;QAAE;MAAsC,CAAC,KAAK,GAAG,KAAK,aAAa,IAAI,QAAQ;MACnG,QAAQ,EAAE,CAAC;QAAE;MAAuB,CAAC,KAAK,GAAG,IAAI,mBAAmB;MACpE,MAAM,EAAE,CAAC;QAAE;MAAuB,CAAC,KAAK,GAAG,IAAI,iBAAiB;MAChE,YAAY,EAAE,2BAA2B;MACzC,QAAQ,EAAE,eAAe;MACzB,cAAc,EAAE,8BAA8B;MAC9C,UAAU,EAAE,mBAAmB;MAC/B,YAAY,EAAE,oBAAoB;MAClC,WAAW,EAAE,CAAC;QAAE;MAA6B,CAAC,KAAK,QAAQ,OAAO,EAAE;MACpE,QAAQ,EAAE,WAAW;MACrB,aAAa,EAAE,CAAC;QAAE;MAAuB,CAAC,KAAK,GAAG,IAAI,iBAAiB;MACvE,SAAS,EAAE,CAAC;QAAE;MAAuB,CAAC,KAAK,QAAQ,IAAI,EAAE;MACzD,UAAU,EAAE,CAAC;QAAE;MAAuB,CAAC,KAAK,SAAS,IAAI,EAAE;MAC3D,KAAK,EAAE,OAAO;MACd,GAAG,EAAE,KAAK;MACV,OAAO,EAAE,CAAC;QAAE;MAAyB,CAAC,KAAK,GAAG,KAAK,SAAS;MAC5D,KAAK,EAAE,CAAC;QAAE;MAAyB,CAAC,KAAK,GAAG,KAAK,OAAO;MACxD,YAAY,EAAE,eAAe;MAC7B,UAAU,EAAE,aAAa;MACzB,MAAM,EAAE;IACV,CAAC;IACD,EAAE,EAAE;MACF,UAAU,EAAE,IAAI;MAChB,YAAY,EAAE,IAAI;MAClB,WAAW,EAAE,MAAM;MACnB,YAAY,EAAE,iBAAiB;MAC/B,aAAa,EAAE,oBAAoB;MACnC,QAAQ,EAAE,CAAC;QAAE;MAAQ,CAAC,KAAK,yBAAyB,OAAO,eAAe;MAC1E,MAAM,EAAE,iBAAiB;MACzB,SAAS,EAAE,kCAAkC;MAC7C,cAAc,EAAE,CAAC;QAAE;MAAK,CAAC,KAAK,6BAA6B,IAAI,GAAG;MAClE,WAAW,EAAE,wCAAwC;MACrD,WAAW,EAAE,CAAC;QAAE;MAAM,CAAC,KAAK,SAAS,KAAK,wBAAwB;MAClE,UAAU,EAAE,CAAC;QAAE,KAAK;QAAE;MAAK,CAAC,KAAK,OAAO,KAAK,YAAY,IAAI,QAAQ;MACrE,QAAQ,EAAE,CAAC;QAAE;MAAK,CAAC,KAAK,iBAAiB,IAAI,GAAG;MAChD,MAAM,EAAE,CAAC;QAAE;MAAK,CAAC,KAAK,iBAAiB,IAAI,GAAG;MAC9C,YAAY,EAAE,+BAA+B;MAC7C,QAAQ,EAAE,2BAA2B;MACrC,cAAc,EAAE,+BAA+B;MAC/C,UAAU,EAAE,+BAA+B;MAC3C,YAAY,EAAE,kCAAkC;MAChD,WAAW,EAAE,CAAC;QAAE;MAAQ,CAAC,KAAK,YAAY,OAAO,EAAE;MACnD,QAAQ,EAAE,eAAe;MACzB,aAAa,EAAE,CAAC;QAAE;MAAK,CAAC,KAAK,GAAG,IAAI,iBAAiB;MACrD,SAAS,EAAE,CAAC;QAAE;MAAK,CAAC,KAAK,MAAM,IAAI,EAAE;MACrC,UAAU,EAAE,CAAC;QAAE;MAAK,CAAC,KAAK,OAAO,IAAI,EAAE;MACvC,KAAK,EAAE,OAAO;MACd,GAAG,EAAE,MAAM;MACX,OAAO,EAAE,CAAC;QAAE;MAAM,CAAC,KAAK,GAAG,KAAK,SAAS;MACzC,KAAK,EAAE,CAAC;QAAE;MAAM,CAAC,KAAK,GAAG,KAAK,QAAQ;MACtC,YAAY,EAAE,aAAa;MAC3B,UAAU,EAAE,YAAY;MACxB,MAAM,EAAE;IACV;EACF;AACF,CAAC,CAAC;AAIF;AACA,OAAO,MAAM,wBAAwB,GAAI,MAAe,IAAwB,iBAAiB,CAAC,OAAO,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;AAE7H,OAAO,MAAM,sBAAsB,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { addDaysToKey, daysBetweenKeys, formatDateInput } from "./date-input";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The line under a typed date field. It always says which day is meant: grey at rest (weekday and distance), blue
|
|
5
|
+
* while typing (the absolute date that a commit would save), red after a commit that failed.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const noon = key => Date.parse(`${key}T12:00:00.000Z`);
|
|
9
|
+
// A known Monday; weekday indexes count from Monday (0).
|
|
10
|
+
const MONDAY = "2026-11-02";
|
|
11
|
+
|
|
12
|
+
/** "Mi., 4. Nov. 2026" / "Wed, Nov 4, 2026": the absolute date of a draft. */
|
|
13
|
+
export const formatDateLong = (key, locale) => new Intl.DateTimeFormat(locale, {
|
|
14
|
+
weekday: "short",
|
|
15
|
+
day: "numeric",
|
|
16
|
+
month: "short",
|
|
17
|
+
year: "numeric",
|
|
18
|
+
timeZone: "UTC"
|
|
19
|
+
}).format(noon(key));
|
|
20
|
+
const weekdayName = (weekday, locale) => new Intl.DateTimeFormat(locale, {
|
|
21
|
+
weekday: "long",
|
|
22
|
+
timeZone: "UTC"
|
|
23
|
+
}).format(noon(addDaysToKey(MONDAY, weekday)));
|
|
24
|
+
const relativeDay = (days, locale) => new Intl.RelativeTimeFormat(locale, {
|
|
25
|
+
numeric: "auto"
|
|
26
|
+
}).format(days, "day");
|
|
27
|
+
|
|
28
|
+
/** "Mittwoch, in 9 Tagen": the saved date at rest. */
|
|
29
|
+
export const restStatusText = (key, today, locale) => `${new Intl.DateTimeFormat(locale, {
|
|
30
|
+
weekday: "long",
|
|
31
|
+
timeZone: "UTC"
|
|
32
|
+
}).format(noon(key))}, ${relativeDay(daysBetweenKeys(today, key), locale)}`;
|
|
33
|
+
const anchorText = (anchor, locale) => {
|
|
34
|
+
if (anchor.kind === "today") return relativeDay(0, locale);
|
|
35
|
+
if (anchor.kind === "day") return relativeDay(anchor.offset, locale);
|
|
36
|
+
if (anchor.kind === "weekday") return weekdayName(anchor.weekday, locale);
|
|
37
|
+
return formatDateInput(anchor.date, locale);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** What a word or offset meant: "morgen", "nächster Mittwoch", "gestern + 34 Tage". */
|
|
41
|
+
export const noteText = (note, locale, t) => {
|
|
42
|
+
if (note.kind === "day") return relativeDay(note.offset, locale);
|
|
43
|
+
if (note.kind === "weekday") return note.nextWeek ? t.nextWeek : t.nextWeekday({
|
|
44
|
+
weekday: weekdayName(note.weekday, locale)
|
|
45
|
+
});
|
|
46
|
+
const amount = new Intl.NumberFormat(locale, {
|
|
47
|
+
style: "unit",
|
|
48
|
+
unit: note.unit,
|
|
49
|
+
unitDisplay: "long"
|
|
50
|
+
}).format(Math.abs(note.amount));
|
|
51
|
+
return `${anchorText(note.anchor, locale)} ${note.amount < 0 ? "−" : "+"} ${amount}`;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** The draft line: "→ Mi., 4. Nov. 2026 · nächster Mittwoch". */
|
|
55
|
+
export const draftStatusText = (key, note, locale, t) => `→ ${formatDateLong(key, locale)}${note ? ` · ${noteText(note, locale, t)}` : ""}`;
|
|
56
|
+
|
|
57
|
+
/** The reason a text is not a date, short enough for one line. */
|
|
58
|
+
export const errorText = (error, locale, t, today) => {
|
|
59
|
+
if (error.code === "day") {
|
|
60
|
+
const month = new Intl.DateTimeFormat(locale, {
|
|
61
|
+
month: "long",
|
|
62
|
+
year: "numeric",
|
|
63
|
+
timeZone: "UTC"
|
|
64
|
+
}).format(Date.UTC(error.year, error.month - 1, 15, 12));
|
|
65
|
+
return t.shortMonth({
|
|
66
|
+
month,
|
|
67
|
+
days: error.days
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (error.code === "month") return t.noSuchMonth({
|
|
71
|
+
month: error.month
|
|
72
|
+
});
|
|
73
|
+
if (error.code === "year") return t.incompleteYear({
|
|
74
|
+
year: today.slice(0, 4)
|
|
75
|
+
});
|
|
76
|
+
if (error.code === "unit") return t.unknownUnit;
|
|
77
|
+
if (error.code === "ambiguous") return t.ambiguous;
|
|
78
|
+
const example = new Intl.DateTimeFormat(locale, {
|
|
79
|
+
day: "2-digit",
|
|
80
|
+
month: "2-digit",
|
|
81
|
+
timeZone: "UTC"
|
|
82
|
+
}).format(Date.UTC(2026, 10, 11, 12));
|
|
83
|
+
return t.notADate({
|
|
84
|
+
example
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/** A date outside `min`/`max` (date keys) is refused with the nearest allowed day. */
|
|
89
|
+
export const limitErrorText = (key, limits, locale, t) => {
|
|
90
|
+
if (limits.min && key < limits.min) return t.earliest({
|
|
91
|
+
date: formatDateInput(limits.min, locale)
|
|
92
|
+
});
|
|
93
|
+
if (limits.max && key > limits.max) return t.latest({
|
|
94
|
+
date: formatDateInput(limits.max, locale)
|
|
95
|
+
});
|
|
96
|
+
return undefined;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/** While typing nothing is red yet: an unfinished entry says so calmly, a definite mistake already names the reason. */
|
|
100
|
+
export const typingStatusText = (error, locale, t, today) => {
|
|
101
|
+
if (error.code === "incomplete") return "…";
|
|
102
|
+
if (error.code === "not-a-date") return t.notYet;
|
|
103
|
+
return errorText(error, locale, t, today);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/** "Mittwoch, 4. November 2026, nächster Mittwoch": what the live region reads after typing pauses. */
|
|
107
|
+
export const spokenDateText = (key, note, locale, t) => {
|
|
108
|
+
const date = new Intl.DateTimeFormat(locale, {
|
|
109
|
+
weekday: "long",
|
|
110
|
+
day: "numeric",
|
|
111
|
+
month: "long",
|
|
112
|
+
year: "numeric",
|
|
113
|
+
timeZone: "UTC"
|
|
114
|
+
}).format(noon(key));
|
|
115
|
+
return note ? `${date}, ${noteText(note, locale, t)}` : date;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/** "Mi., 11. Nov. 2026 – Sa., 14. Nov. 2026 · 4 Tage", or one end with what is missing. */
|
|
119
|
+
export const rangeStatusText = (range, locale, t) => {
|
|
120
|
+
if (range.start && range.end) {
|
|
121
|
+
const days = new Intl.NumberFormat(locale, {
|
|
122
|
+
style: "unit",
|
|
123
|
+
unit: "day",
|
|
124
|
+
unitDisplay: "long"
|
|
125
|
+
}).format(Math.abs(daysBetweenKeys(range.start, range.end)) + 1);
|
|
126
|
+
return `${formatDateLong(range.start, locale)} – ${formatDateLong(range.end, locale)} · ${days}`;
|
|
127
|
+
}
|
|
128
|
+
if (range.start) return `${formatDateLong(range.start, locale)} · ${t.endMissing}`;
|
|
129
|
+
if (range.end) return `${formatDateLong(range.end, locale)} · ${t.startMissing}`;
|
|
130
|
+
return "";
|
|
131
|
+
};
|
|
132
|
+
//# sourceMappingURL=date-input-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/date-input-status.ts"],"sourcesContent":["import {\n addDaysToKey,\n type DateInputAnchor,\n type DateInputError,\n type DateInputNote,\n daysBetweenKeys,\n formatDateInput,\n} from \"./date-input\";\nimport type { DateInputMessages } from \"./date-input-messages\";\n\n/**\n * The line under a typed date field. It always says which day is meant: grey at rest (weekday and distance), blue\n * while typing (the absolute date that a commit would save), red after a commit that failed.\n */\nexport type DateStatusTone = \"rest\" | \"draft\" | \"error\";\nexport type DateStatus = { tone: DateStatusTone; text: string };\n\nconst noon = (key: string): number => Date.parse(`${key}T12:00:00.000Z`);\n// A known Monday; weekday indexes count from Monday (0).\nconst MONDAY = \"2026-11-02\";\n\n/** \"Mi., 4. Nov. 2026\" / \"Wed, Nov 4, 2026\": the absolute date of a draft. */\nexport const formatDateLong = (key: string, locale?: string): string =>\n new Intl.DateTimeFormat(locale, { weekday: \"short\", day: \"numeric\", month: \"short\", year: \"numeric\", timeZone: \"UTC\" }).format(noon(key));\n\nconst weekdayName = (weekday: number, locale?: string): string =>\n new Intl.DateTimeFormat(locale, { weekday: \"long\", timeZone: \"UTC\" }).format(noon(addDaysToKey(MONDAY, weekday)));\n\nconst relativeDay = (days: number, locale?: string): string => new Intl.RelativeTimeFormat(locale, { numeric: \"auto\" }).format(days, \"day\");\n\n/** \"Mittwoch, in 9 Tagen\": the saved date at rest. */\nexport const restStatusText = (key: string, today: string, locale?: string): string =>\n `${new Intl.DateTimeFormat(locale, { weekday: \"long\", timeZone: \"UTC\" }).format(noon(key))}, ${relativeDay(daysBetweenKeys(today, key), locale)}`;\n\nconst anchorText = (anchor: DateInputAnchor, locale?: string): string => {\n if (anchor.kind === \"today\") return relativeDay(0, locale);\n if (anchor.kind === \"day\") return relativeDay(anchor.offset, locale);\n if (anchor.kind === \"weekday\") return weekdayName(anchor.weekday, locale);\n return formatDateInput(anchor.date, locale);\n};\n\n/** What a word or offset meant: \"morgen\", \"nächster Mittwoch\", \"gestern + 34 Tage\". */\nexport const noteText = (note: DateInputNote, locale: string | undefined, t: DateInputMessages): string => {\n if (note.kind === \"day\") return relativeDay(note.offset, locale);\n if (note.kind === \"weekday\") return note.nextWeek ? t.nextWeek : t.nextWeekday({ weekday: weekdayName(note.weekday, locale) });\n const amount = new Intl.NumberFormat(locale, { style: \"unit\", unit: note.unit, unitDisplay: \"long\" }).format(Math.abs(note.amount));\n return `${anchorText(note.anchor, locale)} ${note.amount < 0 ? \"−\" : \"+\"} ${amount}`;\n};\n\n/** The draft line: \"→ Mi., 4. Nov. 2026 · nächster Mittwoch\". */\nexport const draftStatusText = (key: string, note: DateInputNote | undefined, locale: string | undefined, t: DateInputMessages): string =>\n `→ ${formatDateLong(key, locale)}${note ? ` · ${noteText(note, locale, t)}` : \"\"}`;\n\n/** The reason a text is not a date, short enough for one line. */\nexport const errorText = (error: DateInputError, locale: string | undefined, t: DateInputMessages, today: string): string => {\n if (error.code === \"day\") {\n const month = new Intl.DateTimeFormat(locale, { month: \"long\", year: \"numeric\", timeZone: \"UTC\" }).format(\n Date.UTC(error.year, error.month - 1, 15, 12),\n );\n return t.shortMonth({ month, days: error.days });\n }\n if (error.code === \"month\") return t.noSuchMonth({ month: error.month });\n if (error.code === \"year\") return t.incompleteYear({ year: today.slice(0, 4) });\n if (error.code === \"unit\") return t.unknownUnit;\n if (error.code === \"ambiguous\") return t.ambiguous;\n const example = new Intl.DateTimeFormat(locale, { day: \"2-digit\", month: \"2-digit\", timeZone: \"UTC\" }).format(Date.UTC(2026, 10, 11, 12));\n return t.notADate({ example });\n};\n\n/** A date outside `min`/`max` (date keys) is refused with the nearest allowed day. */\nexport const limitErrorText = (\n key: string,\n limits: { min?: string; max?: string },\n locale: string | undefined,\n t: DateInputMessages,\n): string | undefined => {\n if (limits.min && key < limits.min) return t.earliest({ date: formatDateInput(limits.min, locale) });\n if (limits.max && key > limits.max) return t.latest({ date: formatDateInput(limits.max, locale) });\n return undefined;\n};\n\n/** While typing nothing is red yet: an unfinished entry says so calmly, a definite mistake already names the reason. */\nexport const typingStatusText = (error: DateInputError, locale: string | undefined, t: DateInputMessages, today: string): string => {\n if (error.code === \"incomplete\") return \"…\";\n if (error.code === \"not-a-date\") return t.notYet;\n return errorText(error, locale, t, today);\n};\n\n/** \"Mittwoch, 4. November 2026, nächster Mittwoch\": what the live region reads after typing pauses. */\nexport const spokenDateText = (key: string, note: DateInputNote | undefined, locale: string | undefined, t: DateInputMessages): string => {\n const date = new Intl.DateTimeFormat(locale, { weekday: \"long\", day: \"numeric\", month: \"long\", year: \"numeric\", timeZone: \"UTC\" }).format(\n noon(key),\n );\n return note ? `${date}, ${noteText(note, locale, t)}` : date;\n};\n\n/** \"Mi., 11. Nov. 2026 – Sa., 14. Nov. 2026 · 4 Tage\", or one end with what is missing. */\nexport const rangeStatusText = (\n range: { start: string | null; end: string | null },\n locale: string | undefined,\n t: DateInputMessages,\n): string => {\n if (range.start && range.end) {\n const days = new Intl.NumberFormat(locale, { style: \"unit\", unit: \"day\", unitDisplay: \"long\" }).format(\n Math.abs(daysBetweenKeys(range.start, range.end)) + 1,\n );\n return `${formatDateLong(range.start, locale)} – ${formatDateLong(range.end, locale)} · ${days}`;\n }\n if (range.start) return `${formatDateLong(range.start, locale)} · ${t.endMissing}`;\n if (range.end) return `${formatDateLong(range.end, locale)} · ${t.startMissing}`;\n return \"\";\n};\n"],"mappings":"AAAA,SACE,YAAY,EAIZ,eAAe,EACf,eAAe,QACV,cAAc;;AAGrB;AACA;AACA;AACA;;AAIA,MAAM,IAAI,GAAI,GAAW,IAAa,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,gBAAgB,CAAC;AACxE;AACA,MAAM,MAAM,GAAG,YAAY;;AAE3B;AACA,OAAO,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,MAAe,KACzD,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;EAAE,OAAO,EAAE,OAAO;EAAE,GAAG,EAAE,SAAS;EAAE,KAAK,EAAE,OAAO;EAAE,IAAI,EAAE,SAAS;EAAE,QAAQ,EAAE;AAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE3I,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,MAAe,KACnD,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;EAAE,OAAO,EAAE,MAAM;EAAE,QAAQ,EAAE;AAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEnH,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,MAAe,KAAa,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE;EAAE,OAAO,EAAE;AAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC;;AAE3I;AACA,OAAO,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,KAAa,EAAE,MAAe,KACxE,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;EAAE,OAAO,EAAE,MAAM;EAAE,QAAQ,EAAE;AAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,WAAW,CAAC,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE;AAEnJ,MAAM,UAAU,GAAG,CAAC,MAAuB,EAAE,MAAe,KAAa;EACvE,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,OAAO,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC;EAC1D,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,OAAO,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;EACpE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,OAAO,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC;EACzE,OAAO,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;AAC7C,CAAC;;AAED;AACA,OAAO,MAAM,QAAQ,GAAG,CAAC,IAAmB,EAAE,MAA0B,EAAE,CAAoB,KAAa;EACzG,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;EAChE,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,OAAO,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,WAAW,CAAC;IAAE,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM;EAAE,CAAC,CAAC;EAC9H,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM;IAAE,IAAI,EAAE,IAAI,CAAC,IAAI;IAAE,WAAW,EAAE;EAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACnI,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,IAAI,MAAM,EAAE;AACtF,CAAC;;AAED;AACA,OAAO,MAAM,eAAe,GAAG,CAAC,GAAW,EAAE,IAA+B,EAAE,MAA0B,EAAE,CAAoB,KAC5H,KAAK,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;;AAEpF;AACA,OAAO,MAAM,SAAS,GAAG,CAAC,KAAqB,EAAE,MAA0B,EAAE,CAAoB,EAAE,KAAa,KAAa;EAC3H,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE;IACxB,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;MAAE,KAAK,EAAE,MAAM;MAAE,IAAI,EAAE,SAAS;MAAE,QAAQ,EAAE;IAAM,CAAC,CAAC,CAAC,MAAM,CACvG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAC9C,CAAC;IACD,OAAO,CAAC,CAAC,UAAU,CAAC;MAAE,KAAK;MAAE,IAAI,EAAE,KAAK,CAAC;IAAK,CAAC,CAAC;EAClD;EACA,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;EAAM,CAAC,CAAC;EACxE,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,cAAc,CAAC;IAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;EAAE,CAAC,CAAC;EAC/E,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,WAAW;EAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;EAClD,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,SAAS;IAAE,KAAK,EAAE,SAAS;IAAE,QAAQ,EAAE;EAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;EACzI,OAAO,CAAC,CAAC,QAAQ,CAAC;IAAE;EAAQ,CAAC,CAAC;AAChC,CAAC;;AAED;AACA,OAAO,MAAM,cAAc,GAAG,CAC5B,GAAW,EACX,MAAsC,EACtC,MAA0B,EAC1B,CAAoB,KACG;EACvB,IAAI,MAAM,CAAC,GAAG,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC;IAAE,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM;EAAE,CAAC,CAAC;EACpG,IAAI,MAAM,CAAC,GAAG,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC;IAAE,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM;EAAE,CAAC,CAAC;EAClG,OAAO,SAAS;AAClB,CAAC;;AAED;AACA,OAAO,MAAM,gBAAgB,GAAG,CAAC,KAAqB,EAAE,MAA0B,EAAE,CAAoB,EAAE,KAAa,KAAa;EAClI,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,OAAO,GAAG;EAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,OAAO,CAAC,CAAC,MAAM;EAChD,OAAO,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC;AAC3C,CAAC;;AAED;AACA,OAAO,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,IAA+B,EAAE,MAA0B,EAAE,CAAoB,KAAa;EACxI,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM;IAAE,GAAG,EAAE,SAAS;IAAE,KAAK,EAAE,MAAM;IAAE,IAAI,EAAE,SAAS;IAAE,QAAQ,EAAE;EAAM,CAAC,CAAC,CAAC,MAAM,CACvI,IAAI,CAAC,GAAG,CACV,CAAC;EACD,OAAO,IAAI,GAAG,GAAG,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI;AAC9D,CAAC;;AAED;AACA,OAAO,MAAM,eAAe,GAAG,CAC7B,KAAmD,EACnD,MAA0B,EAC1B,CAAoB,KACT;EACX,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE;IAC5B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;MAAE,KAAK,EAAE,MAAM;MAAE,IAAI,EAAE,KAAK;MAAE,WAAW,EAAE;IAAO,CAAC,CAAC,CAAC,MAAM,CACpG,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CACtD,CAAC;IACD,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;EAClG;EACA,IAAI,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE;EAClF,IAAI,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE;EAChF,OAAO,EAAE;AACX,CAAC","ignoreList":[]}
|