@alfakit/react 0.1.0 → 0.1.2
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/CHANGELOG.md +17 -0
- package/dist/components/actions/action-button.d.ts.map +1 -1
- package/dist/components/actions/action-button.js +5 -4
- package/dist/components/actions/action-button.js.map +1 -1
- package/dist/components/actions/action-modals.d.ts.map +1 -1
- package/dist/components/actions/action-modals.js +2 -5
- package/dist/components/actions/action-modals.js.map +1 -1
- package/dist/components/fields/color-picker.js +1 -0
- package/dist/components/fields/color-picker.js.map +1 -1
- package/dist/components/fields/file-upload.js +11 -10
- package/dist/components/fields/file-upload.js.map +1 -1
- package/dist/components/fields/one-time-code-input.js +1 -1
- package/dist/components/fields/one-time-code-input.js.map +1 -1
- package/dist/components/fields/repeater-table.js +12 -1
- package/dist/components/fields/repeater-table.js.map +1 -1
- package/dist/components/fields/select.js +3 -3
- package/dist/components/fields/select.js.map +1 -1
- package/dist/components/file-manager/file-manager.js +1 -1
- package/dist/components/file-manager/file-manager.js.map +1 -1
- package/dist/components/form/form-block.d.ts.map +1 -1
- package/dist/components/form/form-block.js +13 -1
- package/dist/components/form/form-block.js.map +1 -1
- package/dist/components/form/form-context.js +6 -2
- package/dist/components/form/form-context.js.map +1 -1
- package/dist/components/layout/fused-group.js +1 -0
- package/dist/components/layout/fused-group.js.map +1 -1
- package/dist/components/layout/tabs.d.ts.map +1 -1
- package/dist/components/layout/tabs.js +54 -15
- package/dist/components/layout/tabs.js.map +1 -1
- package/dist/components/panel/global-search.js +1 -0
- package/dist/components/panel/global-search.js.map +1 -1
- package/dist/components/panel/shortcut-keys.js +1 -0
- package/dist/components/panel/shortcut-keys.js.map +1 -1
- package/dist/components/panel/tenant-menu.js +2 -2
- package/dist/components/panel/tenant-menu.js.map +1 -1
- package/dist/components/table/cells.js +9 -1
- package/dist/components/table/cells.js.map +1 -1
- package/dist/components/table/grouping.js +11 -1
- package/dist/components/table/grouping.js.map +1 -1
- package/dist/components.css +347 -0
- package/dist/eject-manifest.json +2 -2
- package/dist/standalone/alfakit-toaster.d.ts.map +1 -1
- package/dist/standalone/alfakit-toaster.js +8 -1
- package/dist/standalone/alfakit-toaster.js.map +1 -1
- package/dist/standalone.css +47 -0
- package/dist/starter-kit/widgets-loaded.js +1 -1
- package/dist/starter-kit/widgets-loaded.js.map +1 -1
- package/dist/starter-kit/widgets-triggers.js +1 -0
- package/dist/starter-kit/widgets-triggers.js.map +1 -1
- package/dist/themes.css +2 -334
- package/package.json +2 -2
- package/src/components/actions/action-button.tsx +7 -4
- package/src/components/actions/action-modals.tsx +3 -1
- package/src/components/fields/color-picker.tsx +1 -0
- package/src/components/fields/file-upload.tsx +21 -10
- package/src/components/fields/one-time-code-input.tsx +1 -1
- package/src/components/fields/repeater-table.tsx +12 -1
- package/src/components/fields/select.tsx +7 -3
- package/src/components/file-manager/file-manager.tsx +1 -1
- package/src/components/form/form-block.tsx +24 -0
- package/src/components/form/form-context.tsx +2 -5
- package/src/components/layout/fused-group.tsx +5 -1
- package/src/components/layout/tabs.tsx +72 -17
- package/src/components/panel/global-search.tsx +1 -1
- package/src/components/panel/shortcut-keys.tsx +4 -1
- package/src/components/panel/tenant-menu.tsx +2 -2
- package/src/components/table/cells.tsx +18 -3
- package/src/components/table/grouping.tsx +15 -1
- package/src/standalone/alfakit-toaster.tsx +21 -2
- package/src/starter-kit/widgets-loaded.tsx +1 -1
- package/src/starter-kit/widgets-triggers.tsx +1 -1
|
@@ -27,7 +27,6 @@ function OneTimeCodeInputField({ component }) {
|
|
|
27
27
|
inputMode: "numeric",
|
|
28
28
|
autoComplete: "one-time-code",
|
|
29
29
|
pattern: "[0-9]*",
|
|
30
|
-
maxLength: component.length,
|
|
31
30
|
value: value ?? "",
|
|
32
31
|
onChange: (event) => {
|
|
33
32
|
const code = oneTimeCodeDigits(event.target.value, component.length);
|
|
@@ -42,6 +41,7 @@ function OneTimeCodeInputField({ component }) {
|
|
|
42
41
|
required: component.required,
|
|
43
42
|
autoFocus: component.autofocus,
|
|
44
43
|
"data-slot": "one-time-code-input",
|
|
44
|
+
"data-input": "",
|
|
45
45
|
...aria,
|
|
46
46
|
...extraProps(component.extraInputAttributes, cn("max-w-56 text-center font-mono text-lg tracking-[0.5em] tabular-nums"))
|
|
47
47
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"one-time-code-input.js","names":[],"sources":["../../../src/components/fields/one-time-code-input.tsx"],"sourcesContent":["import { OneTimeCodeSubmitter, oneTimeCodeDigits, type OneTimeCodeInputSchema } from '@alfakit/core'\nimport { useState } from 'react'\nimport { extraProps } from '../../lib/attributes'\nimport { cn } from '../../lib/utils'\nimport { useField } from '../form/form-context'\nimport { FieldWrapper } from '../schema/field-wrapper'\nimport { Input } from '../ui/input'\n\n/**\n * `OneTimeCodeInput`: one numeric input with `autocomplete=\"one-time-code\"` (browsers and\n * password managers fill it from an SMS or email), digits only, left to right in every\n * language. `submitOnCompletion()` submits the form once the last digit is in.\n */\nexport function OneTimeCodeInputField({ component }: { component: OneTimeCodeInputSchema }) {\n const { value, setValue, blur, error, id, disabled, aria } = useField<string | null>(component)\n const [submitter] = useState(() => new OneTimeCodeSubmitter())\n\n return (\n <FieldWrapper field={component} htmlFor={id} error={error}>\n <Input\n id={id}\n name={component.name}\n type=\"text\"\n dir=\"ltr\"\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n pattern=\"[0-9]*\"\n
|
|
1
|
+
{"version":3,"file":"one-time-code-input.js","names":[],"sources":["../../../src/components/fields/one-time-code-input.tsx"],"sourcesContent":["import { OneTimeCodeSubmitter, oneTimeCodeDigits, type OneTimeCodeInputSchema } from '@alfakit/core'\nimport { useState } from 'react'\nimport { extraProps } from '../../lib/attributes'\nimport { cn } from '../../lib/utils'\nimport { useField } from '../form/form-context'\nimport { FieldWrapper } from '../schema/field-wrapper'\nimport { Input } from '../ui/input'\n\n/**\n * `OneTimeCodeInput`: one numeric input with `autocomplete=\"one-time-code\"` (browsers and\n * password managers fill it from an SMS or email), digits only, left to right in every\n * language. `submitOnCompletion()` submits the form once the last digit is in.\n */\nexport function OneTimeCodeInputField({ component }: { component: OneTimeCodeInputSchema }) {\n const { value, setValue, blur, error, id, disabled, aria } = useField<string | null>(component)\n const [submitter] = useState(() => new OneTimeCodeSubmitter())\n\n return (\n <FieldWrapper field={component} htmlFor={id} error={error}>\n <Input\n id={id}\n name={component.name}\n type=\"text\"\n dir=\"ltr\"\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n pattern=\"[0-9]*\"\n value={value ?? ''}\n onChange={(event) => {\n const code = oneTimeCodeDigits(event.target.value, component.length)\n const form = event.currentTarget.form\n\n setValue(code === '' ? null : code)\n\n // After the state reached the form store, so the submitted values include it.\n if (component.submitOnCompletion) {\n queueMicrotask(() => submitter.update(code, component.length, form))\n }\n }}\n onBlur={blur}\n placeholder={component.placeholder}\n disabled={disabled}\n readOnly={component.readOnly}\n required={component.required}\n autoFocus={component.autofocus}\n data-slot=\"one-time-code-input\"\n data-input=\"\"\n {...aria}\n {...extraProps(\n component.extraInputAttributes,\n cn('max-w-56 text-center font-mono text-lg tracking-[0.5em] tabular-nums'),\n )}\n />\n </FieldWrapper>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,sBAAsB,EAAE,aAAoD;CAC1F,MAAM,EAAE,OAAO,UAAU,MAAM,OAAO,IAAI,UAAU,SAAS,SAAwB,SAAS;CAC9F,MAAM,CAAC,aAAa,eAAe,IAAI,qBAAqB,CAAC;CAE7D,OACE,oBAAC,cAAD;EAAc,OAAO;EAAW,SAAS;EAAW;EAClD,UAAA,oBAAC,OAAD;GACM;GACJ,MAAM,UAAU;GAChB,MAAK;GACL,KAAI;GACJ,WAAU;GACV,cAAa;GACb,SAAQ;GACR,OAAO,SAAS;GAChB,WAAW,UAAU;IACnB,MAAM,OAAO,kBAAkB,MAAM,OAAO,OAAO,UAAU,MAAM;IACnE,MAAM,OAAO,MAAM,cAAc;IAEjC,SAAS,SAAS,KAAK,OAAO,IAAI;IAGlC,IAAI,UAAU,oBACZ,qBAAqB,UAAU,OAAO,MAAM,UAAU,QAAQ,IAAI,CAAC;GAEvE;GACA,QAAQ;GACR,aAAa,UAAU;GACb;GACV,UAAU,UAAU;GACpB,UAAU,UAAU;GACpB,WAAW,UAAU;GACrB,aAAU;GACV,cAAW;GACX,GAAI;GACJ,GAAI,WACF,UAAU,sBACV,GAAG,sEAAsE,CAC3E;EACD,CAAA;CACW,CAAA;AAElB"}
|
|
@@ -6,11 +6,22 @@ import { VirtualSpacerRow } from "../schema/virtual-spacer.js";
|
|
|
6
6
|
import { resolveItemAction, tableColumnAlignmentClass, tableColumnCells } from "@alfakit/core";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
//#region src/components/fields/repeater-table.tsx
|
|
9
|
+
/**
|
|
10
|
+
* A fixed `width()` (`9rem`, `120px`) is also the column's minimum, so the table scrolls
|
|
11
|
+
* sideways instead of squeezing its fields; percentages stay flexible.
|
|
12
|
+
*/
|
|
13
|
+
function columnWidthStyle(width) {
|
|
14
|
+
if (!width) return void 0;
|
|
15
|
+
return width.trim().endsWith("%") ? { width } : {
|
|
16
|
+
width,
|
|
17
|
+
minWidth: width
|
|
18
|
+
};
|
|
19
|
+
}
|
|
9
20
|
/** Header cells shared by the Repeater and RepeatableEntry tables. */
|
|
10
21
|
function TableColumnHeaders({ columns }) {
|
|
11
22
|
return /* @__PURE__ */ jsx(Fragment, { children: columns.map((column, index) => /* @__PURE__ */ jsxs("th", {
|
|
12
23
|
scope: "col",
|
|
13
|
-
style: column.width
|
|
24
|
+
style: columnWidthStyle(column.width),
|
|
14
25
|
className: cn("text-muted-foreground px-3 py-2 text-xs font-medium", tableColumnAlignmentClass(column), !column.wrapHeader && "whitespace-nowrap"),
|
|
15
26
|
children: [/* @__PURE__ */ jsx("span", {
|
|
16
27
|
className: cn(column.hiddenLabel && "sr-only"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repeater-table.js","names":[],"sources":["../../../src/components/fields/repeater-table.tsx"],"sourcesContent":["import type {\n ActionContext,\n ActionSchema,\n ItemActionName,\n ItemActionSchema,\n SchemaComponent,\n TableColumnSchema,\n} from '@alfakit/core'\nimport { resolveItemAction, tableColumnAlignmentClass, tableColumnCells } from '@alfakit/core'\nimport { useT } from '../../context'\nimport type { VirtualListBinding } from '../../hooks/use-virtual-list'\nimport { cn } from '../../lib/utils'\nimport { RenderComponent } from '../schema/schema-renderer'\nimport { VirtualSpacerRow } from '../schema/virtual-spacer'\nimport { ItemHeaderActions, useItemActionFallbacks } from './item-actions'\n\nexport interface RepeaterTableProps {\n id: string\n columns: TableColumnSchema[]\n /** The item state path prefix for an index (`lines.0.`). */\n prefixFor: (index: number) => string\n count: number\n schemaFor: (index: number) => SchemaComponent[]\n labelledBy?: string\n describedBy?: string\n reorderable: boolean\n cloneable: boolean\n deletable: boolean\n /** `compact()`: tighter cells. */\n compact?: boolean\n onMove: (from: number, to: number) => void\n onClone: (index: number) => void\n onRemove: (index: number) => void\n /** Windowed rows for long lists (see `useVirtualList`). */\n virtual: VirtualListBinding\n /** The field action context item actions run in. */\n context?: ActionContext\n /** The built-in action `name` of the row at `index` (null when hidden). */\n resolve?: (name: ItemActionName, index: number) => ItemActionSchema | null\n /** `extraItemActions()` of the row at `index`. */\n extraActionsFor?: (index: number) => ActionSchema[] | undefined\n}\n\n/** Header cells shared by the Repeater and RepeatableEntry tables. */\nexport function TableColumnHeaders({ columns }: { columns: TableColumnSchema[] }) {\n return (\n <>\n {columns.map((column, index) => (\n <th\n key={`${column.name ?? 'column'}-${index}`}\n scope=\"col\"\n style={column.width
|
|
1
|
+
{"version":3,"file":"repeater-table.js","names":[],"sources":["../../../src/components/fields/repeater-table.tsx"],"sourcesContent":["import type {\n ActionContext,\n ActionSchema,\n ItemActionName,\n ItemActionSchema,\n SchemaComponent,\n TableColumnSchema,\n} from '@alfakit/core'\nimport { resolveItemAction, tableColumnAlignmentClass, tableColumnCells } from '@alfakit/core'\nimport type { CSSProperties } from 'react'\nimport { useT } from '../../context'\nimport type { VirtualListBinding } from '../../hooks/use-virtual-list'\nimport { cn } from '../../lib/utils'\nimport { RenderComponent } from '../schema/schema-renderer'\nimport { VirtualSpacerRow } from '../schema/virtual-spacer'\nimport { ItemHeaderActions, useItemActionFallbacks } from './item-actions'\n\nexport interface RepeaterTableProps {\n id: string\n columns: TableColumnSchema[]\n /** The item state path prefix for an index (`lines.0.`). */\n prefixFor: (index: number) => string\n count: number\n schemaFor: (index: number) => SchemaComponent[]\n labelledBy?: string\n describedBy?: string\n reorderable: boolean\n cloneable: boolean\n deletable: boolean\n /** `compact()`: tighter cells. */\n compact?: boolean\n onMove: (from: number, to: number) => void\n onClone: (index: number) => void\n onRemove: (index: number) => void\n /** Windowed rows for long lists (see `useVirtualList`). */\n virtual: VirtualListBinding\n /** The field action context item actions run in. */\n context?: ActionContext\n /** The built-in action `name` of the row at `index` (null when hidden). */\n resolve?: (name: ItemActionName, index: number) => ItemActionSchema | null\n /** `extraItemActions()` of the row at `index`. */\n extraActionsFor?: (index: number) => ActionSchema[] | undefined\n}\n\n/**\n * A fixed `width()` (`9rem`, `120px`) is also the column's minimum, so the table scrolls\n * sideways instead of squeezing its fields; percentages stay flexible.\n */\nfunction columnWidthStyle(width?: string | null): CSSProperties | undefined {\n if (!width) return undefined\n\n return width.trim().endsWith('%') ? { width } : { width, minWidth: width }\n}\n\n/** Header cells shared by the Repeater and RepeatableEntry tables. */\nexport function TableColumnHeaders({ columns }: { columns: TableColumnSchema[] }) {\n return (\n <>\n {columns.map((column, index) => (\n <th\n key={`${column.name ?? 'column'}-${index}`}\n scope=\"col\"\n style={columnWidthStyle(column.width)}\n className={cn(\n 'text-muted-foreground px-3 py-2 text-xs font-medium',\n tableColumnAlignmentClass(column),\n !column.wrapHeader && 'whitespace-nowrap',\n )}\n >\n <span className={cn(column.hiddenLabel && 'sr-only')}>{column.label}</span>\n {column.required && (\n <span className=\"text-destructive ms-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </th>\n ))}\n </>\n )\n}\n\n/**\n * Repeater items as table rows (`->table([...])`): one cell per item field, labels kept\n * for screen readers only, and the row controls in the last column.\n */\nexport function RepeaterTable({\n id,\n columns,\n prefixFor,\n count,\n schemaFor,\n labelledBy,\n describedBy,\n reorderable,\n cloneable,\n deletable,\n compact = false,\n onMove,\n onClone,\n onRemove,\n virtual: { range, indexes, attach, item },\n context = { token: '' },\n resolve,\n extraActionsFor,\n}: RepeaterTableProps) {\n const t = useT()\n const fallbacks = useItemActionFallbacks()\n const resolveAction = (name: ItemActionName, index: number) =>\n resolve ? resolve(name, index) : resolveItemAction(name, {}, undefined, fallbacks[name])\n const hasExtraActions = Boolean(\n extraActionsFor && indexes.some((i) => extraActionsFor(i)?.length),\n )\n const hasControls = reorderable || cloneable || deletable || hasExtraActions\n const cellCount = columns.length + Number(hasControls)\n\n return (\n <div\n data-slot=\"repeater-table\"\n data-compact={compact || undefined}\n className=\"bg-card relative overflow-x-auto rounded-lg border shadow-xs\"\n >\n <table\n id={id}\n aria-labelledby={labelledBy}\n aria-describedby={describedBy}\n aria-rowcount={range.active ? count + 1 : undefined}\n className=\"w-full border-collapse text-sm\"\n >\n <thead className=\"bg-muted/40\">\n <tr>\n <TableColumnHeaders columns={columns} />\n {hasControls && (\n <th scope=\"col\" className=\"w-px px-2 py-2\">\n <span className=\"sr-only\">{t('actions', {}, 'Actions')}</span>\n </th>\n )}\n </tr>\n </thead>\n <tbody ref={attach}>\n <VirtualSpacerRow height={range.before} colSpan={cellCount} />\n {indexes.map((index) => {\n const cells = tableColumnCells(columns, schemaFor(index), prefixFor(index))\n\n return (\n <tr\n key={index}\n ref={item}\n data-index={index}\n aria-rowindex={range.active ? index + 2 : undefined}\n data-slot=\"repeater-row\"\n className=\"border-t align-top\"\n >\n {cells.map((cell, cellIndex) => (\n <td\n key={cell?.key ?? `empty-${cellIndex}`}\n className={cn(\n compact ? 'px-1.5 py-1' : 'px-3 py-2',\n '[&_[data-slot=label]]:sr-only',\n tableColumnAlignmentClass(columns[cellIndex] ?? {}),\n )}\n >\n {cell && <RenderComponent component={cell} />}\n </td>\n ))}\n {hasControls && (\n <td className={compact ? 'px-1 py-1' : 'px-2 py-2'}>\n <div className=\"flex items-center justify-end\">\n <ItemHeaderActions\n context={context}\n itemKey={String(index)}\n index={index}\n count={count}\n resolve={(name) => resolveAction(name, index)}\n extraActions={extraActionsFor?.(index)}\n buttons={reorderable}\n canClone={cloneable}\n canDelete={deletable}\n collapsible={false}\n collapsed={false}\n onMove={onMove}\n onClone={() => onClone(index)}\n onDelete={() => onRemove(index)}\n onToggle={() => undefined}\n />\n </div>\n </td>\n )}\n </tr>\n )\n })}\n <VirtualSpacerRow height={range.after} colSpan={cellCount} />\n </tbody>\n </table>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;AAgDA,SAAS,iBAAiB,OAAkD;CAC1E,IAAI,CAAC,OAAO,OAAO,KAAA;CAEnB,OAAO,MAAM,KAAK,CAAC,CAAC,SAAS,GAAG,IAAI,EAAE,MAAM,IAAI;EAAE;EAAO,UAAU;CAAM;AAC3E;;AAGA,SAAgB,mBAAmB,EAAE,WAA6C;CAChF,OACE,oBAAA,UAAA,EAAA,UACG,QAAQ,KAAK,QAAQ,UACpB,qBAAC,MAAD;EAEE,OAAM;EACN,OAAO,iBAAiB,OAAO,KAAK;EACpC,WAAW,GACT,uDACA,0BAA0B,MAAM,GAChC,CAAC,OAAO,cAAc,mBACxB;EARF,UAAA,CAUE,oBAAC,QAAD;GAAM,WAAW,GAAG,OAAO,eAAe,SAAS;GAAI,UAAA,OAAO;EAAY,CAAA,GACzE,OAAO,YACN,oBAAC,QAAD;GAAM,WAAU;GAA0B,eAAY;GAAO,UAAA;EAEvD,CAAA,CAEN;CAfG,GAAA,GAAG,OAAO,QAAQ,SAAS,GAAG,OAejC,CACL,EACD,CAAA;AAEN;;;;;AAMA,SAAgB,cAAc,EAC5B,IACA,SACA,WACA,OACA,WACA,YACA,aACA,aACA,WACA,WACA,UAAU,OACV,QACA,SACA,UACA,SAAS,EAAE,OAAO,SAAS,QAAQ,QACnC,UAAU,EAAE,OAAO,GAAG,GACtB,SACA,mBACqB;CACrB,MAAM,IAAI,KAAK;CACf,MAAM,YAAY,uBAAuB;CACzC,MAAM,iBAAiB,MAAsB,UAC3C,UAAU,QAAQ,MAAM,KAAK,IAAI,kBAAkB,MAAM,CAAC,GAAG,KAAA,GAAW,UAAU,KAAK;CACzF,MAAM,kBAAkB,QACtB,mBAAmB,QAAQ,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,MAAM,CACnE;CACA,MAAM,cAAc,eAAe,aAAa,aAAa;CAC7D,MAAM,YAAY,QAAQ,SAAS,OAAO,WAAW;CAErD,OACE,oBAAC,OAAD;EACE,aAAU;EACV,gBAAc,WAAW,KAAA;EACzB,WAAU;EAEV,UAAA,qBAAC,SAAD;GACM;GACJ,mBAAiB;GACjB,oBAAkB;GAClB,iBAAe,MAAM,SAAS,QAAQ,IAAI,KAAA;GAC1C,WAAU;GALZ,UAAA,CAOE,oBAAC,SAAD;IAAO,WAAU;IACf,UAAA,qBAAC,MAAD,EAAA,UAAA,CACE,oBAAC,oBAAD,EAA6B,QAAU,CAAA,GACtC,eACC,oBAAC,MAAD;KAAI,OAAM;KAAM,WAAU;KACxB,UAAA,oBAAC,QAAD;MAAM,WAAU;MAAW,UAAA,EAAE,WAAW,CAAC,GAAG,SAAS;KAAQ,CAAA;IAC3D,CAAA,CAEJ,EAAA,CAAA;GACC,CAAA,GACP,qBAAC,SAAD;IAAO,KAAK;IAAZ,UAAA;KACE,oBAAC,kBAAD;MAAkB,QAAQ,MAAM;MAAQ,SAAS;KAAY,CAAA;KAC5D,QAAQ,KAAK,UAAU;MACtB,MAAM,QAAQ,iBAAiB,SAAS,UAAU,KAAK,GAAG,UAAU,KAAK,CAAC;MAE1E,OACE,qBAAC,MAAD;OAEE,KAAK;OACL,cAAY;OACZ,iBAAe,MAAM,SAAS,QAAQ,IAAI,KAAA;OAC1C,aAAU;OACV,WAAU;OANZ,UAAA,CAQG,MAAM,KAAK,MAAM,cAChB,oBAAC,MAAD;QAEE,WAAW,GACT,UAAU,gBAAgB,aAC1B,iCACA,0BAA0B,QAAQ,cAAc,CAAC,CAAC,CACpD;QAEC,UAAA,QAAQ,oBAAC,iBAAD,EAAiB,WAAW,KAAO,CAAA;OAC1C,GARG,MAAM,OAAO,SAAS,WAQzB,CACL,GACA,eACC,oBAAC,MAAD;QAAI,WAAW,UAAU,cAAc;QACrC,UAAA,oBAAC,OAAD;SAAK,WAAU;SACb,UAAA,oBAAC,mBAAD;UACW;UACT,SAAS,OAAO,KAAK;UACd;UACA;UACP,UAAU,SAAS,cAAc,MAAM,KAAK;UAC5C,cAAc,kBAAkB,KAAK;UACrC,SAAS;UACT,UAAU;UACV,WAAW;UACX,aAAa;UACb,WAAW;UACH;UACR,eAAe,QAAQ,KAAK;UAC5B,gBAAgB,SAAS,KAAK;UAC9B,gBAAgB,KAAA;SACjB,CAAA;QACE,CAAA;OACH,CAAA,CAEJ;MA1CG,GAAA,KA0CH;KAER,CAAC;KACD,oBAAC,kBAAD;MAAkB,QAAQ,MAAM;MAAO,SAAS;KAAY,CAAA;IACvD;GACF,CAAA,CAAA;;CACJ,CAAA;AAET"}
|
|
@@ -47,7 +47,7 @@ function SelectField({ component }) {
|
|
|
47
47
|
className: "border-input dark:bg-input/30 focus-visible:ring-ring/50 h-9 w-full rounded-md border bg-transparent px-3 text-sm shadow-xs outline-none focus-visible:ring-[3px]",
|
|
48
48
|
children: [component.selectablePlaceholder && /* @__PURE__ */ jsx("option", {
|
|
49
49
|
value: "",
|
|
50
|
-
children: component.placeholder ?? ""
|
|
50
|
+
children: component.placeholder ?? t("select_option", {}, "Select an option")
|
|
51
51
|
}), component.options.map((option) => isOptionGroup(option) ? /* @__PURE__ */ jsx("optgroup", {
|
|
52
52
|
label: option.label,
|
|
53
53
|
children: option.options.map((item) => /* @__PURE__ */ jsx("option", {
|
|
@@ -79,7 +79,7 @@ function SelectField({ component }) {
|
|
|
79
79
|
...aria,
|
|
80
80
|
"aria-readonly": readOnly || void 0,
|
|
81
81
|
className: "w-full",
|
|
82
|
-
children: /* @__PURE__ */ jsx(SelectValue, { placeholder: component.placeholder ?? "" })
|
|
82
|
+
children: /* @__PURE__ */ jsx(SelectValue, { placeholder: component.placeholder ?? t("select_option", {}, "Select an option") })
|
|
83
83
|
}), /* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
84
84
|
component.selectablePlaceholder && value !== null && value !== void 0 && value !== "" && /* @__PURE__ */ jsx(SelectItem, {
|
|
85
85
|
value: "__none__",
|
|
@@ -280,7 +280,7 @@ function ComboboxSelect({ component, value, setValue, id, disabled, readOnly, er
|
|
|
280
280
|
disabled: disabled || readOnly,
|
|
281
281
|
className: cn("h-auto min-h-9 w-full justify-between px-3 py-1.5 font-normal hover:bg-transparent", error && "border-destructive"),
|
|
282
282
|
children: [/* @__PURE__ */ jsxs("span", {
|
|
283
|
-
className: "flex flex-1 flex-wrap items-center gap-1 text-start",
|
|
283
|
+
className: "flex min-w-0 flex-1 flex-wrap items-center gap-1 text-start",
|
|
284
284
|
children: [
|
|
285
285
|
selected.length === 0 && /* @__PURE__ */ jsx("span", {
|
|
286
286
|
className: "text-muted-foreground",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","names":[],"sources":["../../../src/components/fields/select.tsx"],"sourcesContent":["import type { FieldAriaAttributes, Option, OptionOrGroup, SelectSchema } from '@alfakit/core'\nimport { htmlLabelToText, isOptionGroup, moveListItem, reorderOffset } from '@alfakit/core'\nimport { CheckIcon, ChevronsUpDownIcon, GripVerticalIcon, XIcon } from 'lucide-react'\nimport { useEffect, useMemo, useRef, useState, type KeyboardEvent, type ReactNode } from 'react'\nimport { useDirection, useT } from '../../context'\nimport { textColorClasses } from '../../lib/colors'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport { useField, useFormStore } from '../form/form-context'\nimport { FieldWrapper } from '../schema/field-wrapper'\nimport { Badge } from '../ui/badge'\nimport { Button } from '../ui/button'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '../ui/command'\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from '../ui/select'\nimport { Spinner } from '../ui/spinner'\n\nfunction flatten(options: OptionOrGroup[]): Option[] {\n return options.flatMap((option) => (isOptionGroup(option) ? option.options : [option]))\n}\n\n/** Text of an option label for places that can't show markup (`allowHtml()` labels). */\nfunction plainLabel(component: SelectSchema, label: string): string {\n return component.allowHtml ? htmlLabelToText(label) : label\n}\n\nexport function SelectField({ component }: { component: SelectSchema }) {\n const t = useT()\n const noOptions = component.noOptionsMessage ?? t('form.no_options', {}, 'No options available.')\n const { value, setValue, blur, error, id, disabled, readOnly, aria } = useField<\n string | number | Array<string | number> | null\n >(component)\n // Selects have no native read-only mode: lock the control and announce it as read-only.\n const locked = disabled || readOnly\n\n if (component.native && !component.multiple && !component.searchable) {\n return (\n <FieldWrapper field={component} htmlFor={id} error={error}>\n <SelectAffixes component={component} error={error}>\n <select\n id={id}\n name={component.name}\n value={value === null || value === undefined ? '' : String(value)}\n onChange={(event) => setValue(event.target.value === '' ? null : event.target.value)}\n onBlur={blur}\n disabled={locked}\n required={component.required}\n {...aria}\n aria-readonly={readOnly || undefined}\n className=\"border-input dark:bg-input/30 focus-visible:ring-ring/50 h-9 w-full rounded-md border bg-transparent px-3 text-sm shadow-xs outline-none focus-visible:ring-[3px]\"\n >\n {component.selectablePlaceholder && (\n <option value=\"\">{component.placeholder ?? ''}</option>\n )}\n {component.options.map((option) =>\n isOptionGroup(option) ? (\n <optgroup key={option.label} label={option.label}>\n {option.options.map((item) => (\n <option key={item.value} value={item.value} disabled={item.disabled}>\n {plainLabel(component, item.label)}\n </option>\n ))}\n </optgroup>\n ) : (\n <option key={option.value} value={option.value} disabled={option.disabled}>\n {plainLabel(component, option.label)}\n </option>\n ),\n )}\n </select>\n </SelectAffixes>\n </FieldWrapper>\n )\n }\n\n if (!component.multiple && !component.searchable) {\n return (\n <FieldWrapper field={component} htmlFor={id} error={error}>\n <SelectAffixes component={component} error={error}>\n <Select\n value={value === null || value === undefined ? '' : String(value)}\n onValueChange={(next) => setValue(next === '__none__' ? null : next)}\n disabled={locked}\n >\n <SelectTrigger\n id={id}\n {...aria}\n aria-readonly={readOnly || undefined}\n className=\"w-full\"\n >\n <SelectValue placeholder={component.placeholder ?? ''} />\n </SelectTrigger>\n <SelectContent>\n {component.selectablePlaceholder &&\n value !== null &&\n value !== undefined &&\n value !== '' && (\n <SelectItem value=\"__none__\" className=\"text-muted-foreground\">\n {component.placeholder ?? '—'}\n </SelectItem>\n )}\n {component.options.map((option) =>\n isOptionGroup(option) ? (\n <SelectGroup key={option.label}>\n <SelectLabel>{option.label}</SelectLabel>\n {option.options.map((item) => (\n <SelectItem key={item.value} value={item.value} disabled={item.disabled}>\n <OptionLabel option={item} component={component} />\n </SelectItem>\n ))}\n </SelectGroup>\n ) : (\n <SelectItem key={option.value} value={option.value} disabled={option.disabled}>\n <OptionLabel option={option} component={component} />\n </SelectItem>\n ),\n )}\n {component.options.length === 0 && (\n <div data-slot=\"select-empty\" className=\"text-muted-foreground px-2 py-1.5 text-sm\">\n {noOptions}\n </div>\n )}\n </SelectContent>\n </Select>\n </SelectAffixes>\n </FieldWrapper>\n )\n }\n\n return (\n <FieldWrapper field={component} htmlFor={id} error={error}>\n <SelectAffixes component={component} error={error}>\n <ComboboxSelect\n component={component}\n value={value}\n setValue={setValue}\n id={id}\n disabled={disabled}\n readOnly={readOnly}\n error={error}\n aria={aria}\n />\n </SelectAffixes>\n </FieldWrapper>\n )\n}\n\n/** Prefix/suffix text and icons around any of the select variants. */\nfunction SelectAffixes({\n component,\n error,\n children,\n}: {\n component: SelectSchema\n error?: string\n children: ReactNode\n}) {\n const hasPrefix = Boolean(component.prefix || component.prefixIcon)\n const hasSuffix = Boolean(component.suffix || component.suffixIcon)\n\n if (!hasPrefix && !hasSuffix) {\n return children\n }\n\n return (\n <div\n data-slot=\"input-group\"\n className={cn(\n 'border-input dark:bg-input/30 has-[:focus-visible]:border-ring has-[:focus-visible]:ring-ring/50 flex min-h-9 w-full items-stretch overflow-hidden rounded-md border shadow-xs has-[:focus-visible]:ring-[3px]',\n error && 'border-destructive',\n )}\n >\n {hasPrefix && (\n <span className=\"text-muted-foreground bg-muted/50 flex items-center gap-1 border-e px-3 text-sm whitespace-nowrap\">\n <Icon\n name={component.prefixIcon}\n className={component.prefixIconColor && textColorClasses[component.prefixIconColor]}\n />\n {component.prefix}\n </span>\n )}\n <div className=\"min-w-0 flex-1 *:h-full *:w-full *:rounded-none *:border-0 *:bg-transparent *:shadow-none *:focus-visible:ring-0 dark:*:bg-transparent\">\n {children}\n </div>\n {hasSuffix && (\n <span className=\"text-muted-foreground bg-muted/50 flex items-center gap-1 border-s px-3 text-sm whitespace-nowrap\">\n {component.suffix}\n <Icon\n name={component.suffixIcon}\n className={component.suffixIconColor && textColorClasses[component.suffixIconColor]}\n />\n </span>\n )}\n </div>\n )\n}\n\nfunction OptionLabel({ option, component }: { option: Option; component: SelectSchema }) {\n const wrap = component.wrapOptionLabels !== false\n\n return (\n <span className={cn('flex min-w-0 items-center gap-2', !wrap && 'max-w-full')}>\n {option.icon && <Icon name={option.icon} />}\n {component.allowHtml ? (\n <span\n data-slot=\"option-label\"\n className={cn(wrap ? 'break-words' : 'truncate')}\n dangerouslySetInnerHTML={{ __html: option.label }}\n />\n ) : (\n <span data-slot=\"option-label\" className={cn(wrap ? 'break-words' : 'truncate')}>\n {option.label}\n </span>\n )}\n {option.description && (\n <span className=\"text-muted-foreground text-xs\">{option.description}</span>\n )}\n </span>\n )\n}\n\ninterface ComboboxProps {\n component: SelectSchema\n value: string | number | Array<string | number> | null | undefined\n setValue: (value: string | number | Array<string | number> | null) => void\n id: string\n disabled: boolean\n readOnly: boolean\n error?: string\n aria: FieldAriaAttributes\n}\n\nfunction ComboboxSelect({\n component,\n value,\n setValue,\n id,\n disabled,\n readOnly,\n error,\n aria,\n}: ComboboxProps) {\n const t = useT()\n const store = useFormStore()\n const [open, setOpen] = useState(false)\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(false)\n const [remoteOptions, setRemoteOptions] = useState<Option[] | null>(null)\n const [labels, setLabels] = useState<Record<string, string>>(component.selectedLabels ?? {})\n const requestIdRef = useRef(0)\n // Values whose labels were already requested: the server may not know a value (deleted\n // record, stale state), so asking again on every render would loop forever.\n const requestedLabelsRef = useRef(new Set<string>())\n\n // Labels the server sends with a refresh win (e.g. after the edit option modal renamed\n // the selected record).\n const knownLabels = useMemo(\n () => ({ ...labels, ...component.selectedLabels }),\n [labels, component.selectedLabels],\n )\n\n const selected = useMemo<string[]>(\n () =>\n Array.isArray(value)\n ? value.map(String)\n : value === null || value === undefined || value === ''\n ? []\n : [String(value)],\n [value],\n )\n const staticOptions = useMemo(() => flatten(component.options), [component.options])\n const options = remoteOptions ?? staticOptions\n const isRemote = Boolean(component.searchable)\n\n // Debounced remote search: every keystroke restarts the timer and invalidates in-flight requests.\n useEffect(() => {\n if (!open || !isRemote) {\n return\n }\n\n const timer = setTimeout(() => {\n const current = ++requestIdRef.current\n setLoading(true)\n\n void store\n .searchOptions(component.statePath, search)\n .then((results) => {\n if (current === requestIdRef.current) {\n setRemoteOptions(results)\n }\n })\n .finally(() => {\n if (current === requestIdRef.current) {\n setLoading(false)\n }\n })\n }, component.searchDebounce ?? 300)\n\n return () => clearTimeout(timer)\n }, [open, search, isRemote, store, component.statePath, component.searchDebounce])\n\n // Resolve labels for values we have not seen yet (e.g. after a server refresh).\n useEffect(() => {\n if (!isRemote) {\n return\n }\n\n const missing = selected.filter(\n (key) =>\n !knownLabels[key] &&\n !requestedLabelsRef.current.has(key) &&\n !staticOptions.some((option) => option.value === key),\n )\n\n if (missing.length === 0) {\n return\n }\n\n for (const key of missing) {\n requestedLabelsRef.current.add(key)\n }\n\n void store\n .optionLabels(component.statePath, missing)\n .then((resolved) => setLabels((current) => ({ ...current, ...resolved })))\n }, [selected, knownLabels, staticOptions, isRemote, store, component.statePath])\n\n const labelFor = (key: string) =>\n knownLabels[key] ??\n options.find((option) => option.value === key)?.label ??\n staticOptions.find((option) => option.value === key)?.label ??\n key\n\n const toggle = (key: string, label: string) => {\n setLabels((current) => ({ ...current, [key]: label }))\n\n if (component.multiple) {\n const next = selected.includes(key)\n ? selected.filter((item) => item !== key)\n : [...selected, key]\n\n if (component.maxItems && next.length > component.maxItems) {\n return\n }\n\n // `minItems()`: the last required selections cannot be removed.\n if (component.minItems && next.length < selected.length && next.length < component.minItems) {\n return\n }\n\n setValue(next)\n } else {\n setValue(selected.includes(key) && component.selectablePlaceholder ? null : key)\n setOpen(false)\n }\n }\n\n const canRemove = !component.minItems || selected.length > component.minItems\n // `reorderable()`: chosen options are listed under the trigger, where they can be dragged\n // or moved with Alt + arrow keys (chips inside the trigger button can't hold controls).\n const reorderable = Boolean(component.multiple && component.reorderable)\n\n const filtered = isRemote\n ? options\n : options.filter((option) =>\n plainLabel(component, option.label).toLowerCase().includes(search.toLowerCase()),\n )\n // Nothing to choose from at all (not a search without matches).\n const isEmpty = search === '' && options.length === 0\n\n const popover = (\n <Popover\n open={open}\n onOpenChange={(next) => {\n setOpen(next)\n\n if (!next) {\n setSearch('')\n store.blur(component.statePath)\n }\n }}\n >\n <PopoverTrigger asChild>\n <Button\n id={id}\n type=\"button\"\n variant=\"outline\"\n data-input=\"\"\n role=\"combobox\"\n aria-expanded={open}\n {...aria}\n aria-readonly={readOnly || undefined}\n disabled={disabled || readOnly}\n className={cn(\n 'h-auto min-h-9 w-full justify-between px-3 py-1.5 font-normal hover:bg-transparent',\n error && 'border-destructive',\n )}\n >\n <span className=\"flex flex-1 flex-wrap items-center gap-1 text-start\">\n {selected.length === 0 && (\n <span className=\"text-muted-foreground\">\n {component.placeholder ?? t('select_option', {}, 'Select an option')}\n </span>\n )}\n {component.multiple && reorderable && selected.length > 0 && (\n <span className=\"text-muted-foreground\">\n {component.placeholder ?? t('select_option', {}, 'Select an option')}\n </span>\n )}\n {component.multiple\n ? !reorderable &&\n selected.map((key) => (\n <Badge key={key} variant=\"secondary\" className=\"gap-1 pe-1\">\n <SelectedLabel component={component} label={labelFor(key)} />\n {!readOnly && !disabled && canRemove && (\n <span\n role=\"button\"\n tabIndex={-1}\n aria-label={t('remove', {}, 'Remove')}\n className=\"hover:bg-foreground/10 rounded-sm\"\n onClick={(event) => {\n event.stopPropagation()\n setValue(selected.filter((item) => item !== key))\n }}\n >\n <XIcon className=\"size-3\" />\n </span>\n )}\n </Badge>\n ))\n : selected[0] !== undefined && (\n <SelectedLabel\n component={component}\n label={labelFor(selected[0])}\n className=\"truncate\"\n />\n )}\n </span>\n {loading ? (\n <Spinner className=\"opacity-50\" />\n ) : (\n <ChevronsUpDownIcon className=\"size-4 shrink-0 opacity-50\" />\n )}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-(--radix-popover-trigger-width) p-0\" align=\"start\">\n <Command shouldFilter={false}>\n <CommandInput\n placeholder={\n component.searchPrompt ?? t('form.search_placeholder', {}, 'Type to search…')\n }\n value={search}\n onValueChange={setSearch}\n />\n <CommandList>\n {loading && filtered.length === 0 ? (\n <div\n data-slot=\"select-loading\"\n className=\"text-muted-foreground flex items-center justify-center gap-2 py-6 text-sm\"\n >\n <Spinner />{' '}\n {search !== ''\n ? (component.searchingMessage ?? t('form.searching', {}, 'Searching…'))\n : (component.loadingMessage ?? t('loading', {}, 'Loading…'))}\n </div>\n ) : (\n <CommandEmpty>\n {isEmpty\n ? (component.noOptionsMessage ??\n t('form.no_options', {}, 'No options available.'))\n : (component.noSearchResultsMessage ?? t('no_results', {}, 'No results.'))}\n </CommandEmpty>\n )}\n <CommandGroup>\n {filtered.map((option) => {\n const isSelected = selected.includes(option.value)\n\n return (\n <CommandItem\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n onSelect={() => toggle(option.value, option.label)}\n >\n <CheckIcon className={cn('size-4', isSelected ? 'opacity-100' : 'opacity-0')} />\n <OptionLabel option={option} component={component} />\n </CommandItem>\n )\n })}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n )\n\n if (!reorderable) {\n return popover\n }\n\n return (\n <>\n {popover}\n <ReorderableSelection\n id={id}\n values={Array.isArray(value) ? value : []}\n labelFor={(key) => plainLabel(component, labelFor(key))}\n locked={disabled || readOnly}\n canRemove={canRemove}\n onChange={setValue}\n />\n </>\n )\n}\n\n/** The chosen options of a `reorderable()` multi-select, in order. */\nfunction ReorderableSelection({\n id,\n values,\n labelFor,\n locked,\n canRemove,\n onChange,\n}: {\n id: string\n values: Array<string | number>\n labelFor: (key: string) => string\n locked: boolean\n canRemove: boolean\n onChange: (values: Array<string | number>) => void\n}) {\n const t = useT()\n const direction = useDirection()\n const listRef = useRef<HTMLUListElement>(null)\n const focusIndex = useRef<number | null>(null)\n const [dragIndex, setDragIndex] = useState<number | null>(null)\n const [announcement, setAnnouncement] = useState('')\n\n useEffect(() => {\n if (focusIndex.current === null) {\n return\n }\n\n listRef.current\n ?.querySelectorAll<HTMLElement>('[data-select-chip]')\n [focusIndex.current]?.focus()\n focusIndex.current = null\n }, [values])\n\n if (values.length === 0) {\n return null\n }\n\n const move = (from: number, to: number) => {\n if (to < 0 || to >= values.length) {\n return\n }\n\n onChange(moveListItem(values, from, to))\n focusIndex.current = to\n setAnnouncement(\n t(\n 'form.option_moved',\n { option: labelFor(String(values[from])), position: to + 1, total: values.length },\n ':option moved to position :position of :total',\n ),\n )\n }\n\n const onKeyDown = (event: KeyboardEvent<HTMLElement>, index: number) => {\n const offset = reorderOffset(event, 'horizontal', direction)\n\n if (locked || offset === null) {\n return\n }\n\n event.preventDefault()\n move(index, index + offset)\n }\n\n return (\n <>\n <ul ref={listRef} data-slot=\"select-reorder-list\" className=\"mt-2 flex flex-wrap gap-1.5\">\n {values.map((item, index) => {\n const key = String(item)\n const label = labelFor(key)\n\n return (\n <li\n key={key}\n data-select-chip=\"\"\n tabIndex={locked ? undefined : 0}\n aria-describedby={locked ? undefined : `${id}-reorder-hint`}\n draggable={!locked}\n onKeyDown={(event) => onKeyDown(event, index)}\n onDragStart={() => setDragIndex(index)}\n onDragOver={(event) => !locked && event.preventDefault()}\n onDrop={() => {\n if (dragIndex !== null && dragIndex !== index) move(dragIndex, index)\n setDragIndex(null)\n }}\n onDragEnd={() => setDragIndex(null)}\n className={cn(\n 'bg-secondary text-secondary-foreground focus-visible:ring-ring/50 inline-flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-xs font-medium outline-none focus-visible:ring-[3px]',\n !locked && 'cursor-grab',\n dragIndex === index && 'opacity-50',\n )}\n >\n {!locked && <GripVerticalIcon aria-hidden className=\"text-muted-foreground size-3\" />}\n <span>{label}</span>\n {!locked && canRemove && (\n <button\n type=\"button\"\n aria-label={t('form.remove_tag', { tag: label }, 'Remove :tag')}\n className=\"hover:bg-foreground/10 rounded-sm\"\n onClick={() => onChange(values.filter((_, i) => i !== index))}\n >\n <XIcon className=\"size-3\" />\n </button>\n )}\n </li>\n )\n })}\n </ul>\n {!locked && (\n <span id={`${id}-reorder-hint`} className=\"sr-only\">\n {t('form.reorder_options_hint', {}, 'Press Alt with an arrow key to move this option.')}\n </span>\n )}\n <span aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {announcement}\n </span>\n </>\n )\n}\n\n/** A selected value's label in the trigger (HTML with `allowHtml()`). */\nfunction SelectedLabel({\n component,\n label,\n className,\n}: {\n component: SelectSchema\n label: string\n className?: string\n}) {\n return component.allowHtml ? (\n <span className={className} dangerouslySetInnerHTML={{ __html: label }} />\n ) : (\n <span className={className}>{label}</span>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"select.js","names":[],"sources":["../../../src/components/fields/select.tsx"],"sourcesContent":["import type { FieldAriaAttributes, Option, OptionOrGroup, SelectSchema } from '@alfakit/core'\nimport { htmlLabelToText, isOptionGroup, moveListItem, reorderOffset } from '@alfakit/core'\nimport { CheckIcon, ChevronsUpDownIcon, GripVerticalIcon, XIcon } from 'lucide-react'\nimport { useEffect, useMemo, useRef, useState, type KeyboardEvent, type ReactNode } from 'react'\nimport { useDirection, useT } from '../../context'\nimport { textColorClasses } from '../../lib/colors'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport { useField, useFormStore } from '../form/form-context'\nimport { FieldWrapper } from '../schema/field-wrapper'\nimport { Badge } from '../ui/badge'\nimport { Button } from '../ui/button'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '../ui/command'\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from '../ui/select'\nimport { Spinner } from '../ui/spinner'\n\nfunction flatten(options: OptionOrGroup[]): Option[] {\n return options.flatMap((option) => (isOptionGroup(option) ? option.options : [option]))\n}\n\n/** Text of an option label for places that can't show markup (`allowHtml()` labels). */\nfunction plainLabel(component: SelectSchema, label: string): string {\n return component.allowHtml ? htmlLabelToText(label) : label\n}\n\nexport function SelectField({ component }: { component: SelectSchema }) {\n const t = useT()\n const noOptions = component.noOptionsMessage ?? t('form.no_options', {}, 'No options available.')\n const { value, setValue, blur, error, id, disabled, readOnly, aria } = useField<\n string | number | Array<string | number> | null\n >(component)\n // Selects have no native read-only mode: lock the control and announce it as read-only.\n const locked = disabled || readOnly\n\n if (component.native && !component.multiple && !component.searchable) {\n return (\n <FieldWrapper field={component} htmlFor={id} error={error}>\n <SelectAffixes component={component} error={error}>\n <select\n id={id}\n name={component.name}\n value={value === null || value === undefined ? '' : String(value)}\n onChange={(event) => setValue(event.target.value === '' ? null : event.target.value)}\n onBlur={blur}\n disabled={locked}\n required={component.required}\n {...aria}\n aria-readonly={readOnly || undefined}\n className=\"border-input dark:bg-input/30 focus-visible:ring-ring/50 h-9 w-full rounded-md border bg-transparent px-3 text-sm shadow-xs outline-none focus-visible:ring-[3px]\"\n >\n {component.selectablePlaceholder && (\n <option value=\"\">\n {component.placeholder ?? t('select_option', {}, 'Select an option')}\n </option>\n )}\n {component.options.map((option) =>\n isOptionGroup(option) ? (\n <optgroup key={option.label} label={option.label}>\n {option.options.map((item) => (\n <option key={item.value} value={item.value} disabled={item.disabled}>\n {plainLabel(component, item.label)}\n </option>\n ))}\n </optgroup>\n ) : (\n <option key={option.value} value={option.value} disabled={option.disabled}>\n {plainLabel(component, option.label)}\n </option>\n ),\n )}\n </select>\n </SelectAffixes>\n </FieldWrapper>\n )\n }\n\n if (!component.multiple && !component.searchable) {\n return (\n <FieldWrapper field={component} htmlFor={id} error={error}>\n <SelectAffixes component={component} error={error}>\n <Select\n value={value === null || value === undefined ? '' : String(value)}\n onValueChange={(next) => setValue(next === '__none__' ? null : next)}\n disabled={locked}\n >\n <SelectTrigger\n id={id}\n {...aria}\n aria-readonly={readOnly || undefined}\n className=\"w-full\"\n >\n <SelectValue\n placeholder={component.placeholder ?? t('select_option', {}, 'Select an option')}\n />\n </SelectTrigger>\n <SelectContent>\n {component.selectablePlaceholder &&\n value !== null &&\n value !== undefined &&\n value !== '' && (\n <SelectItem value=\"__none__\" className=\"text-muted-foreground\">\n {component.placeholder ?? '—'}\n </SelectItem>\n )}\n {component.options.map((option) =>\n isOptionGroup(option) ? (\n <SelectGroup key={option.label}>\n <SelectLabel>{option.label}</SelectLabel>\n {option.options.map((item) => (\n <SelectItem key={item.value} value={item.value} disabled={item.disabled}>\n <OptionLabel option={item} component={component} />\n </SelectItem>\n ))}\n </SelectGroup>\n ) : (\n <SelectItem key={option.value} value={option.value} disabled={option.disabled}>\n <OptionLabel option={option} component={component} />\n </SelectItem>\n ),\n )}\n {component.options.length === 0 && (\n <div data-slot=\"select-empty\" className=\"text-muted-foreground px-2 py-1.5 text-sm\">\n {noOptions}\n </div>\n )}\n </SelectContent>\n </Select>\n </SelectAffixes>\n </FieldWrapper>\n )\n }\n\n return (\n <FieldWrapper field={component} htmlFor={id} error={error}>\n <SelectAffixes component={component} error={error}>\n <ComboboxSelect\n component={component}\n value={value}\n setValue={setValue}\n id={id}\n disabled={disabled}\n readOnly={readOnly}\n error={error}\n aria={aria}\n />\n </SelectAffixes>\n </FieldWrapper>\n )\n}\n\n/** Prefix/suffix text and icons around any of the select variants. */\nfunction SelectAffixes({\n component,\n error,\n children,\n}: {\n component: SelectSchema\n error?: string\n children: ReactNode\n}) {\n const hasPrefix = Boolean(component.prefix || component.prefixIcon)\n const hasSuffix = Boolean(component.suffix || component.suffixIcon)\n\n if (!hasPrefix && !hasSuffix) {\n return children\n }\n\n return (\n <div\n data-slot=\"input-group\"\n className={cn(\n 'border-input dark:bg-input/30 has-[:focus-visible]:border-ring has-[:focus-visible]:ring-ring/50 flex min-h-9 w-full items-stretch overflow-hidden rounded-md border shadow-xs has-[:focus-visible]:ring-[3px]',\n error && 'border-destructive',\n )}\n >\n {hasPrefix && (\n <span className=\"text-muted-foreground bg-muted/50 flex items-center gap-1 border-e px-3 text-sm whitespace-nowrap\">\n <Icon\n name={component.prefixIcon}\n className={component.prefixIconColor && textColorClasses[component.prefixIconColor]}\n />\n {component.prefix}\n </span>\n )}\n <div className=\"min-w-0 flex-1 *:h-full *:w-full *:rounded-none *:border-0 *:bg-transparent *:shadow-none *:focus-visible:ring-0 dark:*:bg-transparent\">\n {children}\n </div>\n {hasSuffix && (\n <span className=\"text-muted-foreground bg-muted/50 flex items-center gap-1 border-s px-3 text-sm whitespace-nowrap\">\n {component.suffix}\n <Icon\n name={component.suffixIcon}\n className={component.suffixIconColor && textColorClasses[component.suffixIconColor]}\n />\n </span>\n )}\n </div>\n )\n}\n\nfunction OptionLabel({ option, component }: { option: Option; component: SelectSchema }) {\n const wrap = component.wrapOptionLabels !== false\n\n return (\n <span className={cn('flex min-w-0 items-center gap-2', !wrap && 'max-w-full')}>\n {option.icon && <Icon name={option.icon} />}\n {component.allowHtml ? (\n <span\n data-slot=\"option-label\"\n className={cn(wrap ? 'break-words' : 'truncate')}\n dangerouslySetInnerHTML={{ __html: option.label }}\n />\n ) : (\n <span data-slot=\"option-label\" className={cn(wrap ? 'break-words' : 'truncate')}>\n {option.label}\n </span>\n )}\n {option.description && (\n <span className=\"text-muted-foreground text-xs\">{option.description}</span>\n )}\n </span>\n )\n}\n\ninterface ComboboxProps {\n component: SelectSchema\n value: string | number | Array<string | number> | null | undefined\n setValue: (value: string | number | Array<string | number> | null) => void\n id: string\n disabled: boolean\n readOnly: boolean\n error?: string\n aria: FieldAriaAttributes\n}\n\nfunction ComboboxSelect({\n component,\n value,\n setValue,\n id,\n disabled,\n readOnly,\n error,\n aria,\n}: ComboboxProps) {\n const t = useT()\n const store = useFormStore()\n const [open, setOpen] = useState(false)\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(false)\n const [remoteOptions, setRemoteOptions] = useState<Option[] | null>(null)\n const [labels, setLabels] = useState<Record<string, string>>(component.selectedLabels ?? {})\n const requestIdRef = useRef(0)\n // Values whose labels were already requested: the server may not know a value (deleted\n // record, stale state), so asking again on every render would loop forever.\n const requestedLabelsRef = useRef(new Set<string>())\n\n // Labels the server sends with a refresh win (e.g. after the edit option modal renamed\n // the selected record).\n const knownLabels = useMemo(\n () => ({ ...labels, ...component.selectedLabels }),\n [labels, component.selectedLabels],\n )\n\n const selected = useMemo<string[]>(\n () =>\n Array.isArray(value)\n ? value.map(String)\n : value === null || value === undefined || value === ''\n ? []\n : [String(value)],\n [value],\n )\n const staticOptions = useMemo(() => flatten(component.options), [component.options])\n const options = remoteOptions ?? staticOptions\n const isRemote = Boolean(component.searchable)\n\n // Debounced remote search: every keystroke restarts the timer and invalidates in-flight requests.\n useEffect(() => {\n if (!open || !isRemote) {\n return\n }\n\n const timer = setTimeout(() => {\n const current = ++requestIdRef.current\n setLoading(true)\n\n void store\n .searchOptions(component.statePath, search)\n .then((results) => {\n if (current === requestIdRef.current) {\n setRemoteOptions(results)\n }\n })\n .finally(() => {\n if (current === requestIdRef.current) {\n setLoading(false)\n }\n })\n }, component.searchDebounce ?? 300)\n\n return () => clearTimeout(timer)\n }, [open, search, isRemote, store, component.statePath, component.searchDebounce])\n\n // Resolve labels for values we have not seen yet (e.g. after a server refresh).\n useEffect(() => {\n if (!isRemote) {\n return\n }\n\n const missing = selected.filter(\n (key) =>\n !knownLabels[key] &&\n !requestedLabelsRef.current.has(key) &&\n !staticOptions.some((option) => option.value === key),\n )\n\n if (missing.length === 0) {\n return\n }\n\n for (const key of missing) {\n requestedLabelsRef.current.add(key)\n }\n\n void store\n .optionLabels(component.statePath, missing)\n .then((resolved) => setLabels((current) => ({ ...current, ...resolved })))\n }, [selected, knownLabels, staticOptions, isRemote, store, component.statePath])\n\n const labelFor = (key: string) =>\n knownLabels[key] ??\n options.find((option) => option.value === key)?.label ??\n staticOptions.find((option) => option.value === key)?.label ??\n key\n\n const toggle = (key: string, label: string) => {\n setLabels((current) => ({ ...current, [key]: label }))\n\n if (component.multiple) {\n const next = selected.includes(key)\n ? selected.filter((item) => item !== key)\n : [...selected, key]\n\n if (component.maxItems && next.length > component.maxItems) {\n return\n }\n\n // `minItems()`: the last required selections cannot be removed.\n if (component.minItems && next.length < selected.length && next.length < component.minItems) {\n return\n }\n\n setValue(next)\n } else {\n setValue(selected.includes(key) && component.selectablePlaceholder ? null : key)\n setOpen(false)\n }\n }\n\n const canRemove = !component.minItems || selected.length > component.minItems\n // `reorderable()`: chosen options are listed under the trigger, where they can be dragged\n // or moved with Alt + arrow keys (chips inside the trigger button can't hold controls).\n const reorderable = Boolean(component.multiple && component.reorderable)\n\n const filtered = isRemote\n ? options\n : options.filter((option) =>\n plainLabel(component, option.label).toLowerCase().includes(search.toLowerCase()),\n )\n // Nothing to choose from at all (not a search without matches).\n const isEmpty = search === '' && options.length === 0\n\n const popover = (\n <Popover\n open={open}\n onOpenChange={(next) => {\n setOpen(next)\n\n if (!next) {\n setSearch('')\n store.blur(component.statePath)\n }\n }}\n >\n <PopoverTrigger asChild>\n <Button\n id={id}\n type=\"button\"\n variant=\"outline\"\n data-input=\"\"\n role=\"combobox\"\n aria-expanded={open}\n {...aria}\n aria-readonly={readOnly || undefined}\n disabled={disabled || readOnly}\n className={cn(\n 'h-auto min-h-9 w-full justify-between px-3 py-1.5 font-normal hover:bg-transparent',\n error && 'border-destructive',\n )}\n >\n <span className=\"flex min-w-0 flex-1 flex-wrap items-center gap-1 text-start\">\n {selected.length === 0 && (\n <span className=\"text-muted-foreground\">\n {component.placeholder ?? t('select_option', {}, 'Select an option')}\n </span>\n )}\n {component.multiple && reorderable && selected.length > 0 && (\n <span className=\"text-muted-foreground\">\n {component.placeholder ?? t('select_option', {}, 'Select an option')}\n </span>\n )}\n {component.multiple\n ? !reorderable &&\n selected.map((key) => (\n <Badge key={key} variant=\"secondary\" className=\"gap-1 pe-1\">\n <SelectedLabel component={component} label={labelFor(key)} />\n {!readOnly && !disabled && canRemove && (\n <span\n role=\"button\"\n tabIndex={-1}\n aria-label={t('remove', {}, 'Remove')}\n className=\"hover:bg-foreground/10 rounded-sm\"\n onClick={(event) => {\n event.stopPropagation()\n setValue(selected.filter((item) => item !== key))\n }}\n >\n <XIcon className=\"size-3\" />\n </span>\n )}\n </Badge>\n ))\n : selected[0] !== undefined && (\n <SelectedLabel\n component={component}\n label={labelFor(selected[0])}\n className=\"truncate\"\n />\n )}\n </span>\n {loading ? (\n <Spinner className=\"opacity-50\" />\n ) : (\n <ChevronsUpDownIcon className=\"size-4 shrink-0 opacity-50\" />\n )}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-(--radix-popover-trigger-width) p-0\" align=\"start\">\n <Command shouldFilter={false}>\n <CommandInput\n placeholder={\n component.searchPrompt ?? t('form.search_placeholder', {}, 'Type to search…')\n }\n value={search}\n onValueChange={setSearch}\n />\n <CommandList>\n {loading && filtered.length === 0 ? (\n <div\n data-slot=\"select-loading\"\n className=\"text-muted-foreground flex items-center justify-center gap-2 py-6 text-sm\"\n >\n <Spinner />{' '}\n {search !== ''\n ? (component.searchingMessage ?? t('form.searching', {}, 'Searching…'))\n : (component.loadingMessage ?? t('loading', {}, 'Loading…'))}\n </div>\n ) : (\n <CommandEmpty>\n {isEmpty\n ? (component.noOptionsMessage ??\n t('form.no_options', {}, 'No options available.'))\n : (component.noSearchResultsMessage ?? t('no_results', {}, 'No results.'))}\n </CommandEmpty>\n )}\n <CommandGroup>\n {filtered.map((option) => {\n const isSelected = selected.includes(option.value)\n\n return (\n <CommandItem\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n onSelect={() => toggle(option.value, option.label)}\n >\n <CheckIcon className={cn('size-4', isSelected ? 'opacity-100' : 'opacity-0')} />\n <OptionLabel option={option} component={component} />\n </CommandItem>\n )\n })}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n )\n\n if (!reorderable) {\n return popover\n }\n\n return (\n <>\n {popover}\n <ReorderableSelection\n id={id}\n values={Array.isArray(value) ? value : []}\n labelFor={(key) => plainLabel(component, labelFor(key))}\n locked={disabled || readOnly}\n canRemove={canRemove}\n onChange={setValue}\n />\n </>\n )\n}\n\n/** The chosen options of a `reorderable()` multi-select, in order. */\nfunction ReorderableSelection({\n id,\n values,\n labelFor,\n locked,\n canRemove,\n onChange,\n}: {\n id: string\n values: Array<string | number>\n labelFor: (key: string) => string\n locked: boolean\n canRemove: boolean\n onChange: (values: Array<string | number>) => void\n}) {\n const t = useT()\n const direction = useDirection()\n const listRef = useRef<HTMLUListElement>(null)\n const focusIndex = useRef<number | null>(null)\n const [dragIndex, setDragIndex] = useState<number | null>(null)\n const [announcement, setAnnouncement] = useState('')\n\n useEffect(() => {\n if (focusIndex.current === null) {\n return\n }\n\n listRef.current\n ?.querySelectorAll<HTMLElement>('[data-select-chip]')\n [focusIndex.current]?.focus()\n focusIndex.current = null\n }, [values])\n\n if (values.length === 0) {\n return null\n }\n\n const move = (from: number, to: number) => {\n if (to < 0 || to >= values.length) {\n return\n }\n\n onChange(moveListItem(values, from, to))\n focusIndex.current = to\n setAnnouncement(\n t(\n 'form.option_moved',\n { option: labelFor(String(values[from])), position: to + 1, total: values.length },\n ':option moved to position :position of :total',\n ),\n )\n }\n\n const onKeyDown = (event: KeyboardEvent<HTMLElement>, index: number) => {\n const offset = reorderOffset(event, 'horizontal', direction)\n\n if (locked || offset === null) {\n return\n }\n\n event.preventDefault()\n move(index, index + offset)\n }\n\n return (\n <>\n <ul ref={listRef} data-slot=\"select-reorder-list\" className=\"mt-2 flex flex-wrap gap-1.5\">\n {values.map((item, index) => {\n const key = String(item)\n const label = labelFor(key)\n\n return (\n <li\n key={key}\n data-select-chip=\"\"\n tabIndex={locked ? undefined : 0}\n aria-describedby={locked ? undefined : `${id}-reorder-hint`}\n draggable={!locked}\n onKeyDown={(event) => onKeyDown(event, index)}\n onDragStart={() => setDragIndex(index)}\n onDragOver={(event) => !locked && event.preventDefault()}\n onDrop={() => {\n if (dragIndex !== null && dragIndex !== index) move(dragIndex, index)\n setDragIndex(null)\n }}\n onDragEnd={() => setDragIndex(null)}\n className={cn(\n 'bg-secondary text-secondary-foreground focus-visible:ring-ring/50 inline-flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-xs font-medium outline-none focus-visible:ring-[3px]',\n !locked && 'cursor-grab',\n dragIndex === index && 'opacity-50',\n )}\n >\n {!locked && <GripVerticalIcon aria-hidden className=\"text-muted-foreground size-3\" />}\n <span>{label}</span>\n {!locked && canRemove && (\n <button\n type=\"button\"\n aria-label={t('form.remove_tag', { tag: label }, 'Remove :tag')}\n className=\"hover:bg-foreground/10 rounded-sm\"\n onClick={() => onChange(values.filter((_, i) => i !== index))}\n >\n <XIcon className=\"size-3\" />\n </button>\n )}\n </li>\n )\n })}\n </ul>\n {!locked && (\n <span id={`${id}-reorder-hint`} className=\"sr-only\">\n {t('form.reorder_options_hint', {}, 'Press Alt with an arrow key to move this option.')}\n </span>\n )}\n <span aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {announcement}\n </span>\n </>\n )\n}\n\n/** A selected value's label in the trigger (HTML with `allowHtml()`). */\nfunction SelectedLabel({\n component,\n label,\n className,\n}: {\n component: SelectSchema\n label: string\n className?: string\n}) {\n return component.allowHtml ? (\n <span className={className} dangerouslySetInnerHTML={{ __html: label }} />\n ) : (\n <span className={className}>{label}</span>\n )\n}\n"],"mappings":"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"}
|
|
@@ -207,7 +207,7 @@ function FileManagerView({ schema, onChoose, onCancel }) {
|
|
|
207
207
|
}),
|
|
208
208
|
/* @__PURE__ */ jsx("nav", {
|
|
209
209
|
"aria-label": tt("breadcrumb", {}, "Folder path"),
|
|
210
|
-
className: "min-w-0 flex-
|
|
210
|
+
className: "min-w-0 flex-[1_1_12rem]",
|
|
211
211
|
"data-slot": "file-manager-breadcrumb",
|
|
212
212
|
children: /* @__PURE__ */ jsxs("ol", {
|
|
213
213
|
className: "flex min-w-0 flex-wrap items-center gap-1 text-sm",
|