rich-react-component 0.2.0 → 0.3.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/LICENSE +21 -21
- package/README.md +314 -120
- package/dist/base/Appearance.d.ts +116 -0
- package/dist/base/AppearanceMenu.d.ts +65 -0
- package/dist/base/Badge.d.ts +8 -1
- package/dist/base/Button.d.ts +9 -1
- package/dist/base/Sidebar.d.ts +111 -21
- package/dist/base/Tag.d.ts +4 -2
- package/dist/base/Tooltip.d.ts +8 -1
- package/dist/base/appearanceSchemes.d.ts +92 -0
- package/dist/base/index.d.ts +4 -0
- package/dist/base/sidebarModel.d.ts +171 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -15
- package/dist/index.js +2211 -1333
- package/dist/index.js.map +1 -1
- package/dist/style.css +1 -0
- package/package.json +72 -68
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/base/shared/classNames.ts","../src/base/shared/Label.tsx","../src/base/shared/ValidationMessage.tsx","../src/base/shared/FieldShell.tsx","../src/base/shared/useControllableState.ts","../src/base/Input.tsx","../src/base/TextArea.tsx","../src/base/NumberInput.tsx","../src/base/PasswordInput.tsx","../src/base/FileInput.tsx","../src/base/shared/BooleanFieldControl.tsx","../src/base/CheckBox.tsx","../src/base/Switch.tsx","../src/base/RadioButton.tsx","../src/base/RadioGroup.tsx","../src/base/Select.tsx","../src/base/shared/useEscapeKey.ts","../src/base/shared/Popup.tsx","../src/base/shared/useListNavigation.ts","../src/base/MultiSelect.tsx","../src/base/DatePicker.tsx","../src/base/TimePicker.tsx","../src/base/DateTimePicker.tsx","../src/base/ComboBox.tsx","../src/base/AutoComplete.tsx","../src/base/FormField.tsx","../src/base/Modal.tsx","../src/base/Pagination.tsx","../src/base/DataGrid.tsx","../src/base/Spinner.tsx","../src/base/Button.tsx","../src/base/Alert.tsx","../src/base/Toast.tsx","../src/base/Confirm.tsx","../src/base/Badge.tsx","../src/base/Icon.tsx","../src/base/Tabs.tsx","../src/base/Accordion.tsx","../src/base/Tooltip.tsx","../src/base/Popover.tsx","../src/base/Skeleton.tsx","../src/base/Stack.tsx","../src/base/Text.tsx","../src/base/Card.tsx","../src/base/Divider.tsx","../src/base/Container.tsx","../src/base/Row.tsx","../src/base/Col.tsx","../src/base/Breadcrumb.tsx","../src/base/Menu.tsx","../src/base/Stepper.tsx","../src/base/Avatar.tsx","../src/base/Tag.tsx","../src/base/Slider.tsx","../src/base/Rating.tsx","../src/base/ProgressBar.tsx","../src/base/Navbar.tsx","../src/base/Sidebar.tsx","../src/base/PageHeader.tsx","../src/base/Flex.tsx","../src/base/IconButton.tsx","../src/base/ListItem.tsx","../src/base/Sparkline.tsx","../src/base/Statistic.tsx","../src/remote/http/HttpClient.ts","../src/remote/hooks/useRemoteData.ts","../src/remote/hooks/useDebouncedValue.ts","../src/remote/mapping.ts","../src/remote/RemoteComboBox.tsx","../src/remote/RemoteAutoComplete.tsx","../src/remote/RemoteDataGrid.tsx","../src/remote/RemoteSelect.tsx","../src/remote/RemoteMultiSelect.tsx","../src/smart/componentRegistry.ts","../src/smart/dataSourceRegistry.ts","../src/smart/actionRegistry.ts","../src/smart/useSmartField.ts","../src/smart/useSmartDependencies.ts","../src/smart/useSmartAction.ts","../src/smart/resolvers/comboBoxResolver.tsx","../src/smart/resolvers/dataGridResolver.tsx","../src/smart/resolvers/datePickerResolver.tsx","../src/smart/resolvers/inputResolver.tsx","../src/smart/resolvers/index.ts","../src/smart/SmartField.tsx","../src/smart/SmartForm.tsx","../src/smart/SmartAction.tsx","../src/smart/SmartActions.tsx"],"sourcesContent":["export function cx(...values: Array<string | false | null | undefined>): string {\n return values.filter(Boolean).join(\" \");\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./classNames\";\n\nexport interface LabelProps {\n htmlFor?: string;\n required?: boolean;\n className?: string;\n children: ReactNode;\n}\n\n/** Extracted out of FieldShell so it's independently usable (doc \"Form Infrastructure\" section). */\nexport function Label({ htmlFor, required, className, children }: LabelProps) {\n return (\n <label htmlFor={htmlFor} className={cx(\"form-label\", className)}>\n {children}\n {required && <span className=\"text-danger\"> *</span>}\n </label>\n );\n}\n","import { cx } from \"./classNames\";\n\nexport interface ValidationMessageProps {\n error?: string;\n helpText?: string;\n className?: string;\n}\n\n/**\n * Presentation only — owns no validation rules (doc section 10). Extracted\n * out of FieldShell so CheckBox/Switch (which don't use FieldShell's\n * `form-label` layout) can still reuse the identical error/help rendering.\n */\nexport function ValidationMessage({ error, helpText, className }: ValidationMessageProps) {\n if (error) return <div className={cx(\"invalid-feedback d-block\", className)}>{error}</div>;\n if (helpText) return <div className={cx(\"form-text\", className)}>{helpText}</div>;\n return null;\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./classNames\";\nimport { Label } from \"./Label\";\nimport { ValidationMessage } from \"./ValidationMessage\";\n\nexport interface FieldShellProps {\n id?: string;\n label?: string;\n required?: boolean;\n error?: string;\n helpText?: string;\n className?: string;\n children: ReactNode;\n}\n\n/**\n * Shared label / help-text / validation-message presentation wrapper reused\n * by every Base field that has that shape (Input, TextArea, NumberInput,\n * DatePicker, TimePicker, ComboBox, AutoComplete, Select, MultiSelect,\n * RadioGroup, DateTimePicker). CheckBox/Switch and DataGrid have a\n * genuinely different layout and intentionally don't use this (they reuse\n * ValidationMessage directly instead — see BooleanFieldControl).\n *\n * Bootstrap conventions (`form-label`, `invalid-feedback`, `form-text`) are\n * used directly rather than reinventing a styling layer (doc section 15).\n */\nexport function FieldShell({ id, label, required, error, helpText, className, children }: FieldShellProps) {\n return (\n <div className={cx(\"mb-3\", className)}>\n {label && (\n <Label htmlFor={id} required={required}>\n {label}\n </Label>\n )}\n {children}\n <ValidationMessage error={error} helpText={helpText} />\n </div>\n );\n}\n","import { useCallback, useRef, useState } from \"react\";\n\nexport interface ControllableStateOptions<T> {\n /** When defined, the component is controlled: this value always wins. */\n value?: T;\n defaultValue: T;\n onChange?: (value: T) => void;\n}\n\n/**\n * Single shared implementation of the library's controlled/uncontrolled policy\n * (doc section 14). Every Base form field composes this instead of\n * reimplementing its own controlled/uncontrolled logic.\n *\n * Policy: presence of `value !== undefined` on first render decides the mode\n * for the component's lifetime. Switching modes afterwards is a programmer\n * error and is flagged in development, mirroring React's own <input> warning.\n */\nexport function useControllableState<T>({\n value,\n defaultValue,\n onChange,\n}: ControllableStateOptions<T>): [T, (next: T) => void] {\n const isControlled = value !== undefined;\n const isControlledRef = useRef(isControlled);\n\n if (process.env.NODE_ENV !== \"production\" && isControlledRef.current !== isControlled) {\n // eslint-disable-next-line no-console\n console.error(\n \"[react-components] A component switched between controlled and uncontrolled `value`. \" +\n \"Decide between passing `value` (controlled) or `defaultValue` (uncontrolled) for the \" +\n \"lifetime of the component, per the library's controlled/uncontrolled policy.\"\n );\n }\n\n const [internalValue, setInternalValue] = useState<T>(defaultValue);\n const currentValue = isControlled ? (value as T) : internalValue;\n\n const setValue = useCallback(\n (next: T) => {\n if (!isControlled) {\n setInternalValue(next);\n }\n onChange?.(next);\n },\n [isControlled, onChange]\n );\n\n return [currentValue, setValue];\n}\n","import { useId, type FocusEventHandler, type InputHTMLAttributes, type ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { FieldShell } from \"./shared/FieldShell\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\n\ntype NativePassthroughProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"id\" | \"name\" | \"value\" | \"defaultValue\" | \"onChange\" | \"onBlur\" | \"className\" | \"disabled\" | \"readOnly\" | \"required\" | \"placeholder\"\n>;\n\nexport interface InputProps extends FieldIdentity, FieldState, FieldPresentation {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n onBlur?: FocusEventHandler<HTMLInputElement>;\n type?: \"text\" | \"email\" | \"password\" | \"tel\" | \"url\" | \"search\";\n maxLength?: number;\n autoFocus?: boolean;\n /**\n * Escape hatch for native attributes that don't deserve a first-class prop\n * on every text-like field (e.g. `inputMode`, `min`/`max`/`step`, `type`\n * override). Keeps the primary prop surface small (doc section 13) while\n * still letting NumberInput/DatePicker compose Input instead of\n * reimplementing it.\n */\n inputProps?: NativePassthroughProps;\n /**\n * Generic trailing slot rendered inside a Bootstrap `input-group` (e.g. a\n * visibility-toggle button, a unit suffix, a clear button). Not\n * password-specific — PasswordInput is just its first consumer, reusing\n * Input's full controlled-state/markup instead of reimplementing a\n * parallel text field (doc section 4/19).\n */\n endAdornment?: ReactNode;\n}\n\nexport function Input(props: InputProps) {\n const {\n id,\n name,\n disabled,\n readOnly,\n required,\n className,\n label,\n placeholder,\n helpText,\n error,\n value,\n defaultValue,\n onChange,\n onBlur,\n type = \"text\",\n maxLength,\n autoFocus,\n inputProps,\n endAdornment,\n } = props;\n\n const [currentValue, setValue] = useControllableState<string>({\n value,\n defaultValue: defaultValue ?? \"\",\n onChange,\n });\n\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n const control = (\n <input\n id={fieldId}\n name={name}\n className={cx(\"form-control\", error && \"is-invalid\")}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n placeholder={placeholder}\n maxLength={maxLength}\n autoFocus={autoFocus}\n value={currentValue}\n onChange={(event) => setValue(event.target.value)}\n onBlur={onBlur}\n type={type}\n {...inputProps}\n />\n );\n\n return (\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\n {endAdornment ? (\n <div className=\"input-group\">\n {control}\n {endAdornment}\n </div>\n ) : (\n control\n )}\n </FieldShell>\n );\n}\n","import { useId, type FocusEventHandler } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { FieldShell } from \"./shared/FieldShell\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\n\nexport interface TextAreaProps extends FieldIdentity, FieldState, FieldPresentation {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n onBlur?: FocusEventHandler<HTMLTextAreaElement>;\n rows?: number;\n maxLength?: number;\n}\n\nexport function TextArea(props: TextAreaProps) {\n const {\n id,\n name,\n disabled,\n readOnly,\n required,\n className,\n label,\n placeholder,\n helpText,\n error,\n value,\n defaultValue,\n onChange,\n onBlur,\n rows = 3,\n maxLength,\n } = props;\n\n const [currentValue, setValue] = useControllableState<string>({\n value,\n defaultValue: defaultValue ?? \"\",\n onChange,\n });\n\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n return (\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\n <textarea\n id={fieldId}\n name={name}\n className={cx(\"form-control\", error && \"is-invalid\")}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n placeholder={placeholder}\n rows={rows}\n maxLength={maxLength}\n value={currentValue}\n onChange={(event) => setValue(event.target.value)}\n onBlur={onBlur}\n />\n </FieldShell>\n );\n}\n","import type { FocusEventHandler } from \"react\";\nimport { Input } from \"./Input\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\n\nexport interface NumberInputProps extends FieldIdentity, FieldState, FieldPresentation {\n value?: number | null;\n defaultValue?: number | null;\n onChange?: (value: number | null) => void;\n onBlur?: FocusEventHandler<HTMLInputElement>;\n min?: number;\n max?: number;\n step?: number;\n}\n\n/**\n * Composes Input (the \"Input foundation\" from doc section 19) instead of\n * reimplementing field markup/controlled-state logic — only the numeric\n * value coercion is unique to NumberInput.\n */\nexport function NumberInput({ value, defaultValue, onChange, min, max, step, ...rest }: NumberInputProps) {\n const [currentValue, setValue] = useControllableState<number | null>({\n value,\n defaultValue: defaultValue ?? null,\n onChange,\n });\n\n return (\n <Input\n {...rest}\n value={currentValue === null ? \"\" : String(currentValue)}\n onChange={(raw) => {\n if (raw.trim() === \"\") {\n setValue(null);\n return;\n }\n const parsed = Number(raw);\n if (!Number.isNaN(parsed)) setValue(parsed);\n }}\n inputProps={{ inputMode: \"decimal\", min, max, step }}\n />\n );\n}\n","import { useState } from \"react\";\nimport { Input, type InputProps } from \"./Input\";\n\nexport interface PasswordInputProps extends Omit<InputProps, \"type\" | \"endAdornment\" | \"inputProps\"> {}\n\n/**\n * Reuses Input entirely (controlled/uncontrolled logic, FieldShell,\n * markup) via Input's `endAdornment`/`inputProps` extension points instead\n * of building an independent text field (doc section 4). No password\n * strength infrastructure — just visibility toggling.\n */\nexport function PasswordInput(props: PasswordInputProps) {\n const [visible, setVisible] = useState(false);\n\n return (\n <Input\n {...props}\n inputProps={{ type: visible ? \"text\" : \"password\", autoComplete: \"current-password\" }}\n endAdornment={\n <button\n type=\"button\"\n className=\"btn btn-outline-secondary\"\n aria-label={visible ? \"Hide password\" : \"Show password\"}\n aria-pressed={visible}\n onClick={() => setVisible((prev) => !prev)}\n >\n {visible ? \"Hide\" : \"Show\"}\n </button>\n }\n />\n );\n}\n","import { useId } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { FieldShell } from \"./shared/FieldShell\";\nimport type { FieldIdentity, FieldPresentation } from \"./shared/fieldTypes\";\n\nexport interface FileInputProps extends FieldIdentity, FieldPresentation {\n disabled?: boolean;\n required?: boolean;\n accept?: string;\n multiple?: boolean;\n onChange?: (files: FileList | null) => void;\n}\n\n/**\n * File selection only — no upload/API/cloud-storage/chunking (doc section\n * 11; that belongs to a future Remote-layer concern, not Base).\n *\n * Intentionally uncontrolled-only: browsers do not allow programmatically\n * setting `<input type=\"file\">`'s value for security reasons, so this is a\n * documented, deliberate exception to the library's controlled/uncontrolled\n * policy rather than an inconsistency — there is no `value`/`defaultValue`\n * to be controlled.\n */\nexport function FileInput({ id, name, disabled, required, className, label, helpText, error, accept, multiple, onChange }: FileInputProps) {\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n return (\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\n <input\n id={fieldId}\n name={name}\n type=\"file\"\n className={cx(\"form-control\", error && \"is-invalid\")}\n disabled={disabled}\n required={required}\n accept={accept}\n multiple={multiple}\n onChange={(event) => onChange?.(event.target.files)}\n />\n </FieldShell>\n );\n}\n","import { useId } from \"react\";\nimport { cx } from \"./classNames\";\nimport { ValidationMessage } from \"./ValidationMessage\";\nimport type { FieldIdentity } from \"./fieldTypes\";\n\nexport interface BooleanFieldControlProps extends FieldIdentity {\n disabled?: boolean;\n required?: boolean;\n className?: string;\n wrapperClassName: string;\n role?: string;\n label?: string;\n helpText?: string;\n error?: string;\n checked: boolean;\n onChange: (checked: boolean) => void;\n}\n\n/**\n * Internal-only shared rendering for CheckBox and Switch: their public APIs\n * are genuinely identical (checked/defaultChecked/onChange/label/error/\n * helpText) and their markup differs only by wrapper class + `role` (doc\n * section 8: \"reuse if semantically correct, but don't couple them through\n * an abstraction that makes either public API worse\" — this doesn't, since\n * both components keep their own separate, unchanged public props).\n */\nexport function BooleanFieldControl({\n id,\n name,\n disabled,\n required,\n wrapperClassName,\n role,\n label,\n helpText,\n error,\n checked,\n onChange,\n className,\n}: BooleanFieldControlProps) {\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n return (\n <div className={cx(wrapperClassName, className)}>\n <input\n id={fieldId}\n name={name}\n type=\"checkbox\"\n role={role}\n className={cx(\"form-check-input\", error && \"is-invalid\")}\n disabled={disabled}\n required={required}\n checked={checked}\n onChange={(event) => onChange(event.target.checked)}\n />\n {label && (\n <label htmlFor={fieldId} className=\"form-check-label\">\n {label}\n </label>\n )}\n <ValidationMessage error={error} helpText={helpText} />\n </div>\n );\n}\n","import { BooleanFieldControl } from \"./shared/BooleanFieldControl\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport type { FieldIdentity, FieldState } from \"./shared/fieldTypes\";\n\nexport interface CheckBoxProps extends FieldIdentity, FieldState {\n className?: string;\n label?: string;\n helpText?: string;\n error?: string;\n checked?: boolean;\n defaultChecked?: boolean;\n onChange?: (checked: boolean) => void;\n}\n\n/**\n * Deliberately doesn't use FieldShell — a checkbox's label sits beside the\n * control, not above it, so the layout genuinely differs (doc section 13:\n * shared contracts only where a real semantic relationship exists). Shares\n * its actual rendering with Switch via BooleanFieldControl.\n */\nexport function CheckBox(props: CheckBoxProps) {\n const [checked, setChecked] = useControllableState<boolean>({\n value: props.checked,\n defaultValue: props.defaultChecked ?? false,\n onChange: props.onChange,\n });\n\n return (\n <BooleanFieldControl\n id={props.id}\n name={props.name}\n disabled={props.disabled}\n required={props.required}\n className={props.className}\n wrapperClassName=\"form-check mb-3\"\n label={props.label}\n helpText={props.helpText}\n error={props.error}\n checked={checked}\n onChange={setChecked}\n />\n );\n}\n","import { BooleanFieldControl } from \"./shared/BooleanFieldControl\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport type { FieldIdentity, FieldState } from \"./shared/fieldTypes\";\n\nexport interface SwitchProps extends FieldIdentity, FieldState {\n className?: string;\n label?: string;\n helpText?: string;\n error?: string;\n checked?: boolean;\n defaultChecked?: boolean;\n onChange?: (checked: boolean) => void;\n}\n\n/**\n * Same controlled/uncontrolled boolean behavior as CheckBox, reused via\n * BooleanFieldControl — only the wrapper class (`form-switch`) and\n * `role=\"switch\"` differ (doc section 8).\n */\nexport function Switch(props: SwitchProps) {\n const [checked, setChecked] = useControllableState<boolean>({\n value: props.checked,\n defaultValue: props.defaultChecked ?? false,\n onChange: props.onChange,\n });\n\n return (\n <BooleanFieldControl\n id={props.id}\n name={props.name}\n disabled={props.disabled}\n required={props.required}\n className={props.className}\n wrapperClassName=\"form-check form-switch mb-3\"\n role=\"switch\"\n label={props.label}\n helpText={props.helpText}\n error={props.error}\n checked={checked}\n onChange={setChecked}\n />\n );\n}\n","import { useId } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface RadioButtonProps<TValue extends string | number = string> {\n id?: string;\n name?: string;\n value: TValue;\n label?: string;\n checked: boolean;\n disabled?: boolean;\n className?: string;\n onChange?: (value: TValue) => void;\n}\n\n/**\n * A single radio input. Always controlled by `checked` — a lone HTML radio\n * doesn't have meaningful independent uncontrolled state the way a\n * checkbox does (mutual exclusivity requires a group), so it's normally\n * composed by RadioGroup, which owns the actual controlled/uncontrolled\n * value. Usable standalone by a consumer who wants to manage state itself.\n */\nexport function RadioButton<TValue extends string | number = string>({\n id,\n name,\n value,\n label,\n checked,\n disabled,\n className,\n onChange,\n}: RadioButtonProps<TValue>) {\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n return (\n <div className={cx(\"form-check\", className)}>\n <input\n id={fieldId}\n name={name}\n type=\"radio\"\n className=\"form-check-input\"\n value={String(value)}\n checked={checked}\n disabled={disabled}\n onChange={() => onChange?.(value)}\n />\n {label && (\n <label htmlFor={fieldId} className=\"form-check-label\">\n {label}\n </label>\n )}\n </div>\n );\n}\n","import { useId } from \"react\";\nimport { RadioButton } from \"./RadioButton\";\nimport { cx } from \"./shared/classNames\";\nimport { FieldShell } from \"./shared/FieldShell\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport type { FieldIdentity, FieldPresentation, FieldState, SelectOption } from \"./shared/fieldTypes\";\n\nexport interface RadioGroupProps<TValue extends string | number = string> extends FieldIdentity, FieldState, FieldPresentation {\n options: SelectOption<TValue>[];\n value?: TValue | null;\n defaultValue?: TValue | null;\n onChange?: (value: TValue) => void;\n inline?: boolean;\n}\n\n/**\n * Composes RadioButton rather than reproducing radio rendering (doc\n * section 7) — this is the component that actually owns the group's\n * controlled/uncontrolled value.\n */\nexport function RadioGroup<TValue extends string | number = string>({\n options,\n value,\n defaultValue,\n onChange,\n inline,\n id,\n name,\n disabled,\n required,\n className,\n label,\n helpText,\n error,\n}: RadioGroupProps<TValue>) {\n const [currentValue, setValue] = useControllableState<TValue | null>({\n value,\n defaultValue: defaultValue ?? null,\n onChange: (next) => {\n if (next !== null) onChange?.(next);\n },\n });\n\n const generatedId = useId();\n const groupName = name ?? id ?? generatedId;\n\n return (\n <FieldShell label={label} required={required} error={error} helpText={helpText} className={className}>\n <div role=\"radiogroup\" aria-label={label} aria-required={required} className={cx(inline && \"d-flex gap-3\")}>\n {options.map((option) => (\n <RadioButton\n key={String(option.value)}\n name={groupName}\n value={option.value}\n label={option.label}\n checked={option.value === currentValue}\n disabled={disabled || option.disabled}\n onChange={(next) => setValue(next)}\n />\n ))}\n </div>\n </FieldShell>\n );\n}\n","import { useId } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { FieldShell } from \"./shared/FieldShell\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport type { FieldIdentity, FieldPresentation, FieldState, SelectOption } from \"./shared/fieldTypes\";\n\nexport interface SelectProps<TValue extends string | number = string> extends FieldIdentity, FieldState, FieldPresentation {\n options: SelectOption<TValue>[];\n value?: TValue | null;\n defaultValue?: TValue | null;\n onChange?: (value: TValue | null) => void;\n /**\n * Presentational-only loading flag, same convention as ComboBox/\n * AutoComplete/MultiSelect's `loading` prop — Select has no idea *why*\n * it's loading (doc section 8). Disables the control and shows a\n * \"Loading…\" placeholder option; set by RemoteSelect.\n */\n loading?: boolean;\n}\n\n/**\n * Not remote-aware (doc section 5). Deliberately a native `<select>` rather\n * than reusing ComboBox's Popup/keyboard-list UI — their UI semantics\n * genuinely differ (native select already has full built-in keyboard/\n * screen-reader support, so reusing Popup here would be a *regression*, not\n * a simplification). The two DO share the same typed option abstraction\n * (`SelectOption`) and the same FieldShell/useControllableState — that's\n * the \"smallest appropriate abstraction\" the doc asks for.\n */\nexport function Select<TValue extends string | number = string>({\n options,\n value,\n defaultValue,\n onChange,\n placeholder,\n loading,\n id,\n name,\n disabled,\n readOnly,\n required,\n className,\n label,\n helpText,\n error,\n}: SelectProps<TValue>) {\n const [currentValue, setValue] = useControllableState<TValue | null>({\n value,\n defaultValue: defaultValue ?? null,\n onChange,\n });\n\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n return (\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\n <select\n id={fieldId}\n name={name}\n className={cx(\"form-select\", error && \"is-invalid\")}\n disabled={disabled || readOnly || loading}\n required={required}\n value={currentValue === null ? \"\" : String(currentValue)}\n onChange={(event) => {\n const raw = event.target.value;\n if (raw === \"\") {\n setValue(null);\n return;\n }\n const matched = options.find((option) => String(option.value) === raw);\n setValue(matched ? matched.value : null);\n }}\n >\n {loading && <option value=\"\">Loading…</option>}\n {!loading && placeholder && <option value=\"\">{placeholder}</option>}\n {options.map((option) => (\n <option key={String(option.value)} value={String(option.value)} disabled={option.disabled}>\n {option.label}\n </option>\n ))}\n </select>\n </FieldShell>\n );\n}\n","import { useEffect } from \"react\";\n\n/** Shared by Popup and Modal so escape-to-close isn't reimplemented per component. */\nexport function useEscapeKey(active: boolean, onEscape: () => void): void {\n useEffect(() => {\n if (!active) return;\n function handleKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") onEscape();\n }\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [active, onEscape]);\n}\n","import { useEffect, useRef, type ReactNode, type RefObject } from \"react\";\nimport { cx } from \"./classNames\";\nimport { useEscapeKey } from \"./useEscapeKey\";\n\nexport interface PopupProps {\n open: boolean;\n onClose: () => void;\n anchorRef: RefObject<HTMLElement>;\n className?: string;\n /** ARIA role of the floating panel — callers set this (e.g. \"listbox\" for ComboBox, none for Tooltip/Popover). */\n role?: string;\n children: ReactNode;\n}\n\n/**\n * Anchored floating panel: open/close, escape-to-close, outside-click\n * dismissal, cleanup. Reused by ComboBox/AutoComplete/MultiSelect (as a\n * dropdown listbox) and by Tooltip/Popover (as a hover/click overlay) — so\n * it only forces Bootstrap's universal `show` visibility class; the\n * dropdown-specific (`dropdown-menu`) vs. tooltip/popover-specific\n * (`tooltip`, `popover`) presentation classes are each caller's own\n * responsibility via `className`.\n *\n * Known limitation (documented, not silently ignored): positioning is plain\n * CSS (`position: relative` on the anchor's wrapper), no portal/collision\n * detection yet. A portal-based strategy can be layered in later without\n * changing this component's public API.\n */\nexport function Popup({ open, onClose, anchorRef, className, role, children }: PopupProps) {\n const popupRef = useRef<HTMLDivElement>(null);\n\n useEscapeKey(open, onClose);\n\n useEffect(() => {\n if (!open) return;\n function handlePointerDown(event: MouseEvent) {\n const target = event.target as Node;\n if (popupRef.current?.contains(target)) return;\n if (anchorRef.current?.contains(target)) return;\n onClose();\n }\n document.addEventListener(\"mousedown\", handlePointerDown);\n return () => document.removeEventListener(\"mousedown\", handlePointerDown);\n }, [open, onClose, anchorRef]);\n\n if (!open) return null;\n\n return (\n <div ref={popupRef} className={cx(\"show\", className)} role={role}>\n {children}\n </div>\n );\n}\n","import { useCallback, useEffect, useState, type KeyboardEvent } from \"react\";\nimport { useEscapeKey } from \"./useEscapeKey\";\n\nexport interface UseListNavigationOptions {\n itemCount: number;\n isOpen: boolean;\n onSelect: (index: number) => void;\n onClose: () => void;\n}\n\nexport interface UseListNavigationResult {\n activeIndex: number;\n setActiveIndex: (index: number) => void;\n handleKeyDown: (event: KeyboardEvent) => void;\n}\n\n/**\n * Headless keyboard-navigation behavior shared by ComboBox and AutoComplete\n * (doc section 19 — \"shared behavior\" reuse for the list-selection concern\n * that both components genuinely have in common).\n */\nexport function useListNavigation({\n itemCount,\n isOpen,\n onSelect,\n onClose,\n}: UseListNavigationOptions): UseListNavigationResult {\n const [activeIndex, setActiveIndex] = useState(-1);\n\n useEffect(() => {\n if (!isOpen) setActiveIndex(-1);\n }, [isOpen]);\n\n useEscapeKey(isOpen, onClose);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (!isOpen) {\n if (event.key === \"ArrowDown\" || event.key === \"Enter\") {\n event.preventDefault();\n }\n return;\n }\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n setActiveIndex((prev) => (itemCount === 0 ? -1 : (prev + 1) % itemCount));\n break;\n case \"ArrowUp\":\n event.preventDefault();\n setActiveIndex((prev) => (itemCount === 0 ? -1 : (prev - 1 + itemCount) % itemCount));\n break;\n case \"Home\":\n event.preventDefault();\n setActiveIndex(itemCount === 0 ? -1 : 0);\n break;\n case \"End\":\n event.preventDefault();\n setActiveIndex(itemCount === 0 ? -1 : itemCount - 1);\n break;\n case \"Enter\":\n if (activeIndex >= 0) {\n event.preventDefault();\n onSelect(activeIndex);\n }\n break;\n default:\n break;\n }\n },\n [isOpen, itemCount, activeIndex, onSelect]\n );\n\n return { activeIndex, setActiveIndex, handleKeyDown };\n}\n","import { useCallback, useId, useRef, useState } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { FieldShell } from \"./shared/FieldShell\";\nimport { Popup } from \"./shared/Popup\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport { useListNavigation } from \"./shared/useListNavigation\";\nimport type { FieldIdentity, FieldPresentation, FieldState, SelectOption } from \"./shared/fieldTypes\";\n\nexport interface MultiSelectProps<TValue extends string | number = string> extends FieldIdentity, FieldState, FieldPresentation {\n options: SelectOption<TValue>[];\n values?: TValue[];\n defaultValues?: TValue[];\n onChange?: (values: TValue[]) => void;\n loading?: boolean;\n emptyText?: string;\n}\n\n/**\n * Follows ComboBox's established `options: SelectOption<TValue>[]` /\n * FieldShell / Popup / useListNavigation conventions rather than the raw\n * `items`+`valueMember`+`displayMember` shape shown as a *conceptual*\n * example in the source spec — that mapping-by-key convention belongs to\n * the Remote layer (where raw API objects need mapping); Base MultiSelect\n * receives already-typed `SelectOption`s, consistent with Base ComboBox.\n * (Documented in the final report as a deliberate reconciliation of the\n * spec's own two instructions: \"follow this example\" vs. \"follow ComboBox's\n * existing, good convention\" — the latter wins per the spec's own priority.)\n *\n * Reuses Popup + useListNavigation from ComboBox/AutoComplete; the only\n * real behavioral difference is that selecting an option toggles it in a\n * `values` array and leaves the popup open instead of closing it.\n */\nexport function MultiSelect<TValue extends string | number = string>({\n options,\n values,\n defaultValues,\n onChange,\n loading,\n emptyText = \"No options\",\n id,\n name,\n disabled,\n readOnly,\n required,\n className,\n label,\n placeholder = \"Select...\",\n helpText,\n error,\n}: MultiSelectProps<TValue>) {\n const [currentValues, setValues] = useControllableState<TValue[]>({\n value: values,\n defaultValue: defaultValues ?? [],\n onChange,\n });\n const [open, setOpen] = useState(false);\n const anchorRef = useRef<HTMLButtonElement>(null);\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n const selectedSet = new Set(currentValues);\n\n const close = useCallback(() => setOpen(false), []);\n const toggleIndex = useCallback(\n (index: number) => {\n const option = options[index];\n if (!option || option.disabled) return;\n const next = selectedSet.has(option.value)\n ? currentValues.filter((v) => v !== option.value)\n : [...currentValues, option.value];\n setValues(next);\n },\n [options, currentValues, selectedSet, setValues]\n );\n\n const { activeIndex, setActiveIndex, handleKeyDown } = useListNavigation({\n itemCount: options.length,\n isOpen: open,\n onSelect: toggleIndex,\n onClose: close,\n });\n\n const selectedOptions = options.filter((option) => selectedSet.has(option.value));\n const summary = selectedOptions.map((option) => option.label).join(\", \");\n\n return (\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\n <div className=\"position-relative\">\n <button\n ref={anchorRef}\n id={fieldId}\n type=\"button\"\n name={name}\n className={cx(\"form-select text-start\", error && \"is-invalid\")}\n disabled={disabled || readOnly}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n onClick={() => setOpen((prev) => !prev)}\n onKeyDown={handleKeyDown}\n >\n {summary || <span className=\"text-body-secondary\">{placeholder}</span>}\n </button>\n <Popup open={open} onClose={close} anchorRef={anchorRef} className=\"dropdown-menu w-100\" role=\"listbox\">\n {loading ? (\n <div className=\"px-3 py-2 text-body-secondary\">Loading…</div>\n ) : options.length === 0 ? (\n <div className=\"px-3 py-2 text-body-secondary\">{emptyText}</div>\n ) : (\n options.map((option, index) => (\n <div\n key={String(option.value)}\n role=\"option\"\n aria-selected={selectedSet.has(option.value)}\n className={cx(\n \"dropdown-item d-flex align-items-center gap-2\",\n index === activeIndex && \"active\",\n option.disabled && \"disabled\"\n )}\n onMouseEnter={() => setActiveIndex(index)}\n onMouseDown={(event) => {\n event.preventDefault();\n if (!option.disabled) toggleIndex(index);\n }}\n >\n <input type=\"checkbox\" className=\"form-check-input m-0\" checked={selectedSet.has(option.value)} readOnly tabIndex={-1} />\n {option.label}\n </div>\n ))\n )}\n </Popup>\n </div>\n </FieldShell>\n );\n}\n","import { Input } from \"./Input\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\n\nexport interface DatePickerProps extends FieldIdentity, FieldState, FieldPresentation {\n value?: Date | null;\n defaultValue?: Date | null;\n onChange?: (value: Date | null) => void;\n min?: Date;\n max?: Date;\n}\n\n/**\n * Exported so TimePicker/DateTimePicker can compose the exact same\n * date-part parsing/formatting instead of reimplementing it (doc section\n * 12 — a coherent Date/Time value strategy across the whole family).\n */\nexport function toDateInputValue(date: Date | null | undefined): string {\n if (!date) return \"\";\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n\nexport function fromDateInputValue(raw: string): Date | null {\n if (!raw) return null;\n const parts = raw.split(\"-\").map(Number);\n const [year, month, day] = parts;\n if (!year || !month || !day) return null;\n return new Date(year, month - 1, day);\n}\n\n/**\n * Intentionally minimal: reuses Input + the native date picker UI rather\n * than building a calendar widget (doc section 10/18 — don't overbuild the\n * first iteration). value/onChange work in terms of `Date`, so a richer\n * Popup-based calendar can replace the native input later without breaking\n * this public contract. See \"Known Limitations\" in the final report.\n */\nexport function DatePicker({ value, defaultValue, onChange, min, max, ...rest }: DatePickerProps) {\n const [currentValue, setValue] = useControllableState<Date | null>({\n value,\n defaultValue: defaultValue ?? null,\n onChange,\n });\n\n return (\n <Input\n {...rest}\n value={toDateInputValue(currentValue)}\n onChange={(raw) => setValue(fromDateInputValue(raw))}\n inputProps={{\n type: \"date\",\n min: min ? toDateInputValue(min) : undefined,\n max: max ? toDateInputValue(max) : undefined,\n }}\n />\n );\n}\n","import { Input } from \"./Input\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\n\nexport interface TimePickerProps extends FieldIdentity, FieldState, FieldPresentation {\n value?: Date | null;\n defaultValue?: Date | null;\n onChange?: (value: Date | null) => void;\n /** Native `<input type=\"time\">` step, in seconds. */\n step?: number;\n}\n\n/**\n * Value strategy (doc section 12): TimePicker uses `Date`, same as\n * DatePicker/DateTimePicker, for a coherent family — but only the\n * hours/minutes are meaningful; the date part is normalized to the epoch so\n * consumers can't accidentally depend on it. This is what lets\n * DateTimePicker combine a DatePicker date-part with a TimePicker\n * time-part into one `Date` without any string/format juggling.\n */\nexport function toTimeInputValue(date: Date | null | undefined): string {\n if (!date) return \"\";\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n return `${hours}:${minutes}`;\n}\n\nexport function fromTimeInputValue(raw: string): Date | null {\n if (!raw) return null;\n const [hours, minutes] = raw.split(\":\").map(Number);\n if (hours === undefined || minutes === undefined || Number.isNaN(hours) || Number.isNaN(minutes)) return null;\n return new Date(1970, 0, 1, hours, minutes, 0, 0);\n}\n\n/** Composes Input, same pattern as DatePicker/NumberInput (doc section 19). */\nexport function TimePicker({ value, defaultValue, onChange, step, ...rest }: TimePickerProps) {\n const [currentValue, setValue] = useControllableState<Date | null>({\n value,\n defaultValue: defaultValue ?? null,\n onChange,\n });\n\n return (\n <Input\n {...rest}\n value={toTimeInputValue(currentValue)}\n onChange={(raw) => setValue(fromTimeInputValue(raw))}\n inputProps={{ type: \"time\", step }}\n />\n );\n}\n","import { useId } from \"react\";\nimport { fromDateInputValue, toDateInputValue } from \"./DatePicker\";\nimport { cx } from \"./shared/classNames\";\nimport { FieldShell } from \"./shared/FieldShell\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport { fromTimeInputValue, toTimeInputValue } from \"./TimePicker\";\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\n\nexport interface DateTimePickerProps extends FieldIdentity, FieldState, FieldPresentation {\n value?: Date | null;\n defaultValue?: Date | null;\n onChange?: (value: Date | null) => void;\n min?: Date;\n max?: Date;\n}\n\nfunction combine(datePart: string, timePart: string): Date | null {\n const date = fromDateInputValue(datePart);\n if (!date) return null;\n const time = fromTimeInputValue(timePart || \"00:00\");\n if (time) date.setHours(time.getHours(), time.getMinutes(), 0, 0);\n return date;\n}\n\n/**\n * Reuses DatePicker's/TimePicker's exported date-part/time-part parsing so\n * the whole family shares one coherent `Date` value strategy (doc section\n * 12) — this is the actual \"behavior reuse\" the doc asks for. Renders two\n * plain native inputs rather than nesting two <Input>s: Input always wraps\n * itself in FieldShell, and nesting it twice here would produce two labels\n * for one field. A single FieldShell wraps both inputs as one field group.\n */\nexport function DateTimePicker({\n value,\n defaultValue,\n onChange,\n min,\n max,\n id,\n name,\n disabled,\n readOnly,\n required,\n className,\n label,\n helpText,\n error,\n}: DateTimePickerProps) {\n const [currentValue, setValue] = useControllableState<Date | null>({\n value,\n defaultValue: defaultValue ?? null,\n onChange,\n });\n\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n const datePart = toDateInputValue(currentValue);\n const timePart = toTimeInputValue(currentValue);\n\n return (\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\n <div className=\"d-flex gap-2\">\n <input\n id={fieldId}\n name={name ? `${name}-date` : undefined}\n type=\"date\"\n className={cx(\"form-control\", error && \"is-invalid\")}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n min={min ? toDateInputValue(min) : undefined}\n max={max ? toDateInputValue(max) : undefined}\n value={datePart}\n onChange={(event) => setValue(combine(event.target.value, timePart))}\n />\n <input\n name={name ? `${name}-time` : undefined}\n type=\"time\"\n className={cx(\"form-control\", error && \"is-invalid\")}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n value={timePart}\n onChange={(event) => setValue(combine(datePart || toDateInputValue(new Date()), event.target.value))}\n />\n </div>\n </FieldShell>\n );\n}\n","import { useCallback, useId, useRef, useState } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { FieldShell } from \"./shared/FieldShell\";\nimport { Popup } from \"./shared/Popup\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport { useListNavigation } from \"./shared/useListNavigation\";\nimport type { FieldIdentity, FieldPresentation, FieldState, SelectOption } from \"./shared/fieldTypes\";\n\nexport type { SelectOption };\n\nexport interface ComboBoxProps<TValue extends string | number = string> extends FieldIdentity, FieldState, FieldPresentation {\n options: SelectOption<TValue>[];\n value?: TValue | null;\n defaultValue?: TValue | null;\n onChange?: (value: TValue | null) => void;\n /**\n * Presentational-only loading flag. ComboBox has no idea *why* it's\n * loading (doc section 8: don't pollute Base with HTTP concepts) — this\n * is set by RemoteComboBox, but could equally be driven by any other\n * async source.\n */\n loading?: boolean;\n emptyText?: string;\n}\n\nexport function ComboBox<TValue extends string | number = string>({\n options,\n value,\n defaultValue,\n onChange,\n loading,\n emptyText = \"No options\",\n id,\n name,\n disabled,\n readOnly,\n required,\n className,\n label,\n placeholder = \"Select...\",\n helpText,\n error,\n}: ComboBoxProps<TValue>) {\n const [currentValue, setValue] = useControllableState<TValue | null>({\n value,\n defaultValue: defaultValue ?? null,\n onChange,\n });\n const [open, setOpen] = useState(false);\n const anchorRef = useRef<HTMLButtonElement>(null);\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n const selectedOption = options.find((option) => option.value === currentValue) ?? null;\n\n const close = useCallback(() => setOpen(false), []);\n const selectIndex = useCallback(\n (index: number) => {\n const option = options[index];\n if (!option || option.disabled) return;\n setValue(option.value);\n close();\n },\n [options, setValue, close]\n );\n\n const { activeIndex, setActiveIndex, handleKeyDown } = useListNavigation({\n itemCount: options.length,\n isOpen: open,\n onSelect: selectIndex,\n onClose: close,\n });\n\n return (\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\n <div className=\"position-relative\">\n <button\n ref={anchorRef}\n id={fieldId}\n type=\"button\"\n name={name}\n className={cx(\"form-select text-start\", error && \"is-invalid\")}\n disabled={disabled || readOnly}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n onClick={() => setOpen((prev) => !prev)}\n onKeyDown={handleKeyDown}\n >\n {selectedOption ? selectedOption.label : <span className=\"text-body-secondary\">{placeholder}</span>}\n </button>\n <Popup open={open} onClose={close} anchorRef={anchorRef} className=\"dropdown-menu w-100\" role=\"listbox\">\n {loading ? (\n <div className=\"px-3 py-2 text-body-secondary\">Loading…</div>\n ) : options.length === 0 ? (\n <div className=\"px-3 py-2 text-body-secondary\">{emptyText}</div>\n ) : (\n options.map((option, index) => (\n <div\n key={String(option.value)}\n role=\"option\"\n aria-selected={option.value === currentValue}\n className={cx(\"dropdown-item\", index === activeIndex && \"active\", option.disabled && \"disabled\")}\n onMouseEnter={() => setActiveIndex(index)}\n onMouseDown={(event) => {\n event.preventDefault();\n if (!option.disabled) selectIndex(index);\n }}\n >\n {option.label}\n </div>\n ))\n )}\n </Popup>\n </div>\n </FieldShell>\n );\n}\n","import { useCallback, useId, useRef, useState } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { FieldShell } from \"./shared/FieldShell\";\nimport { Popup } from \"./shared/Popup\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport { useListNavigation } from \"./shared/useListNavigation\";\nimport type { FieldIdentity, FieldPresentation, FieldState, SelectOption } from \"./shared/fieldTypes\";\n\nexport interface AutoCompleteProps<TValue extends string | number = string> extends FieldIdentity, FieldState, FieldPresentation {\n options: SelectOption<TValue>[];\n value?: TValue | null;\n defaultValue?: TValue | null;\n onChange?: (value: TValue | null) => void;\n /** Controlled search text, independent from the selected `value`. */\n inputValue?: string;\n onInputValueChange?: (text: string) => void;\n /** Presentational-only loading flag — see ComboBox's `loading` prop. */\n loading?: boolean;\n emptyText?: string;\n /**\n * Local filter predicate. Defaults to a case-insensitive substring match.\n * RemoteAutoComplete overrides this with `() => true` because the server\n * already filtered the results — Base must never re-filter server output.\n */\n filter?: (option: SelectOption<TValue>, query: string) => boolean;\n}\n\nfunction defaultFilter<TValue extends string | number>(option: SelectOption<TValue>, query: string): boolean {\n if (!query) return true;\n return option.label.toLowerCase().includes(query.toLowerCase());\n}\n\nexport function AutoComplete<TValue extends string | number = string>({\n options,\n value,\n defaultValue,\n onChange,\n inputValue,\n onInputValueChange,\n loading,\n emptyText = \"No results\",\n filter,\n id,\n name,\n disabled,\n readOnly,\n required,\n className,\n label,\n placeholder,\n helpText,\n error,\n}: AutoCompleteProps<TValue>) {\n const [currentValue, setValue] = useControllableState<TValue | null>({\n value,\n defaultValue: defaultValue ?? null,\n onChange,\n });\n const selectedOption = options.find((option) => option.value === currentValue) ?? null;\n\n const [internalText, setInternalText] = useControllableState<string>({\n value: inputValue,\n defaultValue: selectedOption?.label ?? \"\",\n onChange: onInputValueChange,\n });\n\n const [open, setOpen] = useState(false);\n const anchorRef = useRef<HTMLInputElement>(null);\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n const matchFilter = filter ?? defaultFilter;\n const filteredOptions = options.filter((option) => matchFilter(option, internalText));\n\n const close = useCallback(() => setOpen(false), []);\n const selectIndex = useCallback(\n (index: number) => {\n const option = filteredOptions[index];\n if (!option || option.disabled) return;\n setValue(option.value);\n setInternalText(option.label);\n close();\n },\n [filteredOptions, setValue, setInternalText, close]\n );\n\n const { activeIndex, setActiveIndex, handleKeyDown } = useListNavigation({\n itemCount: filteredOptions.length,\n isOpen: open,\n onSelect: selectIndex,\n onClose: close,\n });\n\n return (\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\n <div className=\"position-relative\">\n <input\n ref={anchorRef}\n id={fieldId}\n name={name}\n type=\"text\"\n className={cx(\"form-control\", error && \"is-invalid\")}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n placeholder={placeholder}\n autoComplete=\"off\"\n role=\"combobox\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n value={internalText}\n onFocus={() => setOpen(true)}\n onChange={(event) => {\n const text = event.target.value;\n setInternalText(text);\n setOpen(true);\n if (currentValue !== null) setValue(null);\n }}\n onKeyDown={handleKeyDown}\n />\n <Popup open={open} onClose={close} anchorRef={anchorRef} className=\"dropdown-menu w-100\" role=\"listbox\">\n {loading ? (\n <div className=\"px-3 py-2 text-body-secondary\">Loading…</div>\n ) : filteredOptions.length === 0 ? (\n <div className=\"px-3 py-2 text-body-secondary\">{emptyText}</div>\n ) : (\n filteredOptions.map((option, index) => (\n <div\n key={String(option.value)}\n role=\"option\"\n aria-selected={option.value === currentValue}\n className={cx(\"dropdown-item\", index === activeIndex && \"active\", option.disabled && \"disabled\")}\n onMouseEnter={() => setActiveIndex(index)}\n onMouseDown={(event) => {\n event.preventDefault();\n if (!option.disabled) selectIndex(index);\n }}\n >\n {option.label}\n </div>\n ))\n )}\n </Popup>\n </div>\n </FieldShell>\n );\n}\n","import { FieldShell, type FieldShellProps } from \"./shared/FieldShell\";\n\nexport type FormFieldProps = FieldShellProps;\n\n/**\n * Public composition of Label + control + ValidationMessage for consumers\n * who need our field chrome around a *custom* control (e.g. a group of\n * RadioButtons, a Switch, a third-party widget) rather than one of our own\n * field components. Deliberately a thin re-export of FieldShell — the two\n * names serve different audiences (FieldShell: internal plumbing for our\n * own fields; FormField: the same behavior, public), not two\n * implementations (doc section 9 — no form-framework infrastructure here).\n */\nexport function FormField(props: FormFieldProps) {\n return <FieldShell {...props} />;\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { useEscapeKey } from \"./shared/useEscapeKey\";\n\nexport interface ModalProps {\n open: boolean;\n onClose: () => void;\n title?: string;\n children: ReactNode;\n footer?: ReactNode;\n className?: string;\n}\n\n/**\n * Centered/backdrop dialog overlay — a different interaction model from\n * Popup's anchored dropdown, so it's a separate component, but shares the\n * escape-to-close behavior via useEscapeKey.\n *\n * Known limitation: not rendered through a portal yet (renders in place).\n * Can be swapped to `createPortal(..., document.body)` later without\n * changing this component's props.\n */\nexport function Modal({ open, onClose, title, children, footer, className }: ModalProps) {\n useEscapeKey(open, onClose);\n\n if (!open) return null;\n\n return (\n <>\n <div className=\"modal d-block\" tabIndex={-1} role=\"dialog\" aria-modal=\"true\">\n <div className={cx(\"modal-dialog\", className)} role=\"document\">\n <div className=\"modal-content\">\n <div className=\"modal-header\">\n {title && <h5 className=\"modal-title\">{title}</h5>}\n <button type=\"button\" className=\"btn-close\" aria-label=\"Close\" onClick={onClose} />\n </div>\n <div className=\"modal-body\">{children}</div>\n {footer && <div className=\"modal-footer\">{footer}</div>}\n </div>\n </div>\n </div>\n <div className=\"modal-backdrop show\" onClick={onClose} />\n </>\n );\n}\n","import { cx } from \"./shared/classNames\";\n\nexport interface PaginationProps {\n currentPage: number;\n pageSize: number;\n totalItems: number;\n onPageChange: (page: number) => void;\n /** How many numbered page buttons to show on each side of the current page. */\n siblingCount?: number;\n className?: string;\n}\n\ntype PageEntry = number | \"ellipsis\";\n\nfunction getPageList(current: number, total: number, siblingCount: number): PageEntry[] {\n const pages: PageEntry[] = [];\n const start = Math.max(1, current - siblingCount);\n const end = Math.min(total, current + siblingCount);\n\n if (start > 1) {\n pages.push(1);\n if (start > 2) pages.push(\"ellipsis\");\n }\n for (let page = start; page <= end; page++) pages.push(page);\n if (end < total) {\n if (end < total - 1) pages.push(\"ellipsis\");\n pages.push(total);\n }\n return pages;\n}\n\n/**\n * UI-only, like DataGrid's other UI concerns — no API calls (doc section\n * 19). This is what lets it be reused by DataGrid (and later\n * RemoteDataGrid/SmartDataGrid) regardless of where the rows came from.\n */\nexport function Pagination({ currentPage, pageSize, totalItems, onPageChange, siblingCount = 1, className }: PaginationProps) {\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));\n const pages = getPageList(currentPage, totalPages, siblingCount);\n\n return (\n <nav aria-label=\"Pagination\" className={className}>\n <ul className=\"pagination mb-0\">\n <li className={cx(\"page-item\", currentPage <= 1 && \"disabled\")}>\n <button\n type=\"button\"\n className=\"page-link\"\n disabled={currentPage <= 1}\n onClick={() => onPageChange(currentPage - 1)}\n >\n Previous\n </button>\n </li>\n {pages.map((page, index) =>\n page === \"ellipsis\" ? (\n <li key={`ellipsis-${index}`} className=\"page-item disabled\">\n <span className=\"page-link\">…</span>\n </li>\n ) : (\n <li key={page} className={cx(\"page-item\", page === currentPage && \"active\")}>\n <button\n type=\"button\"\n className=\"page-link\"\n aria-current={page === currentPage ? \"page\" : undefined}\n onClick={() => onPageChange(page)}\n >\n {page}\n </button>\n </li>\n )\n )}\n <li className={cx(\"page-item\", currentPage >= totalPages && \"disabled\")}>\n <button\n type=\"button\"\n className=\"page-link\"\n disabled={currentPage >= totalPages}\n onClick={() => onPageChange(currentPage + 1)}\n >\n Next\n </button>\n </li>\n </ul>\n </nav>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Pagination } from \"./Pagination\";\nimport { cx } from \"./shared/classNames\";\n\nexport type DataGridAlign = \"start\" | \"center\" | \"end\";\n\n/**\n * Closed, finite formatter set — the same contract the Smart layer's\n * `format` metadata already targeted, now owned here instead of being\n * duplicated in a second Smart-side formatter map (doc: \"Base DataGrid owns\n * reusable presentation capability, Smart chooses a supported formatter\").\n * Never accepts an arbitrary/serialized function — that stays Smart's\n * closed-enum contract too.\n */\nexport type DataGridFormat = \"text\" | \"date\" | \"currency\" | \"boolean\";\n\nexport const dataGridFormatters: Record<DataGridFormat, (value: unknown) => ReactNode> = {\n text: (value) => (value == null ? \"\" : String(value)),\n boolean: (value) => (value ? \"Yes\" : \"No\"),\n date: (value) => {\n if (value == null || value === \"\") return \"\";\n const date = value instanceof Date ? value : new Date(String(value));\n return Number.isNaN(date.getTime()) ? String(value) : date.toLocaleDateString();\n },\n currency: (value) => {\n const amount = Number(value);\n return Number.isFinite(amount) ? amount.toLocaleString(undefined, { style: \"currency\", currency: \"USD\" }) : String(value ?? \"\");\n },\n};\n\nexport interface DataGridColumn<TRow> {\n /** Row-identity/sort key. Defaults to `field` when omitted — required only if `field` is also omitted (a fully custom `render`-only column). */\n key?: string;\n /** Row property this column reads its value from — strongly typed against `TRow`. Enables the declarative `align`/`format`/`formatter` path below instead of a `render` callback. */\n field?: keyof TRow & string;\n header: string;\n align?: DataGridAlign;\n /** Defaults to `align` when omitted. */\n headerAlign?: DataGridAlign;\n width?: string;\n minWidth?: string;\n maxWidth?: string;\n sortable?: boolean;\n /** Built-in formatter selection — the normal way to display a field (see `dataGridFormatters`). */\n format?: DataGridFormat;\n /** Escape hatch for a computed display value that still gets the standard aligned cell wrapper. */\n formatter?: (value: unknown, row: TRow) => ReactNode;\n /** Escape hatch for a fully custom cell — the exception, not the default way to display a field. */\n render?: (row: TRow) => ReactNode;\n}\n\nexport type DataGridSort = { key: string; direction: \"asc\" | \"desc\" };\n\nexport interface DataGridProps<TRow> {\n columns: DataGridColumn<TRow>[];\n rows: TRow[];\n rowKey: (row: TRow) => string | number;\n loading?: boolean;\n error?: string;\n emptyText?: string;\n className?: string;\n\n /** Selection is a generic UI concern — Base doesn't know how selection maps to anything remote. */\n selectedRowKeys?: Array<string | number>;\n onSelectionChange?: (keys: Array<string | number>) => void;\n\n /**\n * Sort UI only. Base renders sort indicators and calls back on header\n * click — it has no idea whether sorting happens client-side or via a\n * server request (doc section 10).\n */\n sort?: DataGridSort | null;\n onSortChange?: (sort: DataGridSort | null) => void;\n\n /** Pagination UI only, fully controlled from outside — same principle as sort. */\n page?: number;\n pageSize?: number;\n totalCount?: number;\n onPageChange?: (page: number) => void;\n}\n\nfunction nextSortDirection(current: DataGridSort | null | undefined, key: string): DataGridSort | null {\n if (!current || current.key !== key) return { key, direction: \"asc\" };\n if (current.direction === \"asc\") return { key, direction: \"desc\" };\n return null;\n}\n\nfunction columnKeyOf<TRow>(column: DataGridColumn<TRow>): string {\n return column.key ?? column.field ?? column.header;\n}\n\nfunction columnValueOf<TRow>(column: DataGridColumn<TRow>, row: TRow): unknown {\n const accessor = column.field ?? column.key;\n return accessor ? (row as Record<string, unknown>)[accessor] : undefined;\n}\n\nfunction renderCell<TRow>(column: DataGridColumn<TRow>, row: TRow): ReactNode {\n if (column.render) return column.render(row);\n const value = columnValueOf(column, row);\n if (column.formatter) return column.formatter(value, row);\n if (column.format) return dataGridFormatters[column.format](value);\n return value == null ? \"\" : String(value);\n}\n\nfunction alignClass(align: DataGridAlign | undefined): string | undefined {\n return align && `text-${align}`;\n}\n\n/**\n * Intentionally focused first iteration (doc section 10/18): columns, rows,\n * selection, sort UI, pagination UI, loading/empty/error presentation.\n * No built-in filtering UI, column resize/reorder, or virtualization yet —\n * those are future extensions, not implemented speculatively.\n */\nexport function DataGrid<TRow>({\n columns,\n rows,\n rowKey,\n loading,\n error,\n emptyText = \"No data\",\n className,\n selectedRowKeys,\n onSelectionChange,\n sort,\n onSortChange,\n page,\n pageSize,\n totalCount,\n onPageChange,\n}: DataGridProps<TRow>) {\n const selectable = Boolean(onSelectionChange);\n const selectedSet = new Set(selectedRowKeys ?? []);\n const paginated = page !== undefined && pageSize !== undefined && totalCount !== undefined;\n const totalPages = paginated ? Math.max(1, Math.ceil(totalCount / pageSize)) : 1;\n\n function toggleAll() {\n if (!onSelectionChange) return;\n if (selectedSet.size === rows.length) {\n onSelectionChange([]);\n } else {\n onSelectionChange(rows.map(rowKey));\n }\n }\n\n function toggleRow(key: string | number) {\n if (!onSelectionChange) return;\n const next = new Set(selectedSet);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n onSelectionChange(Array.from(next));\n }\n\n return (\n <div className={cx(\"table-responsive\", className)}>\n <table className=\"table table-hover align-middle\">\n <thead>\n <tr>\n {selectable && (\n <th style={{ width: \"2.5rem\" }}>\n <input\n type=\"checkbox\"\n className=\"form-check-input\"\n checked={rows.length > 0 && selectedSet.size === rows.length}\n onChange={toggleAll}\n aria-label=\"Select all rows\"\n />\n </th>\n )}\n {columns.map((column) => {\n const key = columnKeyOf(column);\n return (\n <th\n key={key}\n className={alignClass(column.headerAlign ?? column.align)}\n style={{ width: column.width, minWidth: column.minWidth, maxWidth: column.maxWidth }}\n role={column.sortable ? \"button\" : undefined}\n onClick={column.sortable && onSortChange ? () => onSortChange(nextSortDirection(sort, key)) : undefined}\n >\n {column.header}\n {column.sortable && sort?.key === key && <span aria-hidden=\"true\"> {sort.direction === \"asc\" ? \"▲\" : \"▼\"}</span>}\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {loading ? (\n <tr>\n <td colSpan={columns.length + (selectable ? 1 : 0)} className=\"text-center text-body-secondary py-4\">\n Loading…\n </td>\n </tr>\n ) : error ? (\n <tr>\n <td colSpan={columns.length + (selectable ? 1 : 0)} className=\"text-center text-danger py-4\">\n {error}\n </td>\n </tr>\n ) : rows.length === 0 ? (\n <tr>\n <td colSpan={columns.length + (selectable ? 1 : 0)} className=\"text-center text-body-secondary py-4\">\n {emptyText}\n </td>\n </tr>\n ) : (\n rows.map((row) => {\n const key = rowKey(row);\n return (\n <tr key={key}>\n {selectable && (\n <td>\n <input\n type=\"checkbox\"\n className=\"form-check-input\"\n checked={selectedSet.has(key)}\n onChange={() => toggleRow(key)}\n aria-label=\"Select row\"\n />\n </td>\n )}\n {columns.map((column) => (\n <td key={columnKeyOf(column)} className={alignClass(column.align)}>\n {renderCell(column, row)}\n </td>\n ))}\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n\n {paginated && (\n <div className=\"d-flex justify-content-between align-items-center mt-2\">\n <span className=\"text-body-secondary small\">\n Page {page} of {totalPages} ({totalCount} rows)\n </span>\n <Pagination currentPage={page!} pageSize={pageSize!} totalItems={totalCount!} onPageChange={onPageChange!} />\n </div>\n )}\n </div>\n );\n}\n","import { cx } from \"./shared/classNames\";\n\nexport interface SpinnerProps {\n size?: \"sm\" | \"md\";\n variant?: string;\n className?: string;\n label?: string;\n}\n\nexport function Spinner({ size = \"md\", variant, className, label = \"Loading...\" }: SpinnerProps) {\n return (\n <span\n className={cx(\"spinner-border\", size === \"sm\" && \"spinner-border-sm\", variant && `text-${variant}`, className)}\n role=\"status\"\n >\n <span className=\"visually-hidden\">{label}</span>\n </span>\n );\n}\n","import type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { Spinner } from \"./Spinner\";\nimport { cx } from \"./shared/classNames\";\n\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"danger\"\n | \"warning\"\n | \"info\"\n | \"light\"\n | \"dark\"\n | \"link\"\n | \"outline-primary\"\n | \"outline-secondary\";\n\nexport interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"className\" | \"type\" | \"disabled\"> {\n variant?: ButtonVariant;\n size?: \"sm\" | \"lg\";\n disabled?: boolean;\n loading?: boolean;\n type?: \"button\" | \"submit\" | \"reset\";\n className?: string;\n children?: ReactNode;\n}\n\n/** Reuses Spinner for the loading indicator (doc section 13) instead of a bespoke inline spinner. */\nexport function Button({\n variant = \"primary\",\n size,\n disabled,\n loading,\n type = \"button\",\n className,\n children,\n onClick,\n ...rest\n}: ButtonProps) {\n const isDisabled = disabled || loading;\n\n return (\n <button\n type={type}\n className={cx(\"btn\", `btn-${variant}`, size && `btn-${size}`, className)}\n disabled={isDisabled}\n aria-busy={loading || undefined}\n onClick={isDisabled ? undefined : onClick}\n {...rest}\n >\n {loading && <Spinner size=\"sm\" className=\"me-2\" label=\"\" />}\n {children}\n </button>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport type AlertVariant = \"primary\" | \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" | \"light\" | \"dark\";\n\nexport interface AlertProps {\n variant?: AlertVariant;\n dismissible?: boolean;\n onDismiss?: () => void;\n className?: string;\n children: ReactNode;\n}\n\n/**\n * Presentation only (doc section 15) — deliberately not a toast\n * service/notification bus/error-management system. A consumer owns when\n * an Alert mounts/unmounts and what triggers it.\n */\nexport function Alert({ variant = \"info\", dismissible, onDismiss, className, children }: AlertProps) {\n return (\n <div className={cx(\"alert\", `alert-${variant}`, dismissible && \"alert-dismissible\", className)} role=\"alert\">\n {children}\n {dismissible && <button type=\"button\" className=\"btn-close\" aria-label=\"Close\" onClick={onDismiss} />}\n </div>\n );\n}\n","import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { Alert, type AlertVariant } from \"./Alert\";\n\nexport interface ToastOptions {\n variant?: AlertVariant;\n /** Auto-dismiss delay in ms. Pass 0 to require manual dismissal via the Alert's close button. */\n duration?: number;\n}\n\ninterface ToastItem {\n id: number;\n message: ReactNode;\n variant: AlertVariant;\n}\n\nexport interface ToastApi {\n show: (message: ReactNode, options?: ToastOptions) => number;\n dismiss: (id: number) => void;\n success: (message: ReactNode, options?: Omit<ToastOptions, \"variant\">) => number;\n error: (message: ReactNode, options?: Omit<ToastOptions, \"variant\">) => number;\n info: (message: ReactNode, options?: Omit<ToastOptions, \"variant\">) => number;\n warning: (message: ReactNode, options?: Omit<ToastOptions, \"variant\">) => number;\n}\n\nconst ToastContext = createContext<ToastApi | null>(null);\n\nconst DEFAULT_DURATION = 4000;\n\n/**\n * Global toast notifications. Reuses Alert's variant styling and dismiss\n * button (doc section 20: capability layers must not duplicate an existing\n * implementation) for the actual message presentation — this module only\n * owns the queue/timing/positioning concerns Alert's own doc comment\n * deliberately left out of Alert itself.\n */\nexport function ToastProvider({ children }: { children: ReactNode }) {\n const [toasts, setToasts] = useState<ToastItem[]>([]);\n const nextId = useRef(0);\n const timers = useRef(new Map<number, ReturnType<typeof setTimeout>>());\n\n useEffect(() => {\n const activeTimers = timers.current;\n return () => {\n activeTimers.forEach(clearTimeout);\n activeTimers.clear();\n };\n }, []);\n\n const dismiss = useCallback((id: number) => {\n const timer = timers.current.get(id);\n if (timer) {\n clearTimeout(timer);\n timers.current.delete(id);\n }\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n const show = useCallback(\n (message: ReactNode, options?: ToastOptions) => {\n const id = nextId.current++;\n const variant = options?.variant ?? \"info\";\n const duration = options?.duration ?? DEFAULT_DURATION;\n setToasts((prev) => [...prev, { id, message, variant }]);\n if (duration > 0) {\n timers.current.set(\n id,\n setTimeout(() => dismiss(id), duration)\n );\n }\n return id;\n },\n [dismiss]\n );\n\n const api = useMemo<ToastApi>(\n () => ({\n show,\n dismiss,\n success: (message, options) => show(message, { ...options, variant: \"success\" }),\n error: (message, options) => show(message, { ...options, variant: \"danger\" }),\n info: (message, options) => show(message, { ...options, variant: \"info\" }),\n warning: (message, options) => show(message, { ...options, variant: \"warning\" }),\n }),\n [show, dismiss]\n );\n\n return (\n <ToastContext.Provider value={api}>\n {children}\n <div className=\"toast-container position-fixed bottom-0 end-0 p-3\" style={{ zIndex: 1090 }}>\n {toasts.map((toast) => (\n <Alert key={toast.id} variant={toast.variant} dismissible onDismiss={() => dismiss(toast.id)} className=\"shadow-sm\">\n {toast.message}\n </Alert>\n ))}\n </div>\n </ToastContext.Provider>\n );\n}\n\n/** Throws outside ToastProvider — same fail-fast contract as other context-backed hooks in this library. */\nexport function useToast(): ToastApi {\n const context = useContext(ToastContext);\n if (!context) throw new Error(\"useToast must be used within a ToastProvider\");\n return context;\n}\n","import { createContext, useCallback, useContext, useState, type ReactNode } from \"react\";\nimport { Button, type ButtonVariant } from \"./Button\";\nimport { Modal } from \"./Modal\";\n\nexport interface ConfirmOptions {\n title?: string;\n message: ReactNode;\n confirmLabel?: string;\n cancelLabel?: string;\n confirmVariant?: ButtonVariant;\n}\n\nexport type ConfirmFn = (options: ConfirmOptions) => Promise<boolean>;\n\nconst ConfirmContext = createContext<ConfirmFn | null>(null);\n\ninterface PendingConfirm extends ConfirmOptions {\n resolve: (value: boolean) => void;\n}\n\n/**\n * Imperative yes/no dialog. Built on Modal + Button (doc section 20: reuse,\n * don't reimplement) instead of every screen wiring its own \"are you sure\"\n * modal-open state and footer buttons by hand.\n *\n * Known limitation: a second confirm() call while one is still pending\n * replaces it — the first promise never settles. Acceptable for v1 (doc\n * section 6: avoid speculative infrastructure); a queue can be added if a\n * real screen needs overlapping confirms.\n */\nexport function ConfirmProvider({ children }: { children: ReactNode }) {\n const [pending, setPending] = useState<PendingConfirm | null>(null);\n\n const confirm = useCallback<ConfirmFn>((options) => {\n return new Promise<boolean>((resolve) => {\n setPending({ ...options, resolve });\n });\n }, []);\n\n const settle = useCallback(\n (result: boolean) => {\n pending?.resolve(result);\n setPending(null);\n },\n [pending]\n );\n\n return (\n <ConfirmContext.Provider value={confirm}>\n {children}\n <Modal\n open={pending !== null}\n onClose={() => settle(false)}\n title={pending?.title ?? \"Confirm\"}\n footer={\n <>\n <Button variant=\"outline-secondary\" onClick={() => settle(false)}>\n {pending?.cancelLabel ?? \"Cancel\"}\n </Button>\n <Button variant={pending?.confirmVariant ?? \"danger\"} onClick={() => settle(true)}>\n {pending?.confirmLabel ?? \"Confirm\"}\n </Button>\n </>\n }\n >\n {pending?.message}\n </Modal>\n </ConfirmContext.Provider>\n );\n}\n\n/** Throws outside ConfirmProvider — same fail-fast contract as other context-backed hooks in this library. */\nexport function useConfirm(): ConfirmFn {\n const context = useContext(ConfirmContext);\n if (!context) throw new Error(\"useConfirm must be used within a ConfirmProvider\");\n return context;\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport type BadgeVariant = \"primary\" | \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" | \"light\" | \"dark\";\n\nexport interface BadgeProps {\n variant?: BadgeVariant;\n pill?: boolean;\n className?: string;\n children: ReactNode;\n}\n\nexport function Badge({ variant = \"primary\", pill, className, children }: BadgeProps) {\n return <span className={cx(\"badge\", `bg-${variant}`, pill && \"rounded-pill\", className)}>{children}</span>;\n}\n","import { cx } from \"./shared/classNames\";\n\nexport interface IconProps {\n /**\n * Full icon class name(s) — e.g. \"bi bi-trash\" (Bootstrap Icons) or\n * \"ki-outline ki-trash\" (Metronic Keenicons). Icon-set agnostic by design:\n * this component bundles no icon font of its own (doc section 15 — stay\n * on Bootstrap/Metronic, don't introduce another framework or a\n * duplicate asset), it only standardizes sizing and accessibility.\n */\n name: string;\n size?: \"sm\" | \"lg\" | \"xl\";\n className?: string;\n /** Accessible label. Omit for a purely decorative icon (default: aria-hidden). */\n label?: string;\n}\n\nconst SIZE_EM: Record<NonNullable<IconProps[\"size\"]>, string> = {\n sm: \"0.875em\",\n lg: \"1.5em\",\n xl: \"2em\",\n};\n\nexport function Icon({ name, size, className, label }: IconProps) {\n return (\n <i\n className={cx(name, className)}\n style={size ? { fontSize: SIZE_EM[size] } : undefined}\n role={label ? \"img\" : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n />\n );\n}\n","import { useRef, type KeyboardEvent, type ReactNode } from \"react\";\nimport { Badge } from \"./Badge\";\nimport { Icon } from \"./Icon\";\nimport { cx } from \"./shared/classNames\";\nimport { useControllableState } from \"./shared/useControllableState\";\n\nexport type TabsVariant = \"default\" | \"underline\" | \"pill\" | \"card\" | \"button\";\nexport type TabsOrientation = \"horizontal\" | \"vertical\";\nexport type TabsSize = \"sm\" | \"lg\";\n\nexport interface TabItem {\n key: string;\n label: ReactNode;\n /** Icon class name(s), passed straight through to `Icon` (icon-set agnostic — doc section 15). */\n icon?: string;\n badge?: ReactNode;\n disabled?: boolean;\n /**\n * Optional — a tab can be nav-only (content driven externally, e.g. by\n * the same `activeKey` state feeding a sibling `DataGrid`) instead of\n * owning its panel.\n */\n content?: ReactNode;\n}\n\nexport interface TabsProps {\n items: TabItem[];\n activeKey?: string;\n defaultActiveKey?: string;\n onChange?: (key: string) => void;\n /** Generic nav look, not a Metronic widget name — express a Metronic visual as `variant=\"pill\"` + `icon`, not a new named variant. */\n variant?: TabsVariant;\n orientation?: TabsOrientation;\n size?: TabsSize;\n /** Tab list fills its container width (`nav-fill`). */\n stretch?: boolean;\n className?: string;\n}\n\nfunction navClass(variant: TabsVariant): string {\n switch (variant) {\n case \"pill\":\n return \"nav-pills\";\n case \"underline\":\n return \"nav-underline\";\n case \"card\":\n return \"nav-tabs card-header-tabs\";\n default:\n return \"nav-tabs\";\n }\n}\n\nconst SIZE_CLASS: Record<TabsSize, string> = {\n sm: \"small\",\n lg: \"fs-5\",\n};\n\n/** Tab definitions (`items`) are kept separate from rendering, per doc section 16. */\nexport function Tabs({ items, activeKey, defaultActiveKey, onChange, variant = \"default\", orientation = \"horizontal\", size, stretch, className }: TabsProps) {\n const [currentKey, setKey] = useControllableState<string>({\n value: activeKey,\n defaultValue: defaultActiveKey ?? items[0]?.key ?? \"\",\n onChange,\n });\n\n const activeItem = items.find((item) => item.key === currentKey);\n const isButtonVariant = variant === \"button\";\n const isVertical = orientation === \"vertical\";\n const tabRefs = useRef<Array<HTMLButtonElement | null>>([]);\n\n function activate(index: number, focus: boolean) {\n const item = items[index];\n if (!item) return;\n setKey(item.key);\n if (focus) tabRefs.current[index]?.focus();\n }\n\n function findEnabled(from: number, step: 1 | -1): number {\n if (items.length === 0) return from;\n let index = from;\n for (let i = 0; i < items.length; i++) {\n index = (index + step + items.length) % items.length;\n if (!items[index]?.disabled) return index;\n }\n return from;\n }\n\n /** Roving-tabindex arrow-key navigation with automatic activation, per the WAI-ARIA Tabs authoring pattern. */\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n const currentIndex = items.findIndex((item) => item.key === currentKey);\n const nextKey = isVertical ? \"ArrowDown\" : \"ArrowRight\";\n const prevKey = isVertical ? \"ArrowUp\" : \"ArrowLeft\";\n\n if (event.key === nextKey) {\n event.preventDefault();\n activate(findEnabled(currentIndex, 1), true);\n } else if (event.key === prevKey) {\n event.preventDefault();\n activate(findEnabled(currentIndex, -1), true);\n } else if (event.key === \"Home\") {\n event.preventDefault();\n const first = items.findIndex((item) => !item.disabled);\n if (first >= 0) activate(first, true);\n } else if (event.key === \"End\") {\n event.preventDefault();\n for (let i = items.length - 1; i >= 0; i--) {\n if (!items[i]?.disabled) {\n activate(i, true);\n break;\n }\n }\n }\n }\n\n const tabList = (\n <div\n className={cx(\n isButtonVariant ? \"btn-group\" : \"nav\",\n !isButtonVariant && navClass(variant),\n !isButtonVariant && isVertical && \"flex-column\",\n !isButtonVariant && stretch && \"nav-fill\",\n !isButtonVariant && size && SIZE_CLASS[size]\n )}\n role=\"tablist\"\n aria-orientation={orientation}\n onKeyDown={handleKeyDown}\n >\n {items.map((item, index) => {\n const active = item.key === currentKey;\n const buttonContent = (\n <>\n {item.icon && <Icon name={item.icon} size=\"sm\" className=\"me-1\" />}\n {item.label}\n {item.badge != null && (\n <Badge variant={active && !isButtonVariant ? \"primary\" : \"secondary\"} pill className=\"ms-2\">\n {item.badge}\n </Badge>\n )}\n </>\n );\n\n const button = (\n <button\n key={item.key}\n ref={(node) => {\n tabRefs.current[index] = node;\n }}\n type=\"button\"\n id={`tab-${item.key}`}\n className={cx(isButtonVariant ? cx(\"btn\", size ? `btn-${size}` : \"btn-sm\", active ? \"btn-primary\" : \"btn-outline-primary\") : cx(\"nav-link\", active && \"active\"))}\n role=\"tab\"\n aria-selected={active}\n aria-controls={`tabpanel-${item.key}`}\n tabIndex={active ? 0 : -1}\n disabled={item.disabled}\n onClick={() => activate(index, false)}\n >\n {buttonContent}\n </button>\n );\n\n return isButtonVariant ? button : (\n <div key={item.key} className=\"nav-item\" role=\"presentation\">\n {button}\n </div>\n );\n })}\n </div>\n );\n\n const panel = activeItem?.content != null && (\n <div id={`tabpanel-${activeItem.key}`} className={cx(\"tab-content\", !isVertical && \"pt-3\")} role=\"tabpanel\" aria-labelledby={`tab-${activeItem.key}`}>\n {activeItem.content}\n </div>\n );\n\n if (isVertical) {\n return (\n <div className={cx(\"d-flex align-items-start gap-3\", className)}>\n {tabList}\n {panel && <div className=\"flex-grow-1\">{panel}</div>}\n </div>\n );\n }\n\n return (\n <div className={className}>\n {tabList}\n {panel}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { useControllableState } from \"./shared/useControllableState\";\n\nexport interface AccordionItem {\n key: string;\n header: string;\n content: ReactNode;\n disabled?: boolean;\n}\n\nexport interface AccordionProps {\n items: AccordionItem[];\n /** false (default) = single-open (classic accordion); true = multiple sections can be open at once. */\n multiple?: boolean;\n openKeys?: string[];\n defaultOpenKeys?: string[];\n onChange?: (openKeys: string[]) => void;\n className?: string;\n}\n\nexport function Accordion({ items, multiple = false, openKeys, defaultOpenKeys, onChange, className }: AccordionProps) {\n const [currentOpenKeys, setOpenKeys] = useControllableState<string[]>({\n value: openKeys,\n defaultValue: defaultOpenKeys ?? [],\n onChange,\n });\n\n const openSet = new Set(currentOpenKeys);\n\n function toggle(key: string) {\n if (openSet.has(key)) {\n setOpenKeys(currentOpenKeys.filter((k) => k !== key));\n } else {\n setOpenKeys(multiple ? [...currentOpenKeys, key] : [key]);\n }\n }\n\n return (\n <div className={cx(\"accordion\", className)}>\n {items.map((item) => {\n const isOpen = openSet.has(item.key);\n return (\n <div className=\"accordion-item\" key={item.key}>\n <h2 className=\"accordion-header\">\n <button\n type=\"button\"\n className={cx(\"accordion-button\", !isOpen && \"collapsed\")}\n aria-expanded={isOpen}\n disabled={item.disabled}\n onClick={() => toggle(item.key)}\n >\n {item.header}\n </button>\n </h2>\n {isOpen && (\n <div className=\"accordion-collapse\">\n <div className=\"accordion-body\">{item.content}</div>\n </div>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","import { useId, useRef, useState, type ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { Popup } from \"./shared/Popup\";\n\nexport interface TooltipProps {\n content: ReactNode;\n children: ReactNode;\n placement?: \"top\" | \"bottom\";\n className?: string;\n}\n\n/**\n * Reuses the existing Popup primitive (open/close, escape-to-close, outside\n * click, cleanup — all already implemented and tested) with Bootstrap's\n * real tooltip CSS classes for visual fidelity.\n *\n * Deliberately NOT wired to Bootstrap's own JS Tooltip plugin: that plugin\n * needs `@popperjs/core` (the plain `bootstrap` package doesn't bundle it —\n * only its non-ESM `bootstrap.bundle.js` does), so wiring it up would mean\n * either adding a new dependency or a fragile UMD-inside-an-ESM-library\n * dynamic import. Reusing our own already-tested Popup is the more\n * conservative choice here, not less (doc section 18: \"do NOT introduce\n * another positioning library unless actually necessary\").\n */\nexport function Tooltip({ content, children, placement = \"top\", className }: TooltipProps) {\n const [open, setOpen] = useState(false);\n const anchorRef = useRef<HTMLSpanElement>(null);\n const tooltipId = useId();\n\n return (\n <span\n ref={anchorRef}\n className=\"position-relative d-inline-block\"\n onMouseEnter={() => setOpen(true)}\n onMouseLeave={() => setOpen(false)}\n onFocus={() => setOpen(true)}\n onBlur={() => setOpen(false)}\n aria-describedby={open ? tooltipId : undefined}\n >\n {children}\n <Popup\n open={open}\n onClose={() => setOpen(false)}\n anchorRef={anchorRef}\n className={cx(\"tooltip show\", `bs-tooltip-${placement}`, \"position-absolute\", \"w-auto\", className)}\n >\n <span id={tooltipId} role=\"tooltip\" className=\"tooltip-inner\">\n {content}\n </span>\n </Popup>\n </span>\n );\n}\n","import { useRef, useState, type ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { Popup } from \"./shared/Popup\";\n\nexport interface PopoverProps {\n title?: ReactNode;\n content: ReactNode;\n children: ReactNode;\n placement?: \"top\" | \"bottom\";\n className?: string;\n}\n\n/** Click-triggered variant of Tooltip — same Popup-reuse rationale (see Tooltip.tsx). */\nexport function Popover({ title, content, children, placement = \"bottom\", className }: PopoverProps) {\n const [open, setOpen] = useState(false);\n const anchorRef = useRef<HTMLSpanElement>(null);\n\n return (\n <span ref={anchorRef} className=\"position-relative d-inline-block\" onClick={() => setOpen((prev) => !prev)}>\n {children}\n <Popup\n open={open}\n onClose={() => setOpen(false)}\n anchorRef={anchorRef}\n className={cx(\"popover show\", `bs-popover-${placement}`, \"position-absolute\", \"w-auto\", className)}\n >\n {title && <h3 className=\"popover-header\">{title}</h3>}\n <div className=\"popover-body\">{content}</div>\n </Popup>\n </span>\n );\n}\n","import { cx } from \"./shared/classNames\";\n\nexport interface SkeletonProps {\n width?: string | number;\n height?: string | number;\n circle?: boolean;\n className?: string;\n}\n\n/** Uses Bootstrap's built-in `placeholder`/`placeholder-glow` classes rather than inventing a new loading-shimmer animation. */\nexport function Skeleton({ width = \"100%\", height = \"1rem\", circle, className }: SkeletonProps) {\n return (\n <span className={cx(\"placeholder-glow d-inline-block\", className)} style={{ width, height }} aria-hidden=\"true\">\n <span className={cx(\"placeholder w-100 h-100 d-block\", circle && \"rounded-circle\")} />\n </span>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface StackProps {\n direction?: \"row\" | \"column\";\n gap?: 0 | 1 | 2 | 3 | 4 | 5;\n align?: \"start\" | \"center\" | \"end\" | \"stretch\" | \"baseline\";\n justify?: \"start\" | \"center\" | \"end\" | \"between\" | \"around\" | \"evenly\";\n wrap?: boolean;\n className?: string;\n children?: ReactNode;\n}\n\n/** Thin wrapper over Bootstrap's flex utilities — replaces repeated `d-flex gap-2` one-offs with one typed contract. */\nexport function Stack({ direction = \"column\", gap = 2, align, justify, wrap, className, children }: StackProps) {\n return (\n <div\n className={cx(\n \"d-flex\",\n direction === \"row\" ? \"flex-row\" : \"flex-column\",\n `gap-${gap}`,\n align && `align-items-${align}`,\n justify && `justify-content-${justify}`,\n wrap && \"flex-wrap\",\n className\n )}\n >\n {children}\n </div>\n );\n}\n","import type { ElementType, ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport type TextSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type TextWeight = \"normal\" | \"medium\" | \"semibold\" | \"bold\";\nexport type TextTone = \"default\" | \"muted\" | \"primary\" | \"success\" | \"danger\" | \"warning\" | \"info\";\nexport type TextAlign = \"start\" | \"center\" | \"end\";\n\nexport interface TextProps {\n /** Rendered element — defaults to `span`. Pass e.g. `\"h3\"`/`\"p\"`/`\"label\"` for a semantic element without losing the typography contract. */\n as?: ElementType;\n size?: TextSize;\n weight?: TextWeight;\n tone?: TextTone;\n align?: TextAlign;\n /** Single-line ellipsis truncation. */\n truncate?: boolean;\n /** `false` disables wrapping (`text-nowrap`) without truncating. */\n wrap?: boolean;\n className?: string;\n children?: ReactNode;\n}\n\n// em-based sizing (like Icon's SIZE_EM) rather than Bootstrap's fs-1..fs-6\n// heading scale or Metronic's fs-7/fs-8 extension — keeps Text usable in\n// any consuming app regardless of which font-size utilities it ships.\nconst SIZE_REM: Record<TextSize, string> = {\n xs: \"0.75rem\",\n sm: \"0.875rem\",\n md: \"1rem\",\n lg: \"1.25rem\",\n xl: \"1.5rem\",\n};\n\nconst WEIGHT_CLASS: Record<TextWeight, string> = {\n normal: \"fw-normal\",\n medium: \"fw-medium\",\n semibold: \"fw-semibold\",\n bold: \"fw-bold\",\n};\n\nconst TONE_CLASS: Record<TextTone, string | undefined> = {\n default: undefined,\n muted: \"text-body-secondary\",\n primary: \"text-primary\",\n success: \"text-success\",\n danger: \"text-danger\",\n warning: \"text-warning\",\n info: \"text-info\",\n};\n\n/** Generic typography primitive — replaces ad hoc `<span className=\"text-gray-500 fw-semibold fs-7\">` markup at call sites. */\nexport function Text({ as, size = \"md\", weight, tone = \"default\", align, truncate, wrap = true, className, children }: TextProps) {\n const Component = as ?? \"span\";\n\n return (\n <Component\n className={cx(\n weight && WEIGHT_CLASS[weight],\n TONE_CLASS[tone],\n align && `text-${align}`,\n truncate && \"text-truncate\",\n !wrap && !truncate && \"text-nowrap\",\n className\n )}\n style={{ fontSize: SIZE_REM[size] }}\n >\n {children}\n </Component>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Skeleton } from \"./Skeleton\";\nimport { Stack } from \"./Stack\";\nimport { Text } from \"./Text\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface CardProps {\n /** Standard header — renders an icon/avatar + title + subtitle row with a right-aligned actions slot, no manual header markup required. */\n title?: ReactNode;\n subtitle?: ReactNode;\n /** Mutually exclusive with `avatar` — `avatar` wins if both are given. */\n icon?: ReactNode;\n avatar?: ReactNode;\n /** Right-aligned header slot, typically Buttons/IconButtons/Menu. */\n actions?: ReactNode;\n /**\n * Escape hatch for header content the title/subtitle/icon/avatar/actions\n * shape can't express. Wins over all of the above when provided.\n */\n header?: ReactNode;\n footer?: ReactNode;\n /** Replaces `children` with a generic loading skeleton (reuses `Skeleton`, doc: no bespoke shimmer). */\n loading?: boolean;\n className?: string;\n children?: ReactNode;\n}\n\nfunction DefaultHeader({ title, subtitle, icon, avatar, actions }: Pick<CardProps, \"title\" | \"subtitle\" | \"icon\" | \"avatar\" | \"actions\">) {\n return (\n <div className=\"d-flex align-items-center justify-content-between gap-3\">\n <div className=\"d-flex align-items-center gap-3\" style={{ minWidth: 0 }}>\n {avatar ? avatar : icon && <span className=\"fs-2 lh-1\">{icon}</span>}\n {(title || subtitle) && (\n <div style={{ minWidth: 0 }}>\n {title && (\n <Text as=\"div\" size=\"lg\" weight=\"semibold\" truncate>\n {title}\n </Text>\n )}\n {subtitle && (\n <Text as=\"div\" size=\"sm\" tone=\"muted\" truncate>\n {subtitle}\n </Text>\n )}\n </div>\n )}\n </div>\n {actions && <div className=\"d-flex align-items-center gap-2 flex-shrink-0\">{actions}</div>}\n </div>\n );\n}\n\n/** Generic content container — the most basic layout primitive, used to group everything else. */\nexport function Card({ title, subtitle, icon, avatar, actions, header, footer, loading, className, children }: CardProps) {\n const hasStandardHeader = Boolean(title || subtitle || icon || avatar || actions);\n const resolvedHeader = header ?? (hasStandardHeader ? <DefaultHeader title={title} subtitle={subtitle} icon={icon} avatar={avatar} actions={actions} /> : undefined);\n\n return (\n <div className={cx(\"card\", className)}>\n {resolvedHeader && <div className=\"card-header\">{resolvedHeader}</div>}\n <div className=\"card-body\">\n {loading ? (\n <Stack gap={2}>\n <Skeleton height=\"1rem\" width=\"60%\" />\n <Skeleton height=\"1rem\" />\n <Skeleton height=\"1rem\" width=\"80%\" />\n </Stack>\n ) : (\n children\n )}\n </div>\n {footer && <div className=\"card-footer\">{footer}</div>}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface DividerProps {\n className?: string;\n vertical?: boolean;\n /** Optional centered label (e.g. \"OR\") — renders a labeled horizontal divider instead of a plain line. */\n label?: ReactNode;\n}\n\nexport function Divider({ className, vertical, label }: DividerProps) {\n if (vertical) {\n return <div className={cx(\"vr\", className)} role=\"separator\" aria-orientation=\"vertical\" />;\n }\n\n if (label) {\n return (\n <div className={cx(\"d-flex align-items-center gap-2 my-3\", className)} role=\"separator\">\n <hr className=\"flex-grow-1 m-0\" />\n <span className=\"text-body-secondary small\">{label}</span>\n <hr className=\"flex-grow-1 m-0\" />\n </div>\n );\n }\n\n return <hr className={cx(\"my-3\", className)} role=\"separator\" />;\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface ContainerProps {\n fluid?: boolean;\n className?: string;\n children?: ReactNode;\n}\n\nexport function Container({ fluid, className, children }: ContainerProps) {\n return <div className={cx(fluid ? \"container-fluid\" : \"container\", className)}>{children}</div>;\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface RowProps {\n className?: string;\n children?: ReactNode;\n}\n\nexport function Row({ className, children }: RowProps) {\n return <div className={cx(\"row\", className)}>{children}</div>;\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface ColProps {\n /** Column width at the default breakpoint (1-12). Omit for `col` (auto-width). */\n span?: number;\n sm?: number;\n md?: number;\n lg?: number;\n xl?: number;\n className?: string;\n children?: ReactNode;\n}\n\nexport function Col({ span, sm, md, lg, xl, className, children }: ColProps) {\n return (\n <div\n className={cx(\n span ? `col-${span}` : \"col\",\n sm ? `col-sm-${sm}` : undefined,\n md ? `col-md-${md}` : undefined,\n lg ? `col-lg-${lg}` : undefined,\n xl ? `col-xl-${xl}` : undefined,\n className\n )}\n >\n {children}\n </div>\n );\n}\n","import { cx } from \"./shared/classNames\";\n\nexport interface BreadcrumbItem {\n label: string;\n href?: string;\n onClick?: () => void;\n}\n\nexport interface BreadcrumbProps {\n items: BreadcrumbItem[];\n className?: string;\n}\n\nexport function Breadcrumb({ items, className }: BreadcrumbProps) {\n return (\n <nav aria-label=\"breadcrumb\" className={className}>\n <ol className=\"breadcrumb mb-0\">\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n const isInteractive = !isLast && (item.href || item.onClick);\n return (\n <li key={index} className={cx(\"breadcrumb-item\", isLast && \"active\")} aria-current={isLast ? \"page\" : undefined}>\n {isInteractive ? (\n <a\n href={item.href ?? \"#\"}\n onClick={(event) => {\n if (!item.href) event.preventDefault();\n item.onClick?.();\n }}\n >\n {item.label}\n </a>\n ) : (\n item.label\n )}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n}\n","import { useCallback, useRef, useState, type ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\nimport { Popup } from \"./shared/Popup\";\nimport { useListNavigation } from \"./shared/useListNavigation\";\n\nexport interface MenuItem {\n key: string;\n label: ReactNode;\n disabled?: boolean;\n danger?: boolean;\n onSelect?: () => void;\n}\n\nexport interface MenuProps {\n items: MenuItem[];\n children: ReactNode;\n placement?: \"start\" | \"end\";\n className?: string;\n}\n\n/**\n * A generic click-triggered action menu (e.g. a \"...\" row action button) —\n * distinct from Select/ComboBox, which pick a *value*. Reuses Popup +\n * useListNavigation, the same headless pair ComboBox/AutoComplete/\n * MultiSelect already share (doc's reuse mandate).\n */\nexport function Menu({ items, children, placement = \"start\", className }: MenuProps) {\n const [open, setOpen] = useState(false);\n const anchorRef = useRef<HTMLSpanElement>(null);\n\n const close = useCallback(() => setOpen(false), []);\n const selectIndex = useCallback(\n (index: number) => {\n const item = items[index];\n if (!item || item.disabled) return;\n item.onSelect?.();\n close();\n },\n [items, close]\n );\n\n const { activeIndex, setActiveIndex, handleKeyDown } = useListNavigation({\n itemCount: items.length,\n isOpen: open,\n onSelect: selectIndex,\n onClose: close,\n });\n\n return (\n <span\n ref={anchorRef}\n className=\"position-relative d-inline-block\"\n onClick={() => setOpen((prev) => !prev)}\n onKeyDown={handleKeyDown}\n >\n {children}\n <Popup\n open={open}\n onClose={close}\n anchorRef={anchorRef}\n role=\"menu\"\n className={cx(\"dropdown-menu show\", placement === \"end\" && \"dropdown-menu-end\", className)}\n >\n {items.map((item, index) => (\n <button\n key={item.key}\n type=\"button\"\n role=\"menuitem\"\n className={cx(\"dropdown-item\", index === activeIndex && \"active\", item.disabled && \"disabled\", item.danger && \"text-danger\")}\n disabled={item.disabled}\n onMouseEnter={() => setActiveIndex(index)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={(event) => {\n // Without this, the click bubbles to the trigger <span>'s own\n // onClick (which toggles `open`), racing with close() from\n // selectIndex() in the same batch and leaving the menu open.\n event.stopPropagation();\n selectIndex(index);\n }}\n >\n {item.label}\n </button>\n ))}\n </Popup>\n </span>\n );\n}\n","import { cx } from \"./shared/classNames\";\n\nexport interface StepItem {\n key: string;\n label: string;\n description?: string;\n}\n\nexport interface StepperProps {\n steps: StepItem[];\n /** Index of the current step (0-based). Presentation only — no built-in next/back logic, that's app-level. */\n currentStep: number;\n className?: string;\n}\n\nexport function Stepper({ steps, currentStep, className }: StepperProps) {\n return (\n <ol className={cx(\"d-flex list-unstyled align-items-center\", className)}>\n {steps.map((step, index) => {\n const status = index < currentStep ? \"complete\" : index === currentStep ? \"active\" : \"upcoming\";\n const isLast = index === steps.length - 1;\n return (\n <li key={step.key} className={cx(\"d-flex align-items-center\", !isLast && \"flex-grow-1\")}>\n <div className=\"d-flex align-items-center gap-2\">\n <span\n className={cx(\n \"d-flex align-items-center justify-content-center rounded-circle flex-shrink-0\",\n status === \"complete\" ? \"bg-primary text-white\" : status === \"active\" ? \"border border-primary text-primary\" : \"border text-body-secondary\"\n )}\n style={{ width: \"2rem\", height: \"2rem\" }}\n aria-current={status === \"active\" ? \"step\" : undefined}\n >\n {status === \"complete\" ? \"✓\" : index + 1}\n </span>\n <div>\n <div className={cx(\"small fw-semibold\", status === \"upcoming\" && \"text-body-secondary\")}>{step.label}</div>\n {step.description && <div className=\"small text-body-secondary\">{step.description}</div>}\n </div>\n </div>\n {!isLast && <hr className=\"flex-grow-1 mx-2\" />}\n </li>\n );\n })}\n </ol>\n );\n}\n","import { cx } from \"./shared/classNames\";\n\nexport interface AvatarProps {\n src?: string;\n /** Used both for the image's alt text and for the initials fallback when there's no `src`. */\n name?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n const first = parts[0]?.[0] ?? \"\";\n const last = parts.length > 1 ? (parts[parts.length - 1]?.[0] ?? \"\") : \"\";\n return (first + last).toUpperCase();\n}\n\nconst DIMENSION: Record<NonNullable<AvatarProps[\"size\"]>, string> = {\n sm: \"1.75rem\",\n md: \"2.5rem\",\n lg: \"3.5rem\",\n};\n\nexport function Avatar({ src, name, size = \"md\", className }: AvatarProps) {\n const dimension = DIMENSION[size];\n\n if (src) {\n return (\n <img\n src={src}\n alt={name ?? \"\"}\n className={cx(\"rounded-circle\", className)}\n style={{ width: dimension, height: dimension, objectFit: \"cover\" }}\n />\n );\n }\n\n return (\n <span\n className={cx(\"d-inline-flex align-items-center justify-content-center rounded-circle bg-secondary text-white\", className)}\n style={{ width: dimension, height: dimension, fontSize: `calc(${dimension} * 0.4)` }}\n role={name ? \"img\" : undefined}\n aria-label={name}\n >\n {name ? getInitials(name) : null}\n </span>\n );\n}\n","import type { ReactNode } from \"react\";\nimport type { BadgeVariant } from \"./Badge\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface TagProps {\n variant?: BadgeVariant;\n onRemove?: () => void;\n className?: string;\n children: ReactNode;\n}\n\n/**\n * Reuses Badge's variant type (same visual vocabulary) — the difference\n * from Badge is purely behavioral: Tag is removable/interactive, Badge is\n * static.\n */\nexport function Tag({ variant = \"secondary\", onRemove, className, children }: TagProps) {\n return (\n <span className={cx(\"badge d-inline-flex align-items-center gap-1\", `bg-${variant}`, className)}>\n {children}\n {onRemove && (\n <button\n type=\"button\"\n className=\"btn-close btn-close-white\"\n style={{ fontSize: \"0.55rem\" }}\n aria-label=\"Remove\"\n onClick={onRemove}\n />\n )}\n </span>\n );\n}\n","import { useId } from \"react\";\nimport { FieldShell } from \"./shared/FieldShell\";\nimport { useControllableState } from \"./shared/useControllableState\";\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\n\nexport interface SliderProps extends FieldIdentity, FieldState, FieldPresentation {\n value?: number;\n defaultValue?: number;\n onChange?: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n}\n\nexport function Slider({\n value,\n defaultValue,\n onChange,\n min = 0,\n max = 100,\n step = 1,\n id,\n name,\n disabled,\n required,\n className,\n label,\n helpText,\n error,\n}: SliderProps) {\n const [currentValue, setValue] = useControllableState<number>({\n value,\n defaultValue: defaultValue ?? min,\n onChange,\n });\n\n const generatedId = useId();\n const fieldId = id ?? generatedId;\n\n return (\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\n <input\n id={fieldId}\n name={name}\n type=\"range\"\n className=\"form-range\"\n disabled={disabled}\n required={required}\n min={min}\n max={max}\n step={step}\n value={currentValue}\n onChange={(event) => setValue(Number(event.target.value))}\n />\n <div className=\"small text-body-secondary\">{currentValue}</div>\n </FieldShell>\n );\n}\n","import { cx } from \"./shared/classNames\";\nimport { useControllableState } from \"./shared/useControllableState\";\n\nexport interface RatingProps {\n value?: number;\n defaultValue?: number;\n onChange?: (value: number) => void;\n max?: number;\n disabled?: boolean;\n className?: string;\n}\n\nexport function Rating({ value, defaultValue, onChange, max = 5, disabled, className }: RatingProps) {\n const [currentValue, setValue] = useControllableState<number>({\n value,\n defaultValue: defaultValue ?? 0,\n onChange,\n });\n\n return (\n <div className={cx(\"d-inline-flex gap-1\", className)} role=\"radiogroup\" aria-label=\"Rating\">\n {Array.from({ length: max }, (_, index) => index + 1).map((n) => (\n <button\n key={n}\n type=\"button\"\n className=\"btn btn-link p-0 border-0\"\n disabled={disabled}\n role=\"radio\"\n aria-checked={n === currentValue}\n aria-label={`${n} star${n > 1 ? \"s\" : \"\"}`}\n onClick={() => setValue(n)}\n >\n <span aria-hidden=\"true\" style={{ fontSize: \"1.25rem\", color: n <= currentValue ? \"#f5b301\" : \"#ced4da\" }}>\n ★\n </span>\n </button>\n ))}\n </div>\n );\n}\n","import type { BadgeVariant } from \"./Badge\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface ProgressBarProps {\n /** 0-100. Values outside that range are clamped. */\n value: number;\n variant?: BadgeVariant;\n /** Show the percentage as text inside the bar. */\n label?: boolean;\n className?: string;\n}\n\nexport function ProgressBar({ value, variant = \"primary\", label, className }: ProgressBarProps) {\n const clamped = Math.max(0, Math.min(100, value));\n\n return (\n <div className={cx(\"progress\", className)} role=\"progressbar\" aria-valuenow={clamped} aria-valuemin={0} aria-valuemax={100}>\n <div className={cx(\"progress-bar\", `bg-${variant}`)} style={{ width: `${clamped}%` }}>\n {label ? `${Math.round(clamped)}%` : null}\n </div>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface NavbarProps {\n brand?: ReactNode;\n /** Left-aligned slot, e.g. primary nav links. */\n start?: ReactNode;\n /** Right-aligned slot, e.g. search, notifications, user menu. */\n end?: ReactNode;\n variant?: \"light\" | \"dark\";\n className?: string;\n}\n\n/**\n * Top app bar shell. Brand/start/end are plain slots — actual nav links,\n * routing, and auth/user menus belong to the consuming app (doc section 22:\n * Base must not touch routing or auth), not to this component.\n */\nexport function Navbar({ brand, start, end, variant = \"light\", className }: NavbarProps) {\n return (\n <nav\n className={cx(\n \"navbar navbar-expand-lg border-bottom\",\n variant === \"dark\" ? \"navbar-dark bg-dark\" : \"navbar-light bg-light\",\n className\n )}\n >\n <div className=\"container-fluid\">\n {brand && <span className=\"navbar-brand mb-0\">{brand}</span>}\n {start && <div className=\"d-flex align-items-center gap-3\">{start}</div>}\n {end && <div className=\"d-flex align-items-center gap-3 ms-auto\">{end}</div>}\n </div>\n </nav>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Accordion } from \"./Accordion\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface SidebarLeafItem {\n key: string;\n label: ReactNode;\n icon?: ReactNode;\n href?: string;\n onClick?: () => void;\n active?: boolean;\n disabled?: boolean;\n}\n\nexport interface SidebarGroup {\n key: string;\n label: string;\n items: SidebarLeafItem[];\n defaultOpen?: boolean;\n}\n\nexport type SidebarSection = SidebarLeafItem | SidebarGroup;\n\nexport interface SidebarProps {\n sections: SidebarSection[];\n header?: ReactNode;\n footer?: ReactNode;\n className?: string;\n}\n\nfunction isGroup(section: SidebarSection): section is SidebarGroup {\n return \"items\" in section;\n}\n\nfunction SidebarLink({ item }: { item: SidebarLeafItem }) {\n return (\n <a\n href={item.href ?? \"#\"}\n className={cx(\"nav-link d-flex align-items-center gap-2\", item.active && \"active\", item.disabled && \"disabled\")}\n aria-current={item.active ? \"page\" : undefined}\n aria-disabled={item.disabled}\n onClick={(event) => {\n if (!item.href) event.preventDefault();\n if (item.disabled) return;\n item.onClick?.();\n }}\n >\n {item.icon}\n {item.label}\n </a>\n );\n}\n\n/**\n * Persistent vertical navigation. Leaf entries render as plain nav links;\n * grouped/collapsible sections reuse Accordion (doc section 20 — no second\n * independent collapse implementation) instead of reimplementing open/close\n * state. Active-state comes from the `active` flag the caller passes in —\n * routing/URL matching is the consuming app's job (doc section 22).\n */\nexport function Sidebar({ sections, header, footer, className }: SidebarProps) {\n return (\n <div className={cx(\"d-flex flex-column h-100\", className)}>\n {header && <div className=\"p-3 border-bottom\">{header}</div>}\n <nav className=\"nav flex-column flex-grow-1 p-2 gap-1\">\n {sections.map((section) =>\n isGroup(section) ? (\n <Accordion\n key={section.key}\n className=\"border-0\"\n defaultOpenKeys={section.defaultOpen ? [section.key] : []}\n items={[\n {\n key: section.key,\n header: section.label,\n content: (\n <div className=\"nav flex-column ps-2 gap-1\">\n {section.items.map((item) => (\n <SidebarLink key={item.key} item={item} />\n ))}\n </div>\n ),\n },\n ]}\n />\n ) : (\n <SidebarLink key={section.key} item={section} />\n )\n )}\n </nav>\n {footer && <div className=\"p-3 border-top\">{footer}</div>}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Breadcrumb, type BreadcrumbItem } from \"./Breadcrumb\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface PageHeaderProps {\n title: ReactNode;\n description?: ReactNode;\n breadcrumbItems?: BreadcrumbItem[];\n /** Right-aligned slot, typically page-level Buttons. */\n actions?: ReactNode;\n className?: string;\n}\n\n/** Composes Breadcrumb (doc section 20 — reuse, don't re-derive trail markup) for the standard title/breadcrumb/actions row atop a page. */\nexport function PageHeader({ title, description, breadcrumbItems, actions, className }: PageHeaderProps) {\n return (\n <div className={cx(\"mb-4\", className)}>\n {breadcrumbItems && breadcrumbItems.length > 0 && <Breadcrumb items={breadcrumbItems} className=\"mb-2\" />}\n <div className=\"d-flex align-items-start justify-content-between gap-3 flex-wrap\">\n <div>\n <h1 className=\"h3 mb-1\">{title}</h1>\n {description && <p className=\"text-body-secondary mb-0\">{description}</p>}\n </div>\n {actions && <div className=\"d-flex align-items-center gap-2\">{actions}</div>}\n </div>\n </div>\n );\n}\n","import { Stack, type StackProps } from \"./Stack\";\nimport { cx } from \"./shared/classNames\";\n\nexport type FlexGap = NonNullable<StackProps[\"gap\"]> | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nconst GAP_TOKEN: Record<\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\", NonNullable<StackProps[\"gap\"]>> = {\n xs: 1,\n sm: 2,\n md: 3,\n lg: 4,\n xl: 5,\n};\n\nexport interface FlexProps extends Omit<StackProps, \"gap\"> {\n gap?: FlexGap;\n /** `flex-grow-1` on the container itself (for a Flex nested inside another flex layout). */\n grow?: boolean;\n /** `flex-shrink-0` on the container itself. */\n shrink?: boolean;\n /** `w-100`. */\n fullWidth?: boolean;\n}\n\nfunction resolveGap(gap: FlexGap): NonNullable<StackProps[\"gap\"]> {\n return typeof gap === \"number\" ? gap : GAP_TOKEN[gap];\n}\n\n/**\n * Arbitrary flex layout on top of the same `d-flex` machinery Stack already\n * owns (doc: \"do not duplicate Stack\") — only the defaults and the extra\n * grow/shrink/fullWidth concerns differ. Stack defaults to a column\n * (vertical list of children); Flex defaults to a row, matching the\n * `<div className=\"d-flex align-items-center justify-content-between\">`\n * call sites it's meant to replace.\n */\nexport function Flex({ direction = \"row\", gap = \"sm\", grow, shrink, fullWidth, className, ...rest }: FlexProps) {\n return (\n <Stack\n direction={direction}\n gap={resolveGap(gap)}\n className={cx(grow && \"flex-grow-1\", shrink && \"flex-shrink-0\", fullWidth && \"w-100\", className)}\n {...rest}\n />\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Button, type ButtonProps } from \"./Button\";\nimport { Icon, type IconProps } from \"./Icon\";\nimport { Tooltip } from \"./Tooltip\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface IconButtonProps extends Omit<ButtonProps, \"children\"> {\n /** Icon class name(s), passed straight through to `Icon` (icon-set agnostic — doc section 15). */\n icon: string;\n /** Required — an icon-only control has no visible text, so it must carry its own accessible name. */\n \"aria-label\": string;\n iconSize?: IconProps[\"size\"];\n /** Optional tooltip, composed from the existing `Tooltip` primitive rather than a second hover-label implementation. */\n tooltip?: ReactNode;\n}\n\n/** Composes Button + Icon (doc: reuse, don't build a second button system) for the common icon-only action button. */\nexport function IconButton({ icon, \"aria-label\": ariaLabel, iconSize, tooltip, variant = \"light\", loading, className, ...rest }: IconButtonProps) {\n const button = (\n <Button variant={variant} loading={loading} className={cx(\"btn-icon\", className)} aria-label={ariaLabel} {...rest}>\n {!loading && <Icon name={icon} size={iconSize} />}\n </Button>\n );\n\n return tooltip ? <Tooltip content={tooltip}>{button}</Tooltip> : button;\n}\n","import type { ReactNode } from \"react\";\nimport { cx } from \"./shared/classNames\";\n\nexport interface ListItemProps {\n /** Typically an `Avatar` or `Icon`. */\n leading?: ReactNode;\n title: ReactNode;\n description?: ReactNode;\n /** Typically an `IconButton`, `Badge`, or `Sparkline`. */\n trailing?: ReactNode;\n /** Presence makes the row an interactive `<button>` (established row-action pattern). */\n onClick?: () => void;\n disabled?: boolean;\n /** Tighter vertical rhythm for dense lists (e.g. inside a DataGrid cell). */\n dense?: boolean;\n className?: string;\n}\n\n/**\n * Generic leading/title-description/trailing row — the same shape as MUI's\n * `ListItem` + `ListItemAvatar` + `ListItemText` or Ant Design's\n * `List.Item.Meta`. Replaces repeated `<div className=\"d-flex\n * align-items-center\"><Avatar/><div><span/><span/></div></div>` markup.\n * Intentionally has no domain-specific counterpart (no `AuthorItem`/\n * `UserItem`) — callers pass whatever leading/title/description/trailing\n * content their row needs.\n */\nexport function ListItem({ leading, title, description, trailing, onClick, disabled, dense, className }: ListItemProps) {\n const content = (\n <>\n {leading && <span className=\"flex-shrink-0 d-inline-flex align-items-center\">{leading}</span>}\n <span className=\"flex-grow-1\" style={{ minWidth: 0 }}>\n <span className=\"d-block text-truncate\">{title}</span>\n {description && <span className=\"d-block text-truncate small text-body-secondary\">{description}</span>}\n </span>\n {trailing && <span className=\"flex-shrink-0 d-inline-flex align-items-center\">{trailing}</span>}\n </>\n );\n\n const rowClassName = cx(\n \"d-flex align-items-center text-start\",\n dense ? \"gap-2 py-1\" : \"gap-3 py-2\",\n onClick && \"w-100 border-0 bg-transparent\",\n disabled && \"opacity-50\",\n className\n );\n\n if (onClick) {\n return (\n <button type=\"button\" className={rowClassName} onClick={onClick} disabled={disabled}>\n {content}\n </button>\n );\n }\n\n return (\n <div className={rowClassName} aria-disabled={disabled || undefined}>\n {content}\n </div>\n );\n}\n","import { cx } from \"./shared/classNames\";\n\nexport type SparklineType = \"line\" | \"area\" | \"bar\";\nexport type SparklineTone = \"primary\" | \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" | \"dark\";\n\nexport interface SparklineProps {\n type?: SparklineType;\n data: number[];\n tone?: SparklineTone;\n width?: number;\n height?: number;\n strokeWidth?: number;\n className?: string;\n /** Accessible label — omit for a purely decorative chart (default: aria-hidden), same convention as `Icon`. */\n label?: string;\n}\n\nfunction buildLinePoints(data: number[], width: number, height: number, padding: number): Array<[number, number]> {\n if (data.length === 0) return [];\n const min = Math.min(...data);\n const max = Math.max(...data);\n const range = max - min || 1;\n const innerWidth = width - padding * 2;\n const innerHeight = height - padding * 2;\n const step = data.length > 1 ? innerWidth / (data.length - 1) : 0;\n\n return data.map((value, index) => {\n const x = padding + step * index;\n const y = padding + innerHeight - ((value - min) / range) * innerHeight;\n return [x, y];\n });\n}\n\nfunction LineOrArea({ type, data, width, height, strokeWidth }: { type: \"line\" | \"area\"; data: number[]; width: number; height: number; strokeWidth: number }) {\n const padding = strokeWidth;\n const points = buildLinePoints(data, width, height, padding);\n if (points.length === 0) return null;\n\n const linePoints = points.map(([x, y]) => `${x},${y}`).join(\" \");\n\n return (\n <>\n {type === \"area\" && (\n <polygon\n points={`${padding},${height - padding} ${linePoints} ${width - padding},${height - padding}`}\n fill=\"currentColor\"\n opacity={0.2}\n stroke=\"none\"\n />\n )}\n <polyline points={linePoints} fill=\"none\" stroke=\"currentColor\" strokeWidth={strokeWidth} strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </>\n );\n}\n\nfunction Bars({ data, width, height }: { data: number[]; width: number; height: number }) {\n if (data.length === 0) return null;\n const min = Math.min(0, ...data);\n const max = Math.max(0, ...data);\n const range = max - min || 1;\n const gap = 2;\n const barWidth = Math.max((width - gap * (data.length - 1)) / data.length, 1);\n\n return (\n <>\n {data.map((value, index) => {\n const barHeight = Math.max(((value - min) / range) * height, 1);\n const x = index * (barWidth + gap);\n const y = height - barHeight;\n return <rect key={index} x={x} y={y} width={barWidth} height={barHeight} rx={1} fill=\"currentColor\" />;\n })}\n </>\n );\n}\n\n/**\n * Compact inline chart — the established dashboard \"sparkline\" concept\n * (MUI X `SparkLineChart`, DevExtreme/Kendo Sparkline). Implemented with\n * plain inline SVG rather than a charting dependency: this repo doesn't\n * already depend on one, and a public API shaped around `data`/`type`/\n * `tone` stays implementation-agnostic either way (doc: avoid unnecessary\n * dependencies; don't leak chart-library config as the public API).\n */\nexport function Sparkline({ type = \"line\", data, tone = \"primary\", width = 80, height = 28, strokeWidth = 2, className, label }: SparklineProps) {\n return (\n <svg\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n className={cx(`text-${tone}`, className)}\n role={label ? \"img\" : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n >\n {type === \"bar\" ? <Bars data={data} width={width} height={height} /> : <LineOrArea type={type} data={data} width={width} height={height} strokeWidth={strokeWidth} />}\n </svg>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Icon } from \"./Icon\";\nimport { Skeleton } from \"./Skeleton\";\nimport { Text, type TextTone } from \"./Text\";\nimport { cx } from \"./shared/classNames\";\n\nexport type StatisticTrend = \"up\" | \"down\" | \"neutral\";\n\nexport interface StatisticProps {\n label: ReactNode;\n value: number | string;\n prefix?: ReactNode;\n suffix?: ReactNode;\n /** Decimal places applied when `value` is a number. */\n precision?: number;\n trend?: StatisticTrend;\n delta?: ReactNode;\n loading?: boolean;\n className?: string;\n}\n\nconst TREND_TONE: Record<StatisticTrend, TextTone> = {\n up: \"success\",\n down: \"danger\",\n neutral: \"muted\",\n};\n\nconst TREND_ICON: Record<StatisticTrend, string> = {\n up: \"bi bi-arrow-up-short\",\n down: \"bi bi-arrow-down-short\",\n neutral: \"bi bi-dash\",\n};\n\nfunction formatValue(value: number | string, precision?: number): string {\n return typeof value === \"number\" && precision != null ? value.toFixed(precision) : String(value);\n}\n\n/** Label/value/prefix/suffix/trend — the established dashboard \"Statistic\"/\"Stat\" pattern (MUI, Ant Design, Mantine). No dashboard business logic. */\nexport function Statistic({ label, value, prefix, suffix, precision, trend, delta, loading, className }: StatisticProps) {\n return (\n <div className={cx(\"d-flex flex-column gap-1\", className)}>\n <Text size=\"sm\" tone=\"muted\">\n {label}\n </Text>\n\n {loading ? (\n <Skeleton height=\"1.75rem\" width=\"60%\" />\n ) : (\n <div className=\"d-flex align-items-baseline gap-1\">\n {prefix && (\n <Text size=\"lg\" weight=\"semibold\">\n {prefix}\n </Text>\n )}\n <Text size=\"xl\" weight=\"bold\">\n {formatValue(value, precision)}\n </Text>\n {suffix && (\n <Text size=\"lg\" weight=\"semibold\">\n {suffix}\n </Text>\n )}\n </div>\n )}\n\n {!loading && (trend || delta != null) && (\n <Text size=\"sm\" tone={trend ? TREND_TONE[trend] : \"muted\"} className=\"d-inline-flex align-items-center gap-1\">\n {trend && <Icon name={TREND_ICON[trend]} size=\"sm\" />}\n {delta}\n </Text>\n )}\n </div>\n );\n}\n","export interface HttpRequestOptions {\n params?: Record<string, unknown>;\n signal?: AbortSignal;\n}\n\nexport interface HttpClient {\n get<TResponse>(url: string, options?: HttpRequestOptions): Promise<TResponse>;\n}\n\nexport class HttpError extends Error {\n status: number;\n statusText: string;\n url: string;\n\n constructor(status: number, statusText: string, url: string) {\n super(`HTTP ${status} ${statusText} for ${url}`);\n this.name = \"HttpError\";\n this.status = status;\n this.statusText = statusText;\n this.url = url;\n }\n}\n\nfunction serializeParams(params?: Record<string, unknown>): string {\n if (!params) return \"\";\n const searchParams = new URLSearchParams();\n for (const [key, rawValue] of Object.entries(params)) {\n if (rawValue === undefined || rawValue === null) continue;\n searchParams.set(key, String(rawValue));\n }\n const query = searchParams.toString();\n return query ? `?${query}` : \"\";\n}\n\nexport interface CreateHttpClientOptions {\n baseUrl?: string;\n /** Injectable fetch implementation — used by tests, could also route through a wrapped/instrumented fetch. */\n fetcher?: typeof fetch;\n /**\n * Extension point for cross-cutting concerns the doc explicitly defers\n * (authorization, tenant headers, interceptors) without building them now\n * (doc section 6: only establish extension points where justified).\n */\n buildRequestInit?: (url: string, init: RequestInit) => RequestInit;\n}\n\n/**\n * The single place Remote Components go through to talk to a backend.\n * Base Components never import this (enforced by dependency direction, not\n * just convention — Base has no dependency on `remote/*` at all).\n */\nexport function createHttpClient(options: CreateHttpClientOptions = {}): HttpClient {\n const { baseUrl = \"\", fetcher = fetch, buildRequestInit } = options;\n\n return {\n async get<TResponse>(url: string, requestOptions: HttpRequestOptions = {}): Promise<TResponse> {\n const fullUrl = `${baseUrl}${url}${serializeParams(requestOptions.params)}`;\n let init: RequestInit = { method: \"GET\", signal: requestOptions.signal };\n if (buildRequestInit) init = buildRequestInit(fullUrl, init);\n\n const response = await fetcher(fullUrl, init);\n if (!response.ok) {\n throw new HttpError(response.status, response.statusText, fullUrl);\n }\n return (await response.json()) as TResponse;\n },\n };\n}\n\nexport const defaultHttpClient = createHttpClient();\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { defaultHttpClient, type HttpClient } from \"../http/HttpClient\";\n\nexport type RemoteState = \"idle\" | \"loading\" | \"success\" | \"empty\" | \"error\";\n\nexport interface UseRemoteDataOptions<TResponse, TItem> {\n client?: HttpClient;\n /** `null`/`undefined` disables fetching entirely (e.g. RemoteAutoComplete below minSearchLength). */\n url: string | null | undefined;\n params?: Record<string, unknown>;\n mapResponse: (response: TResponse) => TItem[];\n enabled?: boolean;\n}\n\nexport interface UseRemoteDataResult<TItem> {\n state: RemoteState;\n items: TItem[];\n error: Error | null;\n reload: () => void;\n}\n\nfunction sortKeys(obj: Record<string, unknown>): Record<string, unknown> {\n return Object.keys(obj)\n .sort()\n .reduce<Record<string, unknown>>((acc, key) => {\n acc[key] = obj[key];\n return acc;\n }, {});\n}\n\n/**\n * The one place remote/API data fetching lifecycle logic lives. Every\n * Remote Component (RemoteComboBox, RemoteAutoComplete, RemoteDataGrid)\n * composes this instead of writing its own fetch effect (doc section 6).\n *\n * Handles, per doc sections 5/7/8:\n * - stable request identity: params are compared by serialized *value*,\n * not object reference, so a new `{ ...params }` literal each render\n * does not cause an infinite request loop.\n * - request cancellation via AbortController.\n * - stale-response protection via a monotonically increasing request id,\n * which still guards correctness even if abort doesn't win the race.\n * - a consistent idle/loading/success/empty/error state model.\n */\nexport function useRemoteData<TResponse, TItem>({\n client = defaultHttpClient,\n url,\n params,\n mapResponse,\n enabled = true,\n}: UseRemoteDataOptions<TResponse, TItem>): UseRemoteDataResult<TItem> {\n const [state, setState] = useState<RemoteState>(\"idle\");\n const [items, setItems] = useState<TItem[]>([]);\n const [error, setError] = useState<Error | null>(null);\n const [reloadToken, setReloadToken] = useState(0);\n\n const paramsKey = useMemo(() => (params ? JSON.stringify(sortKeys(params)) : \"\"), [params]);\n\n const latestRequestId = useRef(0);\n const mapResponseRef = useRef(mapResponse);\n mapResponseRef.current = mapResponse;\n\n useEffect(() => {\n if (!enabled || !url) {\n setState(\"idle\");\n setItems([]);\n setError(null);\n return;\n }\n\n const requestId = ++latestRequestId.current;\n const controller = new AbortController();\n setState(\"loading\");\n setError(null);\n\n client\n .get<TResponse>(url, { params, signal: controller.signal })\n .then((response) => {\n if (requestId !== latestRequestId.current) return;\n const mapped = mapResponseRef.current(response);\n setItems(mapped);\n setState(mapped.length === 0 ? \"empty\" : \"success\");\n })\n .catch((err: unknown) => {\n if (requestId !== latestRequestId.current) return;\n if (err instanceof DOMException && err.name === \"AbortError\") return;\n setError(err instanceof Error ? err : new Error(String(err)));\n setState(\"error\");\n });\n\n return () => {\n controller.abort();\n };\n // paramsKey (not params) is the intentional dependency: it's the stable,\n // value-based identity for \"did the request actually change\".\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [client, url, paramsKey, enabled, reloadToken]);\n\n const reload = useCallback(() => setReloadToken((token) => token + 1), []);\n\n return { state, items, error, reload };\n}\n","import { useEffect, useState } from \"react\";\n\nexport function useDebouncedValue<T>(value: T, delayMs: number): T {\n const [debounced, setDebounced] = useState(value);\n\n useEffect(() => {\n const timer = setTimeout(() => setDebounced(value), delayMs);\n return () => clearTimeout(timer);\n }, [value, delayMs]);\n\n return debounced;\n}\n","import type { SelectOption } from \"../base\";\n\n/**\n * Handles the two common response envelopes (bare array, `{ items: [...] }`)\n * explicitly (doc section 11). Anything else must be handled via an\n * explicit `mapResponse` — no guessing beyond these two conventions.\n */\nexport function defaultArrayNormalization(response: unknown): unknown[] {\n if (Array.isArray(response)) return response;\n if (response && typeof response === \"object\" && Array.isArray((response as { items?: unknown }).items)) {\n return (response as { items: unknown[] }).items;\n }\n throw new Error(\n \"Unable to normalize remote response into an array. Provide an explicit `mapResponse` for this endpoint's response shape.\"\n );\n}\n\nexport function toSelectOption<TValue extends string | number>(\n raw: unknown,\n valueMember: string,\n displayMember: string\n): SelectOption<TValue> {\n if (raw === null || typeof raw !== \"object\") {\n throw new Error(\"Remote item is not an object; cannot read valueMember/displayMember from it.\");\n }\n const record = raw as Record<string, unknown>;\n return {\n value: record[valueMember] as TValue,\n label: String(record[displayMember] ?? \"\"),\n };\n}\n","import { ComboBox, type ComboBoxProps, type SelectOption } from \"../base\";\nimport type { HttpClient } from \"./http/HttpClient\";\nimport { useRemoteData } from \"./hooks/useRemoteData\";\nimport { defaultArrayNormalization, toSelectOption } from \"./mapping\";\n\nexport interface RemoteComboBoxProps<TValue extends string | number = string, TResponse = unknown>\n extends Omit<ComboBoxProps<TValue>, \"options\" | \"loading\"> {\n url: string;\n params?: Record<string, unknown>;\n /** Key read off each raw remote item to produce the option's `value` (doc section 4). */\n valueMember: string;\n /** Key read off each raw remote item to produce the option's `label`. */\n displayMember: string;\n /** Escape hatch for response envelopes beyond bare array / `{ items: [...] }` (doc section 11). */\n mapResponse?: (response: TResponse) => unknown[];\n client?: HttpClient;\n enabled?: boolean;\n}\n\n/**\n * Adds remote-loading behavior to Base ComboBox by composing it — this is\n * NOT a second independent ComboBox implementation (doc section 20). All\n * selection/keyboard/popup UI behavior is Base ComboBox's; this component\n * only owns fetch lifecycle + raw-item -> SelectOption mapping.\n */\nexport function RemoteComboBox<TValue extends string | number = string, TResponse = unknown>({\n url,\n params,\n valueMember,\n displayMember,\n mapResponse,\n client,\n enabled,\n ...comboBoxProps\n}: RemoteComboBoxProps<TValue, TResponse>) {\n const { state, items, error } = useRemoteData<TResponse, SelectOption<TValue>>({\n client,\n url,\n params,\n enabled,\n mapResponse: (response) => {\n const rawItems = mapResponse ? mapResponse(response) : defaultArrayNormalization(response);\n return rawItems.map((raw) => toSelectOption<TValue>(raw, valueMember, displayMember));\n },\n });\n\n // A consumer-supplied `error` (field validation) wins; otherwise fall back\n // to the remote fetch error so failures are visible without requiring\n // every call site to wire this up by hand.\n const resolvedError = comboBoxProps.error ?? (state === \"error\" ? error?.message ?? \"Failed to load options\" : undefined);\n\n return <ComboBox<TValue> {...comboBoxProps} options={items} loading={state === \"loading\"} error={resolvedError} />;\n}\n","import { AutoComplete, type AutoCompleteProps, type SelectOption } from \"../base\";\nimport { useControllableState } from \"../base/shared/useControllableState\";\nimport type { HttpClient } from \"./http/HttpClient\";\nimport { useDebouncedValue } from \"./hooks/useDebouncedValue\";\nimport { useRemoteData } from \"./hooks/useRemoteData\";\nimport { defaultArrayNormalization, toSelectOption } from \"./mapping\";\n\nexport interface RemoteAutoCompleteProps<TValue extends string | number = string, TResponse = unknown>\n extends Omit<AutoCompleteProps<TValue>, \"options\" | \"loading\" | \"filter\"> {\n url: string;\n params?: Record<string, unknown>;\n /** Query-string parameter name the current search text is sent under. */\n searchParam: string;\n valueMember: string;\n displayMember: string;\n mapResponse?: (response: TResponse) => unknown[];\n minSearchLength?: number;\n debounceMs?: number;\n client?: HttpClient;\n}\n\n/**\n * Adds search input handling (debounce, minimum length, remote loading) to\n * Base AutoComplete by composing it. AutoComplete's own local `filter` is\n * disabled here (`() => true`) because the server has already filtered by\n * `searchParam` — re-filtering client-side would silently drop valid\n * server results whose label doesn't literally contain the query text.\n */\nexport function RemoteAutoComplete<TValue extends string | number = string, TResponse = unknown>({\n url,\n params,\n searchParam,\n valueMember,\n displayMember,\n mapResponse,\n minSearchLength = 1,\n debounceMs = 300,\n client,\n inputValue,\n onInputValueChange,\n ...autoCompleteProps\n}: RemoteAutoCompleteProps<TValue, TResponse>) {\n const [internalSearchText, setInternalSearchText] = useControllableState<string>({\n value: inputValue,\n defaultValue: \"\",\n onChange: onInputValueChange,\n });\n\n const debouncedSearchText = useDebouncedValue(internalSearchText, debounceMs);\n const searchReady = debouncedSearchText.length >= minSearchLength;\n\n const { state, items, error } = useRemoteData<TResponse, SelectOption<TValue>>({\n client,\n url,\n enabled: searchReady,\n params: { ...params, [searchParam]: debouncedSearchText },\n mapResponse: (response) => {\n const rawItems = mapResponse ? mapResponse(response) : defaultArrayNormalization(response);\n return rawItems.map((raw) => toSelectOption<TValue>(raw, valueMember, displayMember));\n },\n });\n\n const resolvedError =\n autoCompleteProps.error ?? (state === \"error\" ? error?.message ?? \"Failed to load suggestions\" : undefined);\n\n return (\n <AutoComplete<TValue>\n {...autoCompleteProps}\n options={items}\n loading={state === \"loading\"}\n error={resolvedError}\n inputValue={internalSearchText}\n onInputValueChange={setInternalSearchText}\n filter={() => true}\n />\n );\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { DataGrid, type DataGridProps, type DataGridSort } from \"../base\";\nimport type { HttpClient } from \"./http/HttpClient\";\nimport { useRemoteData } from \"./hooks/useRemoteData\";\nimport { defaultArrayNormalization } from \"./mapping\";\n\nexport interface RemoteDataGridProps<TRow, TResponse = unknown>\n extends Omit<\n DataGridProps<TRow>,\n \"rows\" | \"loading\" | \"error\" | \"page\" | \"pageSize\" | \"totalCount\" | \"onPageChange\" | \"sort\" | \"onSortChange\"\n > {\n url: string;\n /** Additional filter params (e.g. `{ countryId }`) — page/pageSize/sort are managed internally. */\n params?: Record<string, unknown>;\n mapResponse?: (response: TResponse) => TRow[];\n /**\n * Extension point: read a total row count out of the raw response, when\n * the backend provides one. Strongly recommended — without it, pagination\n * falls back to a has-more heuristic (a full page implies \"at least one\n * more page exists\") which cannot show an exact page count.\n */\n getTotalCount?: (response: TResponse) => number | undefined;\n pageSize?: number;\n client?: HttpClient;\n}\n\n/**\n * Adds paging/sorting-against-a-server-endpoint behavior to Base DataGrid\n * by composing it. All table rendering, selection, and pagination/sort UI\n * remain Base DataGrid's — this component only owns request params\n * (page/pageSize/sort/filters) and response mapping (doc section 10).\n */\nexport function RemoteDataGrid<TRow, TResponse = unknown>({\n url,\n params,\n mapResponse,\n getTotalCount,\n pageSize = 20,\n client,\n ...dataGridProps\n}: RemoteDataGridProps<TRow, TResponse>) {\n const [page, setPage] = useState(1);\n const [sort, setSort] = useState<DataGridSort | null>(null);\n\n const paramsKey = useMemo(() => JSON.stringify(params ?? {}), [params]);\n const isFirstRender = useRef(true);\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n setPage(1);\n }, [paramsKey]);\n\n const requestParams = useMemo(\n () => ({\n ...params,\n page,\n pageSize,\n ...(sort ? { sortKey: sort.key, sortDirection: sort.direction } : {}),\n }),\n [params, page, pageSize, sort]\n );\n\n const lastResponseRef = useRef<TResponse | undefined>(undefined);\n\n const { state, items, error } = useRemoteData<TResponse, TRow>({\n client,\n url,\n params: requestParams,\n mapResponse: (response) => {\n lastResponseRef.current = response;\n return mapResponse ? mapResponse(response) : (defaultArrayNormalization(response) as TRow[]);\n },\n });\n\n const explicitTotalCount = lastResponseRef.current !== undefined ? getTotalCount?.(lastResponseRef.current) : undefined;\n // Without a real total from the backend, `items.length` alone only describes the\n // *current* page and would freeze pagination on page 1 forever (totalPages would\n // never exceed 1). Infer \"there's at least one more page\" from a full page coming\n // back, the same has-more heuristic APIs without a count endpoint commonly use.\n const hasMorePages = items.length >= pageSize && pageSize > 0;\n const inferredTotalCount = hasMorePages ? page * pageSize + 1 : (page - 1) * pageSize + items.length;\n const totalCount = explicitTotalCount ?? inferredTotalCount;\n\n return (\n <DataGrid<TRow>\n {...dataGridProps}\n rows={items}\n loading={state === \"loading\"}\n error={error?.message}\n page={page}\n pageSize={pageSize}\n totalCount={totalCount}\n onPageChange={setPage}\n sort={sort}\n onSortChange={(next) => {\n setSort(next);\n setPage(1);\n }}\n />\n );\n}\n","import { Select, type SelectOption, type SelectProps } from \"../base\";\nimport type { HttpClient } from \"./http/HttpClient\";\nimport { useRemoteData } from \"./hooks/useRemoteData\";\nimport { defaultArrayNormalization, toSelectOption } from \"./mapping\";\n\nexport interface RemoteSelectProps<TValue extends string | number = string, TResponse = unknown>\n extends Omit<SelectProps<TValue>, \"options\" | \"loading\"> {\n url: string;\n params?: Record<string, unknown>;\n valueMember: string;\n displayMember: string;\n mapResponse?: (response: TResponse) => unknown[];\n client?: HttpClient;\n enabled?: boolean;\n}\n\n/**\n * Same reuse pattern as RemoteComboBox: composes Base Select instead of\n * reimplementing it (doc section 20). Thin — only fetch lifecycle +\n * valueMember/displayMember mapping belong here.\n */\nexport function RemoteSelect<TValue extends string | number = string, TResponse = unknown>({\n url,\n params,\n valueMember,\n displayMember,\n mapResponse,\n client,\n enabled,\n ...selectProps\n}: RemoteSelectProps<TValue, TResponse>) {\n const { state, items, error } = useRemoteData<TResponse, SelectOption<TValue>>({\n client,\n url,\n params,\n enabled,\n mapResponse: (response) => {\n const rawItems = mapResponse ? mapResponse(response) : defaultArrayNormalization(response);\n return rawItems.map((raw) => toSelectOption<TValue>(raw, valueMember, displayMember));\n },\n });\n\n const resolvedError = selectProps.error ?? (state === \"error\" ? error?.message ?? \"Failed to load options\" : undefined);\n\n return <Select<TValue> {...selectProps} options={items} loading={state === \"loading\"} error={resolvedError} />;\n}\n","import { MultiSelect, type MultiSelectProps, type SelectOption } from \"../base\";\nimport type { HttpClient } from \"./http/HttpClient\";\nimport { useRemoteData } from \"./hooks/useRemoteData\";\nimport { defaultArrayNormalization, toSelectOption } from \"./mapping\";\n\nexport interface RemoteMultiSelectProps<TValue extends string | number = string, TResponse = unknown>\n extends Omit<MultiSelectProps<TValue>, \"options\" | \"loading\"> {\n url: string;\n params?: Record<string, unknown>;\n valueMember: string;\n displayMember: string;\n mapResponse?: (response: TResponse) => unknown[];\n client?: HttpClient;\n enabled?: boolean;\n}\n\n/** Same reuse pattern as RemoteComboBox/RemoteSelect, composing Base MultiSelect. */\nexport function RemoteMultiSelect<TValue extends string | number = string, TResponse = unknown>({\n url,\n params,\n valueMember,\n displayMember,\n mapResponse,\n client,\n enabled,\n ...multiSelectProps\n}: RemoteMultiSelectProps<TValue, TResponse>) {\n const { state, items, error } = useRemoteData<TResponse, SelectOption<TValue>>({\n client,\n url,\n params,\n enabled,\n mapResponse: (response) => {\n const rawItems = mapResponse ? mapResponse(response) : defaultArrayNormalization(response);\n return rawItems.map((raw) => toSelectOption<TValue>(raw, valueMember, displayMember));\n },\n });\n\n const resolvedError =\n multiSelectProps.error ?? (state === \"error\" ? error?.message ?? \"Failed to load options\" : undefined);\n\n return <MultiSelect<TValue> {...multiSelectProps} options={items} loading={state === \"loading\"} error={resolvedError} />;\n}\n","import type { ReactElement } from \"react\";\nimport type { SmartFieldMetadata } from \"./types\";\nimport type { SmartRuntimeContext } from \"./runtime\";\n\nexport type SmartResolver<M extends SmartFieldMetadata = SmartFieldMetadata> = (\n metadata: M,\n ctx: SmartRuntimeContext\n) => ReactElement | null;\n\nexport interface SmartComponentRegistry {\n register<M extends SmartFieldMetadata>(component: M[\"component\"], resolver: SmartResolver<M>): void;\n resolve(metadata: SmartFieldMetadata, ctx: SmartRuntimeContext): ReactElement | null;\n has(component: string): boolean;\n}\n\n/**\n * Keyed by the `component` discriminant — not a switch, not a plugin\n * framework (doc §04). Type safety lives at the register()/resolve()\n * generic boundary; internal storage type-erases to `SmartResolver`, the\n * same escape hatch any typed registry needs, isolated to this one\n * function. No component type is privileged: Phase 2's built-in Input/\n * ComboBox/DatePicker/DataGrid resolvers will register through this exact\n * same call an application uses for a custom component.\n *\n * An unresolved `component` value never falls back to an unrelated\n * component (doc §12) — resolve() returns null and warns once per unknown\n * component name, so a field silently disappears from the form instead of\n * rendering the wrong thing.\n */\nexport function createSmartComponentRegistry(): SmartComponentRegistry {\n const resolvers = new Map<string, SmartResolver>();\n const warned = new Set<string>();\n\n return {\n register(component, resolver) {\n resolvers.set(component, resolver as SmartResolver);\n },\n resolve(metadata, ctx) {\n const resolver = resolvers.get(metadata.component);\n if (!resolver) {\n if (!warned.has(metadata.component)) {\n warned.add(metadata.component);\n console.warn(\n `Smart: no resolver registered for component \"${metadata.component}\" (field \"${metadata.name}\"). Skipping.`\n );\n }\n return null;\n }\n return resolver(metadata, ctx);\n },\n has(component) {\n return resolvers.has(component);\n },\n };\n}\n","import type { HttpClient } from \"../remote\";\n\nexport interface SmartDataSourceDefinition {\n url: string;\n /** Defaults to Remote's own defaultHttpClient when omitted, same as RemoteComboBox etc. already do. */\n client?: HttpClient;\n}\n\nexport interface SmartDataSourceRegistry {\n register(id: string, definition: SmartDataSourceDefinition): void;\n resolve(id: string): SmartDataSourceDefinition | undefined;\n}\n\n/**\n * Backs the id-based indirection decided in doc §09/§18 (decision 2):\n * metadata never carries a raw URL, only an id an application registers\n * once. The application owns environment/hostname/auth wiring in one\n * place — Smart never needs to know it exists.\n */\nexport function createSmartDataSourceRegistry(initial?: Record<string, SmartDataSourceDefinition>): SmartDataSourceRegistry {\n const definitions = new Map<string, SmartDataSourceDefinition>(Object.entries(initial ?? {}));\n\n return {\n register(id, definition) {\n definitions.set(id, definition);\n },\n resolve(id) {\n return definitions.get(id);\n },\n };\n}\n","export type SmartActionHandler = () => void;\n\nexport interface SmartActionRegistry {\n register(id: string, handler: SmartActionHandler): void;\n resolve(id: string): SmartActionHandler | undefined;\n}\n\n/**\n * Metadata carries an action id, never a function (doc §08/§11 — no\n * executable code from the server, ever). The application registers the\n * real handler once; Smart only looks it up by id.\n */\nexport function createSmartActionRegistry(): SmartActionRegistry {\n const handlers = new Map<string, SmartActionHandler>();\n\n return {\n register(id, handler) {\n handlers.set(id, handler);\n },\n resolve(id) {\n return handlers.get(id);\n },\n };\n}\n","import type { SmartDataSourceRef, SmartFieldMetadata, SmartFormMetadata, SmartParamValue } from \"./types\";\n\nexport interface UseSmartFieldOptions {\n values: Record<string, unknown>;\n /** Absent = fall back to metadata's raw `label`/`helpText`/etc. strings. */\n translate?: (key: string) => string;\n}\n\nexport interface ResolvedSmartField<M extends SmartFieldMetadata = SmartFieldMetadata> {\n metadata: M;\n visible: boolean;\n readOnly: boolean;\n disabled: boolean;\n required: boolean;\n label?: string;\n placeholder?: string;\n helpText?: string;\n validationMessage?: string;\n /**\n * Only present for metadata carrying a `dataSource` (ComboBox/DataGrid).\n * Resolved from `dataSource.params` + the current `values` snapshot —\n * ready to pass straight through as a Remote component's `params` prop\n * (doc §06). Field-name lookups that miss simply resolve to `undefined`,\n * same as reading a missing key off any plain object.\n */\n params?: Record<string, unknown>;\n}\n\nfunction hasDataSource(metadata: SmartFieldMetadata): metadata is Extract<SmartFieldMetadata, { dataSource: SmartDataSourceRef }> {\n return \"dataSource\" in metadata;\n}\n\nfunction resolveParams(paramDefs: Record<string, SmartParamValue> | undefined, values: Record<string, unknown>): Record<string, unknown> | undefined {\n if (!paramDefs) return undefined;\n const resolved: Record<string, unknown> = {};\n for (const [key, def] of Object.entries(paramDefs)) {\n resolved[key] = def.kind === \"static\" ? def.value : values[def.field];\n }\n return resolved;\n}\n\nfunction resolveText(raw: string | undefined, key: string | undefined, translate: ((key: string) => string) | undefined): string | undefined {\n if (key && translate) return translate(key);\n return raw;\n}\n\n/**\n * Resolves one already-known metadata object. Pure function of its\n * arguments — no React state, no effect, no fetch. Exported separately from\n * `useSmartField` so a component-registry resolver that already holds a\n * specific field's metadata (as `SmartResolver` hands it) can reuse this\n * exact translate/params logic instead of re-deriving it (doc §04's\n * resolvers and `useSmartField`'s by-name lookup are two entry points onto\n * the same resolution, not two implementations).\n */\nexport function resolveSmartFieldMetadata<M extends SmartFieldMetadata = SmartFieldMetadata>(\n metadata: M,\n options: UseSmartFieldOptions\n): ResolvedSmartField<M> {\n const { values, translate } = options;\n\n return {\n metadata,\n visible: metadata.visible ?? true,\n readOnly: metadata.readOnly ?? false,\n disabled: metadata.disabled ?? false,\n required: metadata.required ?? false,\n label: resolveText(metadata.label, metadata.labelKey, translate),\n placeholder: metadata.placeholder,\n helpText: metadata.helpText,\n validationMessage: resolveText(metadata.validationMessage, metadata.validationMessageKey, translate),\n params: hasDataSource(metadata) ? resolveParams(metadata.dataSource.params, values) : undefined,\n };\n}\n\n/**\n * The headless engine every Smart component composes (doc §05/§18 —\n * Smart Runtime owns no canonical state). Looks a field up by name in\n * `formMetadata` and resolves it via `resolveSmartFieldMetadata`. Anything\n * not present in the metadata map is left alone: a field with no matching\n * metadata entry returns `undefined`, meaning \"not driven by metadata,\" not\n * \"hidden.\"\n *\n * A future SmartField component will call this directly, the same way\n * RemoteComboBox composes useRemoteData instead of writing its own effect.\n */\nexport function useSmartField<M extends SmartFieldMetadata = SmartFieldMetadata>(\n name: string,\n formMetadata: SmartFormMetadata | undefined,\n options: UseSmartFieldOptions\n): ResolvedSmartField<M> | undefined {\n const metadata = formMetadata?.fields.find((field) => field.name === name) as M | undefined;\n if (!metadata) return undefined;\n\n return resolveSmartFieldMetadata(metadata, options);\n}\n","import { useEffect, useRef } from \"react\";\n\nconst NO_DEPENDENCIES: readonly string[] = [];\n\nfunction pick(values: Record<string, unknown>, keys: readonly string[]): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const key of keys) result[key] = values[key];\n return result;\n}\n\n/**\n * Mechanical dependency tracking only (doc §06/§10): watches the fields a\n * piece of metadata declared via `dependsOn` and calls\n * `onMetadataRefreshNeeded` once per field whose value actually changed\n * since the last render. It never evaluates *why* a change matters — that\n * stays server-owned; this hook only decides *when to ask again*.\n *\n * Uses the same \"stable value-based identity\" strategy as useRemoteData's\n * `paramsKey` (serialize, compare by value, not by object/array reference)\n * to avoid the exact infinite-loop failure mode the original architecture\n * doc warns against for Remote's own params.\n */\nexport function useSmartDependencies(\n dependsOn: string[] | undefined,\n values: Record<string, unknown>,\n onMetadataRefreshNeeded?: (changedField: string) => void\n): void {\n const watched = dependsOn ?? NO_DEPENDENCIES;\n const watchedSnapshot = pick(values, watched);\n const watchedKey = watched.length === 0 ? \"\" : JSON.stringify(watchedSnapshot);\n\n const previousRef = useRef<{ key: string; snapshot: Record<string, unknown> } | null>(null);\n const onRefreshRef = useRef(onMetadataRefreshNeeded);\n onRefreshRef.current = onMetadataRefreshNeeded;\n\n useEffect(() => {\n if (watched.length === 0) return;\n const previous = previousRef.current;\n\n if (previous && previous.key !== watchedKey) {\n for (const field of watched) {\n if (!Object.is(previous.snapshot[field], watchedSnapshot[field])) {\n onRefreshRef.current?.(field);\n }\n }\n }\n\n previousRef.current = { key: watchedKey, snapshot: watchedSnapshot };\n // watchedKey (not watched/values) is the intentional dependency — same\n // pattern as useRemoteData's paramsKey.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [watchedKey]);\n}\n","import type { SmartActionRegistry, SmartActionHandler } from \"./actionRegistry\";\nimport type { SmartActionMetadata, SmartFormMetadata } from \"./types\";\n\nexport interface UseSmartActionOptions {\n actions: SmartActionRegistry;\n /** Absent = fall back to metadata's raw `label` string (doc §07). */\n translate?: (key: string) => string;\n}\n\nexport interface ResolvedSmartAction {\n metadata: SmartActionMetadata;\n visible: boolean;\n /**\n * `metadata.enabled` ANDed with \"a handler actually exists\" — metadata\n * saying `enabled: true` cannot make an action clickable if the\n * application never registered a handler for its id (doc §12 fail-safe:\n * an unregistered action renders disabled, never a no-op that looks\n * clickable).\n */\n enabled: boolean;\n label?: string;\n handler?: SmartActionHandler;\n}\n\n/**\n * Resolves one already-known action's metadata. Pure function, mirrors\n * `resolveSmartFieldMetadata` — action metadata carries an id, never a\n * function; the real handler comes from the application-owned\n * `SmartActionRegistry` (doc §08/§16), looked up here by that id.\n */\nexport function resolveSmartActionMetadata(metadata: SmartActionMetadata, options: UseSmartActionOptions): ResolvedSmartAction {\n const { actions, translate } = options;\n const handler = actions.resolve(metadata.id);\n\n return {\n metadata,\n visible: metadata.visible ?? true,\n enabled: (metadata.enabled ?? true) && Boolean(handler),\n label: metadata.labelKey && translate ? translate(metadata.labelKey) : metadata.label,\n handler,\n };\n}\n\n/**\n * Looks an action up by id in `formMetadata.actions` and resolves it via\n * `resolveSmartActionMetadata` — the action-side counterpart of\n * `useSmartField`. Returns `undefined` when no action with that id is\n * declared, the same \"not present = left alone\" convention `useSmartField`\n * uses for fields.\n */\nexport function useSmartAction(id: string, formMetadata: SmartFormMetadata | undefined, options: UseSmartActionOptions): ResolvedSmartAction | undefined {\n const metadata = formMetadata?.actions?.find((action) => action.id === id);\n if (!metadata) return undefined;\n\n return resolveSmartActionMetadata(metadata, options);\n}\n","import { RemoteComboBox } from \"../../remote\";\nimport { resolveSmartFieldMetadata } from \"../useSmartField\";\nimport type { SmartResolver } from \"../componentRegistry\";\nimport type { ComboBoxMetadata } from \"../types\";\n\n/**\n * Composes RemoteComboBox, not ComboBox directly (doc §04 — Base vs. Remote\n * is inferred from the metadata shape: ComboBoxMetadata always carries a\n * `dataSource`, so this field is always remote-backed). RemoteComboBox in\n * turn composes Base ComboBox, so no selection/keyboard/popup behavior is\n * duplicated anywhere in this chain.\n */\nexport const comboBoxResolver: SmartResolver<ComboBoxMetadata> = (metadata, ctx) => {\n const resolved = resolveSmartFieldMetadata(metadata, { values: ctx.values, translate: ctx.translate });\n if (!resolved.visible) return null;\n\n const dataSourceDef = ctx.dataSources.resolve(metadata.dataSource.id);\n if (!dataSourceDef) {\n console.warn(`Smart: no data source registered for id \"${metadata.dataSource.id}\" (field \"${metadata.name}\"). Skipping.`);\n return null;\n }\n\n return (\n <RemoteComboBox\n label={resolved.label}\n url={dataSourceDef.url}\n client={dataSourceDef.client}\n params={resolved.params}\n valueMember={metadata.valueMember}\n displayMember={metadata.displayMember}\n required={resolved.required}\n readOnly={resolved.readOnly}\n disabled={resolved.disabled}\n helpText={resolved.helpText}\n error={resolved.validationMessage}\n value={(ctx.values[metadata.name] as string | number) ?? null}\n onChange={(value) => ctx.onFieldChange(metadata.name, value)}\n />\n );\n};\n","import type { DataGridColumn } from \"../../base\";\nimport { RemoteDataGrid } from \"../../remote\";\nimport { resolveSmartFieldMetadata } from \"../useSmartField\";\nimport type { SmartResolver } from \"../componentRegistry\";\nimport type { DataGridMetadata, SmartDataGridColumn } from \"../types\";\n\ntype SmartRow = Record<string, unknown>;\n\ntype Translate = (key: string) => string;\n\n/**\n * `format` is a closed enum resolved onto Base DataGrid's own\n * `dataGridFormatters` (text/date/currency/boolean) — Smart requests a\n * formatter, it does not maintain a second rendering system for it (doc\n * §10/§24). Add a new format to Base's `DataGridFormat`, not a `render`\n * field on the metadata.\n *\n * `boolean` is the one case Smart still touches directly, because it's a\n * localization concern Base can't own: with a translate function supplied,\n * the reserved catalog keys below are authoritative, same as label/header\n * resolution elsewhere in Smart — no silent English fallback once a\n * catalog exists. Without translate, it still falls back to Base's own\n * plain \"Yes\"/\"No\", so no behavior is duplicated, only localized.\n */\nfunction resolveColumn(column: SmartDataGridColumn, translate: Translate | undefined): DataGridColumn<SmartRow> | null {\n if (column.visible === false) return null;\n const header = column.headerKey && translate ? translate(column.headerKey) : column.header ?? column.key;\n const isLocalizedBoolean = column.format === \"boolean\" && Boolean(translate);\n\n return {\n key: column.key,\n header,\n sortable: column.sortable,\n format: isLocalizedBoolean ? undefined : column.format,\n formatter: isLocalizedBoolean\n ? (value) => translate!(value ? \"smart.boolean.true\" : \"smart.boolean.false\")\n : undefined,\n };\n}\n\n/**\n * Composes RemoteDataGrid, not Base DataGrid directly (doc §04 — inferred\n * from `dataSource` the same way ComboBoxMetadata is). Column metadata is\n * translated into a real `DataGridColumn<TRow>[]` and handed straight to\n * the existing grid — no second grid engine, no filtering/grouping DSL\n * (doc §10, matching the original library's own DataGrid scope\n * restraint).\n */\nexport const dataGridResolver: SmartResolver<DataGridMetadata> = (metadata, ctx) => {\n const resolved = resolveSmartFieldMetadata(metadata, { values: ctx.values, translate: ctx.translate });\n if (!resolved.visible) return null;\n\n const dataSourceDef = ctx.dataSources.resolve(metadata.dataSource.id);\n if (!dataSourceDef) {\n console.warn(`Smart: no data source registered for id \"${metadata.dataSource.id}\" (field \"${metadata.name}\"). Skipping.`);\n return null;\n }\n\n const columns = metadata.columns\n .map((column) => resolveColumn(column, ctx.translate))\n .filter((column): column is DataGridColumn<SmartRow> => column !== null);\n\n const totalCountField = metadata.totalCountField;\n const getTotalCount = totalCountField\n ? (response: unknown) => {\n const value = (response as Record<string, unknown> | null)?.[totalCountField];\n return typeof value === \"number\" ? value : undefined;\n }\n : undefined;\n\n return (\n <RemoteDataGrid<SmartRow>\n url={dataSourceDef.url}\n client={dataSourceDef.client}\n params={resolved.params}\n columns={columns}\n rowKey={(row) => row[metadata.rowKey] as string | number}\n getTotalCount={getTotalCount}\n />\n );\n};\n","import { DatePicker } from \"../../base\";\nimport { resolveSmartFieldMetadata } from \"../useSmartField\";\nimport type { SmartResolver } from \"../componentRegistry\";\nimport type { DatePickerMetadata } from \"../types\";\n\n/**\n * `minDate`/`maxDate` are ISO strings in metadata (plain JSON, doc §03 —\n * declarative only) but Base DatePicker's `min`/`max` are `Date` objects;\n * this is the one place that conversion happens. `values[metadata.name]`\n * is expected to already hold a `Date | null`, the same native type\n * DatePicker itself uses — Smart's `values` bag stores each field in its\n * Base component's own value shape, never a serialized form.\n */\nfunction parseIsoDate(value: string | undefined): Date | undefined {\n if (!value) return undefined;\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\nexport const datePickerResolver: SmartResolver<DatePickerMetadata> = (metadata, ctx) => {\n const resolved = resolveSmartFieldMetadata(metadata, { values: ctx.values, translate: ctx.translate });\n if (!resolved.visible) return null;\n\n return (\n <DatePicker\n label={resolved.label}\n required={resolved.required}\n readOnly={resolved.readOnly}\n disabled={resolved.disabled}\n helpText={resolved.helpText}\n error={resolved.validationMessage}\n min={parseIsoDate(metadata.minDate)}\n max={parseIsoDate(metadata.maxDate)}\n value={(ctx.values[metadata.name] as Date | null) ?? null}\n onChange={(value) => ctx.onFieldChange(metadata.name, value)}\n />\n );\n};\n","import { Input } from \"../../base\";\nimport { resolveSmartFieldMetadata } from \"../useSmartField\";\nimport type { SmartResolver } from \"../componentRegistry\";\nimport type { InputMetadata } from \"../types\";\n\n/**\n * Composes Base Input (doc §03/§20 — reuse, not a second text-field\n * implementation). The only thing this file owns is translating resolved\n * metadata into Input's existing prop contract.\n */\nexport const inputResolver: SmartResolver<InputMetadata> = (metadata, ctx) => {\n const resolved = resolveSmartFieldMetadata(metadata, { values: ctx.values, translate: ctx.translate });\n if (!resolved.visible) return null;\n\n return (\n <Input\n label={resolved.label}\n required={resolved.required}\n readOnly={resolved.readOnly}\n disabled={resolved.disabled}\n helpText={resolved.helpText}\n placeholder={resolved.placeholder}\n error={resolved.validationMessage}\n maxLength={metadata.maxLength}\n value={(ctx.values[metadata.name] as string) ?? \"\"}\n onChange={(value) => ctx.onFieldChange(metadata.name, value)}\n />\n );\n};\n","import type { SmartComponentRegistry } from \"../componentRegistry\";\nimport { comboBoxResolver } from \"./comboBoxResolver\";\nimport { dataGridResolver } from \"./dataGridResolver\";\nimport { datePickerResolver } from \"./datePickerResolver\";\nimport { inputResolver } from \"./inputResolver\";\n\nexport { comboBoxResolver, dataGridResolver, datePickerResolver, inputResolver };\n\n/**\n * Registers Input/ComboBox/DatePicker/DataGrid through the exact same\n * `register()` call an application uses for a custom component (doc §04 —\n * no privileged core; a custom \"PatientSelector\" resolver is registered\n * the same way).\n */\nexport function registerBuiltInResolvers(registry: SmartComponentRegistry): void {\n registry.register(\"Input\", inputResolver);\n registry.register(\"ComboBox\", comboBoxResolver);\n registry.register(\"DatePicker\", datePickerResolver);\n registry.register(\"DataGrid\", dataGridResolver);\n}\n","import type { ReactElement } from \"react\";\nimport type { SmartRuntimeContext } from \"./runtime\";\nimport type { SmartFieldMetadata } from \"./types\";\nimport { useSmartDependencies } from \"./useSmartDependencies\";\n\nexport interface SmartFieldProps {\n metadata: SmartFieldMetadata;\n ctx: SmartRuntimeContext;\n}\n\n/**\n * Given one field's metadata, resolves it into whatever Base/Remote\n * component its `component` discriminant maps to (doc §09/§14) — it owns\n * no UI of its own, only delegates to `ctx.registry`.\n *\n * Also wires the mechanical dependency tracking every metadata-driven\n * field needs (doc §06): a consuming screen no longer calls\n * useSmartDependencies by hand per field, SmartField does it here and\n * reports which field needed the refresh, not just which value changed.\n */\nexport function SmartField({ metadata, ctx }: SmartFieldProps): ReactElement | null {\n const notifyRefresh = ctx.onMetadataRefreshNeeded;\n useSmartDependencies(\n metadata.dependsOn,\n ctx.values,\n notifyRefresh ? (changedField) => notifyRefresh(metadata.name, changedField) : undefined\n );\n\n if (metadata.visible === false) return null;\n return ctx.registry.resolve(metadata, ctx);\n}\n","import { Alert } from \"../base\";\nimport { SmartField } from \"./SmartField\";\nimport type { SmartRuntimeContext } from \"./runtime\";\nimport type { SmartFormMetadata } from \"./types\";\n\nexport interface SmartFormProps {\n metadata: SmartFormMetadata;\n ctx: SmartRuntimeContext;\n}\n\nconst SUPPORTED_SCHEMA_MAJOR = 1;\n\nfunction isSupportedSchemaVersion(version: string): boolean {\n const major = Number(version.split(\".\")[0]);\n return Number.isFinite(major) && major === SUPPORTED_SCHEMA_MAJOR;\n}\n\n/**\n * A thin iteration helper over SmartField (doc §09/§15/§18 decision 4) —\n * it owns no field values, evaluates no business rule, and decides no\n * layout. Its only two responsibilities: fail the whole form closed on an\n * unsupported schema version instead of rendering a partially-understood\n * form (doc §12, reusing Alert rather than a bespoke error UI), and map\n * each field's metadata to a SmartField.\n *\n * A SmartField used standalone (outside SmartForm) is responsible for its\n * own schemaVersion check — this component is the only place that check\n * happens automatically.\n */\nexport function SmartForm({ metadata, ctx }: SmartFormProps) {\n if (!isSupportedSchemaVersion(metadata.schemaVersion)) {\n return (\n <Alert variant=\"danger\">\n Unsupported form schema version "{metadata.schemaVersion}" — this app understands schema version {SUPPORTED_SCHEMA_MAJOR}.x.\n </Alert>\n );\n }\n\n return (\n <>\n {metadata.fields.map((field) => (\n <SmartField key={field.name} metadata={field} ctx={ctx} />\n ))}\n </>\n );\n}\n","import { Button } from \"../base\";\nimport { resolveSmartActionMetadata } from \"./useSmartAction\";\nimport type { SmartRuntimeContext } from \"./runtime\";\nimport type { SmartActionMetadata } from \"./types\";\n\nexport interface SmartActionProps {\n metadata: SmartActionMetadata;\n ctx: Pick<SmartRuntimeContext, \"actions\" | \"translate\">;\n}\n\n/**\n * Composes Base Button, not a second button implementation (doc §16/§20) —\n * the only component-shaped thing action metadata currently resolves to.\n * Unlike field metadata, an action's `component: \"Button\"` never needs a\n * registry lookup: there is exactly one action UI shape, so there is\n * nothing to resolve between.\n */\nexport function SmartAction({ metadata, ctx }: SmartActionProps) {\n const resolved = resolveSmartActionMetadata(metadata, ctx);\n if (!resolved.visible) return null;\n\n return (\n <Button disabled={!resolved.enabled} onClick={() => resolved.handler?.()}>\n {resolved.label ?? metadata.id}\n </Button>\n );\n}\n","import { SmartAction } from \"./SmartAction\";\nimport type { SmartRuntimeContext } from \"./runtime\";\nimport type { SmartFormMetadata } from \"./types\";\n\nexport interface SmartActionsProps {\n metadata: SmartFormMetadata;\n ctx: Pick<SmartRuntimeContext, \"actions\" | \"translate\">;\n}\n\n/**\n * A thin iteration helper over SmartAction — the action-side counterpart\n * of SmartForm (doc §09/§15). Maps `metadata.actions` to SmartActions and\n * nothing else: no layout, no spacing, no handler logic of its own. The\n * consuming screen wraps this in whatever layout (Stack, a form footer,\n * a toolbar) it needs.\n */\nexport function SmartActions({ metadata, ctx }: SmartActionsProps) {\n if (!metadata.actions || metadata.actions.length === 0) return null;\n\n return (\n <>\n {metadata.actions.map((action) => (\n <SmartAction key={action.id} metadata={action} ctx={ctx} />\n ))}\n </>\n );\n}\n"],"names":["cx","values","Label","htmlFor","required","className","children","jsx","ValidationMessage","error","helpText","FieldShell","id","label","useControllableState","value","defaultValue","onChange","isControlled","isControlledRef","useRef","internalValue","setInternalValue","useState","currentValue","setValue","useCallback","next","Input","props","name","disabled","readOnly","placeholder","onBlur","type","maxLength","autoFocus","inputProps","endAdornment","generatedId","useId","fieldId","control","event","jsxs","TextArea","rows","NumberInput","min","max","step","rest","raw","parsed","PasswordInput","visible","setVisible","prev","FileInput","accept","multiple","BooleanFieldControl","wrapperClassName","role","checked","CheckBox","setChecked","Switch","RadioButton","RadioGroup","options","inline","groupName","option","Select","loading","matched","useEscapeKey","active","onEscape","useEffect","handleKeyDown","Popup","open","onClose","anchorRef","popupRef","handlePointerDown","target","_a","_b","useListNavigation","itemCount","isOpen","onSelect","activeIndex","setActiveIndex","MultiSelect","defaultValues","emptyText","currentValues","setValues","setOpen","selectedSet","close","toggleIndex","index","v","summary","toDateInputValue","date","year","month","day","fromDateInputValue","parts","DatePicker","toTimeInputValue","hours","minutes","fromTimeInputValue","TimePicker","combine","datePart","timePart","time","DateTimePicker","ComboBox","selectedOption","selectIndex","defaultFilter","query","AutoComplete","inputValue","onInputValueChange","filter","internalText","setInternalText","matchFilter","filteredOptions","text","FormField","Modal","title","footer","Fragment","getPageList","current","total","siblingCount","pages","start","end","page","Pagination","currentPage","pageSize","totalItems","onPageChange","totalPages","dataGridFormatters","amount","nextSortDirection","key","columnKeyOf","column","columnValueOf","row","accessor","renderCell","alignClass","align","DataGrid","columns","rowKey","selectedRowKeys","onSelectionChange","sort","onSortChange","totalCount","selectable","paginated","toggleAll","toggleRow","Spinner","size","variant","Button","onClick","isDisabled","Alert","dismissible","onDismiss","ToastContext","createContext","DEFAULT_DURATION","ToastProvider","toasts","setToasts","nextId","timers","activeTimers","dismiss","timer","toast","show","message","duration","api","useMemo","useToast","context","useContext","ConfirmContext","ConfirmProvider","pending","setPending","confirm","resolve","settle","result","useConfirm","Badge","pill","SIZE_EM","Icon","navClass","SIZE_CLASS","Tabs","items","activeKey","defaultActiveKey","orientation","stretch","currentKey","setKey","activeItem","item","isButtonVariant","isVertical","tabRefs","activate","focus","findEnabled","from","i","currentIndex","nextKey","prevKey","first","tabList","buttonContent","button","node","panel","Accordion","openKeys","defaultOpenKeys","currentOpenKeys","setOpenKeys","openSet","toggle","k","Tooltip","content","placement","tooltipId","Popover","Skeleton","width","height","circle","Stack","direction","gap","justify","wrap","SIZE_REM","WEIGHT_CLASS","TONE_CLASS","Text","as","weight","tone","truncate","Component","DefaultHeader","subtitle","icon","avatar","actions","Card","header","resolvedHeader","Divider","vertical","Container","fluid","Row","Col","span","sm","md","lg","xl","Breadcrumb","isLast","isInteractive","Menu","Stepper","steps","currentStep","status","getInitials","last","DIMENSION","Avatar","src","dimension","Tag","onRemove","Slider","Rating","_","n","ProgressBar","clamped","Navbar","brand","isGroup","section","SidebarLink","Sidebar","sections","PageHeader","description","breadcrumbItems","GAP_TOKEN","resolveGap","Flex","grow","shrink","fullWidth","IconButton","ariaLabel","iconSize","tooltip","ListItem","leading","trailing","dense","rowClassName","buildLinePoints","data","padding","range","innerWidth","innerHeight","x","y","LineOrArea","strokeWidth","points","linePoints","Bars","barWidth","barHeight","Sparkline","TREND_TONE","TREND_ICON","formatValue","precision","Statistic","prefix","suffix","trend","delta","HttpError","statusText","url","serializeParams","params","searchParams","rawValue","createHttpClient","baseUrl","fetcher","buildRequestInit","requestOptions","fullUrl","init","response","defaultHttpClient","sortKeys","obj","acc","useRemoteData","client","mapResponse","enabled","state","setState","setItems","setError","reloadToken","setReloadToken","paramsKey","latestRequestId","mapResponseRef","requestId","controller","mapped","err","reload","token","useDebouncedValue","delayMs","debounced","setDebounced","defaultArrayNormalization","toSelectOption","valueMember","displayMember","record","RemoteComboBox","comboBoxProps","resolvedError","RemoteAutoComplete","searchParam","minSearchLength","debounceMs","autoCompleteProps","internalSearchText","setInternalSearchText","debouncedSearchText","searchReady","RemoteDataGrid","getTotalCount","dataGridProps","setPage","setSort","isFirstRender","requestParams","lastResponseRef","explicitTotalCount","inferredTotalCount","RemoteSelect","selectProps","RemoteMultiSelect","multiSelectProps","createSmartComponentRegistry","resolvers","warned","component","resolver","metadata","ctx","createSmartDataSourceRegistry","initial","definitions","definition","createSmartActionRegistry","handlers","handler","hasDataSource","resolveParams","paramDefs","resolved","def","resolveText","translate","resolveSmartFieldMetadata","useSmartField","formMetadata","field","NO_DEPENDENCIES","pick","keys","useSmartDependencies","dependsOn","onMetadataRefreshNeeded","watched","watchedSnapshot","watchedKey","previousRef","onRefreshRef","previous","resolveSmartActionMetadata","useSmartAction","action","comboBoxResolver","dataSourceDef","resolveColumn","isLocalizedBoolean","dataGridResolver","totalCountField","parseIsoDate","datePickerResolver","inputResolver","registerBuiltInResolvers","registry","SmartField","notifyRefresh","changedField","SUPPORTED_SCHEMA_MAJOR","isSupportedSchemaVersion","version","major","SmartForm","SmartAction","SmartActions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/base/shared/classNames.ts","../src/base/shared/Label.tsx","../src/base/shared/ValidationMessage.tsx","../src/base/shared/FieldShell.tsx","../src/base/shared/useControllableState.ts","../src/base/Input.tsx","../src/base/TextArea.tsx","../src/base/NumberInput.tsx","../src/base/PasswordInput.tsx","../src/base/FileInput.tsx","../src/base/shared/BooleanFieldControl.tsx","../src/base/CheckBox.tsx","../src/base/Switch.tsx","../src/base/RadioButton.tsx","../src/base/RadioGroup.tsx","../src/base/Select.tsx","../src/base/shared/useEscapeKey.ts","../src/base/shared/Popup.tsx","../src/base/shared/useListNavigation.ts","../src/base/MultiSelect.tsx","../src/base/DatePicker.tsx","../src/base/TimePicker.tsx","../src/base/DateTimePicker.tsx","../src/base/ComboBox.tsx","../src/base/AutoComplete.tsx","../src/base/FormField.tsx","../src/base/Modal.tsx","../src/base/Pagination.tsx","../src/base/DataGrid.tsx","../src/base/Spinner.tsx","../src/base/Button.tsx","../src/base/Alert.tsx","../src/base/Toast.tsx","../src/base/Confirm.tsx","../src/base/Badge.tsx","../src/base/Icon.tsx","../src/base/Tabs.tsx","../src/base/Accordion.tsx","../src/base/Tooltip.tsx","../src/base/Popover.tsx","../src/base/Skeleton.tsx","../src/base/Stack.tsx","../src/base/Text.tsx","../src/base/Card.tsx","../src/base/Divider.tsx","../src/base/Container.tsx","../src/base/Row.tsx","../src/base/Col.tsx","../src/base/Breadcrumb.tsx","../src/base/Menu.tsx","../src/base/Stepper.tsx","../src/base/Avatar.tsx","../src/base/Tag.tsx","../src/base/Slider.tsx","../src/base/Rating.tsx","../src/base/ProgressBar.tsx","../src/base/Navbar.tsx","../src/base/appearanceSchemes.ts","../src/base/Appearance.tsx","../src/base/sidebarModel.ts","../src/base/Sidebar.tsx","../src/base/PageHeader.tsx","../src/base/Flex.tsx","../src/base/IconButton.tsx","../src/base/ListItem.tsx","../src/base/Sparkline.tsx","../src/base/Statistic.tsx","../src/base/AppearanceMenu.tsx","../src/remote/http/HttpClient.ts","../src/remote/hooks/useRemoteData.ts","../src/remote/hooks/useDebouncedValue.ts","../src/remote/mapping.ts","../src/remote/RemoteComboBox.tsx","../src/remote/RemoteAutoComplete.tsx","../src/remote/RemoteDataGrid.tsx","../src/remote/RemoteSelect.tsx","../src/remote/RemoteMultiSelect.tsx","../src/smart/componentRegistry.ts","../src/smart/dataSourceRegistry.ts","../src/smart/actionRegistry.ts","../src/smart/useSmartField.ts","../src/smart/useSmartDependencies.ts","../src/smart/useSmartAction.ts","../src/smart/resolvers/comboBoxResolver.tsx","../src/smart/resolvers/dataGridResolver.tsx","../src/smart/resolvers/datePickerResolver.tsx","../src/smart/resolvers/inputResolver.tsx","../src/smart/resolvers/index.ts","../src/smart/SmartField.tsx","../src/smart/SmartForm.tsx","../src/smart/SmartAction.tsx","../src/smart/SmartActions.tsx"],"sourcesContent":["export function cx(...values: Array<string | false | null | undefined>): string {\r\n return values.filter(Boolean).join(\" \");\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./classNames\";\r\n\r\nexport interface LabelProps {\r\n htmlFor?: string;\r\n required?: boolean;\r\n className?: string;\r\n children: ReactNode;\r\n}\r\n\r\n/** Extracted out of FieldShell so it's independently usable (doc \"Form Infrastructure\" section). */\r\nexport function Label({ htmlFor, required, className, children }: LabelProps) {\r\n return (\r\n <label htmlFor={htmlFor} className={cx(\"form-label\", \"rrc-label\", className)}>\r\n {children}\r\n {required && <span className=\"text-danger\"> *</span>}\r\n </label>\r\n );\r\n}\r\n","import { cx } from \"./classNames\";\r\n\r\nexport interface ValidationMessageProps {\r\n error?: string;\r\n helpText?: string;\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Presentation only — owns no validation rules (doc section 10). Extracted\r\n * out of FieldShell so CheckBox/Switch (which don't use FieldShell's\r\n * `form-label` layout) can still reuse the identical error/help rendering.\r\n */\r\nexport function ValidationMessage({ error, helpText, className }: ValidationMessageProps) {\r\n if (error) return <div className={cx(\"invalid-feedback d-block\", \"rrc-field__error\", className)}>{error}</div>;\r\n if (helpText) return <div className={cx(\"form-text\", \"rrc-field__help\", className)}>{helpText}</div>;\r\n return null;\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./classNames\";\r\nimport { Label } from \"./Label\";\r\nimport { ValidationMessage } from \"./ValidationMessage\";\r\n\r\nexport interface FieldShellProps {\r\n id?: string;\r\n label?: string;\r\n required?: boolean;\r\n error?: string;\r\n helpText?: string;\r\n className?: string;\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * Shared label / help-text / validation-message presentation wrapper reused\r\n * by every Base field that has that shape (Input, TextArea, NumberInput,\r\n * DatePicker, TimePicker, ComboBox, AutoComplete, Select, MultiSelect,\r\n * RadioGroup, DateTimePicker). CheckBox/Switch and DataGrid have a\r\n * genuinely different layout and intentionally don't use this (they reuse\r\n * ValidationMessage directly instead — see BooleanFieldControl).\r\n *\r\n * Bootstrap conventions (`form-label`, `invalid-feedback`, `form-text`) are\r\n * used directly rather than reinventing a styling layer (doc section 15).\r\n */\r\nexport function FieldShell({ id, label, required, error, helpText, className, children }: FieldShellProps) {\r\n return (\r\n <div className={cx(\"mb-3\", \"rrc-field\", className)}>\r\n {label && (\r\n <Label htmlFor={id} required={required}>\r\n {label}\r\n </Label>\r\n )}\r\n {children}\r\n <ValidationMessage error={error} helpText={helpText} />\r\n </div>\r\n );\r\n}\r\n","import { useCallback, useRef, useState } from \"react\";\r\n\r\nexport interface ControllableStateOptions<T> {\r\n /** When defined, the component is controlled: this value always wins. */\r\n value?: T;\r\n defaultValue: T;\r\n onChange?: (value: T) => void;\r\n}\r\n\r\n/**\r\n * Single shared implementation of the library's controlled/uncontrolled policy\r\n * (doc section 14). Every Base form field composes this instead of\r\n * reimplementing its own controlled/uncontrolled logic.\r\n *\r\n * Policy: presence of `value !== undefined` on first render decides the mode\r\n * for the component's lifetime. Switching modes afterwards is a programmer\r\n * error and is flagged in development, mirroring React's own <input> warning.\r\n */\r\nexport function useControllableState<T>({\r\n value,\r\n defaultValue,\r\n onChange,\r\n}: ControllableStateOptions<T>): [T, (next: T) => void] {\r\n const isControlled = value !== undefined;\r\n const isControlledRef = useRef(isControlled);\r\n\r\n if (process.env.NODE_ENV !== \"production\" && isControlledRef.current !== isControlled) {\r\n // eslint-disable-next-line no-console\r\n console.error(\r\n \"[react-components] A component switched between controlled and uncontrolled `value`. \" +\r\n \"Decide between passing `value` (controlled) or `defaultValue` (uncontrolled) for the \" +\r\n \"lifetime of the component, per the library's controlled/uncontrolled policy.\"\r\n );\r\n }\r\n\r\n const [internalValue, setInternalValue] = useState<T>(defaultValue);\r\n const currentValue = isControlled ? (value as T) : internalValue;\r\n\r\n const setValue = useCallback(\r\n (next: T) => {\r\n if (!isControlled) {\r\n setInternalValue(next);\r\n }\r\n onChange?.(next);\r\n },\r\n [isControlled, onChange]\r\n );\r\n\r\n return [currentValue, setValue];\r\n}\r\n","import { useId, type FocusEventHandler, type InputHTMLAttributes, type ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { FieldShell } from \"./shared/FieldShell\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\r\n\r\ntype NativePassthroughProps = Omit<\r\n InputHTMLAttributes<HTMLInputElement>,\r\n \"id\" | \"name\" | \"value\" | \"defaultValue\" | \"onChange\" | \"onBlur\" | \"className\" | \"disabled\" | \"readOnly\" | \"required\" | \"placeholder\"\r\n>;\r\n\r\nexport interface InputProps extends FieldIdentity, FieldState, FieldPresentation {\r\n value?: string;\r\n defaultValue?: string;\r\n onChange?: (value: string) => void;\r\n onBlur?: FocusEventHandler<HTMLInputElement>;\r\n type?: \"text\" | \"email\" | \"password\" | \"tel\" | \"url\" | \"search\";\r\n maxLength?: number;\r\n autoFocus?: boolean;\r\n /**\r\n * Escape hatch for native attributes that don't deserve a first-class prop\r\n * on every text-like field (e.g. `inputMode`, `min`/`max`/`step`, `type`\r\n * override). Keeps the primary prop surface small (doc section 13) while\r\n * still letting NumberInput/DatePicker compose Input instead of\r\n * reimplementing it.\r\n */\r\n inputProps?: NativePassthroughProps;\r\n /**\r\n * Generic trailing slot rendered inside a Bootstrap `input-group` (e.g. a\r\n * visibility-toggle button, a unit suffix, a clear button). Not\r\n * password-specific — PasswordInput is just its first consumer, reusing\r\n * Input's full controlled-state/markup instead of reimplementing a\r\n * parallel text field (doc section 4/19).\r\n */\r\n endAdornment?: ReactNode;\r\n}\r\n\r\nexport function Input(props: InputProps) {\r\n const {\r\n id,\r\n name,\r\n disabled,\r\n readOnly,\r\n required,\r\n className,\r\n label,\r\n placeholder,\r\n helpText,\r\n error,\r\n value,\r\n defaultValue,\r\n onChange,\r\n onBlur,\r\n type = \"text\",\r\n maxLength,\r\n autoFocus,\r\n inputProps,\r\n endAdornment,\r\n } = props;\r\n\r\n const [currentValue, setValue] = useControllableState<string>({\r\n value,\r\n defaultValue: defaultValue ?? \"\",\r\n onChange,\r\n });\r\n\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n const control = (\r\n <input\r\n id={fieldId}\r\n name={name}\r\n className={cx(\"form-control\", \"rrc-input\", error && \"is-invalid\")}\r\n disabled={disabled}\r\n readOnly={readOnly}\r\n required={required}\r\n placeholder={placeholder}\r\n maxLength={maxLength}\r\n autoFocus={autoFocus}\r\n value={currentValue}\r\n onChange={(event) => setValue(event.target.value)}\r\n onBlur={onBlur}\r\n type={type}\r\n {...inputProps}\r\n />\r\n );\r\n\r\n return (\r\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\r\n {endAdornment ? (\r\n <div className=\"input-group rrc-input-group\">\r\n {control}\r\n {endAdornment}\r\n </div>\r\n ) : (\r\n control\r\n )}\r\n </FieldShell>\r\n );\r\n}\r\n","import { useId, type FocusEventHandler } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { FieldShell } from \"./shared/FieldShell\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\r\n\r\nexport interface TextAreaProps extends FieldIdentity, FieldState, FieldPresentation {\r\n value?: string;\r\n defaultValue?: string;\r\n onChange?: (value: string) => void;\r\n onBlur?: FocusEventHandler<HTMLTextAreaElement>;\r\n rows?: number;\r\n maxLength?: number;\r\n}\r\n\r\nexport function TextArea(props: TextAreaProps) {\r\n const {\r\n id,\r\n name,\r\n disabled,\r\n readOnly,\r\n required,\r\n className,\r\n label,\r\n placeholder,\r\n helpText,\r\n error,\r\n value,\r\n defaultValue,\r\n onChange,\r\n onBlur,\r\n rows = 3,\r\n maxLength,\r\n } = props;\r\n\r\n const [currentValue, setValue] = useControllableState<string>({\r\n value,\r\n defaultValue: defaultValue ?? \"\",\r\n onChange,\r\n });\r\n\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n return (\r\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\r\n <textarea\r\n id={fieldId}\r\n name={name}\r\n className={cx(\"form-control\", \"rrc-input\", error && \"is-invalid\")}\r\n disabled={disabled}\r\n readOnly={readOnly}\r\n required={required}\r\n placeholder={placeholder}\r\n rows={rows}\r\n maxLength={maxLength}\r\n value={currentValue}\r\n onChange={(event) => setValue(event.target.value)}\r\n onBlur={onBlur}\r\n />\r\n </FieldShell>\r\n );\r\n}\r\n","import type { FocusEventHandler } from \"react\";\r\nimport { Input } from \"./Input\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\r\n\r\nexport interface NumberInputProps extends FieldIdentity, FieldState, FieldPresentation {\r\n value?: number | null;\r\n defaultValue?: number | null;\r\n onChange?: (value: number | null) => void;\r\n onBlur?: FocusEventHandler<HTMLInputElement>;\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n}\r\n\r\n/**\r\n * Composes Input (the \"Input foundation\" from doc section 19) instead of\r\n * reimplementing field markup/controlled-state logic — only the numeric\r\n * value coercion is unique to NumberInput.\r\n */\r\nexport function NumberInput({ value, defaultValue, onChange, min, max, step, ...rest }: NumberInputProps) {\r\n const [currentValue, setValue] = useControllableState<number | null>({\r\n value,\r\n defaultValue: defaultValue ?? null,\r\n onChange,\r\n });\r\n\r\n return (\r\n <Input\r\n {...rest}\r\n value={currentValue === null ? \"\" : String(currentValue)}\r\n onChange={(raw) => {\r\n if (raw.trim() === \"\") {\r\n setValue(null);\r\n return;\r\n }\r\n const parsed = Number(raw);\r\n if (!Number.isNaN(parsed)) setValue(parsed);\r\n }}\r\n inputProps={{ inputMode: \"decimal\", min, max, step }}\r\n />\r\n );\r\n}\r\n","import { useState } from \"react\";\r\nimport { Input, type InputProps } from \"./Input\";\r\n\r\nexport interface PasswordInputProps extends Omit<InputProps, \"type\" | \"endAdornment\" | \"inputProps\"> {}\r\n\r\n/**\r\n * Reuses Input entirely (controlled/uncontrolled logic, FieldShell,\r\n * markup) via Input's `endAdornment`/`inputProps` extension points instead\r\n * of building an independent text field (doc section 4). No password\r\n * strength infrastructure — just visibility toggling.\r\n */\r\nexport function PasswordInput(props: PasswordInputProps) {\r\n const [visible, setVisible] = useState(false);\r\n\r\n return (\r\n <Input\r\n {...props}\r\n inputProps={{ type: visible ? \"text\" : \"password\", autoComplete: \"current-password\" }}\r\n endAdornment={\r\n <button\r\n type=\"button\"\r\n className=\"btn btn-outline-secondary rrc-btn rrc-input-group__action\"\r\n aria-label={visible ? \"Hide password\" : \"Show password\"}\r\n aria-pressed={visible}\r\n onClick={() => setVisible((prev) => !prev)}\r\n >\r\n {visible ? \"Hide\" : \"Show\"}\r\n </button>\r\n }\r\n />\r\n );\r\n}\r\n","import { useId } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { FieldShell } from \"./shared/FieldShell\";\r\nimport type { FieldIdentity, FieldPresentation } from \"./shared/fieldTypes\";\r\n\r\nexport interface FileInputProps extends FieldIdentity, FieldPresentation {\r\n disabled?: boolean;\r\n required?: boolean;\r\n accept?: string;\r\n multiple?: boolean;\r\n onChange?: (files: FileList | null) => void;\r\n}\r\n\r\n/**\r\n * File selection only — no upload/API/cloud-storage/chunking (doc section\r\n * 11; that belongs to a future Remote-layer concern, not Base).\r\n *\r\n * Intentionally uncontrolled-only: browsers do not allow programmatically\r\n * setting `<input type=\"file\">`'s value for security reasons, so this is a\r\n * documented, deliberate exception to the library's controlled/uncontrolled\r\n * policy rather than an inconsistency — there is no `value`/`defaultValue`\r\n * to be controlled.\r\n */\r\nexport function FileInput({ id, name, disabled, required, className, label, helpText, error, accept, multiple, onChange }: FileInputProps) {\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n return (\r\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\r\n <input\r\n id={fieldId}\r\n name={name}\r\n type=\"file\"\r\n className={cx(\"form-control\", \"rrc-input\", error && \"is-invalid\")}\r\n disabled={disabled}\r\n required={required}\r\n accept={accept}\r\n multiple={multiple}\r\n onChange={(event) => onChange?.(event.target.files)}\r\n />\r\n </FieldShell>\r\n );\r\n}\r\n","import { useId } from \"react\";\r\nimport { cx } from \"./classNames\";\r\nimport { ValidationMessage } from \"./ValidationMessage\";\r\nimport type { FieldIdentity } from \"./fieldTypes\";\r\n\r\nexport interface BooleanFieldControlProps extends FieldIdentity {\r\n disabled?: boolean;\r\n required?: boolean;\r\n className?: string;\r\n wrapperClassName: string;\r\n role?: string;\r\n label?: string;\r\n helpText?: string;\r\n error?: string;\r\n checked: boolean;\r\n onChange: (checked: boolean) => void;\r\n}\r\n\r\n/**\r\n * Internal-only shared rendering for CheckBox and Switch: their public APIs\r\n * are genuinely identical (checked/defaultChecked/onChange/label/error/\r\n * helpText) and their markup differs only by wrapper class + `role` (doc\r\n * section 8: \"reuse if semantically correct, but don't couple them through\r\n * an abstraction that makes either public API worse\" — this doesn't, since\r\n * both components keep their own separate, unchanged public props).\r\n */\r\nexport function BooleanFieldControl({\r\n id,\r\n name,\r\n disabled,\r\n required,\r\n wrapperClassName,\r\n role,\r\n label,\r\n helpText,\r\n error,\r\n checked,\r\n onChange,\r\n className,\r\n}: BooleanFieldControlProps) {\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n return (\r\n <div className={cx(wrapperClassName, className)}>\r\n <input\r\n id={fieldId}\r\n name={name}\r\n type=\"checkbox\"\r\n role={role}\r\n className={cx(\"form-check-input\", \"rrc-check\", error && \"is-invalid\")}\r\n disabled={disabled}\r\n required={required}\r\n checked={checked}\r\n onChange={(event) => onChange(event.target.checked)}\r\n />\r\n {label && (\r\n <label htmlFor={fieldId} className=\"form-check-label rrc-check__label\">\r\n {label}\r\n </label>\r\n )}\r\n <ValidationMessage error={error} helpText={helpText} />\r\n </div>\r\n );\r\n}\r\n","import { BooleanFieldControl } from \"./shared/BooleanFieldControl\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport type { FieldIdentity, FieldState } from \"./shared/fieldTypes\";\r\n\r\nexport interface CheckBoxProps extends FieldIdentity, FieldState {\r\n className?: string;\r\n label?: string;\r\n helpText?: string;\r\n error?: string;\r\n checked?: boolean;\r\n defaultChecked?: boolean;\r\n onChange?: (checked: boolean) => void;\r\n}\r\n\r\n/**\r\n * Deliberately doesn't use FieldShell — a checkbox's label sits beside the\r\n * control, not above it, so the layout genuinely differs (doc section 13:\r\n * shared contracts only where a real semantic relationship exists). Shares\r\n * its actual rendering with Switch via BooleanFieldControl.\r\n */\r\nexport function CheckBox(props: CheckBoxProps) {\r\n const [checked, setChecked] = useControllableState<boolean>({\r\n value: props.checked,\r\n defaultValue: props.defaultChecked ?? false,\r\n onChange: props.onChange,\r\n });\r\n\r\n return (\r\n <BooleanFieldControl\r\n id={props.id}\r\n name={props.name}\r\n disabled={props.disabled}\r\n required={props.required}\r\n className={props.className}\r\n wrapperClassName=\"form-check mb-3\"\r\n label={props.label}\r\n helpText={props.helpText}\r\n error={props.error}\r\n checked={checked}\r\n onChange={setChecked}\r\n />\r\n );\r\n}\r\n","import { BooleanFieldControl } from \"./shared/BooleanFieldControl\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport type { FieldIdentity, FieldState } from \"./shared/fieldTypes\";\r\n\r\nexport interface SwitchProps extends FieldIdentity, FieldState {\r\n className?: string;\r\n label?: string;\r\n helpText?: string;\r\n error?: string;\r\n checked?: boolean;\r\n defaultChecked?: boolean;\r\n onChange?: (checked: boolean) => void;\r\n}\r\n\r\n/**\r\n * Same controlled/uncontrolled boolean behavior as CheckBox, reused via\r\n * BooleanFieldControl — only the wrapper class (`form-switch`) and\r\n * `role=\"switch\"` differ (doc section 8).\r\n */\r\nexport function Switch(props: SwitchProps) {\r\n const [checked, setChecked] = useControllableState<boolean>({\r\n value: props.checked,\r\n defaultValue: props.defaultChecked ?? false,\r\n onChange: props.onChange,\r\n });\r\n\r\n return (\r\n <BooleanFieldControl\r\n id={props.id}\r\n name={props.name}\r\n disabled={props.disabled}\r\n required={props.required}\r\n className={props.className}\r\n wrapperClassName=\"form-check form-switch mb-3\"\r\n role=\"switch\"\r\n label={props.label}\r\n helpText={props.helpText}\r\n error={props.error}\r\n checked={checked}\r\n onChange={setChecked}\r\n />\r\n );\r\n}\r\n","import { useId } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface RadioButtonProps<TValue extends string | number = string> {\r\n id?: string;\r\n name?: string;\r\n value: TValue;\r\n label?: string;\r\n checked: boolean;\r\n disabled?: boolean;\r\n className?: string;\r\n onChange?: (value: TValue) => void;\r\n}\r\n\r\n/**\r\n * A single radio input. Always controlled by `checked` — a lone HTML radio\r\n * doesn't have meaningful independent uncontrolled state the way a\r\n * checkbox does (mutual exclusivity requires a group), so it's normally\r\n * composed by RadioGroup, which owns the actual controlled/uncontrolled\r\n * value. Usable standalone by a consumer who wants to manage state itself.\r\n */\r\nexport function RadioButton<TValue extends string | number = string>({\r\n id,\r\n name,\r\n value,\r\n label,\r\n checked,\r\n disabled,\r\n className,\r\n onChange,\r\n}: RadioButtonProps<TValue>) {\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n return (\r\n <div className={cx(\"form-check\", \"rrc-check-row\", className)}>\r\n <input\r\n id={fieldId}\r\n name={name}\r\n type=\"radio\"\r\n className=\"form-check-input rrc-check\"\r\n value={String(value)}\r\n checked={checked}\r\n disabled={disabled}\r\n onChange={() => onChange?.(value)}\r\n />\r\n {label && (\r\n <label htmlFor={fieldId} className=\"form-check-label rrc-check__label\">\r\n {label}\r\n </label>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useId } from \"react\";\r\nimport { RadioButton } from \"./RadioButton\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { FieldShell } from \"./shared/FieldShell\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState, SelectOption } from \"./shared/fieldTypes\";\r\n\r\nexport interface RadioGroupProps<TValue extends string | number = string> extends FieldIdentity, FieldState, FieldPresentation {\r\n options: SelectOption<TValue>[];\r\n value?: TValue | null;\r\n defaultValue?: TValue | null;\r\n onChange?: (value: TValue) => void;\r\n inline?: boolean;\r\n}\r\n\r\n/**\r\n * Composes RadioButton rather than reproducing radio rendering (doc\r\n * section 7) — this is the component that actually owns the group's\r\n * controlled/uncontrolled value.\r\n */\r\nexport function RadioGroup<TValue extends string | number = string>({\r\n options,\r\n value,\r\n defaultValue,\r\n onChange,\r\n inline,\r\n id,\r\n name,\r\n disabled,\r\n required,\r\n className,\r\n label,\r\n helpText,\r\n error,\r\n}: RadioGroupProps<TValue>) {\r\n const [currentValue, setValue] = useControllableState<TValue | null>({\r\n value,\r\n defaultValue: defaultValue ?? null,\r\n onChange: (next) => {\r\n if (next !== null) onChange?.(next);\r\n },\r\n });\r\n\r\n const generatedId = useId();\r\n const groupName = name ?? id ?? generatedId;\r\n\r\n return (\r\n <FieldShell label={label} required={required} error={error} helpText={helpText} className={className}>\r\n <div role=\"radiogroup\" aria-label={label} aria-required={required} className={cx(\"rrc-radio-group\", inline && \"d-flex gap-3 rrc-radio-group--inline\")}>\r\n {options.map((option) => (\r\n <RadioButton\r\n key={String(option.value)}\r\n name={groupName}\r\n value={option.value}\r\n label={option.label}\r\n checked={option.value === currentValue}\r\n disabled={disabled || option.disabled}\r\n onChange={(next) => setValue(next)}\r\n />\r\n ))}\r\n </div>\r\n </FieldShell>\r\n );\r\n}\r\n","import { useId } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { FieldShell } from \"./shared/FieldShell\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState, SelectOption } from \"./shared/fieldTypes\";\r\n\r\nexport interface SelectProps<TValue extends string | number = string> extends FieldIdentity, FieldState, FieldPresentation {\r\n options: SelectOption<TValue>[];\r\n value?: TValue | null;\r\n defaultValue?: TValue | null;\r\n onChange?: (value: TValue | null) => void;\r\n /**\r\n * Presentational-only loading flag, same convention as ComboBox/\r\n * AutoComplete/MultiSelect's `loading` prop — Select has no idea *why*\r\n * it's loading (doc section 8). Disables the control and shows a\r\n * \"Loading…\" placeholder option; set by RemoteSelect.\r\n */\r\n loading?: boolean;\r\n}\r\n\r\n/**\r\n * Not remote-aware (doc section 5). Deliberately a native `<select>` rather\r\n * than reusing ComboBox's Popup/keyboard-list UI — their UI semantics\r\n * genuinely differ (native select already has full built-in keyboard/\r\n * screen-reader support, so reusing Popup here would be a *regression*, not\r\n * a simplification). The two DO share the same typed option abstraction\r\n * (`SelectOption`) and the same FieldShell/useControllableState — that's\r\n * the \"smallest appropriate abstraction\" the doc asks for.\r\n */\r\nexport function Select<TValue extends string | number = string>({\r\n options,\r\n value,\r\n defaultValue,\r\n onChange,\r\n placeholder,\r\n loading,\r\n id,\r\n name,\r\n disabled,\r\n readOnly,\r\n required,\r\n className,\r\n label,\r\n helpText,\r\n error,\r\n}: SelectProps<TValue>) {\r\n const [currentValue, setValue] = useControllableState<TValue | null>({\r\n value,\r\n defaultValue: defaultValue ?? null,\r\n onChange,\r\n });\r\n\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n return (\r\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\r\n <select\r\n id={fieldId}\r\n name={name}\r\n className={cx(\"form-select\", \"rrc-select\", error && \"is-invalid\")}\r\n disabled={disabled || readOnly || loading}\r\n required={required}\r\n value={currentValue === null ? \"\" : String(currentValue)}\r\n onChange={(event) => {\r\n const raw = event.target.value;\r\n if (raw === \"\") {\r\n setValue(null);\r\n return;\r\n }\r\n const matched = options.find((option) => String(option.value) === raw);\r\n setValue(matched ? matched.value : null);\r\n }}\r\n >\r\n {loading && <option value=\"\">Loading…</option>}\r\n {!loading && placeholder && <option value=\"\">{placeholder}</option>}\r\n {options.map((option) => (\r\n <option key={String(option.value)} value={String(option.value)} disabled={option.disabled}>\r\n {option.label}\r\n </option>\r\n ))}\r\n </select>\r\n </FieldShell>\r\n );\r\n}\r\n","import { useEffect } from \"react\";\r\n\r\n/** Shared by Popup and Modal so escape-to-close isn't reimplemented per component. */\r\nexport function useEscapeKey(active: boolean, onEscape: () => void): void {\r\n useEffect(() => {\r\n if (!active) return;\r\n function handleKeyDown(event: KeyboardEvent) {\r\n if (event.key === \"Escape\") onEscape();\r\n }\r\n document.addEventListener(\"keydown\", handleKeyDown);\r\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\r\n }, [active, onEscape]);\r\n}\r\n","import { useEffect, useRef, type ReactNode, type RefObject } from \"react\";\r\nimport { cx } from \"./classNames\";\r\nimport { useEscapeKey } from \"./useEscapeKey\";\r\n\r\nexport interface PopupProps {\r\n open: boolean;\r\n onClose: () => void;\r\n anchorRef: RefObject<HTMLElement>;\r\n className?: string;\r\n /** ARIA role of the floating panel — callers set this (e.g. \"listbox\" for ComboBox, none for Tooltip/Popover). */\r\n role?: string;\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * Anchored floating panel: open/close, escape-to-close, outside-click\r\n * dismissal, cleanup. Reused by ComboBox/AutoComplete/MultiSelect (as a\r\n * dropdown listbox) and by Tooltip/Popover (as a hover/click overlay) — so\r\n * it only forces Bootstrap's universal `show` visibility class; the\r\n * dropdown-specific (`dropdown-menu`) vs. tooltip/popover-specific\r\n * (`tooltip`, `popover`) presentation classes are each caller's own\r\n * responsibility via `className`.\r\n *\r\n * Known limitation (documented, not silently ignored): positioning is plain\r\n * CSS (`position: relative` on the anchor's wrapper), no portal/collision\r\n * detection yet. A portal-based strategy can be layered in later without\r\n * changing this component's public API.\r\n */\r\nexport function Popup({ open, onClose, anchorRef, className, role, children }: PopupProps) {\r\n const popupRef = useRef<HTMLDivElement>(null);\r\n\r\n useEscapeKey(open, onClose);\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n function handlePointerDown(event: MouseEvent) {\r\n const target = event.target as Node;\r\n if (popupRef.current?.contains(target)) return;\r\n if (anchorRef.current?.contains(target)) return;\r\n onClose();\r\n }\r\n document.addEventListener(\"mousedown\", handlePointerDown);\r\n return () => document.removeEventListener(\"mousedown\", handlePointerDown);\r\n }, [open, onClose, anchorRef]);\r\n\r\n if (!open) return null;\r\n\r\n return (\r\n <div ref={popupRef} className={cx(\"show\", \"rrc-popup\", className)} role={role}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n","import { useCallback, useEffect, useState, type KeyboardEvent } from \"react\";\r\nimport { useEscapeKey } from \"./useEscapeKey\";\r\n\r\nexport interface UseListNavigationOptions {\r\n itemCount: number;\r\n isOpen: boolean;\r\n onSelect: (index: number) => void;\r\n onClose: () => void;\r\n}\r\n\r\nexport interface UseListNavigationResult {\r\n activeIndex: number;\r\n setActiveIndex: (index: number) => void;\r\n handleKeyDown: (event: KeyboardEvent) => void;\r\n}\r\n\r\n/**\r\n * Headless keyboard-navigation behavior shared by ComboBox and AutoComplete\r\n * (doc section 19 — \"shared behavior\" reuse for the list-selection concern\r\n * that both components genuinely have in common).\r\n */\r\nexport function useListNavigation({\r\n itemCount,\r\n isOpen,\r\n onSelect,\r\n onClose,\r\n}: UseListNavigationOptions): UseListNavigationResult {\r\n const [activeIndex, setActiveIndex] = useState(-1);\r\n\r\n useEffect(() => {\r\n if (!isOpen) setActiveIndex(-1);\r\n }, [isOpen]);\r\n\r\n useEscapeKey(isOpen, onClose);\r\n\r\n const handleKeyDown = useCallback(\r\n (event: KeyboardEvent) => {\r\n if (!isOpen) {\r\n if (event.key === \"ArrowDown\" || event.key === \"Enter\") {\r\n event.preventDefault();\r\n }\r\n return;\r\n }\r\n switch (event.key) {\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n setActiveIndex((prev) => (itemCount === 0 ? -1 : (prev + 1) % itemCount));\r\n break;\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n setActiveIndex((prev) => (itemCount === 0 ? -1 : (prev - 1 + itemCount) % itemCount));\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n setActiveIndex(itemCount === 0 ? -1 : 0);\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n setActiveIndex(itemCount === 0 ? -1 : itemCount - 1);\r\n break;\r\n case \"Enter\":\r\n if (activeIndex >= 0) {\r\n event.preventDefault();\r\n onSelect(activeIndex);\r\n }\r\n break;\r\n default:\r\n break;\r\n }\r\n },\r\n [isOpen, itemCount, activeIndex, onSelect]\r\n );\r\n\r\n return { activeIndex, setActiveIndex, handleKeyDown };\r\n}\r\n","import { useCallback, useId, useRef, useState } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { FieldShell } from \"./shared/FieldShell\";\r\nimport { Popup } from \"./shared/Popup\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport { useListNavigation } from \"./shared/useListNavigation\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState, SelectOption } from \"./shared/fieldTypes\";\r\n\r\nexport interface MultiSelectProps<TValue extends string | number = string> extends FieldIdentity, FieldState, FieldPresentation {\r\n options: SelectOption<TValue>[];\r\n values?: TValue[];\r\n defaultValues?: TValue[];\r\n onChange?: (values: TValue[]) => void;\r\n loading?: boolean;\r\n emptyText?: string;\r\n}\r\n\r\n/**\r\n * Follows ComboBox's established `options: SelectOption<TValue>[]` /\r\n * FieldShell / Popup / useListNavigation conventions rather than the raw\r\n * `items`+`valueMember`+`displayMember` shape shown as a *conceptual*\r\n * example in the source spec — that mapping-by-key convention belongs to\r\n * the Remote layer (where raw API objects need mapping); Base MultiSelect\r\n * receives already-typed `SelectOption`s, consistent with Base ComboBox.\r\n * (Documented in the final report as a deliberate reconciliation of the\r\n * spec's own two instructions: \"follow this example\" vs. \"follow ComboBox's\r\n * existing, good convention\" — the latter wins per the spec's own priority.)\r\n *\r\n * Reuses Popup + useListNavigation from ComboBox/AutoComplete; the only\r\n * real behavioral difference is that selecting an option toggles it in a\r\n * `values` array and leaves the popup open instead of closing it.\r\n */\r\nexport function MultiSelect<TValue extends string | number = string>({\r\n options,\r\n values,\r\n defaultValues,\r\n onChange,\r\n loading,\r\n emptyText = \"No options\",\r\n id,\r\n name,\r\n disabled,\r\n readOnly,\r\n required,\r\n className,\r\n label,\r\n placeholder = \"Select...\",\r\n helpText,\r\n error,\r\n}: MultiSelectProps<TValue>) {\r\n const [currentValues, setValues] = useControllableState<TValue[]>({\r\n value: values,\r\n defaultValue: defaultValues ?? [],\r\n onChange,\r\n });\r\n const [open, setOpen] = useState(false);\r\n const anchorRef = useRef<HTMLButtonElement>(null);\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n const selectedSet = new Set(currentValues);\r\n\r\n const close = useCallback(() => setOpen(false), []);\r\n const toggleIndex = useCallback(\r\n (index: number) => {\r\n const option = options[index];\r\n if (!option || option.disabled) return;\r\n const next = selectedSet.has(option.value)\r\n ? currentValues.filter((v) => v !== option.value)\r\n : [...currentValues, option.value];\r\n setValues(next);\r\n },\r\n [options, currentValues, selectedSet, setValues]\r\n );\r\n\r\n const { activeIndex, setActiveIndex, handleKeyDown } = useListNavigation({\r\n itemCount: options.length,\r\n isOpen: open,\r\n onSelect: toggleIndex,\r\n onClose: close,\r\n });\r\n\r\n const selectedOptions = options.filter((option) => selectedSet.has(option.value));\r\n const summary = selectedOptions.map((option) => option.label).join(\", \");\r\n\r\n return (\r\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\r\n <div className=\"position-relative\">\r\n <button\r\n ref={anchorRef}\r\n id={fieldId}\r\n type=\"button\"\r\n name={name}\r\n className={cx(\"form-select text-start\", \"rrc-select\", \"rrc-select__trigger\", error && \"is-invalid\")}\r\n disabled={disabled || readOnly}\r\n aria-haspopup=\"listbox\"\r\n aria-expanded={open}\r\n onClick={() => setOpen((prev) => !prev)}\r\n onKeyDown={handleKeyDown}\r\n >\r\n {summary || <span className=\"text-body-secondary\">{placeholder}</span>}\r\n </button>\r\n <Popup open={open} onClose={close} anchorRef={anchorRef} className=\"dropdown-menu w-100 rrc-menu rrc-select__menu\" role=\"listbox\">\r\n {loading ? (\r\n <div className=\"px-3 py-2 text-body-secondary\">Loading…</div>\r\n ) : options.length === 0 ? (\r\n <div className=\"px-3 py-2 text-body-secondary\">{emptyText}</div>\r\n ) : (\r\n options.map((option, index) => (\r\n <div\r\n key={String(option.value)}\r\n role=\"option\"\r\n aria-selected={selectedSet.has(option.value)}\r\n className={cx(\r\n \"dropdown-item d-flex align-items-center gap-2\",\r\n index === activeIndex && \"active\",\r\n option.disabled && \"disabled\"\r\n )}\r\n onMouseEnter={() => setActiveIndex(index)}\r\n onMouseDown={(event) => {\r\n event.preventDefault();\r\n if (!option.disabled) toggleIndex(index);\r\n }}\r\n >\r\n <input type=\"checkbox\" className=\"form-check-input m-0\" checked={selectedSet.has(option.value)} readOnly tabIndex={-1} />\r\n {option.label}\r\n </div>\r\n ))\r\n )}\r\n </Popup>\r\n </div>\r\n </FieldShell>\r\n );\r\n}\r\n","import { Input } from \"./Input\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\r\n\r\nexport interface DatePickerProps extends FieldIdentity, FieldState, FieldPresentation {\r\n value?: Date | null;\r\n defaultValue?: Date | null;\r\n onChange?: (value: Date | null) => void;\r\n min?: Date;\r\n max?: Date;\r\n}\r\n\r\n/**\r\n * Exported so TimePicker/DateTimePicker can compose the exact same\r\n * date-part parsing/formatting instead of reimplementing it (doc section\r\n * 12 — a coherent Date/Time value strategy across the whole family).\r\n */\r\nexport function toDateInputValue(date: Date | null | undefined): string {\r\n if (!date) return \"\";\r\n const year = date.getFullYear();\r\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\r\n const day = String(date.getDate()).padStart(2, \"0\");\r\n return `${year}-${month}-${day}`;\r\n}\r\n\r\nexport function fromDateInputValue(raw: string): Date | null {\r\n if (!raw) return null;\r\n const parts = raw.split(\"-\").map(Number);\r\n const [year, month, day] = parts;\r\n if (!year || !month || !day) return null;\r\n return new Date(year, month - 1, day);\r\n}\r\n\r\n/**\r\n * Intentionally minimal: reuses Input + the native date picker UI rather\r\n * than building a calendar widget (doc section 10/18 — don't overbuild the\r\n * first iteration). value/onChange work in terms of `Date`, so a richer\r\n * Popup-based calendar can replace the native input later without breaking\r\n * this public contract. See \"Known Limitations\" in the final report.\r\n */\r\nexport function DatePicker({ value, defaultValue, onChange, min, max, ...rest }: DatePickerProps) {\r\n const [currentValue, setValue] = useControllableState<Date | null>({\r\n value,\r\n defaultValue: defaultValue ?? null,\r\n onChange,\r\n });\r\n\r\n return (\r\n <Input\r\n {...rest}\r\n value={toDateInputValue(currentValue)}\r\n onChange={(raw) => setValue(fromDateInputValue(raw))}\r\n inputProps={{\r\n type: \"date\",\r\n min: min ? toDateInputValue(min) : undefined,\r\n max: max ? toDateInputValue(max) : undefined,\r\n }}\r\n />\r\n );\r\n}\r\n","import { Input } from \"./Input\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\r\n\r\nexport interface TimePickerProps extends FieldIdentity, FieldState, FieldPresentation {\r\n value?: Date | null;\r\n defaultValue?: Date | null;\r\n onChange?: (value: Date | null) => void;\r\n /** Native `<input type=\"time\">` step, in seconds. */\r\n step?: number;\r\n}\r\n\r\n/**\r\n * Value strategy (doc section 12): TimePicker uses `Date`, same as\r\n * DatePicker/DateTimePicker, for a coherent family — but only the\r\n * hours/minutes are meaningful; the date part is normalized to the epoch so\r\n * consumers can't accidentally depend on it. This is what lets\r\n * DateTimePicker combine a DatePicker date-part with a TimePicker\r\n * time-part into one `Date` without any string/format juggling.\r\n */\r\nexport function toTimeInputValue(date: Date | null | undefined): string {\r\n if (!date) return \"\";\r\n const hours = String(date.getHours()).padStart(2, \"0\");\r\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\r\n return `${hours}:${minutes}`;\r\n}\r\n\r\nexport function fromTimeInputValue(raw: string): Date | null {\r\n if (!raw) return null;\r\n const [hours, minutes] = raw.split(\":\").map(Number);\r\n if (hours === undefined || minutes === undefined || Number.isNaN(hours) || Number.isNaN(minutes)) return null;\r\n return new Date(1970, 0, 1, hours, minutes, 0, 0);\r\n}\r\n\r\n/** Composes Input, same pattern as DatePicker/NumberInput (doc section 19). */\r\nexport function TimePicker({ value, defaultValue, onChange, step, ...rest }: TimePickerProps) {\r\n const [currentValue, setValue] = useControllableState<Date | null>({\r\n value,\r\n defaultValue: defaultValue ?? null,\r\n onChange,\r\n });\r\n\r\n return (\r\n <Input\r\n {...rest}\r\n value={toTimeInputValue(currentValue)}\r\n onChange={(raw) => setValue(fromTimeInputValue(raw))}\r\n inputProps={{ type: \"time\", step }}\r\n />\r\n );\r\n}\r\n","import { useId } from \"react\";\r\nimport { fromDateInputValue, toDateInputValue } from \"./DatePicker\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { FieldShell } from \"./shared/FieldShell\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport { fromTimeInputValue, toTimeInputValue } from \"./TimePicker\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\r\n\r\nexport interface DateTimePickerProps extends FieldIdentity, FieldState, FieldPresentation {\r\n value?: Date | null;\r\n defaultValue?: Date | null;\r\n onChange?: (value: Date | null) => void;\r\n min?: Date;\r\n max?: Date;\r\n}\r\n\r\nfunction combine(datePart: string, timePart: string): Date | null {\r\n const date = fromDateInputValue(datePart);\r\n if (!date) return null;\r\n const time = fromTimeInputValue(timePart || \"00:00\");\r\n if (time) date.setHours(time.getHours(), time.getMinutes(), 0, 0);\r\n return date;\r\n}\r\n\r\n/**\r\n * Reuses DatePicker's/TimePicker's exported date-part/time-part parsing so\r\n * the whole family shares one coherent `Date` value strategy (doc section\r\n * 12) — this is the actual \"behavior reuse\" the doc asks for. Renders two\r\n * plain native inputs rather than nesting two <Input>s: Input always wraps\r\n * itself in FieldShell, and nesting it twice here would produce two labels\r\n * for one field. A single FieldShell wraps both inputs as one field group.\r\n */\r\nexport function DateTimePicker({\r\n value,\r\n defaultValue,\r\n onChange,\r\n min,\r\n max,\r\n id,\r\n name,\r\n disabled,\r\n readOnly,\r\n required,\r\n className,\r\n label,\r\n helpText,\r\n error,\r\n}: DateTimePickerProps) {\r\n const [currentValue, setValue] = useControllableState<Date | null>({\r\n value,\r\n defaultValue: defaultValue ?? null,\r\n onChange,\r\n });\r\n\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n const datePart = toDateInputValue(currentValue);\r\n const timePart = toTimeInputValue(currentValue);\r\n\r\n return (\r\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\r\n <div className=\"d-flex gap-2\">\r\n <input\r\n id={fieldId}\r\n name={name ? `${name}-date` : undefined}\r\n type=\"date\"\r\n className={cx(\"form-control\", \"rrc-input\", error && \"is-invalid\")}\r\n disabled={disabled}\r\n readOnly={readOnly}\r\n required={required}\r\n min={min ? toDateInputValue(min) : undefined}\r\n max={max ? toDateInputValue(max) : undefined}\r\n value={datePart}\r\n onChange={(event) => setValue(combine(event.target.value, timePart))}\r\n />\r\n <input\r\n name={name ? `${name}-time` : undefined}\r\n type=\"time\"\r\n className={cx(\"form-control\", \"rrc-input\", error && \"is-invalid\")}\r\n disabled={disabled}\r\n readOnly={readOnly}\r\n required={required}\r\n value={timePart}\r\n onChange={(event) => setValue(combine(datePart || toDateInputValue(new Date()), event.target.value))}\r\n />\r\n </div>\r\n </FieldShell>\r\n );\r\n}\r\n","import { useCallback, useId, useRef, useState } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { FieldShell } from \"./shared/FieldShell\";\r\nimport { Popup } from \"./shared/Popup\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport { useListNavigation } from \"./shared/useListNavigation\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState, SelectOption } from \"./shared/fieldTypes\";\r\n\r\nexport type { SelectOption };\r\n\r\nexport interface ComboBoxProps<TValue extends string | number = string> extends FieldIdentity, FieldState, FieldPresentation {\r\n options: SelectOption<TValue>[];\r\n value?: TValue | null;\r\n defaultValue?: TValue | null;\r\n onChange?: (value: TValue | null) => void;\r\n /**\r\n * Presentational-only loading flag. ComboBox has no idea *why* it's\r\n * loading (doc section 8: don't pollute Base with HTTP concepts) — this\r\n * is set by RemoteComboBox, but could equally be driven by any other\r\n * async source.\r\n */\r\n loading?: boolean;\r\n emptyText?: string;\r\n}\r\n\r\nexport function ComboBox<TValue extends string | number = string>({\r\n options,\r\n value,\r\n defaultValue,\r\n onChange,\r\n loading,\r\n emptyText = \"No options\",\r\n id,\r\n name,\r\n disabled,\r\n readOnly,\r\n required,\r\n className,\r\n label,\r\n placeholder = \"Select...\",\r\n helpText,\r\n error,\r\n}: ComboBoxProps<TValue>) {\r\n const [currentValue, setValue] = useControllableState<TValue | null>({\r\n value,\r\n defaultValue: defaultValue ?? null,\r\n onChange,\r\n });\r\n const [open, setOpen] = useState(false);\r\n const anchorRef = useRef<HTMLButtonElement>(null);\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n const selectedOption = options.find((option) => option.value === currentValue) ?? null;\r\n\r\n const close = useCallback(() => setOpen(false), []);\r\n const selectIndex = useCallback(\r\n (index: number) => {\r\n const option = options[index];\r\n if (!option || option.disabled) return;\r\n setValue(option.value);\r\n close();\r\n },\r\n [options, setValue, close]\r\n );\r\n\r\n const { activeIndex, setActiveIndex, handleKeyDown } = useListNavigation({\r\n itemCount: options.length,\r\n isOpen: open,\r\n onSelect: selectIndex,\r\n onClose: close,\r\n });\r\n\r\n return (\r\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\r\n <div className=\"position-relative\">\r\n <button\r\n ref={anchorRef}\r\n id={fieldId}\r\n type=\"button\"\r\n name={name}\r\n className={cx(\"form-select text-start\", \"rrc-select\", \"rrc-select__trigger\", error && \"is-invalid\")}\r\n disabled={disabled || readOnly}\r\n aria-haspopup=\"listbox\"\r\n aria-expanded={open}\r\n onClick={() => setOpen((prev) => !prev)}\r\n onKeyDown={handleKeyDown}\r\n >\r\n {selectedOption ? selectedOption.label : <span className=\"text-body-secondary\">{placeholder}</span>}\r\n </button>\r\n <Popup open={open} onClose={close} anchorRef={anchorRef} className=\"dropdown-menu w-100 rrc-menu rrc-select__menu\" role=\"listbox\">\r\n {loading ? (\r\n <div className=\"px-3 py-2 text-body-secondary\">Loading…</div>\r\n ) : options.length === 0 ? (\r\n <div className=\"px-3 py-2 text-body-secondary\">{emptyText}</div>\r\n ) : (\r\n options.map((option, index) => (\r\n <div\r\n key={String(option.value)}\r\n role=\"option\"\r\n aria-selected={option.value === currentValue}\r\n className={cx(\"dropdown-item\", \"rrc-menu__item\", index === activeIndex && \"active\", option.disabled && \"disabled\")}\r\n onMouseEnter={() => setActiveIndex(index)}\r\n onMouseDown={(event) => {\r\n event.preventDefault();\r\n if (!option.disabled) selectIndex(index);\r\n }}\r\n >\r\n {option.label}\r\n </div>\r\n ))\r\n )}\r\n </Popup>\r\n </div>\r\n </FieldShell>\r\n );\r\n}\r\n","import { useCallback, useId, useRef, useState } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { FieldShell } from \"./shared/FieldShell\";\r\nimport { Popup } from \"./shared/Popup\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport { useListNavigation } from \"./shared/useListNavigation\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState, SelectOption } from \"./shared/fieldTypes\";\r\n\r\nexport interface AutoCompleteProps<TValue extends string | number = string> extends FieldIdentity, FieldState, FieldPresentation {\r\n options: SelectOption<TValue>[];\r\n value?: TValue | null;\r\n defaultValue?: TValue | null;\r\n onChange?: (value: TValue | null) => void;\r\n /** Controlled search text, independent from the selected `value`. */\r\n inputValue?: string;\r\n onInputValueChange?: (text: string) => void;\r\n /** Presentational-only loading flag — see ComboBox's `loading` prop. */\r\n loading?: boolean;\r\n emptyText?: string;\r\n /**\r\n * Local filter predicate. Defaults to a case-insensitive substring match.\r\n * RemoteAutoComplete overrides this with `() => true` because the server\r\n * already filtered the results — Base must never re-filter server output.\r\n */\r\n filter?: (option: SelectOption<TValue>, query: string) => boolean;\r\n}\r\n\r\nfunction defaultFilter<TValue extends string | number>(option: SelectOption<TValue>, query: string): boolean {\r\n if (!query) return true;\r\n return option.label.toLowerCase().includes(query.toLowerCase());\r\n}\r\n\r\nexport function AutoComplete<TValue extends string | number = string>({\r\n options,\r\n value,\r\n defaultValue,\r\n onChange,\r\n inputValue,\r\n onInputValueChange,\r\n loading,\r\n emptyText = \"No results\",\r\n filter,\r\n id,\r\n name,\r\n disabled,\r\n readOnly,\r\n required,\r\n className,\r\n label,\r\n placeholder,\r\n helpText,\r\n error,\r\n}: AutoCompleteProps<TValue>) {\r\n const [currentValue, setValue] = useControllableState<TValue | null>({\r\n value,\r\n defaultValue: defaultValue ?? null,\r\n onChange,\r\n });\r\n const selectedOption = options.find((option) => option.value === currentValue) ?? null;\r\n\r\n const [internalText, setInternalText] = useControllableState<string>({\r\n value: inputValue,\r\n defaultValue: selectedOption?.label ?? \"\",\r\n onChange: onInputValueChange,\r\n });\r\n\r\n const [open, setOpen] = useState(false);\r\n const anchorRef = useRef<HTMLInputElement>(null);\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n const matchFilter = filter ?? defaultFilter;\r\n const filteredOptions = options.filter((option) => matchFilter(option, internalText));\r\n\r\n const close = useCallback(() => setOpen(false), []);\r\n const selectIndex = useCallback(\r\n (index: number) => {\r\n const option = filteredOptions[index];\r\n if (!option || option.disabled) return;\r\n setValue(option.value);\r\n setInternalText(option.label);\r\n close();\r\n },\r\n [filteredOptions, setValue, setInternalText, close]\r\n );\r\n\r\n const { activeIndex, setActiveIndex, handleKeyDown } = useListNavigation({\r\n itemCount: filteredOptions.length,\r\n isOpen: open,\r\n onSelect: selectIndex,\r\n onClose: close,\r\n });\r\n\r\n return (\r\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\r\n <div className=\"position-relative\">\r\n <input\r\n ref={anchorRef}\r\n id={fieldId}\r\n name={name}\r\n type=\"text\"\r\n className={cx(\"form-control\", \"rrc-input\", error && \"is-invalid\")}\r\n disabled={disabled}\r\n readOnly={readOnly}\r\n required={required}\r\n placeholder={placeholder}\r\n autoComplete=\"off\"\r\n role=\"combobox\"\r\n aria-expanded={open}\r\n aria-haspopup=\"listbox\"\r\n value={internalText}\r\n onFocus={() => setOpen(true)}\r\n onChange={(event) => {\r\n const text = event.target.value;\r\n setInternalText(text);\r\n setOpen(true);\r\n if (currentValue !== null) setValue(null);\r\n }}\r\n onKeyDown={handleKeyDown}\r\n />\r\n <Popup open={open} onClose={close} anchorRef={anchorRef} className=\"dropdown-menu w-100 rrc-menu rrc-select__menu\" role=\"listbox\">\r\n {loading ? (\r\n <div className=\"px-3 py-2 text-body-secondary\">Loading…</div>\r\n ) : filteredOptions.length === 0 ? (\r\n <div className=\"px-3 py-2 text-body-secondary\">{emptyText}</div>\r\n ) : (\r\n filteredOptions.map((option, index) => (\r\n <div\r\n key={String(option.value)}\r\n role=\"option\"\r\n aria-selected={option.value === currentValue}\r\n className={cx(\"dropdown-item\", \"rrc-menu__item\", index === activeIndex && \"active\", option.disabled && \"disabled\")}\r\n onMouseEnter={() => setActiveIndex(index)}\r\n onMouseDown={(event) => {\r\n event.preventDefault();\r\n if (!option.disabled) selectIndex(index);\r\n }}\r\n >\r\n {option.label}\r\n </div>\r\n ))\r\n )}\r\n </Popup>\r\n </div>\r\n </FieldShell>\r\n );\r\n}\r\n","import { FieldShell, type FieldShellProps } from \"./shared/FieldShell\";\r\n\r\nexport type FormFieldProps = FieldShellProps;\r\n\r\n/**\r\n * Public composition of Label + control + ValidationMessage for consumers\r\n * who need our field chrome around a *custom* control (e.g. a group of\r\n * RadioButtons, a Switch, a third-party widget) rather than one of our own\r\n * field components. Deliberately a thin re-export of FieldShell — the two\r\n * names serve different audiences (FieldShell: internal plumbing for our\r\n * own fields; FormField: the same behavior, public), not two\r\n * implementations (doc section 9 — no form-framework infrastructure here).\r\n */\r\nexport function FormField(props: FormFieldProps) {\r\n return <FieldShell {...props} />;\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { useEscapeKey } from \"./shared/useEscapeKey\";\r\n\r\nexport interface ModalProps {\r\n open: boolean;\r\n onClose: () => void;\r\n title?: string;\r\n children: ReactNode;\r\n footer?: ReactNode;\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Centered/backdrop dialog overlay — a different interaction model from\r\n * Popup's anchored dropdown, so it's a separate component, but shares the\r\n * escape-to-close behavior via useEscapeKey.\r\n *\r\n * Known limitation: not rendered through a portal yet (renders in place).\r\n * Can be swapped to `createPortal(..., document.body)` later without\r\n * changing this component's props.\r\n */\r\nexport function Modal({ open, onClose, title, children, footer, className }: ModalProps) {\r\n useEscapeKey(open, onClose);\r\n\r\n if (!open) return null;\r\n\r\n return (\r\n <>\r\n <div className=\"modal d-block rrc-modal\" tabIndex={-1} role=\"dialog\" aria-modal=\"true\">\r\n <div className={cx(\"modal-dialog\", \"rrc-modal__dialog\", className)} role=\"document\">\r\n <div className=\"modal-content rrc-modal__content\">\r\n <div className=\"modal-header rrc-modal__header\">\r\n {title && <h5 className=\"modal-title\">{title}</h5>}\r\n <button type=\"button\" className=\"btn-close\" aria-label=\"Close\" onClick={onClose} />\r\n </div>\r\n <div className=\"modal-body rrc-modal__body\">{children}</div>\r\n {footer && <div className=\"modal-footer rrc-modal__footer\">{footer}</div>}\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"modal-backdrop show rrc-modal__backdrop\" onClick={onClose} />\r\n </>\r\n );\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\n\r\nexport interface PaginationProps {\r\n currentPage: number;\r\n pageSize: number;\r\n totalItems: number;\r\n onPageChange: (page: number) => void;\r\n /** How many numbered page buttons to show on each side of the current page. */\r\n siblingCount?: number;\r\n className?: string;\r\n}\r\n\r\ntype PageEntry = number | \"ellipsis\";\r\n\r\nfunction getPageList(current: number, total: number, siblingCount: number): PageEntry[] {\r\n const pages: PageEntry[] = [];\r\n const start = Math.max(1, current - siblingCount);\r\n const end = Math.min(total, current + siblingCount);\r\n\r\n if (start > 1) {\r\n pages.push(1);\r\n if (start > 2) pages.push(\"ellipsis\");\r\n }\r\n for (let page = start; page <= end; page++) pages.push(page);\r\n if (end < total) {\r\n if (end < total - 1) pages.push(\"ellipsis\");\r\n pages.push(total);\r\n }\r\n return pages;\r\n}\r\n\r\n/**\r\n * UI-only, like DataGrid's other UI concerns — no API calls (doc section\r\n * 19). This is what lets it be reused by DataGrid (and later\r\n * RemoteDataGrid/SmartDataGrid) regardless of where the rows came from.\r\n */\r\nexport function Pagination({ currentPage, pageSize, totalItems, onPageChange, siblingCount = 1, className }: PaginationProps) {\r\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));\r\n const pages = getPageList(currentPage, totalPages, siblingCount);\r\n\r\n return (\r\n <nav aria-label=\"Pagination\" className={className}>\r\n <ul className=\"pagination mb-0 rrc-pagination\">\r\n <li className={cx(\"page-item\", currentPage <= 1 && \"disabled\")}>\r\n <button\r\n type=\"button\"\r\n className=\"page-link\"\r\n disabled={currentPage <= 1}\r\n onClick={() => onPageChange(currentPage - 1)}\r\n >\r\n Previous\r\n </button>\r\n </li>\r\n {pages.map((page, index) =>\r\n page === \"ellipsis\" ? (\r\n <li key={`ellipsis-${index}`} className=\"page-item disabled\">\r\n <span className=\"page-link\">…</span>\r\n </li>\r\n ) : (\r\n <li key={page} className={cx(\"page-item\", page === currentPage && \"active\")}>\r\n <button\r\n type=\"button\"\r\n className=\"page-link\"\r\n aria-current={page === currentPage ? \"page\" : undefined}\r\n onClick={() => onPageChange(page)}\r\n >\r\n {page}\r\n </button>\r\n </li>\r\n )\r\n )}\r\n <li className={cx(\"page-item\", currentPage >= totalPages && \"disabled\")}>\r\n <button\r\n type=\"button\"\r\n className=\"page-link\"\r\n disabled={currentPage >= totalPages}\r\n onClick={() => onPageChange(currentPage + 1)}\r\n >\r\n Next\r\n </button>\r\n </li>\r\n </ul>\r\n </nav>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { Pagination } from \"./Pagination\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport type DataGridAlign = \"start\" | \"center\" | \"end\";\r\n\r\n/**\r\n * Closed, finite formatter set — the same contract the Smart layer's\r\n * `format` metadata already targeted, now owned here instead of being\r\n * duplicated in a second Smart-side formatter map (doc: \"Base DataGrid owns\r\n * reusable presentation capability, Smart chooses a supported formatter\").\r\n * Never accepts an arbitrary/serialized function — that stays Smart's\r\n * closed-enum contract too.\r\n */\r\nexport type DataGridFormat = \"text\" | \"date\" | \"currency\" | \"boolean\";\r\n\r\nexport const dataGridFormatters: Record<DataGridFormat, (value: unknown) => ReactNode> = {\r\n text: (value) => (value == null ? \"\" : String(value)),\r\n boolean: (value) => (value ? \"Yes\" : \"No\"),\r\n date: (value) => {\r\n if (value == null || value === \"\") return \"\";\r\n const date = value instanceof Date ? value : new Date(String(value));\r\n return Number.isNaN(date.getTime()) ? String(value) : date.toLocaleDateString();\r\n },\r\n currency: (value) => {\r\n const amount = Number(value);\r\n return Number.isFinite(amount) ? amount.toLocaleString(undefined, { style: \"currency\", currency: \"USD\" }) : String(value ?? \"\");\r\n },\r\n};\r\n\r\nexport interface DataGridColumn<TRow> {\r\n /** Row-identity/sort key. Defaults to `field` when omitted — required only if `field` is also omitted (a fully custom `render`-only column). */\r\n key?: string;\r\n /** Row property this column reads its value from — strongly typed against `TRow`. Enables the declarative `align`/`format`/`formatter` path below instead of a `render` callback. */\r\n field?: keyof TRow & string;\r\n header: string;\r\n align?: DataGridAlign;\r\n /** Defaults to `align` when omitted. */\r\n headerAlign?: DataGridAlign;\r\n width?: string;\r\n minWidth?: string;\r\n maxWidth?: string;\r\n sortable?: boolean;\r\n /** Built-in formatter selection — the normal way to display a field (see `dataGridFormatters`). */\r\n format?: DataGridFormat;\r\n /** Escape hatch for a computed display value that still gets the standard aligned cell wrapper. */\r\n formatter?: (value: unknown, row: TRow) => ReactNode;\r\n /** Escape hatch for a fully custom cell — the exception, not the default way to display a field. */\r\n render?: (row: TRow) => ReactNode;\r\n}\r\n\r\nexport type DataGridSort = { key: string; direction: \"asc\" | \"desc\" };\r\n\r\nexport interface DataGridProps<TRow> {\r\n columns: DataGridColumn<TRow>[];\r\n rows: TRow[];\r\n rowKey: (row: TRow) => string | number;\r\n loading?: boolean;\r\n error?: string;\r\n emptyText?: string;\r\n className?: string;\r\n\r\n /** Selection is a generic UI concern — Base doesn't know how selection maps to anything remote. */\r\n selectedRowKeys?: Array<string | number>;\r\n onSelectionChange?: (keys: Array<string | number>) => void;\r\n\r\n /**\r\n * Sort UI only. Base renders sort indicators and calls back on header\r\n * click — it has no idea whether sorting happens client-side or via a\r\n * server request (doc section 10).\r\n */\r\n sort?: DataGridSort | null;\r\n onSortChange?: (sort: DataGridSort | null) => void;\r\n\r\n /** Pagination UI only, fully controlled from outside — same principle as sort. */\r\n page?: number;\r\n pageSize?: number;\r\n totalCount?: number;\r\n onPageChange?: (page: number) => void;\r\n}\r\n\r\nfunction nextSortDirection(current: DataGridSort | null | undefined, key: string): DataGridSort | null {\r\n if (!current || current.key !== key) return { key, direction: \"asc\" };\r\n if (current.direction === \"asc\") return { key, direction: \"desc\" };\r\n return null;\r\n}\r\n\r\nfunction columnKeyOf<TRow>(column: DataGridColumn<TRow>): string {\r\n return column.key ?? column.field ?? column.header;\r\n}\r\n\r\nfunction columnValueOf<TRow>(column: DataGridColumn<TRow>, row: TRow): unknown {\r\n const accessor = column.field ?? column.key;\r\n return accessor ? (row as Record<string, unknown>)[accessor] : undefined;\r\n}\r\n\r\nfunction renderCell<TRow>(column: DataGridColumn<TRow>, row: TRow): ReactNode {\r\n if (column.render) return column.render(row);\r\n const value = columnValueOf(column, row);\r\n if (column.formatter) return column.formatter(value, row);\r\n if (column.format) return dataGridFormatters[column.format](value);\r\n return value == null ? \"\" : String(value);\r\n}\r\n\r\nfunction alignClass(align: DataGridAlign | undefined): string | undefined {\r\n return align && `text-${align}`;\r\n}\r\n\r\n/**\r\n * Intentionally focused first iteration (doc section 10/18): columns, rows,\r\n * selection, sort UI, pagination UI, loading/empty/error presentation.\r\n * No built-in filtering UI, column resize/reorder, or virtualization yet —\r\n * those are future extensions, not implemented speculatively.\r\n */\r\nexport function DataGrid<TRow>({\r\n columns,\r\n rows,\r\n rowKey,\r\n loading,\r\n error,\r\n emptyText = \"No data\",\r\n className,\r\n selectedRowKeys,\r\n onSelectionChange,\r\n sort,\r\n onSortChange,\r\n page,\r\n pageSize,\r\n totalCount,\r\n onPageChange,\r\n}: DataGridProps<TRow>) {\r\n const selectable = Boolean(onSelectionChange);\r\n const selectedSet = new Set(selectedRowKeys ?? []);\r\n const paginated = page !== undefined && pageSize !== undefined && totalCount !== undefined;\r\n const totalPages = paginated ? Math.max(1, Math.ceil(totalCount / pageSize)) : 1;\r\n\r\n function toggleAll() {\r\n if (!onSelectionChange) return;\r\n if (selectedSet.size === rows.length) {\r\n onSelectionChange([]);\r\n } else {\r\n onSelectionChange(rows.map(rowKey));\r\n }\r\n }\r\n\r\n function toggleRow(key: string | number) {\r\n if (!onSelectionChange) return;\r\n const next = new Set(selectedSet);\r\n if (next.has(key)) next.delete(key);\r\n else next.add(key);\r\n onSelectionChange(Array.from(next));\r\n }\r\n\r\n return (\r\n <div className={cx(\"table-responsive\", \"rrc-data-grid\", className)}>\r\n <table className=\"table table-hover align-middle rrc-data-grid__table\">\r\n <thead>\r\n <tr>\r\n {selectable && (\r\n <th style={{ width: \"2.5rem\" }}>\r\n <input\r\n type=\"checkbox\"\r\n className=\"form-check-input\"\r\n checked={rows.length > 0 && selectedSet.size === rows.length}\r\n onChange={toggleAll}\r\n aria-label=\"Select all rows\"\r\n />\r\n </th>\r\n )}\r\n {columns.map((column) => {\r\n const key = columnKeyOf(column);\r\n return (\r\n <th\r\n key={key}\r\n className={alignClass(column.headerAlign ?? column.align)}\r\n style={{ width: column.width, minWidth: column.minWidth, maxWidth: column.maxWidth }}\r\n role={column.sortable ? \"button\" : undefined}\r\n onClick={column.sortable && onSortChange ? () => onSortChange(nextSortDirection(sort, key)) : undefined}\r\n >\r\n {column.header}\r\n {column.sortable && sort?.key === key && <span aria-hidden=\"true\"> {sort.direction === \"asc\" ? \"▲\" : \"▼\"}</span>}\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {loading ? (\r\n <tr>\r\n <td colSpan={columns.length + (selectable ? 1 : 0)} className=\"text-center text-body-secondary py-4\">\r\n Loading…\r\n </td>\r\n </tr>\r\n ) : error ? (\r\n <tr>\r\n <td colSpan={columns.length + (selectable ? 1 : 0)} className=\"text-center text-danger py-4\">\r\n {error}\r\n </td>\r\n </tr>\r\n ) : rows.length === 0 ? (\r\n <tr>\r\n <td colSpan={columns.length + (selectable ? 1 : 0)} className=\"text-center text-body-secondary py-4\">\r\n {emptyText}\r\n </td>\r\n </tr>\r\n ) : (\r\n rows.map((row) => {\r\n const key = rowKey(row);\r\n return (\r\n <tr key={key}>\r\n {selectable && (\r\n <td>\r\n <input\r\n type=\"checkbox\"\r\n className=\"form-check-input\"\r\n checked={selectedSet.has(key)}\r\n onChange={() => toggleRow(key)}\r\n aria-label=\"Select row\"\r\n />\r\n </td>\r\n )}\r\n {columns.map((column) => (\r\n <td key={columnKeyOf(column)} className={alignClass(column.align)}>\r\n {renderCell(column, row)}\r\n </td>\r\n ))}\r\n </tr>\r\n );\r\n })\r\n )}\r\n </tbody>\r\n </table>\r\n\r\n {paginated && (\r\n <div className=\"d-flex justify-content-between align-items-center mt-2 rrc-data-grid__footer\">\r\n <span className=\"text-body-secondary small\">\r\n Page {page} of {totalPages} ({totalCount} rows)\r\n </span>\r\n <Pagination currentPage={page!} pageSize={pageSize!} totalItems={totalCount!} onPageChange={onPageChange!} />\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\n\r\nexport interface SpinnerProps {\r\n size?: \"sm\" | \"md\";\r\n variant?: string;\r\n className?: string;\r\n label?: string;\r\n}\r\n\r\nexport function Spinner({ size = \"md\", variant, className, label = \"Loading...\" }: SpinnerProps) {\r\n return (\r\n <span\r\n className={cx(\"spinner-border\", \"rrc-spinner\", size === \"sm\" && \"spinner-border-sm\", variant && `text-${variant}`, className)}\r\n role=\"status\"\r\n >\r\n <span className=\"visually-hidden\">{label}</span>\r\n </span>\r\n );\r\n}\r\n","import type { ButtonHTMLAttributes, ReactNode } from \"react\";\r\nimport { Spinner } from \"./Spinner\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport type ButtonVariant =\r\n | \"primary\"\r\n | \"secondary\"\r\n | \"success\"\r\n | \"danger\"\r\n | \"warning\"\r\n | \"info\"\r\n | \"light\"\r\n | \"dark\"\r\n | \"link\"\r\n | \"outline-primary\"\r\n | \"outline-secondary\"\r\n /**\r\n * Contextual light variants — a soft tinted surface with the contextual\r\n * foreground, the Metronic Bootstrap signature for a secondary action.\r\n * Added additively; Bootstrap has no `btn-light-*` rule of its own, so these\r\n * render as a plain button until `rich-react-component/style.css` is\r\n * imported, and no existing variant changed.\r\n */\r\n | \"light-primary\"\r\n | \"light-secondary\"\r\n | \"light-success\"\r\n | \"light-danger\"\r\n | \"light-warning\"\r\n | \"light-info\";\r\n\r\nexport interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"className\" | \"type\" | \"disabled\"> {\r\n variant?: ButtonVariant;\r\n size?: \"sm\" | \"lg\";\r\n disabled?: boolean;\r\n loading?: boolean;\r\n type?: \"button\" | \"submit\" | \"reset\";\r\n className?: string;\r\n children?: ReactNode;\r\n}\r\n\r\n/** Reuses Spinner for the loading indicator (doc section 13) instead of a bespoke inline spinner. */\r\nexport function Button({\r\n variant = \"primary\",\r\n size,\r\n disabled,\r\n loading,\r\n type = \"button\",\r\n className,\r\n children,\r\n onClick,\r\n ...rest\r\n}: ButtonProps) {\r\n const isDisabled = disabled || loading;\r\n\r\n return (\r\n <button\r\n type={type}\r\n className={cx(\"btn\", `btn-${variant}`, size && `btn-${size}`, \"rrc-btn\", `rrc-btn--${variant}`, className)}\r\n disabled={isDisabled}\r\n aria-busy={loading || undefined}\r\n onClick={isDisabled ? undefined : onClick}\r\n {...rest}\r\n >\r\n {loading && <Spinner size=\"sm\" className=\"me-2\" label=\"\" />}\r\n {children}\r\n </button>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport type AlertVariant = \"primary\" | \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" | \"light\" | \"dark\";\r\n\r\nexport interface AlertProps {\r\n variant?: AlertVariant;\r\n dismissible?: boolean;\r\n onDismiss?: () => void;\r\n className?: string;\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * Presentation only (doc section 15) — deliberately not a toast\r\n * service/notification bus/error-management system. A consumer owns when\r\n * an Alert mounts/unmounts and what triggers it.\r\n */\r\nexport function Alert({ variant = \"info\", dismissible, onDismiss, className, children }: AlertProps) {\r\n return (\r\n <div className={cx(\"alert\", `alert-${variant}`, dismissible && \"alert-dismissible\", \"rrc-alert\", `rrc-alert--${variant}`, className)} role=\"alert\">\r\n {children}\r\n {dismissible && <button type=\"button\" className=\"btn-close\" aria-label=\"Close\" onClick={onDismiss} />}\r\n </div>\r\n );\r\n}\r\n","import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\r\nimport { Alert, type AlertVariant } from \"./Alert\";\r\n\r\nexport interface ToastOptions {\r\n variant?: AlertVariant;\r\n /** Auto-dismiss delay in ms. Pass 0 to require manual dismissal via the Alert's close button. */\r\n duration?: number;\r\n}\r\n\r\ninterface ToastItem {\r\n id: number;\r\n message: ReactNode;\r\n variant: AlertVariant;\r\n}\r\n\r\nexport interface ToastApi {\r\n show: (message: ReactNode, options?: ToastOptions) => number;\r\n dismiss: (id: number) => void;\r\n success: (message: ReactNode, options?: Omit<ToastOptions, \"variant\">) => number;\r\n error: (message: ReactNode, options?: Omit<ToastOptions, \"variant\">) => number;\r\n info: (message: ReactNode, options?: Omit<ToastOptions, \"variant\">) => number;\r\n warning: (message: ReactNode, options?: Omit<ToastOptions, \"variant\">) => number;\r\n}\r\n\r\nconst ToastContext = createContext<ToastApi | null>(null);\r\n\r\nconst DEFAULT_DURATION = 4000;\r\n\r\n/**\r\n * Global toast notifications. Reuses Alert's variant styling and dismiss\r\n * button (doc section 20: capability layers must not duplicate an existing\r\n * implementation) for the actual message presentation — this module only\r\n * owns the queue/timing/positioning concerns Alert's own doc comment\r\n * deliberately left out of Alert itself.\r\n */\r\nexport function ToastProvider({ children }: { children: ReactNode }) {\r\n const [toasts, setToasts] = useState<ToastItem[]>([]);\r\n const nextId = useRef(0);\r\n const timers = useRef(new Map<number, ReturnType<typeof setTimeout>>());\r\n\r\n useEffect(() => {\r\n const activeTimers = timers.current;\r\n return () => {\r\n activeTimers.forEach(clearTimeout);\r\n activeTimers.clear();\r\n };\r\n }, []);\r\n\r\n const dismiss = useCallback((id: number) => {\r\n const timer = timers.current.get(id);\r\n if (timer) {\r\n clearTimeout(timer);\r\n timers.current.delete(id);\r\n }\r\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\r\n }, []);\r\n\r\n const show = useCallback(\r\n (message: ReactNode, options?: ToastOptions) => {\r\n const id = nextId.current++;\r\n const variant = options?.variant ?? \"info\";\r\n const duration = options?.duration ?? DEFAULT_DURATION;\r\n setToasts((prev) => [...prev, { id, message, variant }]);\r\n if (duration > 0) {\r\n timers.current.set(\r\n id,\r\n setTimeout(() => dismiss(id), duration)\r\n );\r\n }\r\n return id;\r\n },\r\n [dismiss]\r\n );\r\n\r\n const api = useMemo<ToastApi>(\r\n () => ({\r\n show,\r\n dismiss,\r\n success: (message, options) => show(message, { ...options, variant: \"success\" }),\r\n error: (message, options) => show(message, { ...options, variant: \"danger\" }),\r\n info: (message, options) => show(message, { ...options, variant: \"info\" }),\r\n warning: (message, options) => show(message, { ...options, variant: \"warning\" }),\r\n }),\r\n [show, dismiss]\r\n );\r\n\r\n return (\r\n <ToastContext.Provider value={api}>\r\n {children}\r\n <div className=\"toast-container position-fixed bottom-0 end-0 p-3 rrc-toast-container\" style={{ zIndex: 1090 }}>\r\n {toasts.map((toast) => (\r\n <Alert key={toast.id} variant={toast.variant} dismissible onDismiss={() => dismiss(toast.id)} className=\"shadow-sm\">\r\n {toast.message}\r\n </Alert>\r\n ))}\r\n </div>\r\n </ToastContext.Provider>\r\n );\r\n}\r\n\r\n/** Throws outside ToastProvider — same fail-fast contract as other context-backed hooks in this library. */\r\nexport function useToast(): ToastApi {\r\n const context = useContext(ToastContext);\r\n if (!context) throw new Error(\"useToast must be used within a ToastProvider\");\r\n return context;\r\n}\r\n","import { createContext, useCallback, useContext, useState, type ReactNode } from \"react\";\r\nimport { Button, type ButtonVariant } from \"./Button\";\r\nimport { Modal } from \"./Modal\";\r\n\r\nexport interface ConfirmOptions {\r\n title?: string;\r\n message: ReactNode;\r\n confirmLabel?: string;\r\n cancelLabel?: string;\r\n confirmVariant?: ButtonVariant;\r\n}\r\n\r\nexport type ConfirmFn = (options: ConfirmOptions) => Promise<boolean>;\r\n\r\nconst ConfirmContext = createContext<ConfirmFn | null>(null);\r\n\r\ninterface PendingConfirm extends ConfirmOptions {\r\n resolve: (value: boolean) => void;\r\n}\r\n\r\n/**\r\n * Imperative yes/no dialog. Built on Modal + Button (doc section 20: reuse,\r\n * don't reimplement) instead of every screen wiring its own \"are you sure\"\r\n * modal-open state and footer buttons by hand.\r\n *\r\n * Known limitation: a second confirm() call while one is still pending\r\n * replaces it — the first promise never settles. Acceptable for v1 (doc\r\n * section 6: avoid speculative infrastructure); a queue can be added if a\r\n * real screen needs overlapping confirms.\r\n */\r\nexport function ConfirmProvider({ children }: { children: ReactNode }) {\r\n const [pending, setPending] = useState<PendingConfirm | null>(null);\r\n\r\n const confirm = useCallback<ConfirmFn>((options) => {\r\n return new Promise<boolean>((resolve) => {\r\n setPending({ ...options, resolve });\r\n });\r\n }, []);\r\n\r\n const settle = useCallback(\r\n (result: boolean) => {\r\n pending?.resolve(result);\r\n setPending(null);\r\n },\r\n [pending]\r\n );\r\n\r\n return (\r\n <ConfirmContext.Provider value={confirm}>\r\n {children}\r\n <Modal\r\n open={pending !== null}\r\n onClose={() => settle(false)}\r\n title={pending?.title ?? \"Confirm\"}\r\n footer={\r\n <>\r\n <Button variant=\"outline-secondary\" onClick={() => settle(false)}>\r\n {pending?.cancelLabel ?? \"Cancel\"}\r\n </Button>\r\n <Button variant={pending?.confirmVariant ?? \"danger\"} onClick={() => settle(true)}>\r\n {pending?.confirmLabel ?? \"Confirm\"}\r\n </Button>\r\n </>\r\n }\r\n >\r\n {pending?.message}\r\n </Modal>\r\n </ConfirmContext.Provider>\r\n );\r\n}\r\n\r\n/** Throws outside ConfirmProvider — same fail-fast contract as other context-backed hooks in this library. */\r\nexport function useConfirm(): ConfirmFn {\r\n const context = useContext(ConfirmContext);\r\n if (!context) throw new Error(\"useConfirm must be used within a ConfirmProvider\");\r\n return context;\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport type BadgeVariant = \"primary\" | \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" | \"light\" | \"dark\";\r\n\r\n/**\r\n * How the variant colour is applied. Additive: `solid` is the existing\r\n * behaviour and stays the default, so no current rendering changes.\r\n */\r\nexport type BadgeAppearance = \"solid\" | \"light\" | \"outline\";\r\n\r\nexport interface BadgeProps {\r\n variant?: BadgeVariant;\r\n /** `light` and `outline` are the restrained forms for ordinary metadata. */\r\n appearance?: BadgeAppearance;\r\n pill?: boolean;\r\n className?: string;\r\n children: ReactNode;\r\n}\r\n\r\nexport function Badge({ variant = \"primary\", appearance = \"solid\", pill, className, children }: BadgeProps) {\r\n return (\r\n <span\r\n className={cx(\r\n \"badge\",\r\n // Bootstrap's own solid fill is only correct for the solid appearance;\r\n // the tinted forms are painted by this library's stylesheet instead.\r\n appearance === \"solid\" && `bg-${variant}`,\r\n pill && \"rounded-pill\",\r\n \"rrc-badge\",\r\n `rrc-badge--${variant}`,\r\n `rrc-badge--${appearance}`,\r\n className\r\n )}\r\n >\r\n {children}\r\n </span>\r\n );\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\n\r\nexport interface IconProps {\r\n /**\r\n * Full icon class name(s) — e.g. \"bi bi-trash\" (Bootstrap Icons) or\r\n * \"ki-outline ki-trash\" (Metronic Keenicons). Icon-set agnostic by design:\r\n * this component bundles no icon font of its own (doc section 15 — stay\r\n * on Bootstrap/Metronic, don't introduce another framework or a\r\n * duplicate asset), it only standardizes sizing and accessibility.\r\n */\r\n name: string;\r\n size?: \"sm\" | \"lg\" | \"xl\";\r\n className?: string;\r\n /** Accessible label. Omit for a purely decorative icon (default: aria-hidden). */\r\n label?: string;\r\n}\r\n\r\nconst SIZE_EM: Record<NonNullable<IconProps[\"size\"]>, string> = {\r\n sm: \"0.875em\",\r\n lg: \"1.5em\",\r\n xl: \"2em\",\r\n};\r\n\r\nexport function Icon({ name, size, className, label }: IconProps) {\r\n return (\r\n <i\r\n className={cx(name, \"rrc-icon\", className)}\r\n style={size ? { fontSize: SIZE_EM[size] } : undefined}\r\n role={label ? \"img\" : undefined}\r\n aria-label={label}\r\n aria-hidden={label ? undefined : true}\r\n />\r\n );\r\n}\r\n","import { useRef, type KeyboardEvent, type ReactNode } from \"react\";\r\nimport { Badge } from \"./Badge\";\r\nimport { Icon } from \"./Icon\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\n\r\nexport type TabsVariant = \"default\" | \"underline\" | \"pill\" | \"card\" | \"button\";\r\nexport type TabsOrientation = \"horizontal\" | \"vertical\";\r\nexport type TabsSize = \"sm\" | \"lg\";\r\n\r\nexport interface TabItem {\r\n key: string;\r\n label: ReactNode;\r\n /** Icon class name(s), passed straight through to `Icon` (icon-set agnostic — doc section 15). */\r\n icon?: string;\r\n badge?: ReactNode;\r\n disabled?: boolean;\r\n /**\r\n * Optional — a tab can be nav-only (content driven externally, e.g. by\r\n * the same `activeKey` state feeding a sibling `DataGrid`) instead of\r\n * owning its panel.\r\n */\r\n content?: ReactNode;\r\n}\r\n\r\nexport interface TabsProps {\r\n items: TabItem[];\r\n activeKey?: string;\r\n defaultActiveKey?: string;\r\n onChange?: (key: string) => void;\r\n /** Generic nav look, not a Metronic widget name — express a Metronic visual as `variant=\"pill\"` + `icon`, not a new named variant. */\r\n variant?: TabsVariant;\r\n orientation?: TabsOrientation;\r\n size?: TabsSize;\r\n /** Tab list fills its container width (`nav-fill`). */\r\n stretch?: boolean;\r\n className?: string;\r\n}\r\n\r\nfunction navClass(variant: TabsVariant): string {\r\n switch (variant) {\r\n case \"pill\":\r\n return \"nav-pills\";\r\n case \"underline\":\r\n return \"nav-underline\";\r\n case \"card\":\r\n return \"nav-tabs card-header-tabs\";\r\n default:\r\n return \"nav-tabs\";\r\n }\r\n}\r\n\r\nconst SIZE_CLASS: Record<TabsSize, string> = {\r\n sm: \"small\",\r\n lg: \"fs-5\",\r\n};\r\n\r\n/** Tab definitions (`items`) are kept separate from rendering, per doc section 16. */\r\nexport function Tabs({ items, activeKey, defaultActiveKey, onChange, variant = \"default\", orientation = \"horizontal\", size, stretch, className }: TabsProps) {\r\n const [currentKey, setKey] = useControllableState<string>({\r\n value: activeKey,\r\n defaultValue: defaultActiveKey ?? items[0]?.key ?? \"\",\r\n onChange,\r\n });\r\n\r\n const activeItem = items.find((item) => item.key === currentKey);\r\n const isButtonVariant = variant === \"button\";\r\n const isVertical = orientation === \"vertical\";\r\n const tabRefs = useRef<Array<HTMLButtonElement | null>>([]);\r\n\r\n function activate(index: number, focus: boolean) {\r\n const item = items[index];\r\n if (!item) return;\r\n setKey(item.key);\r\n if (focus) tabRefs.current[index]?.focus();\r\n }\r\n\r\n function findEnabled(from: number, step: 1 | -1): number {\r\n if (items.length === 0) return from;\r\n let index = from;\r\n for (let i = 0; i < items.length; i++) {\r\n index = (index + step + items.length) % items.length;\r\n if (!items[index]?.disabled) return index;\r\n }\r\n return from;\r\n }\r\n\r\n /** Roving-tabindex arrow-key navigation with automatic activation, per the WAI-ARIA Tabs authoring pattern. */\r\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\r\n const currentIndex = items.findIndex((item) => item.key === currentKey);\r\n const nextKey = isVertical ? \"ArrowDown\" : \"ArrowRight\";\r\n const prevKey = isVertical ? \"ArrowUp\" : \"ArrowLeft\";\r\n\r\n if (event.key === nextKey) {\r\n event.preventDefault();\r\n activate(findEnabled(currentIndex, 1), true);\r\n } else if (event.key === prevKey) {\r\n event.preventDefault();\r\n activate(findEnabled(currentIndex, -1), true);\r\n } else if (event.key === \"Home\") {\r\n event.preventDefault();\r\n const first = items.findIndex((item) => !item.disabled);\r\n if (first >= 0) activate(first, true);\r\n } else if (event.key === \"End\") {\r\n event.preventDefault();\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n if (!items[i]?.disabled) {\r\n activate(i, true);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n const tabList = (\r\n <div\r\n className={cx(\r\n isButtonVariant ? \"btn-group\" : \"nav\",\r\n \"rrc-tabs__list\",\r\n `rrc-tabs__list--${variant}`,\r\n !isButtonVariant && navClass(variant),\r\n !isButtonVariant && isVertical && \"flex-column\",\r\n !isButtonVariant && stretch && \"nav-fill\",\r\n !isButtonVariant && size && SIZE_CLASS[size]\r\n )}\r\n role=\"tablist\"\r\n aria-orientation={orientation}\r\n onKeyDown={handleKeyDown}\r\n >\r\n {items.map((item, index) => {\r\n const active = item.key === currentKey;\r\n const buttonContent = (\r\n <>\r\n {item.icon && <Icon name={item.icon} size=\"sm\" className=\"me-1\" />}\r\n {item.label}\r\n {/* A counter is metadata, not a status: the light appearance keeps\r\n it legible without competing with the tab label. */}\r\n {item.badge != null && (\r\n <Badge variant={active && !isButtonVariant ? \"primary\" : \"secondary\"} appearance=\"light\" pill className=\"ms-2\">\r\n {item.badge}\r\n </Badge>\r\n )}\r\n </>\r\n );\r\n\r\n const button = (\r\n <button\r\n key={item.key}\r\n ref={(node) => {\r\n tabRefs.current[index] = node;\r\n }}\r\n type=\"button\"\r\n id={`tab-${item.key}`}\r\n className={cx(isButtonVariant ? cx(\"btn\", size ? `btn-${size}` : \"btn-sm\", active ? \"btn-primary\" : \"btn-outline-primary\") : cx(\"nav-link\", \"rrc-tabs__link\", active && \"active\"))}\r\n role=\"tab\"\r\n aria-selected={active}\r\n aria-controls={`tabpanel-${item.key}`}\r\n tabIndex={active ? 0 : -1}\r\n disabled={item.disabled}\r\n onClick={() => activate(index, false)}\r\n >\r\n {buttonContent}\r\n </button>\r\n );\r\n\r\n return isButtonVariant ? button : (\r\n <div key={item.key} className=\"nav-item\" role=\"presentation\">\r\n {button}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n\r\n const panel = activeItem?.content != null && (\r\n <div id={`tabpanel-${activeItem.key}`} className={cx(\"tab-content\", \"rrc-tabs__panel\", !isVertical && \"pt-3\")} role=\"tabpanel\" aria-labelledby={`tab-${activeItem.key}`}>\r\n {activeItem.content}\r\n </div>\r\n );\r\n\r\n if (isVertical) {\r\n return (\r\n <div className={cx(\"d-flex align-items-start gap-3\", \"rrc-tabs\", \"rrc-tabs--vertical\", className)}>\r\n {tabList}\r\n {panel && <div className=\"flex-grow-1\">{panel}</div>}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={cx(\"rrc-tabs\", className)}>\r\n {tabList}\r\n {panel}\r\n </div>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\n\r\nexport interface AccordionItem {\r\n key: string;\r\n header: string;\r\n content: ReactNode;\r\n disabled?: boolean;\r\n}\r\n\r\nexport interface AccordionProps {\r\n items: AccordionItem[];\r\n /** false (default) = single-open (classic accordion); true = multiple sections can be open at once. */\r\n multiple?: boolean;\r\n openKeys?: string[];\r\n defaultOpenKeys?: string[];\r\n onChange?: (openKeys: string[]) => void;\r\n className?: string;\r\n}\r\n\r\nexport function Accordion({ items, multiple = false, openKeys, defaultOpenKeys, onChange, className }: AccordionProps) {\r\n const [currentOpenKeys, setOpenKeys] = useControllableState<string[]>({\r\n value: openKeys,\r\n defaultValue: defaultOpenKeys ?? [],\r\n onChange,\r\n });\r\n\r\n const openSet = new Set(currentOpenKeys);\r\n\r\n function toggle(key: string) {\r\n if (openSet.has(key)) {\r\n setOpenKeys(currentOpenKeys.filter((k) => k !== key));\r\n } else {\r\n setOpenKeys(multiple ? [...currentOpenKeys, key] : [key]);\r\n }\r\n }\r\n\r\n return (\r\n <div className={cx(\"accordion\", \"rrc-accordion\", className)}>\r\n {items.map((item) => {\r\n const isOpen = openSet.has(item.key);\r\n return (\r\n <div className=\"accordion-item rrc-accordion__item\" key={item.key}>\r\n <h2 className=\"accordion-header\">\r\n <button\r\n type=\"button\"\r\n className={cx(\"accordion-button\", \"rrc-accordion__button\", !isOpen && \"collapsed\")}\r\n aria-expanded={isOpen}\r\n disabled={item.disabled}\r\n onClick={() => toggle(item.key)}\r\n >\r\n {item.header}\r\n </button>\r\n </h2>\r\n {isOpen && (\r\n <div className=\"accordion-collapse\">\r\n <div className=\"accordion-body rrc-accordion__body\">{item.content}</div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n","import { useId, useRef, useState, type ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { Popup } from \"./shared/Popup\";\r\n\r\nexport interface TooltipProps {\r\n content: ReactNode;\r\n children: ReactNode;\r\n placement?: \"top\" | \"bottom\";\r\n className?: string;\r\n /**\r\n * Class for the trigger wrapper. The wrapper is inline-block by default,\r\n * which is right for an inline trigger but wrong for a full-width row (e.g.\r\n * a collapsed Sidebar item), so callers can override the display here\r\n * instead of reimplementing a second tooltip.\r\n */\r\n wrapperClassName?: string;\r\n}\r\n\r\n/**\r\n * Reuses the existing Popup primitive (open/close, escape-to-close, outside\r\n * click, cleanup — all already implemented and tested) with Bootstrap's\r\n * real tooltip CSS classes for visual fidelity.\r\n *\r\n * Deliberately NOT wired to Bootstrap's own JS Tooltip plugin: that plugin\r\n * needs `@popperjs/core` (the plain `bootstrap` package doesn't bundle it —\r\n * only its non-ESM `bootstrap.bundle.js` does), so wiring it up would mean\r\n * either adding a new dependency or a fragile UMD-inside-an-ESM-library\r\n * dynamic import. Reusing our own already-tested Popup is the more\r\n * conservative choice here, not less (doc section 18: \"do NOT introduce\r\n * another positioning library unless actually necessary\").\r\n */\r\nexport function Tooltip({ content, children, placement = \"top\", className, wrapperClassName }: TooltipProps) {\r\n const [open, setOpen] = useState(false);\r\n const anchorRef = useRef<HTMLSpanElement>(null);\r\n const tooltipId = useId();\r\n\r\n return (\r\n <span\r\n ref={anchorRef}\r\n className={cx(\"position-relative\", wrapperClassName ?? \"d-inline-block\")}\r\n onMouseEnter={() => setOpen(true)}\r\n onMouseLeave={() => setOpen(false)}\r\n onFocus={() => setOpen(true)}\r\n onBlur={() => setOpen(false)}\r\n aria-describedby={open ? tooltipId : undefined}\r\n >\r\n {children}\r\n <Popup\r\n open={open}\r\n onClose={() => setOpen(false)}\r\n anchorRef={anchorRef}\r\n className={cx(\"tooltip show\", `bs-tooltip-${placement}`, \"position-absolute\", \"w-auto\", \"rrc-tooltip\", className)}\r\n >\r\n <span id={tooltipId} role=\"tooltip\" className=\"tooltip-inner\">\r\n {content}\r\n </span>\r\n </Popup>\r\n </span>\r\n );\r\n}\r\n","import { useRef, useState, type ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { Popup } from \"./shared/Popup\";\r\n\r\nexport interface PopoverProps {\r\n title?: ReactNode;\r\n content: ReactNode;\r\n children: ReactNode;\r\n placement?: \"top\" | \"bottom\";\r\n className?: string;\r\n}\r\n\r\n/** Click-triggered variant of Tooltip — same Popup-reuse rationale (see Tooltip.tsx). */\r\nexport function Popover({ title, content, children, placement = \"bottom\", className }: PopoverProps) {\r\n const [open, setOpen] = useState(false);\r\n const anchorRef = useRef<HTMLSpanElement>(null);\r\n\r\n return (\r\n <span ref={anchorRef} className=\"position-relative d-inline-block\" onClick={() => setOpen((prev) => !prev)}>\r\n {children}\r\n <Popup\r\n open={open}\r\n onClose={() => setOpen(false)}\r\n anchorRef={anchorRef}\r\n className={cx(\"popover show\", `bs-popover-${placement}`, \"position-absolute\", \"w-auto\", \"rrc-popover\", className)}\r\n >\r\n {title && <h3 className=\"popover-header rrc-popover__header\">{title}</h3>}\r\n <div className=\"popover-body rrc-popover__body\">{content}</div>\r\n </Popup>\r\n </span>\r\n );\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\n\r\nexport interface SkeletonProps {\r\n width?: string | number;\r\n height?: string | number;\r\n circle?: boolean;\r\n className?: string;\r\n}\r\n\r\n/** Uses Bootstrap's built-in `placeholder`/`placeholder-glow` classes rather than inventing a new loading-shimmer animation. */\r\nexport function Skeleton({ width = \"100%\", height = \"1rem\", circle, className }: SkeletonProps) {\r\n return (\r\n <span className={cx(\"placeholder-glow d-inline-block\", \"rrc-skeleton\", className)} style={{ width, height }} aria-hidden=\"true\">\r\n <span className={cx(\"placeholder w-100 h-100 d-block\", circle && \"rounded-circle\")} />\r\n </span>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface StackProps {\r\n direction?: \"row\" | \"column\";\r\n gap?: 0 | 1 | 2 | 3 | 4 | 5;\r\n align?: \"start\" | \"center\" | \"end\" | \"stretch\" | \"baseline\";\r\n justify?: \"start\" | \"center\" | \"end\" | \"between\" | \"around\" | \"evenly\";\r\n wrap?: boolean;\r\n className?: string;\r\n children?: ReactNode;\r\n}\r\n\r\n/** Thin wrapper over Bootstrap's flex utilities — replaces repeated `d-flex gap-2` one-offs with one typed contract. */\r\nexport function Stack({ direction = \"column\", gap = 2, align, justify, wrap, className, children }: StackProps) {\r\n return (\r\n <div\r\n className={cx(\r\n \"d-flex\",\r\n \"rrc-stack\",\r\n direction === \"row\" ? \"flex-row\" : \"flex-column\",\r\n `gap-${gap}`,\r\n align && `align-items-${align}`,\r\n justify && `justify-content-${justify}`,\r\n wrap && \"flex-wrap\",\r\n className\r\n )}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n","import type { ElementType, ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport type TextSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\r\nexport type TextWeight = \"normal\" | \"medium\" | \"semibold\" | \"bold\";\r\nexport type TextTone = \"default\" | \"muted\" | \"primary\" | \"success\" | \"danger\" | \"warning\" | \"info\";\r\nexport type TextAlign = \"start\" | \"center\" | \"end\";\r\n\r\nexport interface TextProps {\r\n /** Rendered element — defaults to `span`. Pass e.g. `\"h3\"`/`\"p\"`/`\"label\"` for a semantic element without losing the typography contract. */\r\n as?: ElementType;\r\n size?: TextSize;\r\n weight?: TextWeight;\r\n tone?: TextTone;\r\n align?: TextAlign;\r\n /** Single-line ellipsis truncation. */\r\n truncate?: boolean;\r\n /** `false` disables wrapping (`text-nowrap`) without truncating. */\r\n wrap?: boolean;\r\n className?: string;\r\n children?: ReactNode;\r\n}\r\n\r\n// em-based sizing (like Icon's SIZE_EM) rather than Bootstrap's fs-1..fs-6\r\n// heading scale or Metronic's fs-7/fs-8 extension — keeps Text usable in\r\n// any consuming app regardless of which font-size utilities it ships.\r\nconst SIZE_REM: Record<TextSize, string> = {\r\n xs: \"0.75rem\",\r\n sm: \"0.875rem\",\r\n md: \"1rem\",\r\n lg: \"1.25rem\",\r\n xl: \"1.5rem\",\r\n};\r\n\r\nconst WEIGHT_CLASS: Record<TextWeight, string> = {\r\n normal: \"fw-normal\",\r\n medium: \"fw-medium\",\r\n semibold: \"fw-semibold\",\r\n bold: \"fw-bold\",\r\n};\r\n\r\nconst TONE_CLASS: Record<TextTone, string | undefined> = {\r\n default: undefined,\r\n muted: \"text-body-secondary\",\r\n primary: \"text-primary\",\r\n success: \"text-success\",\r\n danger: \"text-danger\",\r\n warning: \"text-warning\",\r\n info: \"text-info\",\r\n};\r\n\r\n/** Generic typography primitive — replaces ad hoc `<span className=\"text-gray-500 fw-semibold fs-7\">` markup at call sites. */\r\nexport function Text({ as, size = \"md\", weight, tone = \"default\", align, truncate, wrap = true, className, children }: TextProps) {\r\n const Component = as ?? \"span\";\r\n\r\n return (\r\n <Component\r\n className={cx(\r\n \"rrc-text\",\r\n weight && WEIGHT_CLASS[weight],\r\n TONE_CLASS[tone],\r\n align && `text-${align}`,\r\n truncate && \"text-truncate\",\r\n !wrap && !truncate && \"text-nowrap\",\r\n className\r\n )}\r\n style={{ fontSize: SIZE_REM[size] }}\r\n >\r\n {children}\r\n </Component>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { Skeleton } from \"./Skeleton\";\r\nimport { Stack } from \"./Stack\";\r\nimport { Text } from \"./Text\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface CardProps {\r\n /** Standard header — renders an icon/avatar + title + subtitle row with a right-aligned actions slot, no manual header markup required. */\r\n title?: ReactNode;\r\n subtitle?: ReactNode;\r\n /** Mutually exclusive with `avatar` — `avatar` wins if both are given. */\r\n icon?: ReactNode;\r\n avatar?: ReactNode;\r\n /** Right-aligned header slot, typically Buttons/IconButtons/Menu. */\r\n actions?: ReactNode;\r\n /**\r\n * Escape hatch for header content the title/subtitle/icon/avatar/actions\r\n * shape can't express. Wins over all of the above when provided.\r\n */\r\n header?: ReactNode;\r\n footer?: ReactNode;\r\n /** Replaces `children` with a generic loading skeleton (reuses `Skeleton`, doc: no bespoke shimmer). */\r\n loading?: boolean;\r\n className?: string;\r\n children?: ReactNode;\r\n}\r\n\r\nfunction DefaultHeader({ title, subtitle, icon, avatar, actions }: Pick<CardProps, \"title\" | \"subtitle\" | \"icon\" | \"avatar\" | \"actions\">) {\r\n return (\r\n <div className=\"d-flex align-items-center justify-content-between gap-3 rrc-card__header-row\">\r\n <div className=\"d-flex align-items-center gap-3\" style={{ minWidth: 0 }}>\r\n {avatar ? avatar : icon && <span className=\"fs-2 lh-1\">{icon}</span>}\r\n {(title || subtitle) && (\r\n <div style={{ minWidth: 0 }}>\r\n {title && (\r\n <Text as=\"div\" size=\"lg\" weight=\"semibold\" truncate>\r\n {title}\r\n </Text>\r\n )}\r\n {subtitle && (\r\n <Text as=\"div\" size=\"sm\" tone=\"muted\" truncate>\r\n {subtitle}\r\n </Text>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n {actions && <div className=\"d-flex align-items-center gap-2 flex-shrink-0\">{actions}</div>}\r\n </div>\r\n );\r\n}\r\n\r\n/** Generic content container — the most basic layout primitive, used to group everything else. */\r\nexport function Card({ title, subtitle, icon, avatar, actions, header, footer, loading, className, children }: CardProps) {\r\n const hasStandardHeader = Boolean(title || subtitle || icon || avatar || actions);\r\n const resolvedHeader = header ?? (hasStandardHeader ? <DefaultHeader title={title} subtitle={subtitle} icon={icon} avatar={avatar} actions={actions} /> : undefined);\r\n\r\n return (\r\n <div className={cx(\"card\", \"rrc-card\", className)}>\r\n {resolvedHeader && <div className=\"card-header rrc-card__header\">{resolvedHeader}</div>}\r\n <div className=\"card-body rrc-card__body\">\r\n {loading ? (\r\n <Stack gap={2}>\r\n <Skeleton height=\"1rem\" width=\"60%\" />\r\n <Skeleton height=\"1rem\" />\r\n <Skeleton height=\"1rem\" width=\"80%\" />\r\n </Stack>\r\n ) : (\r\n children\r\n )}\r\n </div>\r\n {footer && <div className=\"card-footer rrc-card__footer\">{footer}</div>}\r\n </div>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface DividerProps {\r\n className?: string;\r\n vertical?: boolean;\r\n /** Optional centered label (e.g. \"OR\") — renders a labeled horizontal divider instead of a plain line. */\r\n label?: ReactNode;\r\n}\r\n\r\nexport function Divider({ className, vertical, label }: DividerProps) {\r\n if (vertical) {\r\n return <div className={cx(\"vr\", \"rrc-divider\", className)} role=\"separator\" aria-orientation=\"vertical\" />;\r\n }\r\n\r\n if (label) {\r\n return (\r\n <div className={cx(\"d-flex align-items-center gap-2 my-3\", \"rrc-divider\", \"rrc-divider--labelled\", className)} role=\"separator\">\r\n <hr className=\"flex-grow-1 m-0\" />\r\n <span className=\"text-body-secondary small\">{label}</span>\r\n <hr className=\"flex-grow-1 m-0\" />\r\n </div>\r\n );\r\n }\r\n\r\n return <hr className={cx(\"my-3\", \"rrc-divider\", className)} role=\"separator\" />;\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface ContainerProps {\r\n fluid?: boolean;\r\n className?: string;\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Container({ fluid, className, children }: ContainerProps) {\r\n return <div className={cx(fluid ? \"container-fluid\" : \"container\", \"rrc-container\", className)}>{children}</div>;\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface RowProps {\r\n className?: string;\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Row({ className, children }: RowProps) {\r\n return <div className={cx(\"row\", \"rrc-row\", className)}>{children}</div>;\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface ColProps {\r\n /** Column width at the default breakpoint (1-12). Omit for `col` (auto-width). */\r\n span?: number;\r\n sm?: number;\r\n md?: number;\r\n lg?: number;\r\n xl?: number;\r\n className?: string;\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Col({ span, sm, md, lg, xl, className, children }: ColProps) {\r\n return (\r\n <div\r\n className={cx(\r\n span ? `col-${span}` : \"col\",\r\n \"rrc-col\",\r\n sm ? `col-sm-${sm}` : undefined,\r\n md ? `col-md-${md}` : undefined,\r\n lg ? `col-lg-${lg}` : undefined,\r\n xl ? `col-xl-${xl}` : undefined,\r\n className\r\n )}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\n\r\nexport interface BreadcrumbItem {\r\n label: string;\r\n href?: string;\r\n onClick?: () => void;\r\n}\r\n\r\nexport interface BreadcrumbProps {\r\n items: BreadcrumbItem[];\r\n className?: string;\r\n}\r\n\r\nexport function Breadcrumb({ items, className }: BreadcrumbProps) {\r\n return (\r\n <nav aria-label=\"breadcrumb\" className={cx(\"rrc-breadcrumb\", className)}>\r\n <ol className=\"breadcrumb mb-0 rrc-breadcrumb__list\">\r\n {items.map((item, index) => {\r\n const isLast = index === items.length - 1;\r\n const isInteractive = !isLast && (item.href || item.onClick);\r\n return (\r\n <li key={index} className={cx(\"breadcrumb-item\", isLast && \"active\")} aria-current={isLast ? \"page\" : undefined}>\r\n {isInteractive ? (\r\n <a\r\n href={item.href ?? \"#\"}\r\n onClick={(event) => {\r\n if (!item.href) event.preventDefault();\r\n item.onClick?.();\r\n }}\r\n >\r\n {item.label}\r\n </a>\r\n ) : (\r\n item.label\r\n )}\r\n </li>\r\n );\r\n })}\r\n </ol>\r\n </nav>\r\n );\r\n}\r\n","import { useCallback, useRef, useState, type ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { Popup } from \"./shared/Popup\";\r\nimport { useListNavigation } from \"./shared/useListNavigation\";\r\n\r\nexport interface MenuItem {\r\n key: string;\r\n label: ReactNode;\r\n disabled?: boolean;\r\n danger?: boolean;\r\n onSelect?: () => void;\r\n}\r\n\r\nexport interface MenuProps {\r\n items: MenuItem[];\r\n children: ReactNode;\r\n placement?: \"start\" | \"end\";\r\n className?: string;\r\n}\r\n\r\n/**\r\n * A generic click-triggered action menu (e.g. a \"...\" row action button) —\r\n * distinct from Select/ComboBox, which pick a *value*. Reuses Popup +\r\n * useListNavigation, the same headless pair ComboBox/AutoComplete/\r\n * MultiSelect already share (doc's reuse mandate).\r\n */\r\nexport function Menu({ items, children, placement = \"start\", className }: MenuProps) {\r\n const [open, setOpen] = useState(false);\r\n const anchorRef = useRef<HTMLSpanElement>(null);\r\n\r\n const close = useCallback(() => setOpen(false), []);\r\n const selectIndex = useCallback(\r\n (index: number) => {\r\n const item = items[index];\r\n if (!item || item.disabled) return;\r\n item.onSelect?.();\r\n close();\r\n },\r\n [items, close]\r\n );\r\n\r\n const { activeIndex, setActiveIndex, handleKeyDown } = useListNavigation({\r\n itemCount: items.length,\r\n isOpen: open,\r\n onSelect: selectIndex,\r\n onClose: close,\r\n });\r\n\r\n return (\r\n <span\r\n ref={anchorRef}\r\n className=\"position-relative d-inline-block\"\r\n onClick={() => setOpen((prev) => !prev)}\r\n onKeyDown={handleKeyDown}\r\n >\r\n {children}\r\n <Popup\r\n open={open}\r\n onClose={close}\r\n anchorRef={anchorRef}\r\n role=\"menu\"\r\n className={cx(\"dropdown-menu show\", placement === \"end\" && \"dropdown-menu-end\", \"rrc-menu\", className)}\r\n >\r\n {items.map((item, index) => (\r\n <button\r\n key={item.key}\r\n type=\"button\"\r\n role=\"menuitem\"\r\n className={cx(\"dropdown-item\", \"rrc-menu__item\", index === activeIndex && \"active\", item.disabled && \"disabled\", item.danger && \"text-danger\")}\r\n disabled={item.disabled}\r\n onMouseEnter={() => setActiveIndex(index)}\r\n onMouseDown={(event) => event.preventDefault()}\r\n onClick={(event) => {\r\n // Without this, the click bubbles to the trigger <span>'s own\r\n // onClick (which toggles `open`), racing with close() from\r\n // selectIndex() in the same batch and leaving the menu open.\r\n event.stopPropagation();\r\n selectIndex(index);\r\n }}\r\n >\r\n {item.label}\r\n </button>\r\n ))}\r\n </Popup>\r\n </span>\r\n );\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\n\r\nexport interface StepItem {\r\n key: string;\r\n label: string;\r\n description?: string;\r\n}\r\n\r\nexport interface StepperProps {\r\n steps: StepItem[];\r\n /** Index of the current step (0-based). Presentation only — no built-in next/back logic, that's app-level. */\r\n currentStep: number;\r\n className?: string;\r\n}\r\n\r\nexport function Stepper({ steps, currentStep, className }: StepperProps) {\r\n return (\r\n <ol className={cx(\"d-flex list-unstyled align-items-center\", \"rrc-stepper\", className)}>\r\n {steps.map((step, index) => {\r\n const status = index < currentStep ? \"complete\" : index === currentStep ? \"active\" : \"upcoming\";\r\n const isLast = index === steps.length - 1;\r\n return (\r\n <li key={step.key} className={cx(\"d-flex align-items-center\", !isLast && \"flex-grow-1\")}>\r\n <div className=\"d-flex align-items-center gap-2\">\r\n <span\r\n className={cx(\r\n \"d-flex align-items-center justify-content-center rounded-circle flex-shrink-0\",\r\n status === \"complete\" ? \"bg-primary text-white\" : status === \"active\" ? \"border border-primary text-primary\" : \"border text-body-secondary\"\r\n )}\r\n style={{ width: \"2rem\", height: \"2rem\" }}\r\n aria-current={status === \"active\" ? \"step\" : undefined}\r\n >\r\n {status === \"complete\" ? \"✓\" : index + 1}\r\n </span>\r\n <div>\r\n <div className={cx(\"small fw-semibold\", status === \"upcoming\" && \"text-body-secondary\")}>{step.label}</div>\r\n {step.description && <div className=\"small text-body-secondary\">{step.description}</div>}\r\n </div>\r\n </div>\r\n {!isLast && <hr className=\"flex-grow-1 mx-2\" />}\r\n </li>\r\n );\r\n })}\r\n </ol>\r\n );\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\n\r\nexport interface AvatarProps {\r\n src?: string;\r\n /** Used both for the image's alt text and for the initials fallback when there's no `src`. */\r\n name?: string;\r\n size?: \"sm\" | \"md\" | \"lg\";\r\n className?: string;\r\n}\r\n\r\nfunction getInitials(name: string): string {\r\n const parts = name.trim().split(/\\s+/);\r\n const first = parts[0]?.[0] ?? \"\";\r\n const last = parts.length > 1 ? (parts[parts.length - 1]?.[0] ?? \"\") : \"\";\r\n return (first + last).toUpperCase();\r\n}\r\n\r\nconst DIMENSION: Record<NonNullable<AvatarProps[\"size\"]>, string> = {\r\n sm: \"1.75rem\",\r\n md: \"2.5rem\",\r\n lg: \"3.5rem\",\r\n};\r\n\r\nexport function Avatar({ src, name, size = \"md\", className }: AvatarProps) {\r\n const dimension = DIMENSION[size];\r\n\r\n if (src) {\r\n return (\r\n <img\r\n src={src}\r\n alt={name ?? \"\"}\r\n className={cx(\"rounded-circle\", \"rrc-avatar\", className)}\r\n style={{ width: dimension, height: dimension, objectFit: \"cover\" }}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <span\r\n className={cx(\"d-inline-flex align-items-center justify-content-center rounded-circle bg-secondary text-white\", \"rrc-avatar\", \"rrc-avatar--initials\", className)}\r\n style={{ width: dimension, height: dimension, fontSize: `calc(${dimension} * 0.4)` }}\r\n role={name ? \"img\" : undefined}\r\n aria-label={name}\r\n >\r\n {name ? getInitials(name) : null}\r\n </span>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport type { BadgeAppearance, BadgeVariant } from \"./Badge\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface TagProps {\r\n variant?: BadgeVariant;\r\n /** Same additive contract as Badge; `solid` stays the default. */\r\n appearance?: BadgeAppearance;\r\n onRemove?: () => void;\r\n className?: string;\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * Reuses Badge's variant type (same visual vocabulary) — the difference\r\n * from Badge is purely behavioral: Tag is removable/interactive, Badge is\r\n * static.\r\n */\r\nexport function Tag({ variant = \"secondary\", appearance = \"solid\", onRemove, className, children }: TagProps) {\r\n return (\r\n <span className={cx(\"badge d-inline-flex align-items-center gap-1\", appearance === \"solid\" && `bg-${variant}`, \"rrc-tag\", `rrc-tag--${variant}`, `rrc-tag--${appearance}`, className)}>\r\n {children}\r\n {onRemove && (\r\n <button\r\n type=\"button\"\r\n className=\"btn-close btn-close-white\"\r\n style={{ fontSize: \"0.55rem\" }}\r\n aria-label=\"Remove\"\r\n onClick={onRemove}\r\n />\r\n )}\r\n </span>\r\n );\r\n}\r\n","import { useId } from \"react\";\r\nimport { FieldShell } from \"./shared/FieldShell\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport type { FieldIdentity, FieldPresentation, FieldState } from \"./shared/fieldTypes\";\r\n\r\nexport interface SliderProps extends FieldIdentity, FieldState, FieldPresentation {\r\n value?: number;\r\n defaultValue?: number;\r\n onChange?: (value: number) => void;\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n}\r\n\r\nexport function Slider({\r\n value,\r\n defaultValue,\r\n onChange,\r\n min = 0,\r\n max = 100,\r\n step = 1,\r\n id,\r\n name,\r\n disabled,\r\n required,\r\n className,\r\n label,\r\n helpText,\r\n error,\r\n}: SliderProps) {\r\n const [currentValue, setValue] = useControllableState<number>({\r\n value,\r\n defaultValue: defaultValue ?? min,\r\n onChange,\r\n });\r\n\r\n const generatedId = useId();\r\n const fieldId = id ?? generatedId;\r\n\r\n return (\r\n <FieldShell id={fieldId} label={label} required={required} error={error} helpText={helpText} className={className}>\r\n <input\r\n id={fieldId}\r\n name={name}\r\n type=\"range\"\r\n className=\"form-range rrc-range\"\r\n disabled={disabled}\r\n required={required}\r\n min={min}\r\n max={max}\r\n step={step}\r\n value={currentValue}\r\n onChange={(event) => setValue(Number(event.target.value))}\r\n />\r\n <div className=\"small text-body-secondary\">{currentValue}</div>\r\n </FieldShell>\r\n );\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\n\r\nexport interface RatingProps {\r\n value?: number;\r\n defaultValue?: number;\r\n onChange?: (value: number) => void;\r\n max?: number;\r\n disabled?: boolean;\r\n className?: string;\r\n}\r\n\r\nexport function Rating({ value, defaultValue, onChange, max = 5, disabled, className }: RatingProps) {\r\n const [currentValue, setValue] = useControllableState<number>({\r\n value,\r\n defaultValue: defaultValue ?? 0,\r\n onChange,\r\n });\r\n\r\n return (\r\n <div className={cx(\"d-inline-flex gap-1\", \"rrc-rating\", className)} role=\"radiogroup\" aria-label=\"Rating\">\r\n {Array.from({ length: max }, (_, index) => index + 1).map((n) => (\r\n <button\r\n key={n}\r\n type=\"button\"\r\n className=\"btn btn-link p-0 border-0 rrc-rating__star\"\r\n disabled={disabled}\r\n role=\"radio\"\r\n aria-checked={n === currentValue}\r\n aria-label={`${n} star${n > 1 ? \"s\" : \"\"}`}\r\n onClick={() => setValue(n)}\r\n >\r\n <span aria-hidden=\"true\" style={{ fontSize: \"1.25rem\", color: n <= currentValue ? \"#f5b301\" : \"#ced4da\" }}>\r\n ★\r\n </span>\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","import type { BadgeVariant } from \"./Badge\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface ProgressBarProps {\r\n /** 0-100. Values outside that range are clamped. */\r\n value: number;\r\n variant?: BadgeVariant;\r\n /** Show the percentage as text inside the bar. */\r\n label?: boolean;\r\n className?: string;\r\n}\r\n\r\nexport function ProgressBar({ value, variant = \"primary\", label, className }: ProgressBarProps) {\r\n const clamped = Math.max(0, Math.min(100, value));\r\n\r\n return (\r\n <div className={cx(\"progress\", \"rrc-progress\", className)} role=\"progressbar\" aria-valuenow={clamped} aria-valuemin={0} aria-valuemax={100}>\r\n <div className={cx(\"progress-bar\", \"rrc-progress__bar\", `bg-${variant}`)} style={{ width: `${clamped}%` }}>\r\n {label ? `${Math.round(clamped)}%` : null}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface NavbarProps {\r\n brand?: ReactNode;\r\n /** Left-aligned slot, e.g. primary nav links. */\r\n start?: ReactNode;\r\n /** Right-aligned slot, e.g. search, notifications, user menu. */\r\n end?: ReactNode;\r\n variant?: \"light\" | \"dark\";\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Top app bar shell. Brand/start/end are plain slots — actual nav links,\r\n * routing, and auth/user menus belong to the consuming app (doc section 22:\r\n * Base must not touch routing or auth), not to this component.\r\n */\r\nexport function Navbar({ brand, start, end, variant = \"light\", className }: NavbarProps) {\r\n return (\r\n <nav\r\n className={cx(\r\n \"navbar navbar-expand-lg border-bottom\",\r\n \"rrc-navbar\",\r\n variant === \"dark\" ? \"navbar-dark bg-dark\" : \"navbar-light bg-light\",\r\n className\r\n )}\r\n >\r\n <div className=\"container-fluid\">\r\n {brand && <span className=\"navbar-brand mb-0\">{brand}</span>}\r\n {start && <div className=\"d-flex align-items-center gap-3\">{start}</div>}\r\n {end && <div className=\"d-flex align-items-center gap-3 ms-auto\">{end}</div>}\r\n </div>\r\n </nav>\r\n );\r\n}\r\n","/**\r\n * Semantic color schemes.\r\n *\r\n * A scheme is deliberately NOT a single raw color. Changing only the primary\r\n * hue leaves buttons, active components and menu states inconsistent, so a\r\n * scheme is a complete coordinated token family that is validated before it\r\n * can be registered or applied.\r\n *\r\n * Variable mapping (verified against the repository's real styling stack —\r\n * `bootstrap@5.3.8`, which is this package's peer dependency):\r\n *\r\n * - `--bs-primary` and `--bs-primary-rgb` genuinely exist in Bootstrap 5.3 and\r\n * are written directly, so Bootstrap's own components follow the scheme.\r\n * - `--bs-primary-active`, `--bs-primary-light`, `--bs-primary-inverse`,\r\n * `--bs-component-*` and `--bs-menu-link-color-*` do NOT exist in Bootstrap.\r\n * They are Metronic's names. They are emitted anyway so that an application\r\n * that really does ship Metronic gets a coordinated result instead of a\r\n * half-recolored theme.\r\n * - `--rrc-*` are this repository's own tokens, which are what this library's\r\n * stylesheet actually consumes. Each one falls back to the Bootstrap or\r\n * Metronic variable when present, so the mapping works with Metronic, with\r\n * plain Bootstrap, and with neither.\r\n */\r\n\r\n/** The full token family a scheme must define. */\r\nexport interface ColorSchemeTokens {\r\n primary: string;\r\n primaryActive: string;\r\n primaryLight: string;\r\n /** Foreground placed on top of `primary` — the scheme's contrast value. */\r\n primaryInverse: string;\r\n /** Comma-separated channels of `primary`, e.g. \"13, 110, 253\". */\r\n primaryRgb: string;\r\n componentActiveColor: string;\r\n componentActiveBg: string;\r\n componentHoverColor: string;\r\n componentHoverBg: string;\r\n componentCheckedColor: string;\r\n componentCheckedBg: string;\r\n menuLinkColorHover: string;\r\n menuLinkColorShow: string;\r\n menuLinkColorHere: string;\r\n menuLinkColorActive: string;\r\n}\r\n\r\nexport interface ColorScheme {\r\n id: string;\r\n tokens: ColorSchemeTokens;\r\n /**\r\n * Optional swatch color for a selector UI. Defaults to `tokens.primary`.\r\n * Never the scheme's identity — selection must be indicated by more than\r\n * color alone, so the selector also renders a real label and a checked state.\r\n */\r\n swatch?: string;\r\n}\r\n\r\nexport const COLOR_SCHEME_TOKEN_KEYS: readonly (keyof ColorSchemeTokens)[] = [\r\n \"primary\",\r\n \"primaryActive\",\r\n \"primaryLight\",\r\n \"primaryInverse\",\r\n \"primaryRgb\",\r\n \"componentActiveColor\",\r\n \"componentActiveBg\",\r\n \"componentHoverColor\",\r\n \"componentHoverBg\",\r\n \"componentCheckedColor\",\r\n \"componentCheckedBg\",\r\n \"menuLinkColorHover\",\r\n \"menuLinkColorShow\",\r\n \"menuLinkColorHere\",\r\n \"menuLinkColorActive\",\r\n];\r\n\r\n/** True only when every required token is present and non-empty. */\r\nexport function isValidColorScheme(value: unknown): value is ColorScheme {\r\n if (typeof value !== \"object\" || value === null) return false;\r\n const candidate = value as { id?: unknown; tokens?: unknown };\r\n if (typeof candidate.id !== \"string\" || candidate.id.length === 0) return false;\r\n if (typeof candidate.tokens !== \"object\" || candidate.tokens === null) return false;\r\n const tokens = candidate.tokens as Record<string, unknown>;\r\n return COLOR_SCHEME_TOKEN_KEYS.every((key) => typeof tokens[key] === \"string\" && (tokens[key] as string).length > 0);\r\n}\r\n\r\nexport interface ColorSchemeSeed {\r\n id: string;\r\n primary: string;\r\n primaryActive: string;\r\n primaryLight: string;\r\n primaryInverse: string;\r\n primaryRgb: string;\r\n swatch?: string;\r\n}\r\n\r\n/**\r\n * Derives the coordinated component/menu tokens from the four primary shades,\r\n * so a scheme author cannot accidentally register a half-defined family.\r\n * Callers that need full control can build a `ColorScheme` literal instead.\r\n */\r\nexport function createColorScheme(seed: ColorSchemeSeed): ColorScheme {\r\n const { id, primary, primaryActive, primaryLight, primaryInverse, primaryRgb, swatch } = seed;\r\n return {\r\n id,\r\n ...(swatch !== undefined ? { swatch } : {}),\r\n tokens: {\r\n primary,\r\n primaryActive,\r\n primaryLight,\r\n primaryInverse,\r\n primaryRgb,\r\n componentActiveColor: primaryInverse,\r\n componentActiveBg: primary,\r\n componentHoverColor: primaryActive,\r\n componentHoverBg: primaryLight,\r\n componentCheckedColor: primaryInverse,\r\n componentCheckedBg: primary,\r\n menuLinkColorHover: primaryActive,\r\n menuLinkColorShow: primaryActive,\r\n menuLinkColorHere: primaryActive,\r\n menuLinkColorActive: primary,\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Built-ins use Bootstrap 5.3's own palette values (`--bs-blue`, `--bs-indigo`,\r\n * `--bs-teal`, `--bs-green` and their subtle/emphasis pairs) so the defaults\r\n * stay genuinely Bootstrap-compatible and carry no product branding.\r\n */\r\nconst BUILT_IN_SCHEMES: ColorScheme[] = [\r\n createColorScheme({\r\n id: \"blue\",\r\n primary: \"#0d6efd\",\r\n primaryActive: \"#0a58ca\",\r\n primaryLight: \"#cfe2ff\",\r\n primaryInverse: \"#ffffff\",\r\n primaryRgb: \"13, 110, 253\",\r\n }),\r\n createColorScheme({\r\n id: \"indigo\",\r\n primary: \"#6610f2\",\r\n primaryActive: \"#520dc2\",\r\n primaryLight: \"#e0cffc\",\r\n primaryInverse: \"#ffffff\",\r\n primaryRgb: \"102, 16, 242\",\r\n }),\r\n // Deliberately taken from the deeper end of Bootstrap's teal ramp: a scheme\r\n // must carry usable contrast values, and `--bs-teal` (#20c997) is a surface\r\n // color that measures ~2:1 as text on white.\r\n createColorScheme({\r\n id: \"teal\",\r\n primary: \"#13795b\",\r\n primaryActive: \"#0d503c\",\r\n primaryLight: \"#d2f4ea\",\r\n primaryInverse: \"#ffffff\",\r\n primaryRgb: \"19, 121, 91\",\r\n swatch: \"#20c997\",\r\n }),\r\n createColorScheme({\r\n id: \"green\",\r\n primary: \"#198754\",\r\n primaryActive: \"#146c43\",\r\n primaryLight: \"#d1e7dd\",\r\n primaryInverse: \"#ffffff\",\r\n primaryRgb: \"25, 135, 84\",\r\n }),\r\n];\r\n\r\n/** The scheme applied when nothing else is selected — Bootstrap's own primary. */\r\nexport const DEFAULT_COLOR_SCHEME_ID = \"blue\";\r\n\r\nconst registry = new Map<string, ColorScheme>(BUILT_IN_SCHEMES.map((scheme) => [scheme.id, scheme]));\r\n\r\n/**\r\n * Registers an application-owned scheme. Rejects an incomplete family rather\r\n * than applying a partially recolored theme.\r\n */\r\nexport function registerColorScheme(scheme: ColorScheme): void {\r\n if (!isValidColorScheme(scheme)) {\r\n throw new Error(\r\n \"[react-components] registerColorScheme() requires a complete token family: \" +\r\n COLOR_SCHEME_TOKEN_KEYS.join(\", \") +\r\n \".\"\r\n );\r\n }\r\n registry.set(scheme.id, scheme);\r\n}\r\n\r\nexport function getColorScheme(id: string): ColorScheme | undefined {\r\n return registry.get(id);\r\n}\r\n\r\n/** Registered schemes in registration order — built-ins first. */\r\nexport function listColorSchemes(): ColorScheme[] {\r\n return [...registry.values()];\r\n}\r\n\r\n/**\r\n * Resolves an identifier to a scheme, falling back to the default rather than\r\n * throwing, so an unknown persisted value degrades safely.\r\n */\r\nexport function resolveColorScheme(id: string | undefined): ColorScheme {\r\n const scheme = id !== undefined ? registry.get(id) : undefined;\r\n if (scheme) return scheme;\r\n // The default is registered at module init and never removed.\r\n return registry.get(DEFAULT_COLOR_SCHEME_ID) as ColorScheme;\r\n}\r\n\r\n/**\r\n * The scheme as CSS custom properties, ready to spread into a `style` object\r\n * or write onto a DOM node. Emits the real Bootstrap variables, the\r\n * Metronic-compatible names, and this repository's own `--rrc-*` tokens.\r\n */\r\nexport function colorSchemeCssVariables(scheme: ColorScheme): Record<string, string> {\r\n const t = scheme.tokens;\r\n return {\r\n \"--bs-primary\": t.primary,\r\n \"--bs-primary-rgb\": t.primaryRgb,\r\n \"--bs-primary-active\": t.primaryActive,\r\n \"--bs-primary-light\": t.primaryLight,\r\n \"--bs-primary-inverse\": t.primaryInverse,\r\n \"--bs-component-active-color\": t.componentActiveColor,\r\n \"--bs-component-active-bg\": t.componentActiveBg,\r\n \"--bs-component-hover-color\": t.componentHoverColor,\r\n \"--bs-component-hover-bg\": t.componentHoverBg,\r\n \"--bs-component-checked-color\": t.componentCheckedColor,\r\n \"--bs-component-checked-bg\": t.componentCheckedBg,\r\n \"--bs-menu-link-color-hover\": t.menuLinkColorHover,\r\n \"--bs-menu-link-color-show\": t.menuLinkColorShow,\r\n \"--bs-menu-link-color-here\": t.menuLinkColorHere,\r\n \"--bs-menu-link-color-active\": t.menuLinkColorActive,\r\n // This repository's own tokens. Only the theme-independent ones are\r\n // published here: these are applied as an inline style on the root, which\r\n // outranks every stylesheet rule, so a token whose value depends on the\r\n // light/dark theme must not be set from a scheme. The stylesheet resolves\r\n // those from the `--bs-*` names above in light mode and derives its own\r\n // values under `[data-bs-theme=\"dark\"]`; publishing a light-mode shade here\r\n // pinned the dark sidebar's menu links to ~2:1.\r\n \"--rrc-primary\": t.primary,\r\n \"--rrc-primary-rgb\": t.primaryRgb,\r\n \"--rrc-primary-active\": t.primaryActive,\r\n \"--rrc-primary-inverse\": t.primaryInverse,\r\n \"--rrc-component-active-color\": t.componentActiveColor,\r\n \"--rrc-component-active-bg\": t.componentActiveBg,\r\n \"--rrc-component-hover-bg\": t.componentHoverBg,\r\n \"--rrc-component-checked-color\": t.componentCheckedColor,\r\n \"--rrc-component-checked-bg\": t.componentCheckedBg,\r\n };\r\n}\r\n","import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, type CSSProperties, type ReactNode } from \"react\";\r\nimport {\r\n DEFAULT_COLOR_SCHEME_ID,\r\n colorSchemeCssVariables,\r\n getColorScheme,\r\n resolveColorScheme,\r\n type ColorScheme,\r\n} from \"./appearanceSchemes\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\n\r\n/** What the user picked. */\r\nexport type ThemeMode = \"light\" | \"dark\" | \"system\";\r\n/** What that actually resolves to right now. Never \"system\". */\r\nexport type ResolvedTheme = \"light\" | \"dark\";\r\n/** Which Sidebar presentation the application uses. Not a Metronic demo/template switch. */\r\nexport type SidebarPresentation = \"compact\" | \"grouped\";\r\n/** The Sidebar's own surface tone, independent of the resolved page theme. */\r\nexport type SidebarTone = \"light\" | \"dark\" | \"auto\";\r\n\r\nexport const THEME_MODES: readonly ThemeMode[] = [\"light\", \"dark\", \"system\"];\r\nexport const SIDEBAR_PRESENTATIONS: readonly SidebarPresentation[] = [\"compact\", \"grouped\"];\r\nexport const SIDEBAR_TONES: readonly SidebarTone[] = [\"light\", \"dark\", \"auto\"];\r\n\r\n/** The four settings, kept strictly separate so one can never overwrite another. */\r\nexport interface AppearanceSettings {\r\n mode: ThemeMode;\r\n sidebarPresentation: SidebarPresentation;\r\n sidebarTone: SidebarTone;\r\n colorSchemeId: string;\r\n}\r\n\r\nexport interface AppearanceContextValue extends AppearanceSettings {\r\n /** `mode`, with \"system\" already resolved through `prefers-color-scheme`. */\r\n resolvedTheme: ResolvedTheme;\r\n /** The operating-system preference, observed live. */\r\n systemTheme: ResolvedTheme;\r\n colorScheme: ColorScheme;\r\n setMode: (mode: ThemeMode) => void;\r\n setSidebarPresentation: (presentation: SidebarPresentation) => void;\r\n setSidebarTone: (tone: SidebarTone) => void;\r\n setColorSchemeId: (id: string) => void;\r\n /**\r\n * Spread onto your own layout root when the provider is not configured to\r\n * touch the DOM itself (the default). Carries the resolved theme attribute\r\n * and the selected scheme's CSS custom properties.\r\n */\r\n appearanceProps: { \"data-bs-theme\": ResolvedTheme; style: CSSProperties };\r\n}\r\n\r\n/** Minimal `localStorage`-compatible surface — supply your own for SSR or tests. */\r\nexport interface AppearanceStorage {\r\n getItem: (key: string) => string | null;\r\n setItem: (key: string, value: string) => void;\r\n}\r\n\r\nexport interface AppearanceProviderProps {\r\n children: ReactNode;\r\n mode?: ThemeMode;\r\n defaultMode?: ThemeMode;\r\n onModeChange?: (mode: ThemeMode) => void;\r\n sidebarPresentation?: SidebarPresentation;\r\n defaultSidebarPresentation?: SidebarPresentation;\r\n onSidebarPresentationChange?: (presentation: SidebarPresentation) => void;\r\n sidebarTone?: SidebarTone;\r\n defaultSidebarTone?: SidebarTone;\r\n onSidebarToneChange?: (tone: SidebarTone) => void;\r\n colorSchemeId?: string;\r\n defaultColorSchemeId?: string;\r\n onColorSchemeIdChange?: (id: string) => void;\r\n /**\r\n * Opt-in persistence. Both `storage` and `storageKey` are required before\r\n * anything is read or written — this library never invents an application\r\n * storage key.\r\n */\r\n storage?: AppearanceStorage;\r\n storageKey?: string;\r\n /**\r\n * Where to write the resolved theme attribute and the scheme variables.\r\n * Defaults to \"none\": the provider mutates no global DOM unless asked to.\r\n */\r\n applyTo?: \"none\" | \"documentElement\" | \"body\";\r\n /** Attribute used for the resolved theme. Bootstrap 5.3's own mechanism by default. */\r\n themeAttribute?: string;\r\n}\r\n\r\nconst AppearanceContext = createContext<AppearanceContextValue | undefined>(undefined);\r\n\r\nfunction isThemeMode(value: unknown): value is ThemeMode {\r\n return typeof value === \"string\" && (THEME_MODES as readonly string[]).includes(value);\r\n}\r\nfunction isSidebarPresentation(value: unknown): value is SidebarPresentation {\r\n return typeof value === \"string\" && (SIDEBAR_PRESENTATIONS as readonly string[]).includes(value);\r\n}\r\nfunction isSidebarTone(value: unknown): value is SidebarTone {\r\n return typeof value === \"string\" && (SIDEBAR_TONES as readonly string[]).includes(value);\r\n}\r\n\r\nfunction readStoredSettings(storage: AppearanceStorage, key: string): Partial<AppearanceSettings> {\r\n let raw: string | null;\r\n try {\r\n raw = storage.getItem(key);\r\n } catch {\r\n return {};\r\n }\r\n if (!raw) return {};\r\n\r\n let parsed: unknown;\r\n try {\r\n parsed = JSON.parse(raw);\r\n } catch {\r\n return {};\r\n }\r\n if (typeof parsed !== \"object\" || parsed === null) return {};\r\n\r\n // Every field is validated independently: one corrupt value must not discard\r\n // the others, and an unknown value must fall back instead of being applied.\r\n const source = parsed as Record<string, unknown>;\r\n const settings: Partial<AppearanceSettings> = {};\r\n if (isThemeMode(source.mode)) settings.mode = source.mode;\r\n if (isSidebarPresentation(source.sidebarPresentation)) settings.sidebarPresentation = source.sidebarPresentation;\r\n if (isSidebarTone(source.sidebarTone)) settings.sidebarTone = source.sidebarTone;\r\n if (typeof source.colorSchemeId === \"string\" && getColorScheme(source.colorSchemeId)) {\r\n settings.colorSchemeId = source.colorSchemeId;\r\n }\r\n return settings;\r\n}\r\n\r\n/**\r\n * Opt-in appearance controller. Deliberately NOT a Metronic Layout Builder:\r\n * it owns four independent settings and nothing else — no demo/template\r\n * switching, no page-loader, header or icon-style options.\r\n *\r\n * SSR-safe by construction: no `window`, `document`, `localStorage` or\r\n * `matchMedia` is touched during module evaluation or during render. The\r\n * system preference and any persisted values are read in effects, so the\r\n * server and the first client render agree. Use\r\n * `createAppearanceInitScript()` if you also need to avoid the initial\r\n * theme flash.\r\n */\r\nexport function AppearanceProvider({\r\n children,\r\n mode,\r\n defaultMode,\r\n onModeChange,\r\n sidebarPresentation,\r\n defaultSidebarPresentation,\r\n onSidebarPresentationChange,\r\n sidebarTone,\r\n defaultSidebarTone,\r\n onSidebarToneChange,\r\n colorSchemeId,\r\n defaultColorSchemeId,\r\n onColorSchemeIdChange,\r\n storage,\r\n storageKey,\r\n applyTo = \"none\",\r\n themeAttribute = \"data-bs-theme\",\r\n}: AppearanceProviderProps) {\r\n const [currentMode, setMode] = useControllableState<ThemeMode>({\r\n value: mode,\r\n defaultValue: defaultMode ?? \"system\",\r\n onChange: onModeChange,\r\n });\r\n const [currentPresentation, setSidebarPresentation] = useControllableState<SidebarPresentation>({\r\n value: sidebarPresentation,\r\n defaultValue: defaultSidebarPresentation ?? \"grouped\",\r\n onChange: onSidebarPresentationChange,\r\n });\r\n const [currentTone, setSidebarTone] = useControllableState<SidebarTone>({\r\n value: sidebarTone,\r\n defaultValue: defaultSidebarTone ?? \"auto\",\r\n onChange: onSidebarToneChange,\r\n });\r\n const [currentSchemeId, setColorSchemeId] = useControllableState<string>({\r\n value: colorSchemeId,\r\n defaultValue: defaultColorSchemeId ?? DEFAULT_COLOR_SCHEME_ID,\r\n onChange: onColorSchemeIdChange,\r\n });\r\n\r\n // \"light\" until the browser tells us otherwise, so the first client render\r\n // matches whatever the server rendered.\r\n const [systemTheme, setSystemTheme] = useState<ResolvedTheme>(\"light\");\r\n\r\n useEffect(() => {\r\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\r\n const query = window.matchMedia(\"(prefers-color-scheme: dark)\");\r\n setSystemTheme(query.matches ? \"dark\" : \"light\");\r\n\r\n const handleChange = (event: MediaQueryListEvent) => setSystemTheme(event.matches ? \"dark\" : \"light\");\r\n // `addListener` is the pre-Safari-14 spelling; both are cleaned up below.\r\n if (typeof query.addEventListener === \"function\") {\r\n query.addEventListener(\"change\", handleChange);\r\n return () => query.removeEventListener(\"change\", handleChange);\r\n }\r\n if (typeof query.addListener === \"function\") {\r\n query.addListener(handleChange);\r\n return () => query.removeListener(handleChange);\r\n }\r\n return undefined;\r\n }, []);\r\n\r\n const persistenceEnabled = storage !== undefined && storageKey !== undefined;\r\n // A state flag rather than a ref: writing back must not happen until the\r\n // render that actually carries the hydrated values, otherwise the first\r\n // write would clobber storage with the defaults.\r\n const [hydrated, setHydrated] = useState(false);\r\n\r\n const isControlled = {\r\n mode: mode !== undefined,\r\n sidebarPresentation: sidebarPresentation !== undefined,\r\n sidebarTone: sidebarTone !== undefined,\r\n colorSchemeId: colorSchemeId !== undefined,\r\n };\r\n const controlledRef = useRef(isControlled);\r\n controlledRef.current = isControlled;\r\n\r\n const settersRef = useRef({ setMode, setSidebarPresentation, setSidebarTone, setColorSchemeId });\r\n settersRef.current = { setMode, setSidebarPresentation, setSidebarTone, setColorSchemeId };\r\n\r\n useEffect(() => {\r\n if (!persistenceEnabled) return;\r\n // Read once, after mount: a controlled setting is the caller's business\r\n // and is never overwritten from storage.\r\n const stored = readStoredSettings(storage as AppearanceStorage, storageKey as string);\r\n const controlled = controlledRef.current;\r\n const setters = settersRef.current;\r\n if (stored.mode !== undefined && !controlled.mode) setters.setMode(stored.mode);\r\n if (stored.sidebarPresentation !== undefined && !controlled.sidebarPresentation) {\r\n setters.setSidebarPresentation(stored.sidebarPresentation);\r\n }\r\n if (stored.sidebarTone !== undefined && !controlled.sidebarTone) setters.setSidebarTone(stored.sidebarTone);\r\n if (stored.colorSchemeId !== undefined && !controlled.colorSchemeId) setters.setColorSchemeId(stored.colorSchemeId);\r\n setHydrated(true);\r\n }, [persistenceEnabled, storage, storageKey]);\r\n\r\n useEffect(() => {\r\n if (!persistenceEnabled || !hydrated) return;\r\n try {\r\n (storage as AppearanceStorage).setItem(\r\n storageKey as string,\r\n JSON.stringify({\r\n mode: currentMode,\r\n sidebarPresentation: currentPresentation,\r\n sidebarTone: currentTone,\r\n colorSchemeId: currentSchemeId,\r\n })\r\n );\r\n } catch {\r\n // A full or unavailable quota must never break rendering.\r\n }\r\n }, [persistenceEnabled, hydrated, storage, storageKey, currentMode, currentPresentation, currentTone, currentSchemeId]);\r\n\r\n const resolvedTheme: ResolvedTheme = currentMode === \"system\" ? systemTheme : currentMode;\r\n const colorScheme = resolveColorScheme(currentSchemeId);\r\n const cssVariables = useMemo(() => colorSchemeCssVariables(colorScheme), [colorScheme]);\r\n\r\n useEffect(() => {\r\n if (applyTo === \"none\" || typeof document === \"undefined\") return;\r\n const target = applyTo === \"body\" ? document.body : document.documentElement;\r\n if (!target) return;\r\n\r\n const previousTheme = target.getAttribute(themeAttribute);\r\n target.setAttribute(themeAttribute, resolvedTheme);\r\n for (const [name, value] of Object.entries(cssVariables)) target.style.setProperty(name, value);\r\n\r\n return () => {\r\n // Restore rather than blindly remove, so a second provider or a\r\n // server-rendered value is not clobbered on unmount.\r\n if (previousTheme === null) target.removeAttribute(themeAttribute);\r\n else target.setAttribute(themeAttribute, previousTheme);\r\n for (const name of Object.keys(cssVariables)) target.style.removeProperty(name);\r\n };\r\n }, [applyTo, themeAttribute, resolvedTheme, cssVariables]);\r\n\r\n const appearanceProps = useMemo(\r\n () => ({ \"data-bs-theme\": resolvedTheme, style: cssVariables as CSSProperties }),\r\n [resolvedTheme, cssVariables]\r\n );\r\n\r\n const value = useMemo<AppearanceContextValue>(\r\n () => ({\r\n mode: currentMode,\r\n sidebarPresentation: currentPresentation,\r\n sidebarTone: currentTone,\r\n colorSchemeId: currentSchemeId,\r\n resolvedTheme,\r\n systemTheme,\r\n colorScheme,\r\n setMode,\r\n setSidebarPresentation,\r\n setSidebarTone,\r\n setColorSchemeId,\r\n appearanceProps,\r\n }),\r\n [\r\n currentMode,\r\n currentPresentation,\r\n currentTone,\r\n currentSchemeId,\r\n resolvedTheme,\r\n systemTheme,\r\n colorScheme,\r\n setMode,\r\n setSidebarPresentation,\r\n setSidebarTone,\r\n setColorSchemeId,\r\n appearanceProps,\r\n ]\r\n );\r\n\r\n return <AppearanceContext.Provider value={value}>{children}</AppearanceContext.Provider>;\r\n}\r\n\r\n/** Throws outside an `AppearanceProvider`, so a missing provider fails loudly instead of silently. */\r\nexport function useAppearance(): AppearanceContextValue {\r\n const value = useContext(AppearanceContext);\r\n if (!value) {\r\n throw new Error(\"[react-components] useAppearance() must be used inside an <AppearanceProvider>.\");\r\n }\r\n return value;\r\n}\r\n\r\n/**\r\n * Internal: components that merely *follow* the appearance when a provider\r\n * happens to be present (Sidebar) must keep working without one. Not exported\r\n * from the package entry point.\r\n */\r\nexport function useOptionalAppearance(): AppearanceContextValue | undefined {\r\n return useContext(AppearanceContext);\r\n}\r\n\r\nexport interface AppearanceInitScriptOptions {\r\n storageKey: string;\r\n themeAttribute?: string;\r\n target?: \"documentElement\" | \"body\";\r\n /** Must match the provider's `defaultMode`. */\r\n defaultMode?: ThemeMode;\r\n}\r\n\r\n/**\r\n * Returns the source of a tiny synchronous snippet that applies the persisted\r\n * resolved theme before first paint, removing the theme flash.\r\n *\r\n * It is returned as a string and never injected automatically — the consuming\r\n * application decides where and whether to inline it (for example in a\r\n * Next.js `<Script strategy=\"beforeInteractive\">` or a raw `<script>` in the\r\n * document head).\r\n *\r\n * The caller-supplied values are embedded as JSON string literals and their\r\n * `<` characters are escaped, so a key can neither break out of the literal\r\n * nor terminate a surrounding `<script>` element.\r\n */\r\nexport function createAppearanceInitScript({\r\n storageKey,\r\n themeAttribute = \"data-bs-theme\",\r\n target = \"documentElement\",\r\n defaultMode = \"system\",\r\n}: AppearanceInitScriptOptions): string {\r\n const literal = (value: string) => JSON.stringify(value).replace(/</g, \"\\\\u003C\");\r\n const key = literal(storageKey);\r\n const attribute = literal(themeAttribute);\r\n const fallback = literal(defaultMode);\r\n const element = target === \"body\" ? \"document.body\" : \"document.documentElement\";\r\n return (\r\n \"(function(){try{\" +\r\n \"var raw=window.localStorage.getItem(\" +\r\n key +\r\n \");\" +\r\n \"var mode=\" +\r\n fallback +\r\n \";\" +\r\n \"if(raw){var parsed=JSON.parse(raw);if(parsed&&typeof parsed.mode==='string'){mode=parsed.mode;}}\" +\r\n \"var dark=mode==='dark'||(mode==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches);\" +\r\n element +\r\n \".setAttribute(\" +\r\n attribute +\r\n \",dark?'dark':'light');\" +\r\n \"}catch(e){}})();\"\r\n );\r\n}\r\n","import type { MouseEvent, ReactNode } from \"react\";\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Legacy (0.2.0) public contract — preserved verbatim.\r\n * ------------------------------------------------------------------ */\r\n\r\n/**\r\n * @deprecated Use the recursive `SidebarItem` model (`SidebarLinkItem` /\r\n * `SidebarActionItem`) via `Sidebar.items`. Still accepted by\r\n * `Sidebar.sections` and normalized internally — see `toSidebarItems`.\r\n */\r\nexport interface SidebarLeafItem {\r\n key: string;\r\n label: ReactNode;\r\n icon?: ReactNode;\r\n href?: string;\r\n onClick?: () => void;\r\n active?: boolean;\r\n disabled?: boolean;\r\n}\r\n\r\n/**\r\n * @deprecated Use `SidebarGroupItem` (`type: \"group\"`, `collapsible: true`)\r\n * via `Sidebar.items`. Still accepted by `Sidebar.sections`.\r\n */\r\nexport interface SidebarGroup {\r\n key: string;\r\n label: string;\r\n items: SidebarLeafItem[];\r\n defaultOpen?: boolean;\r\n}\r\n\r\n/** @deprecated Use `SidebarItem`. */\r\nexport type SidebarSection = SidebarLeafItem | SidebarGroup;\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Recursive navigation model.\r\n * ------------------------------------------------------------------ */\r\n\r\n/**\r\n * Fired for the two item kinds that represent a destination or a command.\r\n * The original React event is passed through so the consuming app can decide\r\n * for itself whether to take over navigation (`event.preventDefault()` plus a\r\n * router push). The Base layer never calls `preventDefault()` for an enabled\r\n * real link, so modified clicks (ctrl/cmd/middle-click, \"open in new tab\")\r\n * keep working (doc section 22: Base must not know routing).\r\n */\r\nexport type SidebarSelectHandler = (\r\n item: SidebarLinkItem | SidebarActionItem,\r\n event: MouseEvent<HTMLAnchorElement | HTMLButtonElement>\r\n) => void;\r\n\r\ninterface SidebarItemBase {\r\n /** Stable identity. Never derived from an array index; must be unique in the tree. */\r\n key: string;\r\n label: ReactNode;\r\n /** Any React node — an `<Icon />`, an `<img>`, an emoji. Icon-set agnostic (doc section 15). */\r\n icon?: ReactNode;\r\n badge?: ReactNode;\r\n disabled?: boolean;\r\n className?: string;\r\n /**\r\n * Accessible name, required whenever `label` is not plain readable text.\r\n * Also used as the accessible name and the tooltip text while the Sidebar\r\n * is collapsed to icons only.\r\n */\r\n ariaLabel?: string;\r\n}\r\n\r\n/** A real destination. Renders an anchor, or the consumer's `renderLink`. */\r\nexport interface SidebarLinkItem extends SidebarItemBase {\r\n type: \"link\";\r\n /** Required — an item without a destination is an `action`, not a `link`. */\r\n href: string;\r\n target?: string;\r\n rel?: string;\r\n onSelect?: SidebarSelectHandler;\r\n}\r\n\r\n/** A command with no destination. Renders a native button, never an empty-fragment anchor. */\r\nexport interface SidebarActionItem extends SidebarItemBase {\r\n type: \"action\";\r\n onSelect?: SidebarSelectHandler;\r\n}\r\n\r\n/** A parent whose children open and close. Renders an explicit toggle button. */\r\nexport interface SidebarCollapsibleItem extends SidebarItemBase {\r\n type: \"collapsible\";\r\n children: SidebarItem[];\r\n}\r\n\r\n/**\r\n * A visual section. Presentation only: never navigable, and only participates\r\n * in expansion when `collapsible` is explicitly set — which is what the legacy\r\n * `SidebarGroup` normalizes to.\r\n */\r\nexport interface SidebarGroupItem extends SidebarItemBase {\r\n type: \"group\";\r\n children: SidebarItem[];\r\n collapsible?: boolean;\r\n}\r\n\r\nexport interface SidebarDividerItem {\r\n type: \"divider\";\r\n key: string;\r\n className?: string;\r\n}\r\n\r\nexport type SidebarItem =\r\n | SidebarLinkItem\r\n | SidebarActionItem\r\n | SidebarCollapsibleItem\r\n | SidebarGroupItem\r\n | SidebarDividerItem;\r\n\r\n/** Items that own a `children` array and therefore can contain a branch. */\r\nexport type SidebarParentItem = SidebarCollapsibleItem | SidebarGroupItem;\r\n\r\nexport function isSidebarParent(item: SidebarItem): item is SidebarParentItem {\r\n return item.type === \"collapsible\" || item.type === \"group\";\r\n}\r\n\r\n/**\r\n * A `group` is expandable only when the consumer asked for it; a `collapsible`\r\n * always is. Deliberately a plain boolean and not a type predicate: this is a\r\n * runtime capability question, not a narrowing one — a non-expandable group is\r\n * still a `SidebarParentItem`.\r\n */\r\nexport function isSidebarExpandable(item: SidebarItem): boolean {\r\n return item.type === \"collapsible\" || (item.type === \"group\" && item.collapsible === true);\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Legacy adapter.\r\n * ------------------------------------------------------------------ */\r\n\r\nfunction isLegacyGroup(section: SidebarSection): section is SidebarGroup {\r\n return \"items\" in section;\r\n}\r\n\r\n/**\r\n * Additive adapter: turns the legacy `sections` shape into the recursive\r\n * model so there is exactly one rendering path (doc section 20 — the Sidebar\r\n * must not grow a second independent implementation for legacy input).\r\n *\r\n * A legacy leaf carrying a real `href` becomes a `link`; one without a\r\n * destination becomes an `action` and renders as a button rather than the\r\n * previous placeholder anchor (defect 8 — see the README migration notes).\r\n */\r\nexport function toSidebarItems(sections: readonly SidebarSection[]): SidebarItem[] {\r\n return sections.map((section) => (isLegacyGroup(section) ? legacyGroupToItem(section) : legacyLeafToItem(section)));\r\n}\r\n\r\nfunction legacyGroupToItem(group: SidebarGroup): SidebarGroupItem {\r\n return {\r\n type: \"group\",\r\n key: group.key,\r\n label: group.label,\r\n collapsible: true,\r\n children: group.items.map(legacyLeafToItem),\r\n };\r\n}\r\n\r\nfunction legacyLeafToItem(leaf: SidebarLeafItem): SidebarLinkItem | SidebarActionItem {\r\n const shared = {\r\n key: leaf.key,\r\n label: leaf.label,\r\n ...(leaf.icon !== undefined ? { icon: leaf.icon } : {}),\r\n ...(leaf.disabled !== undefined ? { disabled: leaf.disabled } : {}),\r\n };\r\n const onSelect: SidebarSelectHandler | undefined = leaf.onClick ? () => leaf.onClick?.() : undefined;\r\n\r\n if (leaf.href !== undefined) {\r\n return { ...shared, type: \"link\", href: leaf.href, ...(onSelect ? { onSelect } : {}) };\r\n }\r\n return { ...shared, type: \"action\", ...(onSelect ? { onSelect } : {}) };\r\n}\r\n\r\n/** Legacy `defaultOpen` groups, in declaration order, as Sidebar-level expanded keys. */\r\nexport function legacyDefaultExpandedKeys(sections: readonly SidebarSection[]): string[] {\r\n return sections\r\n .filter(isLegacyGroup)\r\n .filter((group) => group.defaultOpen)\r\n .map((group) => group.key);\r\n}\r\n\r\n/**\r\n * Legacy per-item `active` flags collapse into the single authoritative\r\n * `activeKey`. Deliberately deterministic: the first flagged item in\r\n * declaration order wins, so inconsistent caller-supplied flags degrade\r\n * predictably instead of producing two simultaneously \"active\" rows.\r\n */\r\nexport function legacyActiveKey(sections: readonly SidebarSection[]): string | undefined {\r\n for (const section of sections) {\r\n if (isLegacyGroup(section)) {\r\n const child = section.items.find((item) => item.active);\r\n if (child) return child.key;\r\n } else if (section.active) {\r\n return section.key;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Tree.\r\n * ------------------------------------------------------------------ */\r\n\r\nexport interface SidebarNode {\r\n item: SidebarItem;\r\n key: string;\r\n depth: number;\r\n /** Ancestor keys, outermost first. */\r\n ancestors: string[];\r\n children: SidebarNode[];\r\n}\r\n\r\nexport interface SidebarTree {\r\n roots: SidebarNode[];\r\n byKey: Map<string, SidebarNode>;\r\n /** Every key in pre-order — the single source of deterministic key ordering. */\r\n order: string[];\r\n duplicateKeys: string[];\r\n}\r\n\r\nexport function buildSidebarTree(items: readonly SidebarItem[]): SidebarTree {\r\n const byKey = new Map<string, SidebarNode>();\r\n const order: string[] = [];\r\n const duplicateKeys: string[] = [];\r\n\r\n function walk(list: readonly SidebarItem[], depth: number, ancestors: string[]): SidebarNode[] {\r\n const nodes: SidebarNode[] = [];\r\n for (const item of list) {\r\n const node: SidebarNode = { item, key: item.key, depth, ancestors, children: [] };\r\n if (byKey.has(item.key)) {\r\n duplicateKeys.push(item.key);\r\n } else {\r\n byKey.set(item.key, node);\r\n order.push(item.key);\r\n }\r\n if (isSidebarParent(item)) {\r\n node.children = walk(item.children, depth + 1, [...ancestors, item.key]);\r\n }\r\n nodes.push(node);\r\n }\r\n return nodes;\r\n }\r\n\r\n const roots = walk(items, 0, []);\r\n return { roots, byKey, order, duplicateKeys };\r\n}\r\n\r\n/** Orders arbitrary keys by their position in the tree, so callbacks are reproducible. */\r\nexport function sortKeysByTreeOrder(order: readonly string[], keys: Iterable<string>): string[] {\r\n const wanted = new Set(keys);\r\n const sorted = order.filter((key) => wanted.has(key));\r\n // Keys no longer present in the tree are kept after the known ones, so a\r\n // controlled caller never silently loses state for a lazily-added branch.\r\n const known = new Set(sorted);\r\n for (const key of wanted) if (!known.has(key)) sorted.push(key);\r\n return sorted;\r\n}\r\n\r\nexport type SidebarExpandMode = \"single\" | \"multiple\";\r\n\r\n/**\r\n * Authoritative expansion transition for the whole tree.\r\n *\r\n * - `multiple`: independent branches, which is exactly what the legacy\r\n * one-Accordion-per-group layout produced, so it stays the default.\r\n * - `single`: opening a branch keeps only that branch's own ancestor chain,\r\n * closing every competing sibling at every level.\r\n *\r\n * Collapsing a branch also drops its descendants, so `expandedKeys` never\r\n * reports a branch as open while that branch is not visible.\r\n */\r\nexport function toggleExpandedKey(\r\n tree: SidebarTree,\r\n current: readonly string[],\r\n key: string,\r\n mode: SidebarExpandMode\r\n): string[] {\r\n const node = tree.byKey.get(key);\r\n const open = new Set(current);\r\n\r\n if (open.has(key)) {\r\n open.delete(key);\r\n if (node) for (const descendant of descendantKeys(node)) open.delete(descendant);\r\n return sortKeysByTreeOrder(tree.order, open);\r\n }\r\n\r\n if (mode === \"single\") {\r\n const next = new Set<string>(node ? node.ancestors : []);\r\n next.add(key);\r\n return sortKeysByTreeOrder(tree.order, next);\r\n }\r\n\r\n open.add(key);\r\n if (node) for (const ancestor of node.ancestors) open.add(ancestor);\r\n return sortKeysByTreeOrder(tree.order, open);\r\n}\r\n\r\n/**\r\n * Opens an ancestor chain without toggling anything.\r\n *\r\n * Used for route-driven expansion, which is a one-way \"make this visible\"\r\n * request rather than a user toggle: it must never close the branch it was\r\n * asked to open. `single` keeps only the requested chain, matching what\r\n * `toggleExpandedKey` does when a branch is opened by hand, so a route change\r\n * and a click leave the tree in the same shape.\r\n */\r\nexport function expandPath(\r\n tree: SidebarTree,\r\n current: readonly string[],\r\n path: readonly string[],\r\n mode: SidebarExpandMode\r\n): string[] {\r\n if (path.length === 0) return sortKeysByTreeOrder(tree.order, new Set(current));\r\n if (mode === \"single\") return sortKeysByTreeOrder(tree.order, new Set(path));\r\n\r\n const open = new Set(current);\r\n for (const key of path) open.add(key);\r\n return sortKeysByTreeOrder(tree.order, open);\r\n}\r\n\r\n/** True when two key lists describe the same expansion, order included. */\r\nexport function sameExpandedKeys(a: readonly string[], b: readonly string[]): boolean {\r\n return a.length === b.length && a.every((key, index) => key === b[index]);\r\n}\r\n\r\nfunction descendantKeys(node: SidebarNode): string[] {\r\n const keys: string[] = [];\r\n for (const child of node.children) {\r\n keys.push(child.key);\r\n keys.push(...descendantKeys(child));\r\n }\r\n return keys;\r\n}\r\n\r\n/** Ancestor keys of the active item — the \"active branch\" the UI highlights. */\r\nexport function activeAncestorKeys(tree: SidebarTree, activeKey: string | undefined): string[] {\r\n if (activeKey === undefined) return [];\r\n return tree.byKey.get(activeKey)?.ancestors ?? [];\r\n}\r\n\r\n/**\r\n * The subset of the active branch that can actually be opened.\r\n *\r\n * A non-interactive visual group is a caption, not a level of expansion: it has\r\n * no toggle, no `aria-expanded` and no place in `expandedKeys`. Route-driven\r\n * expansion therefore asks for this list, while highlighting still uses the\r\n * full ancestor list above.\r\n */\r\nexport function activeExpandablePath(tree: SidebarTree, activeKey: string | undefined): string[] {\r\n return activeAncestorKeys(tree, activeKey).filter((key) => {\r\n const node = tree.byKey.get(key);\r\n return node !== undefined && isSidebarExpandable(node.item);\r\n });\r\n}\r\n","import {\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useLayoutEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n type CSSProperties,\r\n type MouseEvent,\r\n type ReactNode,\r\n} from \"react\";\r\nimport { Divider } from \"./Divider\";\r\nimport { Tooltip } from \"./Tooltip\";\r\nimport { useOptionalAppearance, type SidebarPresentation, type SidebarTone } from \"./Appearance\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { Popup } from \"./shared/Popup\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\nimport { useEscapeKey } from \"./shared/useEscapeKey\";\r\nimport {\r\n activeAncestorKeys,\r\n activeExpandablePath,\r\n buildSidebarTree,\r\n expandPath,\r\n sameExpandedKeys,\r\n isSidebarExpandable,\r\n legacyActiveKey,\r\n legacyDefaultExpandedKeys,\r\n toSidebarItems,\r\n toggleExpandedKey,\r\n type SidebarActionItem,\r\n type SidebarExpandMode,\r\n type SidebarItem,\r\n type SidebarLinkItem,\r\n type SidebarNode,\r\n type SidebarSection,\r\n type SidebarSelectHandler,\r\n type SidebarTree,\r\n} from \"./sidebarModel\";\r\n\r\nexport type {\r\n SidebarActionItem,\r\n SidebarCollapsibleItem,\r\n SidebarDividerItem,\r\n SidebarExpandMode,\r\n SidebarGroup,\r\n SidebarGroupItem,\r\n SidebarItem,\r\n SidebarLeafItem,\r\n SidebarLinkItem,\r\n SidebarParentItem,\r\n SidebarSection,\r\n SidebarSelectHandler,\r\n} from \"./sidebarModel\";\r\nexport { isSidebarExpandable, isSidebarParent, legacyActiveKey, legacyDefaultExpandedKeys, toSidebarItems } from \"./sidebarModel\";\r\n\r\n/**\r\n * How the current route may change which branches are open.\r\n *\r\n * - `never` — the active route never touches expansion.\r\n * - `on-active-change` — the active branch opens on mount and again whenever\r\n * `activeKey` changes, and the user may close it afterwards. This is what\r\n * `expandActivePath` means.\r\n * - `always` — active ancestors are forced open on every render, so the active\r\n * branch cannot be closed. Kept because it was the behaviour `expandActivePath`\r\n * used to have; it is not the default and not recommended.\r\n */\r\nexport type SidebarActivePathExpansion = \"never\" | \"on-active-change\" | \"always\";\r\n\r\n/**\r\n * `grouped` is the presentation this component has always rendered and stays\r\n * the default. Alias of the appearance layer's `SidebarPresentation` so the\r\n * two can never drift apart.\r\n */\r\nexport type SidebarVariant = SidebarPresentation;\r\n\r\nexport interface SidebarLinkRenderProps {\r\n item: SidebarLinkItem;\r\n href: string;\r\n className: string;\r\n style: CSSProperties;\r\n children: ReactNode;\r\n onClick: (event: MouseEvent<HTMLAnchorElement>) => void;\r\n \"aria-current\": \"page\" | undefined;\r\n \"aria-disabled\": true | undefined;\r\n \"aria-label\": string | undefined;\r\n \"data-active-ancestor\": \"true\" | undefined;\r\n target: string | undefined;\r\n rel: string | undefined;\r\n}\r\n\r\n/**\r\n * Lets the application swap the anchor for its own router link. Base stays\r\n * routing-agnostic: no router package is imported and no route matching\r\n * happens here (doc section 22).\r\n */\r\nexport type SidebarLinkRenderer = (props: SidebarLinkRenderProps) => ReactNode;\r\n\r\nexport interface SidebarCollapseControlProps {\r\n collapsed: boolean;\r\n toggle: () => void;\r\n label: string;\r\n}\r\n\r\nexport interface SidebarProps {\r\n /** Recursive navigation model. Takes precedence over `sections` when both are given. */\r\n items?: SidebarItem[];\r\n /** @deprecated Legacy flat/one-level model. Still fully supported; normalized onto `items`. */\r\n sections?: SidebarSection[];\r\n\r\n /** `grouped` (default, the historical presentation) or the compact Metronic-style aside. */\r\n variant?: SidebarVariant;\r\n /** Surface tone. `auto` inherits the page theme; `light`/`dark` scope Bootstrap 5.3's own `data-bs-theme`. */\r\n tone?: SidebarTone;\r\n\r\n /** The one authoritative active identity. Ancestors are derived, not passed in. */\r\n activeKey?: string;\r\n /**\r\n * Open the branch leading to `activeKey`. Off by default, so legacy rendering\r\n * is unchanged. Shorthand for `activePathExpansion=\"on-active-change\"`: the\r\n * path opens on mount and whenever `activeKey` changes, and stays closable by\r\n * hand in between.\r\n */\r\n expandActivePath?: boolean;\r\n /** Explicit strategy. Wins over `expandActivePath` when both are given. */\r\n activePathExpansion?: SidebarActivePathExpansion;\r\n\r\n expandedKeys?: string[];\r\n defaultExpandedKeys?: string[];\r\n onExpandedKeysChange?: (keys: string[]) => void;\r\n /** `multiple` (default) reproduces the legacy independent-groups behavior. */\r\n expandMode?: SidebarExpandMode;\r\n\r\n collapsed?: boolean;\r\n defaultCollapsed?: boolean;\r\n onCollapsedChange?: (collapsed: boolean) => void;\r\n /** Render the collapse/expand control. */\r\n collapsible?: boolean;\r\n renderCollapseControl?: (props: SidebarCollapseControlProps) => ReactNode;\r\n /** Accessible name of the control while expanded (i.e. the action it performs). */\r\n collapseLabel?: string;\r\n /** Accessible name of the control while collapsed. */\r\n expandLabel?: string;\r\n\r\n mobileOpen?: boolean;\r\n defaultMobileOpen?: boolean;\r\n onMobileOpenChange?: (open: boolean) => void;\r\n /** Accessible name for the mobile drawer dialog. Falls back to `navLabel`. */\r\n mobileLabel?: string;\r\n /** Close the mobile drawer when a link or action is selected. */\r\n closeMobileOnSelect?: boolean;\r\n\r\n header?: ReactNode;\r\n footer?: ReactNode;\r\n /**\r\n * Footer presentation while collapsed. A footer sized for the expanded aside\r\n * cannot survive a ~58px rail — a select or an input would simply be clipped —\r\n * and CSS alone cannot turn one control into another. Supply a compact\r\n * icon-sized control here. Additive: when it is omitted the footer region is\r\n * not rendered while collapsed, so nothing is clipped and no focusable\r\n * control is left in a region the user cannot read.\r\n */\r\n collapsedFooter?: ReactNode;\r\n className?: string;\r\n /** Accessible name of the navigation landmark. */\r\n navLabel?: string;\r\n\r\n onSelect?: SidebarSelectHandler;\r\n renderLink?: SidebarLinkRenderer;\r\n}\r\n\r\ninterface SidebarRenderContext {\r\n variant: SidebarVariant;\r\n collapsed: boolean;\r\n expanded: Set<string>;\r\n activeKey: string | undefined;\r\n activeAncestors: Set<string>;\r\n toggle: (key: string) => void;\r\n select: (item: SidebarLinkItem | SidebarActionItem, event: MouseEvent<HTMLAnchorElement | HTMLButtonElement>) => void;\r\n renderLink: SidebarLinkRenderer | undefined;\r\n idPrefix: string;\r\n /** Subtracted from a node's depth so a flyout's contents start flush. */\r\n depthOffset: number;\r\n}\r\n\r\n/**\r\n * `useLayoutEffect` warns when React renders on the server. The check reads\r\n * only the *existence* of `document`, never a property on it, so importing\r\n * this module stays SSR-safe.\r\n */\r\nconst useIsomorphicLayoutEffect = typeof document !== \"undefined\" ? useLayoutEffect : useEffect;\r\n\r\n/** Distinguishes \"not run yet\" from \"ran, and the active key was undefined\". */\r\nconst UNRESOLVED = Symbol(\"unresolved-active-key\");\r\n\r\nfunction accessibleNameOf(item: SidebarItem): string | undefined {\r\n if (item.type === \"divider\") return undefined;\r\n if (item.ariaLabel !== undefined) return item.ariaLabel;\r\n return typeof item.label === \"string\" ? item.label : undefined;\r\n}\r\n\r\n/** Keys are consumer-supplied and may contain characters that are invalid in a DOM id. */\r\nfunction panelId(idPrefix: string, key: string): string {\r\n return `${idPrefix}-${key.replace(/[^A-Za-z0-9_-]/g, \"_\")}`;\r\n}\r\n\r\nfunction RowContent({ node, expandable }: { node: SidebarNode; expandable: boolean }) {\r\n const item = node.item;\r\n if (item.type === \"divider\") return null;\r\n return (\r\n <>\r\n {item.icon !== undefined && (\r\n <span className=\"rrc-sidebar__icon\" aria-hidden=\"true\">\r\n {item.icon}\r\n </span>\r\n )}\r\n <span className=\"rrc-sidebar__label\">{item.label}</span>\r\n {item.badge !== undefined && <span className=\"rrc-sidebar__badge\">{item.badge}</span>}\r\n {expandable && <span className=\"rrc-sidebar__arrow\" aria-hidden=\"true\" />}\r\n </>\r\n );\r\n}\r\n\r\n/** Wraps a collapsed icon-only row in the existing Tooltip so its name stays discoverable. */\r\nfunction CollapsedRowTooltip({ name, children }: { name: string | undefined; children: ReactNode }) {\r\n if (name === undefined) return <>{children}</>;\r\n return (\r\n <Tooltip content={name} placement=\"bottom\" wrapperClassName=\"rrc-sidebar__tooltip\">\r\n {children}\r\n </Tooltip>\r\n );\r\n}\r\n\r\n/**\r\n * Publishes the coordinates a collapsed row's tooltip is pinned to.\r\n *\r\n * In the rail the tooltip is wider than the rail itself, and the panel clips —\r\n * so an absolutely positioned tooltip is cut off mid-word. It is pinned to the\r\n * viewport instead, from the row's measured rect, exactly as the flyout is.\r\n * Measuring on pointer-enter and focus keeps it to one read per hover, and one\r\n * inline value is published rather than a left/right pair so the CSS can place\r\n * it with `inset-inline-start` in either direction.\r\n */\r\nfunction measureRailTooltipAnchor(anchor: HTMLElement | null): void {\r\n if (!anchor) return;\r\n const rect = anchor.getBoundingClientRect();\r\n const edge = (anchor.closest(\".rrc-sidebar\") ?? anchor).getBoundingClientRect();\r\n const rtl = getComputedStyle(anchor).direction === \"rtl\";\r\n const viewportWidth = document.documentElement.clientWidth;\r\n anchor.style.setProperty(\"--rrc-rail-tip-block-start\", `${Math.round(rect.top + rect.height / 2)}px`);\r\n anchor.style.setProperty(\"--rrc-rail-tip-inline-start\", `${Math.round(rtl ? viewportWidth - edge.left : edge.right)}px`);\r\n}\r\n\r\nfunction railTooltipAnchorProps(collapsed: boolean) {\r\n if (!collapsed) return {};\r\n const measure = (event: { currentTarget: HTMLElement }) => measureRailTooltipAnchor(event.currentTarget);\r\n return { onPointerEnter: measure, onFocusCapture: measure };\r\n}\r\n\r\nfunction SidebarRow({ node, ctx }: { node: SidebarNode; ctx: SidebarRenderContext }) {\r\n const item = node.item;\r\n const flyoutRef = useRef<HTMLLIElement>(null);\r\n const [flyoutOpen, setFlyoutOpen] = useState(false);\r\n const closeFlyout = useCallback(() => setFlyoutOpen(false), []);\r\n\r\n /*\r\n * The scrolling navigation body is a scroll container, so it clips both\r\n * axes — an absolutely positioned flyout inside it is invisible, however it\r\n * is offset. The panel is therefore fixed-positioned and placed from the\r\n * anchor's measured rect. Everything else about it (open/close, Escape,\r\n * outside-click dismissal, listener cleanup) still comes from the existing\r\n * Popup primitive; this only supplies the coordinates, exactly as\r\n * Tooltip/Popover/Menu each supply their own placement.\r\n *\r\n * One value is published, not a left/right pair: the CSS reads it through\r\n * `inset-inline-start`, so the same declaration opens the panel to the right\r\n * in LTR and to the left in RTL.\r\n */\r\n useIsomorphicLayoutEffect(() => {\r\n const anchor = flyoutRef.current;\r\n if (!flyoutOpen || !anchor) return;\r\n\r\n const place = () => {\r\n const rect = anchor.getBoundingClientRect();\r\n // The inline edge comes from the Sidebar, not from the row: the row is\r\n // narrower whenever the navigation body shows a scrollbar, and the panel\r\n // should clear the whole aside rather than overlap it.\r\n const edge = (anchor.closest(\".rrc-sidebar\") ?? anchor).getBoundingClientRect();\r\n const rtl = getComputedStyle(anchor).direction === \"rtl\";\r\n const viewportWidth = document.documentElement.clientWidth;\r\n anchor.style.setProperty(\"--rrc-flyout-block-start\", `${Math.round(rect.top)}px`);\r\n anchor.style.setProperty(\"--rrc-flyout-inline-start\", `${Math.round(rtl ? viewportWidth - edge.left : edge.right)}px`);\r\n };\r\n\r\n place();\r\n // Capture phase, so an ancestor scroll container also repositions it.\r\n window.addEventListener(\"scroll\", place, true);\r\n window.addEventListener(\"resize\", place);\r\n return () => {\r\n window.removeEventListener(\"scroll\", place, true);\r\n window.removeEventListener(\"resize\", place);\r\n };\r\n }, [flyoutOpen]);\r\n\r\n if (item.type === \"divider\") {\r\n return (\r\n <li role=\"none\" className={cx(\"rrc-sidebar__divider\", item.className)}>\r\n <Divider className=\"my-1\" />\r\n </li>\r\n );\r\n }\r\n\r\n const depthStyle = { \"--rrc-sidebar-depth\": String(Math.max(0, node.depth - ctx.depthOffset)) } as CSSProperties;\r\n const name = accessibleNameOf(item);\r\n const isActive = ctx.activeKey === item.key;\r\n const isActiveAncestor = ctx.activeAncestors.has(item.key);\r\n const expandable = isSidebarExpandable(item);\r\n const isExpanded = expandable && ctx.expanded.has(item.key);\r\n const controlsId = panelId(ctx.idPrefix, item.key);\r\n\r\n const rowClass = cx(\r\n \"rrc-sidebar__row\",\r\n isActive && \"rrc-sidebar__row--active\",\r\n isActiveAncestor && \"rrc-sidebar__row--active-ancestor\",\r\n item.disabled && \"rrc-sidebar__row--disabled\",\r\n item.className\r\n );\r\n\r\n /* ---------------- link ---------------- */\r\n if (item.type === \"link\") {\r\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\r\n if (item.disabled) {\r\n // The only case where Base prevents navigation on its own.\r\n event.preventDefault();\r\n return;\r\n }\r\n ctx.select(item, event);\r\n };\r\n\r\n const linkProps: SidebarLinkRenderProps = {\r\n item,\r\n href: item.href,\r\n className: cx(rowClass, \"rrc-sidebar__row--link\"),\r\n style: depthStyle,\r\n children: <RowContent node={node} expandable={false} />,\r\n onClick: handleClick,\r\n \"aria-current\": isActive ? \"page\" : undefined,\r\n \"aria-disabled\": item.disabled ? true : undefined,\r\n \"aria-label\": ctx.collapsed ? name : undefined,\r\n \"data-active-ancestor\": isActiveAncestor ? \"true\" : undefined,\r\n target: item.target,\r\n rel: item.rel,\r\n };\r\n\r\n const anchor = ctx.renderLink ? (\r\n ctx.renderLink(linkProps)\r\n ) : (\r\n <a\r\n href={linkProps.href}\r\n className={linkProps.className}\r\n style={linkProps.style}\r\n onClick={linkProps.onClick}\r\n aria-current={linkProps[\"aria-current\"]}\r\n aria-disabled={linkProps[\"aria-disabled\"]}\r\n aria-label={linkProps[\"aria-label\"]}\r\n data-active-ancestor={linkProps[\"data-active-ancestor\"]}\r\n target={linkProps.target}\r\n rel={linkProps.rel}\r\n >\r\n {linkProps.children}\r\n </a>\r\n );\r\n\r\n return (\r\n <li className=\"rrc-sidebar__item\" {...railTooltipAnchorProps(ctx.collapsed)}>\r\n {ctx.collapsed ? <CollapsedRowTooltip name={name}>{anchor}</CollapsedRowTooltip> : anchor}\r\n </li>\r\n );\r\n }\r\n\r\n /* ---------------- action ---------------- */\r\n if (item.type === \"action\") {\r\n const button = (\r\n <button\r\n type=\"button\"\r\n className={cx(rowClass, \"rrc-sidebar__row--action\")}\r\n style={depthStyle}\r\n disabled={item.disabled}\r\n aria-label={ctx.collapsed ? name : undefined}\r\n data-active-ancestor={isActiveAncestor ? \"true\" : undefined}\r\n data-active={isActive ? \"true\" : undefined}\r\n onClick={(event) => ctx.select(item, event)}\r\n >\r\n <RowContent node={node} expandable={false} />\r\n </button>\r\n );\r\n\r\n return (\r\n <li className=\"rrc-sidebar__item\" {...railTooltipAnchorProps(ctx.collapsed)}>\r\n {ctx.collapsed ? <CollapsedRowTooltip name={name}>{button}</CollapsedRowTooltip> : button}\r\n </li>\r\n );\r\n }\r\n\r\n /* ---------------- non-collapsible visual group ---------------- */\r\n if (!expandable) {\r\n const titleId = `${controlsId}-title`;\r\n return (\r\n <li className={cx(\"rrc-sidebar__item\", \"rrc-sidebar__group\", item.className)}>\r\n <div className=\"rrc-sidebar__group-title\" id={titleId} style={depthStyle}>\r\n {item.icon !== undefined && (\r\n <span className=\"rrc-sidebar__icon\" aria-hidden=\"true\">\r\n {item.icon}\r\n </span>\r\n )}\r\n <span className=\"rrc-sidebar__label\">{item.label}</span>\r\n {item.badge !== undefined && <span className=\"rrc-sidebar__badge\">{item.badge}</span>}\r\n </div>\r\n {/*\r\n A visual category heading is a caption, not a level of hierarchy: its\r\n contents sit in the same column it does. The extra depth step the tree\r\n gives them is subtracted rather than rendered as indentation.\r\n */}\r\n <ul className=\"rrc-sidebar__menu rrc-sidebar__submenu\" aria-labelledby={titleId}>\r\n {node.children.map((child) => (\r\n <SidebarRow key={child.key} node={child} ctx={{ ...ctx, depthOffset: ctx.depthOffset + 1 }} />\r\n ))}\r\n </ul>\r\n </li>\r\n );\r\n }\r\n\r\n /* ---------------- collapsible parent / collapsible group ---------------- */\r\n const submenu = (\r\n <ul className=\"rrc-sidebar__menu rrc-sidebar__submenu\" id={controlsId}>\r\n {node.children.map((child) => (\r\n <SidebarRow key={child.key} node={child} ctx={ctx} />\r\n ))}\r\n </ul>\r\n );\r\n\r\n // While the Sidebar is collapsed to icons, an inline submenu would render\r\n // clipped text, so the branch opens as an anchored flyout built from the\r\n // existing Popup primitive instead — and it keeps its own local open state,\r\n // so the authoritative `expandedKeys` are never touched.\r\n const iconOnlyBranch = ctx.collapsed;\r\n const toggleExpanded = () => {\r\n if (item.disabled) return;\r\n if (iconOnlyBranch) setFlyoutOpen((previous) => !previous);\r\n else ctx.toggle(item.key);\r\n };\r\n\r\n const toggleButton = (\r\n <button\r\n type=\"button\"\r\n className={cx(rowClass, \"rrc-sidebar__row--toggle\", item.type === \"group\" && \"rrc-sidebar__row--group-toggle\")}\r\n style={depthStyle}\r\n disabled={item.disabled}\r\n aria-expanded={iconOnlyBranch ? flyoutOpen : isExpanded}\r\n aria-controls={controlsId}\r\n aria-label={ctx.collapsed ? name : undefined}\r\n data-active-ancestor={isActiveAncestor ? \"true\" : undefined}\r\n onClick={toggleExpanded}\r\n >\r\n <RowContent node={node} expandable />\r\n </button>\r\n );\r\n\r\n return (\r\n <li\r\n ref={flyoutRef}\r\n className={cx(\"rrc-sidebar__item\", iconOnlyBranch && \"rrc-sidebar__item--flyout-anchor\")}\r\n {...railTooltipAnchorProps(ctx.collapsed)}\r\n >\r\n {iconOnlyBranch ? <CollapsedRowTooltip name={name}>{toggleButton}</CollapsedRowTooltip> : toggleButton}\r\n {iconOnlyBranch ? (\r\n <Popup open={flyoutOpen} onClose={closeFlyout} anchorRef={flyoutRef} className=\"rrc-sidebar__flyout\">\r\n <ul className=\"rrc-sidebar__menu rrc-sidebar__submenu\" id={controlsId}>\r\n {node.children.map((child) => (\r\n // Inside the panel the branch is fully expanded again, and its\r\n // rows start flush rather than inheriting the aside's indentation.\r\n <SidebarRow key={child.key} node={child} ctx={{ ...ctx, collapsed: false, depthOffset: node.depth + 1 }} />\r\n ))}\r\n </ul>\r\n </Popup>\r\n ) : (\r\n isExpanded && submenu\r\n )}\r\n </li>\r\n );\r\n}\r\n\r\n/**\r\n * The edge collapse control.\r\n *\r\n * One original chevron, drawn inline and pointed by CSS rotation rather than by\r\n * swapping glyphs, so the two states can transition into each other and the RTL\r\n * mirror is a single extra rule. It is not a text character and not a borrowed\r\n * icon set.\r\n */\r\nfunction DefaultCollapseControl({ collapsed, toggle, label }: SidebarCollapseControlProps) {\r\n return (\r\n <button type=\"button\" className=\"rrc-sidebar__collapse-btn\" aria-label={label} onClick={toggle}>\r\n <svg\r\n className={cx(\"rrc-sidebar__collapse-icon\", collapsed && \"rrc-sidebar__collapse-icon--collapsed\")}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"M14.5 6.5 9 12l5.5 5.5\" />\r\n </svg>\r\n </button>\r\n );\r\n}\r\n\r\n/**\r\n * Persistent vertical navigation.\r\n *\r\n * One recursive tree, one authoritative expansion state and one authoritative\r\n * `activeKey` — no per-group Accordion instance and no per-item `active`\r\n * boolean to keep in sync. The legacy `sections` shape is normalized onto the\r\n * same model (`toSidebarItems`) so there is a single rendering path\r\n * (doc section 20).\r\n *\r\n * Routing stays out of Base: real destinations render as anchors (or the\r\n * consumer's `renderLink`), commands render as buttons, and URL matching\r\n * remains the application's job (doc section 22).\r\n */\r\nexport function Sidebar({\r\n items,\r\n sections,\r\n variant,\r\n tone,\r\n activeKey,\r\n expandActivePath = false,\r\n activePathExpansion,\r\n expandedKeys,\r\n defaultExpandedKeys,\r\n onExpandedKeysChange,\r\n expandMode = \"multiple\",\r\n collapsed,\r\n defaultCollapsed,\r\n onCollapsedChange,\r\n collapsible = false,\r\n renderCollapseControl,\r\n collapseLabel = \"Collapse sidebar\",\r\n expandLabel = \"Expand sidebar\",\r\n mobileOpen,\r\n defaultMobileOpen,\r\n onMobileOpenChange,\r\n mobileLabel,\r\n closeMobileOnSelect = true,\r\n header,\r\n footer,\r\n collapsedFooter,\r\n className,\r\n navLabel,\r\n onSelect,\r\n renderLink,\r\n}: SidebarProps) {\r\n const appearance = useOptionalAppearance();\r\n const legacySections = sections ?? [];\r\n\r\n const resolvedItems = useMemo(\r\n () => (items !== undefined ? items : toSidebarItems(legacySections)),\r\n // `legacySections` is a fresh array only when `sections` changes.\r\n [items, sections] // eslint-disable-line react-hooks/exhaustive-deps\r\n );\r\n const tree: SidebarTree = useMemo(() => buildSidebarTree(resolvedItems), [resolvedItems]);\r\n\r\n const duplicates = tree.duplicateKeys.join(\", \");\r\n useEffect(() => {\r\n if (process.env.NODE_ENV !== \"production\" && duplicates.length > 0) {\r\n // eslint-disable-next-line no-console\r\n console.error(\r\n \"[react-components] Sidebar received duplicate item keys: \" +\r\n duplicates +\r\n \". Keys must be unique and stable: expansion and active state are keyed by them, so every \" +\r\n \"duplicate shares one identity and the first occurrence in tree order defines it.\"\r\n );\r\n }\r\n }, [duplicates]);\r\n\r\n const legacyDefaults = useMemo(() => legacyDefaultExpandedKeys(legacySections), [sections]); // eslint-disable-line react-hooks/exhaustive-deps\r\n\r\n const resolvedActiveKeyForInit = activeKey ?? (items === undefined ? legacyActiveKey(legacySections) : undefined);\r\n const expansionStrategy: SidebarActivePathExpansion =\r\n activePathExpansion ?? (expandActivePath ? \"on-active-change\" : \"never\");\r\n\r\n /*\r\n * The initial expansion, computed once.\r\n *\r\n * Seeding the *initial* value — rather than opening the path in an effect —\r\n * is what makes a full refresh land with the active branch already open, in\r\n * the first painted frame and with no second render. From here on the value\r\n * is ordinary UI state that the user owns.\r\n */\r\n const initialExpandedRef = useRef<string[] | null>(null);\r\n if (initialExpandedRef.current === null) {\r\n const base = defaultExpandedKeys ?? legacyDefaults;\r\n initialExpandedRef.current =\r\n expansionStrategy === \"never\"\r\n ? base\r\n : expandPath(tree, base, activeExpandablePath(tree, resolvedActiveKeyForInit), expandMode);\r\n }\r\n\r\n const [currentExpanded, setExpanded] = useControllableState<string[]>({\r\n value: expandedKeys,\r\n defaultValue: initialExpandedRef.current,\r\n onChange: onExpandedKeysChange,\r\n });\r\n const [currentCollapsed, setCollapsed] = useControllableState<boolean>({\r\n value: collapsed,\r\n defaultValue: defaultCollapsed ?? false,\r\n onChange: onCollapsedChange,\r\n });\r\n const [currentMobileOpen, setMobileOpen] = useControllableState<boolean>({\r\n value: mobileOpen,\r\n defaultValue: defaultMobileOpen ?? false,\r\n onChange: onMobileOpenChange,\r\n });\r\n\r\n const resolvedActiveKey = resolvedActiveKeyForInit;\r\n const activeAncestors = useMemo(\r\n () => new Set(activeAncestorKeys(tree, resolvedActiveKey)),\r\n [tree, resolvedActiveKey]\r\n );\r\n\r\n /*\r\n * Active and expanded are two different relationships.\r\n *\r\n * `always` is the only strategy that keeps deriving expansion from the route\r\n * on every render — which is precisely why a branch under it cannot be closed.\r\n * Under `on-active-change` the rendered set is the state and nothing else, so\r\n * a manual close survives every unrelated re-render.\r\n */\r\n const expandedSet = useMemo(() => {\r\n const set = new Set(currentExpanded);\r\n if (expansionStrategy === \"always\") for (const key of activeAncestors) set.add(key);\r\n return set;\r\n }, [currentExpanded, expansionStrategy, activeAncestors]);\r\n\r\n /*\r\n * Route-driven expansion, keyed on the active identity rather than on\r\n * rendering. The ref carries the current keys so that toggling does not\r\n * re-trigger this, and a sentinel start value lets the first run happen on\r\n * mount — where an uncontrolled Sidebar finds the seed already applied and\r\n * does nothing, while a controlled one asks its owner exactly once.\r\n */\r\n const expandedRef = useRef(currentExpanded);\r\n expandedRef.current = currentExpanded;\r\n const previousActiveKeyRef = useRef<string | undefined | typeof UNRESOLVED>(UNRESOLVED);\r\n\r\n useEffect(() => {\r\n if (expansionStrategy !== \"on-active-change\") {\r\n previousActiveKeyRef.current = resolvedActiveKey;\r\n return;\r\n }\r\n if (previousActiveKeyRef.current === resolvedActiveKey) return;\r\n previousActiveKeyRef.current = resolvedActiveKey;\r\n\r\n const path = activeExpandablePath(tree, resolvedActiveKey);\r\n if (path.length === 0) return;\r\n const next = expandPath(tree, expandedRef.current, path, expandMode);\r\n if (!sameExpandedKeys(next, expandedRef.current)) setExpanded(next);\r\n }, [expansionStrategy, resolvedActiveKey, tree, expandMode, setExpanded]);\r\n\r\n const toggle = useCallback(\r\n (key: string) => setExpanded(toggleExpandedKey(tree, currentExpanded, key, expandMode)),\r\n [tree, currentExpanded, expandMode, setExpanded]\r\n );\r\n\r\n const closeMobile = useCallback(() => setMobileOpen(false), [setMobileOpen]);\r\n useEscapeKey(currentMobileOpen, closeMobile);\r\n\r\n // Focus returns to whatever opened the drawer — the opener lives in the\r\n // application, so it is captured rather than assumed.\r\n const openerRef = useRef<Element | null>(null);\r\n useEffect(() => {\r\n if (typeof document === \"undefined\") return;\r\n if (currentMobileOpen) {\r\n openerRef.current = document.activeElement;\r\n return;\r\n }\r\n const opener = openerRef.current;\r\n openerRef.current = null;\r\n if (opener instanceof HTMLElement && opener.isConnected) opener.focus();\r\n }, [currentMobileOpen]);\r\n\r\n const select = useCallback(\r\n (item: SidebarLinkItem | SidebarActionItem, event: MouseEvent<HTMLAnchorElement | HTMLButtonElement>) => {\r\n if (item.disabled) return;\r\n item.onSelect?.(item, event);\r\n onSelect?.(item, event);\r\n if (closeMobileOnSelect && currentMobileOpen) setMobileOpen(false);\r\n },\r\n [onSelect, closeMobileOnSelect, currentMobileOpen, setMobileOpen]\r\n );\r\n\r\n const idPrefix = useId();\r\n const resolvedVariant: SidebarVariant = variant ?? appearance?.sidebarPresentation ?? \"grouped\";\r\n const resolvedTone: SidebarTone = tone ?? appearance?.sidebarTone ?? \"auto\";\r\n // The mobile drawer always shows labels; the desktop collapse choice is kept intact.\r\n const effectiveCollapsed = currentCollapsed && !currentMobileOpen;\r\n\r\n const ctx: SidebarRenderContext = useMemo(\r\n () => ({\r\n variant: resolvedVariant,\r\n collapsed: effectiveCollapsed,\r\n expanded: expandedSet,\r\n activeKey: resolvedActiveKey,\r\n activeAncestors,\r\n toggle,\r\n select,\r\n renderLink,\r\n idPrefix,\r\n depthOffset: 0,\r\n }),\r\n [resolvedVariant, effectiveCollapsed, expandedSet, resolvedActiveKey, activeAncestors, toggle, select, renderLink, idPrefix]\r\n );\r\n\r\n const collapseControlProps: SidebarCollapseControlProps = {\r\n collapsed: currentCollapsed,\r\n toggle: () => setCollapsed(!currentCollapsed),\r\n label: currentCollapsed ? expandLabel : collapseLabel,\r\n };\r\n\r\n /*\r\n * Footer while collapsed: the supplied compact renderer, or nothing. Clipping\r\n * an expanded-width control into the rail is the one outcome that is never\r\n * acceptable, and leaving it in the DOM would hand the user a control they\r\n * cannot read. See `collapsedFooter`.\r\n */\r\n const resolvedFooter = effectiveCollapsed ? collapsedFooter : footer;\r\n\r\n /*\r\n * Two elements, deliberately.\r\n *\r\n * The outer element is the layout box: it owns the inline size, so it is the\r\n * thing that animates and the thing the application's flex row measures. The\r\n * inner panel owns the surface and clips — labels and submenu content are cut\r\n * off by the narrowing panel instead of wrapping. The collapse control sits\r\n * between them, outside the clipping panel, which is the only way it can\r\n * straddle the Sidebar's outer edge without being cut in half.\r\n */\r\n const aside = (\r\n <aside\r\n className={cx(\r\n \"rrc-sidebar\",\r\n `rrc-sidebar--${resolvedVariant}`,\r\n effectiveCollapsed ? \"rrc-sidebar--collapsed\" : \"rrc-sidebar--expanded\",\r\n currentMobileOpen && \"rrc-sidebar--mobile-open\",\r\n className\r\n )}\r\n data-variant={resolvedVariant}\r\n data-collapsed={effectiveCollapsed ? \"true\" : \"false\"}\r\n data-bs-theme={resolvedTone === \"auto\" ? undefined : resolvedTone}\r\n {...(currentMobileOpen ? { role: \"dialog\", \"aria-modal\": true, \"aria-label\": mobileLabel ?? navLabel } : {})}\r\n >\r\n <div className=\"rrc-sidebar__panel\">\r\n {(header !== undefined || collapsible) && (\r\n <div className=\"rrc-sidebar__header\">\r\n {header !== undefined && <div className=\"rrc-sidebar__brand\">{header}</div>}\r\n </div>\r\n )}\r\n\r\n <nav className=\"rrc-sidebar__body\" aria-label={navLabel}>\r\n <ul className=\"rrc-sidebar__menu rrc-sidebar__menu--root\">\r\n {tree.roots.map((node) => (\r\n <SidebarRow key={node.key} node={node} ctx={ctx} />\r\n ))}\r\n </ul>\r\n </nav>\r\n\r\n {resolvedFooter !== undefined && <div className=\"rrc-sidebar__footer\">{resolvedFooter}</div>}\r\n </div>\r\n\r\n {collapsible && (\r\n <div className=\"rrc-sidebar__collapse\">\r\n {renderCollapseControl ? renderCollapseControl(collapseControlProps) : <DefaultCollapseControl {...collapseControlProps} />}\r\n </div>\r\n )}\r\n </aside>\r\n );\r\n\r\n if (!currentMobileOpen) return aside;\r\n\r\n return (\r\n <div className=\"rrc-sidebar-drawer\">\r\n <div className=\"rrc-sidebar-drawer__backdrop\" onClick={closeMobile} data-testid=\"rrc-sidebar-backdrop\" />\r\n {aside}\r\n </div>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { Breadcrumb, type BreadcrumbItem } from \"./Breadcrumb\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface PageHeaderProps {\r\n title: ReactNode;\r\n description?: ReactNode;\r\n breadcrumbItems?: BreadcrumbItem[];\r\n /** Right-aligned slot, typically page-level Buttons. */\r\n actions?: ReactNode;\r\n className?: string;\r\n}\r\n\r\n/** Composes Breadcrumb (doc section 20 — reuse, don't re-derive trail markup) for the standard title/breadcrumb/actions row atop a page. */\r\nexport function PageHeader({ title, description, breadcrumbItems, actions, className }: PageHeaderProps) {\r\n return (\r\n <div className={cx(\"mb-4\", \"rrc-page-header\", className)}>\r\n {breadcrumbItems && breadcrumbItems.length > 0 && <Breadcrumb items={breadcrumbItems} className=\"mb-2 rrc-page-header__breadcrumb\" />}\r\n <div className=\"d-flex align-items-start justify-content-between gap-3 flex-wrap rrc-page-header__row\">\r\n <div>\r\n <h1 className=\"h3 mb-1 rrc-page-header__title\">{title}</h1>\r\n {description && <p className=\"text-body-secondary mb-0 rrc-page-header__description\">{description}</p>}\r\n </div>\r\n {actions && <div className=\"d-flex align-items-center gap-2 rrc-page-header__actions\">{actions}</div>}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { Stack, type StackProps } from \"./Stack\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport type FlexGap = NonNullable<StackProps[\"gap\"]> | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\r\n\r\nconst GAP_TOKEN: Record<\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\", NonNullable<StackProps[\"gap\"]>> = {\r\n xs: 1,\r\n sm: 2,\r\n md: 3,\r\n lg: 4,\r\n xl: 5,\r\n};\r\n\r\nexport interface FlexProps extends Omit<StackProps, \"gap\"> {\r\n gap?: FlexGap;\r\n /** `flex-grow-1` on the container itself (for a Flex nested inside another flex layout). */\r\n grow?: boolean;\r\n /** `flex-shrink-0` on the container itself. */\r\n shrink?: boolean;\r\n /** `w-100`. */\r\n fullWidth?: boolean;\r\n}\r\n\r\nfunction resolveGap(gap: FlexGap): NonNullable<StackProps[\"gap\"]> {\r\n return typeof gap === \"number\" ? gap : GAP_TOKEN[gap];\r\n}\r\n\r\n/**\r\n * Arbitrary flex layout on top of the same `d-flex` machinery Stack already\r\n * owns (doc: \"do not duplicate Stack\") — only the defaults and the extra\r\n * grow/shrink/fullWidth concerns differ. Stack defaults to a column\r\n * (vertical list of children); Flex defaults to a row, matching the\r\n * `<div className=\"d-flex align-items-center justify-content-between\">`\r\n * call sites it's meant to replace.\r\n */\r\nexport function Flex({ direction = \"row\", gap = \"sm\", grow, shrink, fullWidth, className, ...rest }: FlexProps) {\r\n return (\r\n <Stack\r\n direction={direction}\r\n gap={resolveGap(gap)}\r\n className={cx(\"rrc-flex\", grow && \"flex-grow-1\", shrink && \"flex-shrink-0\", fullWidth && \"w-100\", className)}\r\n {...rest}\r\n />\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { Button, type ButtonProps } from \"./Button\";\r\nimport { Icon, type IconProps } from \"./Icon\";\r\nimport { Tooltip } from \"./Tooltip\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface IconButtonProps extends Omit<ButtonProps, \"children\"> {\r\n /** Icon class name(s), passed straight through to `Icon` (icon-set agnostic — doc section 15). */\r\n icon: string;\r\n /** Required — an icon-only control has no visible text, so it must carry its own accessible name. */\r\n \"aria-label\": string;\r\n iconSize?: IconProps[\"size\"];\r\n /** Optional tooltip, composed from the existing `Tooltip` primitive rather than a second hover-label implementation. */\r\n tooltip?: ReactNode;\r\n}\r\n\r\n/** Composes Button + Icon (doc: reuse, don't build a second button system) for the common icon-only action button. */\r\nexport function IconButton({ icon, \"aria-label\": ariaLabel, iconSize, tooltip, variant = \"light\", loading, className, ...rest }: IconButtonProps) {\r\n const button = (\r\n <Button variant={variant} loading={loading} className={cx(\"btn-icon\", \"rrc-btn-icon\", className)} aria-label={ariaLabel} {...rest}>\r\n {!loading && <Icon name={icon} size={iconSize} />}\r\n </Button>\r\n );\r\n\r\n return tooltip ? <Tooltip content={tooltip}>{button}</Tooltip> : button;\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport interface ListItemProps {\r\n /** Typically an `Avatar` or `Icon`. */\r\n leading?: ReactNode;\r\n title: ReactNode;\r\n description?: ReactNode;\r\n /** Typically an `IconButton`, `Badge`, or `Sparkline`. */\r\n trailing?: ReactNode;\r\n /** Presence makes the row an interactive `<button>` (established row-action pattern). */\r\n onClick?: () => void;\r\n disabled?: boolean;\r\n /** Tighter vertical rhythm for dense lists (e.g. inside a DataGrid cell). */\r\n dense?: boolean;\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Generic leading/title-description/trailing row — the same shape as MUI's\r\n * `ListItem` + `ListItemAvatar` + `ListItemText` or Ant Design's\r\n * `List.Item.Meta`. Replaces repeated `<div className=\"d-flex\r\n * align-items-center\"><Avatar/><div><span/><span/></div></div>` markup.\r\n * Intentionally has no domain-specific counterpart (no `AuthorItem`/\r\n * `UserItem`) — callers pass whatever leading/title/description/trailing\r\n * content their row needs.\r\n */\r\nexport function ListItem({ leading, title, description, trailing, onClick, disabled, dense, className }: ListItemProps) {\r\n const content = (\r\n <>\r\n {leading && <span className=\"flex-shrink-0 d-inline-flex align-items-center rrc-list-item__leading\">{leading}</span>}\r\n <span className=\"flex-grow-1\" style={{ minWidth: 0 }}>\r\n <span className=\"d-block text-truncate rrc-list-item__title\">{title}</span>\r\n {description && <span className=\"d-block text-truncate small text-body-secondary rrc-list-item__description\">{description}</span>}\r\n </span>\r\n {trailing && <span className=\"flex-shrink-0 d-inline-flex align-items-center rrc-list-item__trailing\">{trailing}</span>}\r\n </>\r\n );\r\n\r\n const rowClassName = cx(\r\n \"d-flex align-items-center text-start\",\r\n \"rrc-list-item\",\r\n onClick && \"rrc-list-item--interactive\",\r\n dense ? \"gap-2 py-1\" : \"gap-3 py-2\",\r\n onClick && \"w-100 border-0 bg-transparent\",\r\n disabled && \"opacity-50\",\r\n className\r\n );\r\n\r\n if (onClick) {\r\n return (\r\n <button type=\"button\" className={rowClassName} onClick={onClick} disabled={disabled}>\r\n {content}\r\n </button>\r\n );\r\n }\r\n\r\n return (\r\n <div className={rowClassName} aria-disabled={disabled || undefined}>\r\n {content}\r\n </div>\r\n );\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\n\r\nexport type SparklineType = \"line\" | \"area\" | \"bar\";\r\nexport type SparklineTone = \"primary\" | \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" | \"dark\";\r\n\r\nexport interface SparklineProps {\r\n type?: SparklineType;\r\n data: number[];\r\n tone?: SparklineTone;\r\n width?: number;\r\n height?: number;\r\n strokeWidth?: number;\r\n className?: string;\r\n /** Accessible label — omit for a purely decorative chart (default: aria-hidden), same convention as `Icon`. */\r\n label?: string;\r\n}\r\n\r\nfunction buildLinePoints(data: number[], width: number, height: number, padding: number): Array<[number, number]> {\r\n if (data.length === 0) return [];\r\n const min = Math.min(...data);\r\n const max = Math.max(...data);\r\n const range = max - min || 1;\r\n const innerWidth = width - padding * 2;\r\n const innerHeight = height - padding * 2;\r\n const step = data.length > 1 ? innerWidth / (data.length - 1) : 0;\r\n\r\n return data.map((value, index) => {\r\n const x = padding + step * index;\r\n const y = padding + innerHeight - ((value - min) / range) * innerHeight;\r\n return [x, y];\r\n });\r\n}\r\n\r\nfunction LineOrArea({ type, data, width, height, strokeWidth }: { type: \"line\" | \"area\"; data: number[]; width: number; height: number; strokeWidth: number }) {\r\n const padding = strokeWidth;\r\n const points = buildLinePoints(data, width, height, padding);\r\n if (points.length === 0) return null;\r\n\r\n const linePoints = points.map(([x, y]) => `${x},${y}`).join(\" \");\r\n\r\n return (\r\n <>\r\n {type === \"area\" && (\r\n <polygon\r\n points={`${padding},${height - padding} ${linePoints} ${width - padding},${height - padding}`}\r\n fill=\"currentColor\"\r\n opacity={0.2}\r\n stroke=\"none\"\r\n />\r\n )}\r\n <polyline points={linePoints} fill=\"none\" stroke=\"currentColor\" strokeWidth={strokeWidth} strokeLinecap=\"round\" strokeLinejoin=\"round\" />\r\n </>\r\n );\r\n}\r\n\r\nfunction Bars({ data, width, height }: { data: number[]; width: number; height: number }) {\r\n if (data.length === 0) return null;\r\n const min = Math.min(0, ...data);\r\n const max = Math.max(0, ...data);\r\n const range = max - min || 1;\r\n const gap = 2;\r\n const barWidth = Math.max((width - gap * (data.length - 1)) / data.length, 1);\r\n\r\n return (\r\n <>\r\n {data.map((value, index) => {\r\n const barHeight = Math.max(((value - min) / range) * height, 1);\r\n const x = index * (barWidth + gap);\r\n const y = height - barHeight;\r\n return <rect key={index} x={x} y={y} width={barWidth} height={barHeight} rx={1} fill=\"currentColor\" />;\r\n })}\r\n </>\r\n );\r\n}\r\n\r\n/**\r\n * Compact inline chart — the established dashboard \"sparkline\" concept\r\n * (MUI X `SparkLineChart`, DevExtreme/Kendo Sparkline). Implemented with\r\n * plain inline SVG rather than a charting dependency: this repo doesn't\r\n * already depend on one, and a public API shaped around `data`/`type`/\r\n * `tone` stays implementation-agnostic either way (doc: avoid unnecessary\r\n * dependencies; don't leak chart-library config as the public API).\r\n */\r\nexport function Sparkline({ type = \"line\", data, tone = \"primary\", width = 80, height = 28, strokeWidth = 2, className, label }: SparklineProps) {\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${width} ${height}`}\r\n className={cx(`text-${tone}`, \"rrc-sparkline\", className)}\r\n role={label ? \"img\" : undefined}\r\n aria-label={label}\r\n aria-hidden={label ? undefined : true}\r\n >\r\n {type === \"bar\" ? <Bars data={data} width={width} height={height} /> : <LineOrArea type={type} data={data} width={width} height={height} strokeWidth={strokeWidth} />}\r\n </svg>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { Icon } from \"./Icon\";\r\nimport { Skeleton } from \"./Skeleton\";\r\nimport { Text, type TextTone } from \"./Text\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\nexport type StatisticTrend = \"up\" | \"down\" | \"neutral\";\r\n\r\nexport interface StatisticProps {\r\n label: ReactNode;\r\n value: number | string;\r\n prefix?: ReactNode;\r\n suffix?: ReactNode;\r\n /** Decimal places applied when `value` is a number. */\r\n precision?: number;\r\n trend?: StatisticTrend;\r\n delta?: ReactNode;\r\n loading?: boolean;\r\n className?: string;\r\n}\r\n\r\nconst TREND_TONE: Record<StatisticTrend, TextTone> = {\r\n up: \"success\",\r\n down: \"danger\",\r\n neutral: \"muted\",\r\n};\r\n\r\nconst TREND_ICON: Record<StatisticTrend, string> = {\r\n up: \"bi bi-arrow-up-short\",\r\n down: \"bi bi-arrow-down-short\",\r\n neutral: \"bi bi-dash\",\r\n};\r\n\r\nfunction formatValue(value: number | string, precision?: number): string {\r\n return typeof value === \"number\" && precision != null ? value.toFixed(precision) : String(value);\r\n}\r\n\r\n/** Label/value/prefix/suffix/trend — the established dashboard \"Statistic\"/\"Stat\" pattern (MUI, Ant Design, Mantine). No dashboard business logic. */\r\nexport function Statistic({ label, value, prefix, suffix, precision, trend, delta, loading, className }: StatisticProps) {\r\n return (\r\n <div className={cx(\"d-flex flex-column gap-1\", \"rrc-statistic\", className)}>\r\n <Text size=\"sm\" tone=\"muted\">\r\n {label}\r\n </Text>\r\n\r\n {loading ? (\r\n <Skeleton height=\"1.75rem\" width=\"60%\" />\r\n ) : (\r\n <div className=\"d-flex align-items-baseline gap-1\">\r\n {prefix && (\r\n <Text size=\"lg\" weight=\"semibold\">\r\n {prefix}\r\n </Text>\r\n )}\r\n <Text size=\"xl\" weight=\"bold\">\r\n {formatValue(value, precision)}\r\n </Text>\r\n {suffix && (\r\n <Text size=\"lg\" weight=\"semibold\">\r\n {suffix}\r\n </Text>\r\n )}\r\n </div>\r\n )}\r\n\r\n {!loading && (trend || delta != null) && (\r\n <Text size=\"sm\" tone={trend ? TREND_TONE[trend] : \"muted\"} className=\"d-inline-flex align-items-center gap-1\">\r\n {trend && <Icon name={TREND_ICON[trend]} size=\"sm\" />}\r\n {delta}\r\n </Text>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useId, useRef, type KeyboardEvent, type ReactNode } from \"react\";\nimport {\n SIDEBAR_PRESENTATIONS,\n SIDEBAR_TONES,\n THEME_MODES,\n useOptionalAppearance,\n type SidebarPresentation,\n type SidebarTone,\n type ThemeMode,\n} from \"./Appearance\";\nimport { DEFAULT_COLOR_SCHEME_ID, listColorSchemes, type ColorScheme } from \"./appearanceSchemes\";\nimport { cx } from \"./shared/classNames\";\n\n/**\n * Every visible string is supplied by the caller — this component ships no\n * built-in copy in any language, so it can be dropped into an application that\n * owns its own localization.\n */\nexport interface AppearanceMenuLabels {\n presentation: { title: string; compact: string; grouped: string };\n mode: { title: string; light: string; dark: string; system: string };\n tone: { title: string; light: string; dark: string; auto: string };\n /** `options` maps a registered scheme id to its display name. */\n colorScheme: { title: string; options: Record<string, string> };\n}\n\n/** Each section is hideable on its own. Omitted entries default to visible. */\nexport interface AppearanceMenuSections {\n presentation?: boolean;\n mode?: boolean;\n tone?: boolean;\n colorScheme?: boolean;\n}\n\nexport interface AppearanceMenuProps {\n labels: AppearanceMenuLabels;\n sections?: AppearanceMenuSections;\n className?: string;\n\n /** Controlled values. When given, the provider is not written to for that setting. */\n mode?: ThemeMode;\n onModeChange?: (mode: ThemeMode) => void;\n sidebarPresentation?: SidebarPresentation;\n onSidebarPresentationChange?: (presentation: SidebarPresentation) => void;\n sidebarTone?: SidebarTone;\n onSidebarToneChange?: (tone: SidebarTone) => void;\n colorSchemeId?: string;\n onColorSchemeIdChange?: (id: string) => void;\n\n /** Restrict/order the offered schemes. Defaults to every registered scheme. */\n colorSchemes?: ColorScheme[];\n}\n\ninterface RadioOption<T extends string> {\n value: T;\n label: string;\n /** Extra visual, e.g. a color swatch. Never the only indicator of selection. */\n adornment?: ReactNode;\n}\n\n/**\n * A settings radio group, deliberately not the Base `RadioGroup`.\n *\n * `RadioGroup` is a *form field*: it composes `FieldShell` (form label,\n * help text, validation message, `mb-3` field spacing), takes a form `name`,\n * and its options carry string-only labels. An appearance menu is not a form\n * field and needs `ReactNode` option content for the color swatches, so\n * reusing it would mean fighting its field semantics rather than sharing\n * behavior (doc section 19).\n */\nfunction AppearanceRadioGroup<T extends string>({\n title,\n options,\n value,\n onChange,\n className,\n}: {\n title: string;\n options: RadioOption<T>[];\n value: T;\n onChange: (value: T) => void;\n className?: string;\n}) {\n const titleId = useId();\n const refs = useRef<Array<HTMLButtonElement | null>>([]);\n\n function move(from: number, step: 1 | -1) {\n if (options.length === 0) return;\n const next = (from + step + options.length) % options.length;\n const option = options[next];\n if (!option) return;\n onChange(option.value);\n refs.current[next]?.focus();\n }\n\n /** Roving tabindex with automatic selection, per the WAI-ARIA radiogroup pattern. */\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n const current = options.findIndex((option) => option.value === value);\n if (event.key === \"ArrowDown\" || event.key === \"ArrowRight\") {\n event.preventDefault();\n move(current, 1);\n } else if (event.key === \"ArrowUp\" || event.key === \"ArrowLeft\") {\n event.preventDefault();\n move(current, -1);\n }\n }\n\n return (\n <div className={cx(\"rrc-appearance__section\", className)}>\n <div className=\"rrc-appearance__title\" id={titleId}>\n {title}\n </div>\n <div className=\"rrc-appearance__options\" role=\"radiogroup\" aria-labelledby={titleId} onKeyDown={handleKeyDown}>\n {options.map((option, index) => {\n const selected = option.value === value;\n return (\n <button\n key={option.value}\n ref={(node) => {\n refs.current[index] = node;\n }}\n type=\"button\"\n role=\"radio\"\n aria-checked={selected}\n tabIndex={selected ? 0 : -1}\n className={cx(\"rrc-appearance__option\", selected && \"rrc-appearance__option--selected\")}\n onClick={() => onChange(option.value)}\n >\n {option.adornment}\n <span className=\"rrc-appearance__option-label\">{option.label}</span>\n {/* A shape, not a color — selection stays visible to color-blind users and in forced-colors mode. */}\n <span className=\"rrc-appearance__check\" aria-hidden=\"true\" />\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\n/**\n * Composable appearance selector. Drop it into a `Navbar` slot, a `Popover`,\n * a `Menu` trigger's content, a settings drawer, or any application-owned\n * container.\n *\n * Deliberately NOT a Metronic Layout Builder: it exposes exactly four\n * independent settings and nothing else. It forces no persistence, mutates no\n * global DOM, and makes no decision about who is allowed to change branding —\n * those belong to the application.\n */\nexport function AppearanceMenu({\n labels,\n sections,\n className,\n mode,\n onModeChange,\n sidebarPresentation,\n onSidebarPresentationChange,\n sidebarTone,\n onSidebarToneChange,\n colorSchemeId,\n onColorSchemeIdChange,\n colorSchemes,\n}: AppearanceMenuProps) {\n const appearance = useOptionalAppearance();\n\n const show = {\n presentation: sections?.presentation ?? true,\n mode: sections?.mode ?? true,\n tone: sections?.tone ?? true,\n colorScheme: sections?.colorScheme ?? true,\n };\n\n const currentMode = mode ?? appearance?.mode ?? \"system\";\n const currentPresentation = sidebarPresentation ?? appearance?.sidebarPresentation ?? \"grouped\";\n const currentTone = sidebarTone ?? appearance?.sidebarTone ?? \"auto\";\n const currentSchemeId = colorSchemeId ?? appearance?.colorSchemeId ?? DEFAULT_COLOR_SCHEME_ID;\n\n // Each setting is written independently: changing one never re-writes another.\n const changeMode = (next: ThemeMode) => {\n onModeChange?.(next);\n if (mode === undefined) appearance?.setMode(next);\n };\n const changePresentation = (next: SidebarPresentation) => {\n onSidebarPresentationChange?.(next);\n if (sidebarPresentation === undefined) appearance?.setSidebarPresentation(next);\n };\n const changeTone = (next: SidebarTone) => {\n onSidebarToneChange?.(next);\n if (sidebarTone === undefined) appearance?.setSidebarTone(next);\n };\n const changeScheme = (next: string) => {\n onColorSchemeIdChange?.(next);\n if (colorSchemeId === undefined) appearance?.setColorSchemeId(next);\n };\n\n const schemes = colorSchemes ?? listColorSchemes();\n\n return (\n <div className={cx(\"rrc-appearance\", className)}>\n {show.presentation && (\n <AppearanceRadioGroup<SidebarPresentation>\n title={labels.presentation.title}\n value={currentPresentation}\n onChange={changePresentation}\n options={SIDEBAR_PRESENTATIONS.map((value) => ({ value, label: labels.presentation[value] }))}\n />\n )}\n\n {show.mode && (\n <AppearanceRadioGroup<ThemeMode>\n title={labels.mode.title}\n value={currentMode}\n onChange={changeMode}\n options={THEME_MODES.map((value) => ({ value, label: labels.mode[value] }))}\n />\n )}\n\n {show.tone && (\n <AppearanceRadioGroup<SidebarTone>\n title={labels.tone.title}\n value={currentTone}\n onChange={changeTone}\n options={SIDEBAR_TONES.map((value) => ({ value, label: labels.tone[value] }))}\n />\n )}\n\n {show.colorScheme && (\n <AppearanceRadioGroup<string>\n title={labels.colorScheme.title}\n value={currentSchemeId}\n onChange={changeScheme}\n className=\"rrc-appearance__section--schemes\"\n options={schemes.map((scheme) => ({\n value: scheme.id,\n // Falls back to the registered identifier rather than to invented\n // English copy, so a swatch always has a real accessible name.\n label: labels.colorScheme.options[scheme.id] ?? scheme.id,\n adornment: (\n <span\n className=\"rrc-appearance__swatch\"\n style={{ backgroundColor: scheme.swatch ?? scheme.tokens.primary }}\n aria-hidden=\"true\"\n />\n ),\n }))}\n />\n )}\n </div>\n );\n}\n","export interface HttpRequestOptions {\r\n params?: Record<string, unknown>;\r\n signal?: AbortSignal;\r\n}\r\n\r\nexport interface HttpClient {\r\n get<TResponse>(url: string, options?: HttpRequestOptions): Promise<TResponse>;\r\n}\r\n\r\nexport class HttpError extends Error {\r\n status: number;\r\n statusText: string;\r\n url: string;\r\n\r\n constructor(status: number, statusText: string, url: string) {\r\n super(`HTTP ${status} ${statusText} for ${url}`);\r\n this.name = \"HttpError\";\r\n this.status = status;\r\n this.statusText = statusText;\r\n this.url = url;\r\n }\r\n}\r\n\r\nfunction serializeParams(params?: Record<string, unknown>): string {\r\n if (!params) return \"\";\r\n const searchParams = new URLSearchParams();\r\n for (const [key, rawValue] of Object.entries(params)) {\r\n if (rawValue === undefined || rawValue === null) continue;\r\n searchParams.set(key, String(rawValue));\r\n }\r\n const query = searchParams.toString();\r\n return query ? `?${query}` : \"\";\r\n}\r\n\r\nexport interface CreateHttpClientOptions {\r\n baseUrl?: string;\r\n /** Injectable fetch implementation — used by tests, could also route through a wrapped/instrumented fetch. */\r\n fetcher?: typeof fetch;\r\n /**\r\n * Extension point for cross-cutting concerns the doc explicitly defers\r\n * (authorization, tenant headers, interceptors) without building them now\r\n * (doc section 6: only establish extension points where justified).\r\n */\r\n buildRequestInit?: (url: string, init: RequestInit) => RequestInit;\r\n}\r\n\r\n/**\r\n * The single place Remote Components go through to talk to a backend.\r\n * Base Components never import this (enforced by dependency direction, not\r\n * just convention — Base has no dependency on `remote/*` at all).\r\n */\r\nexport function createHttpClient(options: CreateHttpClientOptions = {}): HttpClient {\r\n const { baseUrl = \"\", fetcher = fetch, buildRequestInit } = options;\r\n\r\n return {\r\n async get<TResponse>(url: string, requestOptions: HttpRequestOptions = {}): Promise<TResponse> {\r\n const fullUrl = `${baseUrl}${url}${serializeParams(requestOptions.params)}`;\r\n let init: RequestInit = { method: \"GET\", signal: requestOptions.signal };\r\n if (buildRequestInit) init = buildRequestInit(fullUrl, init);\r\n\r\n const response = await fetcher(fullUrl, init);\r\n if (!response.ok) {\r\n throw new HttpError(response.status, response.statusText, fullUrl);\r\n }\r\n return (await response.json()) as TResponse;\r\n },\r\n };\r\n}\r\n\r\nexport const defaultHttpClient = createHttpClient();\r\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { defaultHttpClient, type HttpClient } from \"../http/HttpClient\";\r\n\r\nexport type RemoteState = \"idle\" | \"loading\" | \"success\" | \"empty\" | \"error\";\r\n\r\nexport interface UseRemoteDataOptions<TResponse, TItem> {\r\n client?: HttpClient;\r\n /** `null`/`undefined` disables fetching entirely (e.g. RemoteAutoComplete below minSearchLength). */\r\n url: string | null | undefined;\r\n params?: Record<string, unknown>;\r\n mapResponse: (response: TResponse) => TItem[];\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseRemoteDataResult<TItem> {\r\n state: RemoteState;\r\n items: TItem[];\r\n error: Error | null;\r\n reload: () => void;\r\n}\r\n\r\nfunction sortKeys(obj: Record<string, unknown>): Record<string, unknown> {\r\n return Object.keys(obj)\r\n .sort()\r\n .reduce<Record<string, unknown>>((acc, key) => {\r\n acc[key] = obj[key];\r\n return acc;\r\n }, {});\r\n}\r\n\r\n/**\r\n * The one place remote/API data fetching lifecycle logic lives. Every\r\n * Remote Component (RemoteComboBox, RemoteAutoComplete, RemoteDataGrid)\r\n * composes this instead of writing its own fetch effect (doc section 6).\r\n *\r\n * Handles, per doc sections 5/7/8:\r\n * - stable request identity: params are compared by serialized *value*,\r\n * not object reference, so a new `{ ...params }` literal each render\r\n * does not cause an infinite request loop.\r\n * - request cancellation via AbortController.\r\n * - stale-response protection via a monotonically increasing request id,\r\n * which still guards correctness even if abort doesn't win the race.\r\n * - a consistent idle/loading/success/empty/error state model.\r\n */\r\nexport function useRemoteData<TResponse, TItem>({\r\n client = defaultHttpClient,\r\n url,\r\n params,\r\n mapResponse,\r\n enabled = true,\r\n}: UseRemoteDataOptions<TResponse, TItem>): UseRemoteDataResult<TItem> {\r\n const [state, setState] = useState<RemoteState>(\"idle\");\r\n const [items, setItems] = useState<TItem[]>([]);\r\n const [error, setError] = useState<Error | null>(null);\r\n const [reloadToken, setReloadToken] = useState(0);\r\n\r\n const paramsKey = useMemo(() => (params ? JSON.stringify(sortKeys(params)) : \"\"), [params]);\r\n\r\n const latestRequestId = useRef(0);\r\n const mapResponseRef = useRef(mapResponse);\r\n mapResponseRef.current = mapResponse;\r\n\r\n useEffect(() => {\r\n if (!enabled || !url) {\r\n setState(\"idle\");\r\n setItems([]);\r\n setError(null);\r\n return;\r\n }\r\n\r\n const requestId = ++latestRequestId.current;\r\n const controller = new AbortController();\r\n setState(\"loading\");\r\n setError(null);\r\n\r\n client\r\n .get<TResponse>(url, { params, signal: controller.signal })\r\n .then((response) => {\r\n if (requestId !== latestRequestId.current) return;\r\n const mapped = mapResponseRef.current(response);\r\n setItems(mapped);\r\n setState(mapped.length === 0 ? \"empty\" : \"success\");\r\n })\r\n .catch((err: unknown) => {\r\n if (requestId !== latestRequestId.current) return;\r\n if (err instanceof DOMException && err.name === \"AbortError\") return;\r\n setError(err instanceof Error ? err : new Error(String(err)));\r\n setState(\"error\");\r\n });\r\n\r\n return () => {\r\n controller.abort();\r\n };\r\n // paramsKey (not params) is the intentional dependency: it's the stable,\r\n // value-based identity for \"did the request actually change\".\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [client, url, paramsKey, enabled, reloadToken]);\r\n\r\n const reload = useCallback(() => setReloadToken((token) => token + 1), []);\r\n\r\n return { state, items, error, reload };\r\n}\r\n","import { useEffect, useState } from \"react\";\r\n\r\nexport function useDebouncedValue<T>(value: T, delayMs: number): T {\r\n const [debounced, setDebounced] = useState(value);\r\n\r\n useEffect(() => {\r\n const timer = setTimeout(() => setDebounced(value), delayMs);\r\n return () => clearTimeout(timer);\r\n }, [value, delayMs]);\r\n\r\n return debounced;\r\n}\r\n","import type { SelectOption } from \"../base\";\r\n\r\n/**\r\n * Handles the two common response envelopes (bare array, `{ items: [...] }`)\r\n * explicitly (doc section 11). Anything else must be handled via an\r\n * explicit `mapResponse` — no guessing beyond these two conventions.\r\n */\r\nexport function defaultArrayNormalization(response: unknown): unknown[] {\r\n if (Array.isArray(response)) return response;\r\n if (response && typeof response === \"object\" && Array.isArray((response as { items?: unknown }).items)) {\r\n return (response as { items: unknown[] }).items;\r\n }\r\n throw new Error(\r\n \"Unable to normalize remote response into an array. Provide an explicit `mapResponse` for this endpoint's response shape.\"\r\n );\r\n}\r\n\r\nexport function toSelectOption<TValue extends string | number>(\r\n raw: unknown,\r\n valueMember: string,\r\n displayMember: string\r\n): SelectOption<TValue> {\r\n if (raw === null || typeof raw !== \"object\") {\r\n throw new Error(\"Remote item is not an object; cannot read valueMember/displayMember from it.\");\r\n }\r\n const record = raw as Record<string, unknown>;\r\n return {\r\n value: record[valueMember] as TValue,\r\n label: String(record[displayMember] ?? \"\"),\r\n };\r\n}\r\n","import { ComboBox, type ComboBoxProps, type SelectOption } from \"../base\";\r\nimport type { HttpClient } from \"./http/HttpClient\";\r\nimport { useRemoteData } from \"./hooks/useRemoteData\";\r\nimport { defaultArrayNormalization, toSelectOption } from \"./mapping\";\r\n\r\nexport interface RemoteComboBoxProps<TValue extends string | number = string, TResponse = unknown>\r\n extends Omit<ComboBoxProps<TValue>, \"options\" | \"loading\"> {\r\n url: string;\r\n params?: Record<string, unknown>;\r\n /** Key read off each raw remote item to produce the option's `value` (doc section 4). */\r\n valueMember: string;\r\n /** Key read off each raw remote item to produce the option's `label`. */\r\n displayMember: string;\r\n /** Escape hatch for response envelopes beyond bare array / `{ items: [...] }` (doc section 11). */\r\n mapResponse?: (response: TResponse) => unknown[];\r\n client?: HttpClient;\r\n enabled?: boolean;\r\n}\r\n\r\n/**\r\n * Adds remote-loading behavior to Base ComboBox by composing it — this is\r\n * NOT a second independent ComboBox implementation (doc section 20). All\r\n * selection/keyboard/popup UI behavior is Base ComboBox's; this component\r\n * only owns fetch lifecycle + raw-item -> SelectOption mapping.\r\n */\r\nexport function RemoteComboBox<TValue extends string | number = string, TResponse = unknown>({\r\n url,\r\n params,\r\n valueMember,\r\n displayMember,\r\n mapResponse,\r\n client,\r\n enabled,\r\n ...comboBoxProps\r\n}: RemoteComboBoxProps<TValue, TResponse>) {\r\n const { state, items, error } = useRemoteData<TResponse, SelectOption<TValue>>({\r\n client,\r\n url,\r\n params,\r\n enabled,\r\n mapResponse: (response) => {\r\n const rawItems = mapResponse ? mapResponse(response) : defaultArrayNormalization(response);\r\n return rawItems.map((raw) => toSelectOption<TValue>(raw, valueMember, displayMember));\r\n },\r\n });\r\n\r\n // A consumer-supplied `error` (field validation) wins; otherwise fall back\r\n // to the remote fetch error so failures are visible without requiring\r\n // every call site to wire this up by hand.\r\n const resolvedError = comboBoxProps.error ?? (state === \"error\" ? error?.message ?? \"Failed to load options\" : undefined);\r\n\r\n return <ComboBox<TValue> {...comboBoxProps} options={items} loading={state === \"loading\"} error={resolvedError} />;\r\n}\r\n","import { AutoComplete, type AutoCompleteProps, type SelectOption } from \"../base\";\r\nimport { useControllableState } from \"../base/shared/useControllableState\";\r\nimport type { HttpClient } from \"./http/HttpClient\";\r\nimport { useDebouncedValue } from \"./hooks/useDebouncedValue\";\r\nimport { useRemoteData } from \"./hooks/useRemoteData\";\r\nimport { defaultArrayNormalization, toSelectOption } from \"./mapping\";\r\n\r\nexport interface RemoteAutoCompleteProps<TValue extends string | number = string, TResponse = unknown>\r\n extends Omit<AutoCompleteProps<TValue>, \"options\" | \"loading\" | \"filter\"> {\r\n url: string;\r\n params?: Record<string, unknown>;\r\n /** Query-string parameter name the current search text is sent under. */\r\n searchParam: string;\r\n valueMember: string;\r\n displayMember: string;\r\n mapResponse?: (response: TResponse) => unknown[];\r\n minSearchLength?: number;\r\n debounceMs?: number;\r\n client?: HttpClient;\r\n}\r\n\r\n/**\r\n * Adds search input handling (debounce, minimum length, remote loading) to\r\n * Base AutoComplete by composing it. AutoComplete's own local `filter` is\r\n * disabled here (`() => true`) because the server has already filtered by\r\n * `searchParam` — re-filtering client-side would silently drop valid\r\n * server results whose label doesn't literally contain the query text.\r\n */\r\nexport function RemoteAutoComplete<TValue extends string | number = string, TResponse = unknown>({\r\n url,\r\n params,\r\n searchParam,\r\n valueMember,\r\n displayMember,\r\n mapResponse,\r\n minSearchLength = 1,\r\n debounceMs = 300,\r\n client,\r\n inputValue,\r\n onInputValueChange,\r\n ...autoCompleteProps\r\n}: RemoteAutoCompleteProps<TValue, TResponse>) {\r\n const [internalSearchText, setInternalSearchText] = useControllableState<string>({\r\n value: inputValue,\r\n defaultValue: \"\",\r\n onChange: onInputValueChange,\r\n });\r\n\r\n const debouncedSearchText = useDebouncedValue(internalSearchText, debounceMs);\r\n const searchReady = debouncedSearchText.length >= minSearchLength;\r\n\r\n const { state, items, error } = useRemoteData<TResponse, SelectOption<TValue>>({\r\n client,\r\n url,\r\n enabled: searchReady,\r\n params: { ...params, [searchParam]: debouncedSearchText },\r\n mapResponse: (response) => {\r\n const rawItems = mapResponse ? mapResponse(response) : defaultArrayNormalization(response);\r\n return rawItems.map((raw) => toSelectOption<TValue>(raw, valueMember, displayMember));\r\n },\r\n });\r\n\r\n const resolvedError =\r\n autoCompleteProps.error ?? (state === \"error\" ? error?.message ?? \"Failed to load suggestions\" : undefined);\r\n\r\n return (\r\n <AutoComplete<TValue>\r\n {...autoCompleteProps}\r\n options={items}\r\n loading={state === \"loading\"}\r\n error={resolvedError}\r\n inputValue={internalSearchText}\r\n onInputValueChange={setInternalSearchText}\r\n filter={() => true}\r\n />\r\n );\r\n}\r\n","import { useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { DataGrid, type DataGridProps, type DataGridSort } from \"../base\";\r\nimport type { HttpClient } from \"./http/HttpClient\";\r\nimport { useRemoteData } from \"./hooks/useRemoteData\";\r\nimport { defaultArrayNormalization } from \"./mapping\";\r\n\r\nexport interface RemoteDataGridProps<TRow, TResponse = unknown>\r\n extends Omit<\r\n DataGridProps<TRow>,\r\n \"rows\" | \"loading\" | \"error\" | \"page\" | \"pageSize\" | \"totalCount\" | \"onPageChange\" | \"sort\" | \"onSortChange\"\r\n > {\r\n url: string;\r\n /** Additional filter params (e.g. `{ countryId }`) — page/pageSize/sort are managed internally. */\r\n params?: Record<string, unknown>;\r\n mapResponse?: (response: TResponse) => TRow[];\r\n /**\r\n * Extension point: read a total row count out of the raw response, when\r\n * the backend provides one. Strongly recommended — without it, pagination\r\n * falls back to a has-more heuristic (a full page implies \"at least one\r\n * more page exists\") which cannot show an exact page count.\r\n */\r\n getTotalCount?: (response: TResponse) => number | undefined;\r\n pageSize?: number;\r\n client?: HttpClient;\r\n}\r\n\r\n/**\r\n * Adds paging/sorting-against-a-server-endpoint behavior to Base DataGrid\r\n * by composing it. All table rendering, selection, and pagination/sort UI\r\n * remain Base DataGrid's — this component only owns request params\r\n * (page/pageSize/sort/filters) and response mapping (doc section 10).\r\n */\r\nexport function RemoteDataGrid<TRow, TResponse = unknown>({\r\n url,\r\n params,\r\n mapResponse,\r\n getTotalCount,\r\n pageSize = 20,\r\n client,\r\n ...dataGridProps\r\n}: RemoteDataGridProps<TRow, TResponse>) {\r\n const [page, setPage] = useState(1);\r\n const [sort, setSort] = useState<DataGridSort | null>(null);\r\n\r\n const paramsKey = useMemo(() => JSON.stringify(params ?? {}), [params]);\r\n const isFirstRender = useRef(true);\r\n useEffect(() => {\r\n if (isFirstRender.current) {\r\n isFirstRender.current = false;\r\n return;\r\n }\r\n setPage(1);\r\n }, [paramsKey]);\r\n\r\n const requestParams = useMemo(\r\n () => ({\r\n ...params,\r\n page,\r\n pageSize,\r\n ...(sort ? { sortKey: sort.key, sortDirection: sort.direction } : {}),\r\n }),\r\n [params, page, pageSize, sort]\r\n );\r\n\r\n const lastResponseRef = useRef<TResponse | undefined>(undefined);\r\n\r\n const { state, items, error } = useRemoteData<TResponse, TRow>({\r\n client,\r\n url,\r\n params: requestParams,\r\n mapResponse: (response) => {\r\n lastResponseRef.current = response;\r\n return mapResponse ? mapResponse(response) : (defaultArrayNormalization(response) as TRow[]);\r\n },\r\n });\r\n\r\n const explicitTotalCount = lastResponseRef.current !== undefined ? getTotalCount?.(lastResponseRef.current) : undefined;\r\n // Without a real total from the backend, `items.length` alone only describes the\r\n // *current* page and would freeze pagination on page 1 forever (totalPages would\r\n // never exceed 1). Infer \"there's at least one more page\" from a full page coming\r\n // back, the same has-more heuristic APIs without a count endpoint commonly use.\r\n const hasMorePages = items.length >= pageSize && pageSize > 0;\r\n const inferredTotalCount = hasMorePages ? page * pageSize + 1 : (page - 1) * pageSize + items.length;\r\n const totalCount = explicitTotalCount ?? inferredTotalCount;\r\n\r\n return (\r\n <DataGrid<TRow>\r\n {...dataGridProps}\r\n rows={items}\r\n loading={state === \"loading\"}\r\n error={error?.message}\r\n page={page}\r\n pageSize={pageSize}\r\n totalCount={totalCount}\r\n onPageChange={setPage}\r\n sort={sort}\r\n onSortChange={(next) => {\r\n setSort(next);\r\n setPage(1);\r\n }}\r\n />\r\n );\r\n}\r\n","import { Select, type SelectOption, type SelectProps } from \"../base\";\r\nimport type { HttpClient } from \"./http/HttpClient\";\r\nimport { useRemoteData } from \"./hooks/useRemoteData\";\r\nimport { defaultArrayNormalization, toSelectOption } from \"./mapping\";\r\n\r\nexport interface RemoteSelectProps<TValue extends string | number = string, TResponse = unknown>\r\n extends Omit<SelectProps<TValue>, \"options\" | \"loading\"> {\r\n url: string;\r\n params?: Record<string, unknown>;\r\n valueMember: string;\r\n displayMember: string;\r\n mapResponse?: (response: TResponse) => unknown[];\r\n client?: HttpClient;\r\n enabled?: boolean;\r\n}\r\n\r\n/**\r\n * Same reuse pattern as RemoteComboBox: composes Base Select instead of\r\n * reimplementing it (doc section 20). Thin — only fetch lifecycle +\r\n * valueMember/displayMember mapping belong here.\r\n */\r\nexport function RemoteSelect<TValue extends string | number = string, TResponse = unknown>({\r\n url,\r\n params,\r\n valueMember,\r\n displayMember,\r\n mapResponse,\r\n client,\r\n enabled,\r\n ...selectProps\r\n}: RemoteSelectProps<TValue, TResponse>) {\r\n const { state, items, error } = useRemoteData<TResponse, SelectOption<TValue>>({\r\n client,\r\n url,\r\n params,\r\n enabled,\r\n mapResponse: (response) => {\r\n const rawItems = mapResponse ? mapResponse(response) : defaultArrayNormalization(response);\r\n return rawItems.map((raw) => toSelectOption<TValue>(raw, valueMember, displayMember));\r\n },\r\n });\r\n\r\n const resolvedError = selectProps.error ?? (state === \"error\" ? error?.message ?? \"Failed to load options\" : undefined);\r\n\r\n return <Select<TValue> {...selectProps} options={items} loading={state === \"loading\"} error={resolvedError} />;\r\n}\r\n","import { MultiSelect, type MultiSelectProps, type SelectOption } from \"../base\";\r\nimport type { HttpClient } from \"./http/HttpClient\";\r\nimport { useRemoteData } from \"./hooks/useRemoteData\";\r\nimport { defaultArrayNormalization, toSelectOption } from \"./mapping\";\r\n\r\nexport interface RemoteMultiSelectProps<TValue extends string | number = string, TResponse = unknown>\r\n extends Omit<MultiSelectProps<TValue>, \"options\" | \"loading\"> {\r\n url: string;\r\n params?: Record<string, unknown>;\r\n valueMember: string;\r\n displayMember: string;\r\n mapResponse?: (response: TResponse) => unknown[];\r\n client?: HttpClient;\r\n enabled?: boolean;\r\n}\r\n\r\n/** Same reuse pattern as RemoteComboBox/RemoteSelect, composing Base MultiSelect. */\r\nexport function RemoteMultiSelect<TValue extends string | number = string, TResponse = unknown>({\r\n url,\r\n params,\r\n valueMember,\r\n displayMember,\r\n mapResponse,\r\n client,\r\n enabled,\r\n ...multiSelectProps\r\n}: RemoteMultiSelectProps<TValue, TResponse>) {\r\n const { state, items, error } = useRemoteData<TResponse, SelectOption<TValue>>({\r\n client,\r\n url,\r\n params,\r\n enabled,\r\n mapResponse: (response) => {\r\n const rawItems = mapResponse ? mapResponse(response) : defaultArrayNormalization(response);\r\n return rawItems.map((raw) => toSelectOption<TValue>(raw, valueMember, displayMember));\r\n },\r\n });\r\n\r\n const resolvedError =\r\n multiSelectProps.error ?? (state === \"error\" ? error?.message ?? \"Failed to load options\" : undefined);\r\n\r\n return <MultiSelect<TValue> {...multiSelectProps} options={items} loading={state === \"loading\"} error={resolvedError} />;\r\n}\r\n","import type { ReactElement } from \"react\";\r\nimport type { SmartFieldMetadata } from \"./types\";\r\nimport type { SmartRuntimeContext } from \"./runtime\";\r\n\r\nexport type SmartResolver<M extends SmartFieldMetadata = SmartFieldMetadata> = (\r\n metadata: M,\r\n ctx: SmartRuntimeContext\r\n) => ReactElement | null;\r\n\r\nexport interface SmartComponentRegistry {\r\n register<M extends SmartFieldMetadata>(component: M[\"component\"], resolver: SmartResolver<M>): void;\r\n resolve(metadata: SmartFieldMetadata, ctx: SmartRuntimeContext): ReactElement | null;\r\n has(component: string): boolean;\r\n}\r\n\r\n/**\r\n * Keyed by the `component` discriminant — not a switch, not a plugin\r\n * framework (doc §04). Type safety lives at the register()/resolve()\r\n * generic boundary; internal storage type-erases to `SmartResolver`, the\r\n * same escape hatch any typed registry needs, isolated to this one\r\n * function. No component type is privileged: Phase 2's built-in Input/\r\n * ComboBox/DatePicker/DataGrid resolvers will register through this exact\r\n * same call an application uses for a custom component.\r\n *\r\n * An unresolved `component` value never falls back to an unrelated\r\n * component (doc §12) — resolve() returns null and warns once per unknown\r\n * component name, so a field silently disappears from the form instead of\r\n * rendering the wrong thing.\r\n */\r\nexport function createSmartComponentRegistry(): SmartComponentRegistry {\r\n const resolvers = new Map<string, SmartResolver>();\r\n const warned = new Set<string>();\r\n\r\n return {\r\n register(component, resolver) {\r\n resolvers.set(component, resolver as SmartResolver);\r\n },\r\n resolve(metadata, ctx) {\r\n const resolver = resolvers.get(metadata.component);\r\n if (!resolver) {\r\n if (!warned.has(metadata.component)) {\r\n warned.add(metadata.component);\r\n console.warn(\r\n `Smart: no resolver registered for component \"${metadata.component}\" (field \"${metadata.name}\"). Skipping.`\r\n );\r\n }\r\n return null;\r\n }\r\n return resolver(metadata, ctx);\r\n },\r\n has(component) {\r\n return resolvers.has(component);\r\n },\r\n };\r\n}\r\n","import type { HttpClient } from \"../remote\";\r\n\r\nexport interface SmartDataSourceDefinition {\r\n url: string;\r\n /** Defaults to Remote's own defaultHttpClient when omitted, same as RemoteComboBox etc. already do. */\r\n client?: HttpClient;\r\n}\r\n\r\nexport interface SmartDataSourceRegistry {\r\n register(id: string, definition: SmartDataSourceDefinition): void;\r\n resolve(id: string): SmartDataSourceDefinition | undefined;\r\n}\r\n\r\n/**\r\n * Backs the id-based indirection decided in doc §09/§18 (decision 2):\r\n * metadata never carries a raw URL, only an id an application registers\r\n * once. The application owns environment/hostname/auth wiring in one\r\n * place — Smart never needs to know it exists.\r\n */\r\nexport function createSmartDataSourceRegistry(initial?: Record<string, SmartDataSourceDefinition>): SmartDataSourceRegistry {\r\n const definitions = new Map<string, SmartDataSourceDefinition>(Object.entries(initial ?? {}));\r\n\r\n return {\r\n register(id, definition) {\r\n definitions.set(id, definition);\r\n },\r\n resolve(id) {\r\n return definitions.get(id);\r\n },\r\n };\r\n}\r\n","export type SmartActionHandler = () => void;\r\n\r\nexport interface SmartActionRegistry {\r\n register(id: string, handler: SmartActionHandler): void;\r\n resolve(id: string): SmartActionHandler | undefined;\r\n}\r\n\r\n/**\r\n * Metadata carries an action id, never a function (doc §08/§11 — no\r\n * executable code from the server, ever). The application registers the\r\n * real handler once; Smart only looks it up by id.\r\n */\r\nexport function createSmartActionRegistry(): SmartActionRegistry {\r\n const handlers = new Map<string, SmartActionHandler>();\r\n\r\n return {\r\n register(id, handler) {\r\n handlers.set(id, handler);\r\n },\r\n resolve(id) {\r\n return handlers.get(id);\r\n },\r\n };\r\n}\r\n","import type { SmartDataSourceRef, SmartFieldMetadata, SmartFormMetadata, SmartParamValue } from \"./types\";\r\n\r\nexport interface UseSmartFieldOptions {\r\n values: Record<string, unknown>;\r\n /** Absent = fall back to metadata's raw `label`/`helpText`/etc. strings. */\r\n translate?: (key: string) => string;\r\n}\r\n\r\nexport interface ResolvedSmartField<M extends SmartFieldMetadata = SmartFieldMetadata> {\r\n metadata: M;\r\n visible: boolean;\r\n readOnly: boolean;\r\n disabled: boolean;\r\n required: boolean;\r\n label?: string;\r\n placeholder?: string;\r\n helpText?: string;\r\n validationMessage?: string;\r\n /**\r\n * Only present for metadata carrying a `dataSource` (ComboBox/DataGrid).\r\n * Resolved from `dataSource.params` + the current `values` snapshot —\r\n * ready to pass straight through as a Remote component's `params` prop\r\n * (doc §06). Field-name lookups that miss simply resolve to `undefined`,\r\n * same as reading a missing key off any plain object.\r\n */\r\n params?: Record<string, unknown>;\r\n}\r\n\r\nfunction hasDataSource(metadata: SmartFieldMetadata): metadata is Extract<SmartFieldMetadata, { dataSource: SmartDataSourceRef }> {\r\n return \"dataSource\" in metadata;\r\n}\r\n\r\nfunction resolveParams(paramDefs: Record<string, SmartParamValue> | undefined, values: Record<string, unknown>): Record<string, unknown> | undefined {\r\n if (!paramDefs) return undefined;\r\n const resolved: Record<string, unknown> = {};\r\n for (const [key, def] of Object.entries(paramDefs)) {\r\n resolved[key] = def.kind === \"static\" ? def.value : values[def.field];\r\n }\r\n return resolved;\r\n}\r\n\r\nfunction resolveText(raw: string | undefined, key: string | undefined, translate: ((key: string) => string) | undefined): string | undefined {\r\n if (key && translate) return translate(key);\r\n return raw;\r\n}\r\n\r\n/**\r\n * Resolves one already-known metadata object. Pure function of its\r\n * arguments — no React state, no effect, no fetch. Exported separately from\r\n * `useSmartField` so a component-registry resolver that already holds a\r\n * specific field's metadata (as `SmartResolver` hands it) can reuse this\r\n * exact translate/params logic instead of re-deriving it (doc §04's\r\n * resolvers and `useSmartField`'s by-name lookup are two entry points onto\r\n * the same resolution, not two implementations).\r\n */\r\nexport function resolveSmartFieldMetadata<M extends SmartFieldMetadata = SmartFieldMetadata>(\r\n metadata: M,\r\n options: UseSmartFieldOptions\r\n): ResolvedSmartField<M> {\r\n const { values, translate } = options;\r\n\r\n return {\r\n metadata,\r\n visible: metadata.visible ?? true,\r\n readOnly: metadata.readOnly ?? false,\r\n disabled: metadata.disabled ?? false,\r\n required: metadata.required ?? false,\r\n label: resolveText(metadata.label, metadata.labelKey, translate),\r\n placeholder: metadata.placeholder,\r\n helpText: metadata.helpText,\r\n validationMessage: resolveText(metadata.validationMessage, metadata.validationMessageKey, translate),\r\n params: hasDataSource(metadata) ? resolveParams(metadata.dataSource.params, values) : undefined,\r\n };\r\n}\r\n\r\n/**\r\n * The headless engine every Smart component composes (doc §05/§18 —\r\n * Smart Runtime owns no canonical state). Looks a field up by name in\r\n * `formMetadata` and resolves it via `resolveSmartFieldMetadata`. Anything\r\n * not present in the metadata map is left alone: a field with no matching\r\n * metadata entry returns `undefined`, meaning \"not driven by metadata,\" not\r\n * \"hidden.\"\r\n *\r\n * A future SmartField component will call this directly, the same way\r\n * RemoteComboBox composes useRemoteData instead of writing its own effect.\r\n */\r\nexport function useSmartField<M extends SmartFieldMetadata = SmartFieldMetadata>(\r\n name: string,\r\n formMetadata: SmartFormMetadata | undefined,\r\n options: UseSmartFieldOptions\r\n): ResolvedSmartField<M> | undefined {\r\n const metadata = formMetadata?.fields.find((field) => field.name === name) as M | undefined;\r\n if (!metadata) return undefined;\r\n\r\n return resolveSmartFieldMetadata(metadata, options);\r\n}\r\n","import { useEffect, useRef } from \"react\";\r\n\r\nconst NO_DEPENDENCIES: readonly string[] = [];\r\n\r\nfunction pick(values: Record<string, unknown>, keys: readonly string[]): Record<string, unknown> {\r\n const result: Record<string, unknown> = {};\r\n for (const key of keys) result[key] = values[key];\r\n return result;\r\n}\r\n\r\n/**\r\n * Mechanical dependency tracking only (doc §06/§10): watches the fields a\r\n * piece of metadata declared via `dependsOn` and calls\r\n * `onMetadataRefreshNeeded` once per field whose value actually changed\r\n * since the last render. It never evaluates *why* a change matters — that\r\n * stays server-owned; this hook only decides *when to ask again*.\r\n *\r\n * Uses the same \"stable value-based identity\" strategy as useRemoteData's\r\n * `paramsKey` (serialize, compare by value, not by object/array reference)\r\n * to avoid the exact infinite-loop failure mode the original architecture\r\n * doc warns against for Remote's own params.\r\n */\r\nexport function useSmartDependencies(\r\n dependsOn: string[] | undefined,\r\n values: Record<string, unknown>,\r\n onMetadataRefreshNeeded?: (changedField: string) => void\r\n): void {\r\n const watched = dependsOn ?? NO_DEPENDENCIES;\r\n const watchedSnapshot = pick(values, watched);\r\n const watchedKey = watched.length === 0 ? \"\" : JSON.stringify(watchedSnapshot);\r\n\r\n const previousRef = useRef<{ key: string; snapshot: Record<string, unknown> } | null>(null);\r\n const onRefreshRef = useRef(onMetadataRefreshNeeded);\r\n onRefreshRef.current = onMetadataRefreshNeeded;\r\n\r\n useEffect(() => {\r\n if (watched.length === 0) return;\r\n const previous = previousRef.current;\r\n\r\n if (previous && previous.key !== watchedKey) {\r\n for (const field of watched) {\r\n if (!Object.is(previous.snapshot[field], watchedSnapshot[field])) {\r\n onRefreshRef.current?.(field);\r\n }\r\n }\r\n }\r\n\r\n previousRef.current = { key: watchedKey, snapshot: watchedSnapshot };\r\n // watchedKey (not watched/values) is the intentional dependency — same\r\n // pattern as useRemoteData's paramsKey.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [watchedKey]);\r\n}\r\n","import type { SmartActionRegistry, SmartActionHandler } from \"./actionRegistry\";\r\nimport type { SmartActionMetadata, SmartFormMetadata } from \"./types\";\r\n\r\nexport interface UseSmartActionOptions {\r\n actions: SmartActionRegistry;\r\n /** Absent = fall back to metadata's raw `label` string (doc §07). */\r\n translate?: (key: string) => string;\r\n}\r\n\r\nexport interface ResolvedSmartAction {\r\n metadata: SmartActionMetadata;\r\n visible: boolean;\r\n /**\r\n * `metadata.enabled` ANDed with \"a handler actually exists\" — metadata\r\n * saying `enabled: true` cannot make an action clickable if the\r\n * application never registered a handler for its id (doc §12 fail-safe:\r\n * an unregistered action renders disabled, never a no-op that looks\r\n * clickable).\r\n */\r\n enabled: boolean;\r\n label?: string;\r\n handler?: SmartActionHandler;\r\n}\r\n\r\n/**\r\n * Resolves one already-known action's metadata. Pure function, mirrors\r\n * `resolveSmartFieldMetadata` — action metadata carries an id, never a\r\n * function; the real handler comes from the application-owned\r\n * `SmartActionRegistry` (doc §08/§16), looked up here by that id.\r\n */\r\nexport function resolveSmartActionMetadata(metadata: SmartActionMetadata, options: UseSmartActionOptions): ResolvedSmartAction {\r\n const { actions, translate } = options;\r\n const handler = actions.resolve(metadata.id);\r\n\r\n return {\r\n metadata,\r\n visible: metadata.visible ?? true,\r\n enabled: (metadata.enabled ?? true) && Boolean(handler),\r\n label: metadata.labelKey && translate ? translate(metadata.labelKey) : metadata.label,\r\n handler,\r\n };\r\n}\r\n\r\n/**\r\n * Looks an action up by id in `formMetadata.actions` and resolves it via\r\n * `resolveSmartActionMetadata` — the action-side counterpart of\r\n * `useSmartField`. Returns `undefined` when no action with that id is\r\n * declared, the same \"not present = left alone\" convention `useSmartField`\r\n * uses for fields.\r\n */\r\nexport function useSmartAction(id: string, formMetadata: SmartFormMetadata | undefined, options: UseSmartActionOptions): ResolvedSmartAction | undefined {\r\n const metadata = formMetadata?.actions?.find((action) => action.id === id);\r\n if (!metadata) return undefined;\r\n\r\n return resolveSmartActionMetadata(metadata, options);\r\n}\r\n","import { RemoteComboBox } from \"../../remote\";\r\nimport { resolveSmartFieldMetadata } from \"../useSmartField\";\r\nimport type { SmartResolver } from \"../componentRegistry\";\r\nimport type { ComboBoxMetadata } from \"../types\";\r\n\r\n/**\r\n * Composes RemoteComboBox, not ComboBox directly (doc §04 — Base vs. Remote\r\n * is inferred from the metadata shape: ComboBoxMetadata always carries a\r\n * `dataSource`, so this field is always remote-backed). RemoteComboBox in\r\n * turn composes Base ComboBox, so no selection/keyboard/popup behavior is\r\n * duplicated anywhere in this chain.\r\n */\r\nexport const comboBoxResolver: SmartResolver<ComboBoxMetadata> = (metadata, ctx) => {\r\n const resolved = resolveSmartFieldMetadata(metadata, { values: ctx.values, translate: ctx.translate });\r\n if (!resolved.visible) return null;\r\n\r\n const dataSourceDef = ctx.dataSources.resolve(metadata.dataSource.id);\r\n if (!dataSourceDef) {\r\n console.warn(`Smart: no data source registered for id \"${metadata.dataSource.id}\" (field \"${metadata.name}\"). Skipping.`);\r\n return null;\r\n }\r\n\r\n return (\r\n <RemoteComboBox\r\n label={resolved.label}\r\n url={dataSourceDef.url}\r\n client={dataSourceDef.client}\r\n params={resolved.params}\r\n valueMember={metadata.valueMember}\r\n displayMember={metadata.displayMember}\r\n required={resolved.required}\r\n readOnly={resolved.readOnly}\r\n disabled={resolved.disabled}\r\n helpText={resolved.helpText}\r\n error={resolved.validationMessage}\r\n value={(ctx.values[metadata.name] as string | number) ?? null}\r\n onChange={(value) => ctx.onFieldChange(metadata.name, value)}\r\n />\r\n );\r\n};\r\n","import type { DataGridColumn } from \"../../base\";\r\nimport { RemoteDataGrid } from \"../../remote\";\r\nimport { resolveSmartFieldMetadata } from \"../useSmartField\";\r\nimport type { SmartResolver } from \"../componentRegistry\";\r\nimport type { DataGridMetadata, SmartDataGridColumn } from \"../types\";\r\n\r\ntype SmartRow = Record<string, unknown>;\r\n\r\ntype Translate = (key: string) => string;\r\n\r\n/**\r\n * `format` is a closed enum resolved onto Base DataGrid's own\r\n * `dataGridFormatters` (text/date/currency/boolean) — Smart requests a\r\n * formatter, it does not maintain a second rendering system for it (doc\r\n * §10/§24). Add a new format to Base's `DataGridFormat`, not a `render`\r\n * field on the metadata.\r\n *\r\n * `boolean` is the one case Smart still touches directly, because it's a\r\n * localization concern Base can't own: with a translate function supplied,\r\n * the reserved catalog keys below are authoritative, same as label/header\r\n * resolution elsewhere in Smart — no silent English fallback once a\r\n * catalog exists. Without translate, it still falls back to Base's own\r\n * plain \"Yes\"/\"No\", so no behavior is duplicated, only localized.\r\n */\r\nfunction resolveColumn(column: SmartDataGridColumn, translate: Translate | undefined): DataGridColumn<SmartRow> | null {\r\n if (column.visible === false) return null;\r\n const header = column.headerKey && translate ? translate(column.headerKey) : column.header ?? column.key;\r\n const isLocalizedBoolean = column.format === \"boolean\" && Boolean(translate);\r\n\r\n return {\r\n key: column.key,\r\n header,\r\n sortable: column.sortable,\r\n format: isLocalizedBoolean ? undefined : column.format,\r\n formatter: isLocalizedBoolean\r\n ? (value) => translate!(value ? \"smart.boolean.true\" : \"smart.boolean.false\")\r\n : undefined,\r\n };\r\n}\r\n\r\n/**\r\n * Composes RemoteDataGrid, not Base DataGrid directly (doc §04 — inferred\r\n * from `dataSource` the same way ComboBoxMetadata is). Column metadata is\r\n * translated into a real `DataGridColumn<TRow>[]` and handed straight to\r\n * the existing grid — no second grid engine, no filtering/grouping DSL\r\n * (doc §10, matching the original library's own DataGrid scope\r\n * restraint).\r\n */\r\nexport const dataGridResolver: SmartResolver<DataGridMetadata> = (metadata, ctx) => {\r\n const resolved = resolveSmartFieldMetadata(metadata, { values: ctx.values, translate: ctx.translate });\r\n if (!resolved.visible) return null;\r\n\r\n const dataSourceDef = ctx.dataSources.resolve(metadata.dataSource.id);\r\n if (!dataSourceDef) {\r\n console.warn(`Smart: no data source registered for id \"${metadata.dataSource.id}\" (field \"${metadata.name}\"). Skipping.`);\r\n return null;\r\n }\r\n\r\n const columns = metadata.columns\r\n .map((column) => resolveColumn(column, ctx.translate))\r\n .filter((column): column is DataGridColumn<SmartRow> => column !== null);\r\n\r\n const totalCountField = metadata.totalCountField;\r\n const getTotalCount = totalCountField\r\n ? (response: unknown) => {\r\n const value = (response as Record<string, unknown> | null)?.[totalCountField];\r\n return typeof value === \"number\" ? value : undefined;\r\n }\r\n : undefined;\r\n\r\n return (\r\n <RemoteDataGrid<SmartRow>\r\n url={dataSourceDef.url}\r\n client={dataSourceDef.client}\r\n params={resolved.params}\r\n columns={columns}\r\n rowKey={(row) => row[metadata.rowKey] as string | number}\r\n getTotalCount={getTotalCount}\r\n />\r\n );\r\n};\r\n","import { DatePicker } from \"../../base\";\r\nimport { resolveSmartFieldMetadata } from \"../useSmartField\";\r\nimport type { SmartResolver } from \"../componentRegistry\";\r\nimport type { DatePickerMetadata } from \"../types\";\r\n\r\n/**\r\n * `minDate`/`maxDate` are ISO strings in metadata (plain JSON, doc §03 —\r\n * declarative only) but Base DatePicker's `min`/`max` are `Date` objects;\r\n * this is the one place that conversion happens. `values[metadata.name]`\r\n * is expected to already hold a `Date | null`, the same native type\r\n * DatePicker itself uses — Smart's `values` bag stores each field in its\r\n * Base component's own value shape, never a serialized form.\r\n */\r\nfunction parseIsoDate(value: string | undefined): Date | undefined {\r\n if (!value) return undefined;\r\n const date = new Date(value);\r\n return Number.isNaN(date.getTime()) ? undefined : date;\r\n}\r\n\r\nexport const datePickerResolver: SmartResolver<DatePickerMetadata> = (metadata, ctx) => {\r\n const resolved = resolveSmartFieldMetadata(metadata, { values: ctx.values, translate: ctx.translate });\r\n if (!resolved.visible) return null;\r\n\r\n return (\r\n <DatePicker\r\n label={resolved.label}\r\n required={resolved.required}\r\n readOnly={resolved.readOnly}\r\n disabled={resolved.disabled}\r\n helpText={resolved.helpText}\r\n error={resolved.validationMessage}\r\n min={parseIsoDate(metadata.minDate)}\r\n max={parseIsoDate(metadata.maxDate)}\r\n value={(ctx.values[metadata.name] as Date | null) ?? null}\r\n onChange={(value) => ctx.onFieldChange(metadata.name, value)}\r\n />\r\n );\r\n};\r\n","import { Input } from \"../../base\";\r\nimport { resolveSmartFieldMetadata } from \"../useSmartField\";\r\nimport type { SmartResolver } from \"../componentRegistry\";\r\nimport type { InputMetadata } from \"../types\";\r\n\r\n/**\r\n * Composes Base Input (doc §03/§20 — reuse, not a second text-field\r\n * implementation). The only thing this file owns is translating resolved\r\n * metadata into Input's existing prop contract.\r\n */\r\nexport const inputResolver: SmartResolver<InputMetadata> = (metadata, ctx) => {\r\n const resolved = resolveSmartFieldMetadata(metadata, { values: ctx.values, translate: ctx.translate });\r\n if (!resolved.visible) return null;\r\n\r\n return (\r\n <Input\r\n label={resolved.label}\r\n required={resolved.required}\r\n readOnly={resolved.readOnly}\r\n disabled={resolved.disabled}\r\n helpText={resolved.helpText}\r\n placeholder={resolved.placeholder}\r\n error={resolved.validationMessage}\r\n maxLength={metadata.maxLength}\r\n value={(ctx.values[metadata.name] as string) ?? \"\"}\r\n onChange={(value) => ctx.onFieldChange(metadata.name, value)}\r\n />\r\n );\r\n};\r\n","import type { SmartComponentRegistry } from \"../componentRegistry\";\r\nimport { comboBoxResolver } from \"./comboBoxResolver\";\r\nimport { dataGridResolver } from \"./dataGridResolver\";\r\nimport { datePickerResolver } from \"./datePickerResolver\";\r\nimport { inputResolver } from \"./inputResolver\";\r\n\r\nexport { comboBoxResolver, dataGridResolver, datePickerResolver, inputResolver };\r\n\r\n/**\r\n * Registers Input/ComboBox/DatePicker/DataGrid through the exact same\r\n * `register()` call an application uses for a custom component (doc §04 —\r\n * no privileged core; a custom \"PatientSelector\" resolver is registered\r\n * the same way).\r\n */\r\nexport function registerBuiltInResolvers(registry: SmartComponentRegistry): void {\r\n registry.register(\"Input\", inputResolver);\r\n registry.register(\"ComboBox\", comboBoxResolver);\r\n registry.register(\"DatePicker\", datePickerResolver);\r\n registry.register(\"DataGrid\", dataGridResolver);\r\n}\r\n","import type { ReactElement } from \"react\";\r\nimport type { SmartRuntimeContext } from \"./runtime\";\r\nimport type { SmartFieldMetadata } from \"./types\";\r\nimport { useSmartDependencies } from \"./useSmartDependencies\";\r\n\r\nexport interface SmartFieldProps {\r\n metadata: SmartFieldMetadata;\r\n ctx: SmartRuntimeContext;\r\n}\r\n\r\n/**\r\n * Given one field's metadata, resolves it into whatever Base/Remote\r\n * component its `component` discriminant maps to (doc §09/§14) — it owns\r\n * no UI of its own, only delegates to `ctx.registry`.\r\n *\r\n * Also wires the mechanical dependency tracking every metadata-driven\r\n * field needs (doc §06): a consuming screen no longer calls\r\n * useSmartDependencies by hand per field, SmartField does it here and\r\n * reports which field needed the refresh, not just which value changed.\r\n */\r\nexport function SmartField({ metadata, ctx }: SmartFieldProps): ReactElement | null {\r\n const notifyRefresh = ctx.onMetadataRefreshNeeded;\r\n useSmartDependencies(\r\n metadata.dependsOn,\r\n ctx.values,\r\n notifyRefresh ? (changedField) => notifyRefresh(metadata.name, changedField) : undefined\r\n );\r\n\r\n if (metadata.visible === false) return null;\r\n return ctx.registry.resolve(metadata, ctx);\r\n}\r\n","import { Alert } from \"../base\";\r\nimport { SmartField } from \"./SmartField\";\r\nimport type { SmartRuntimeContext } from \"./runtime\";\r\nimport type { SmartFormMetadata } from \"./types\";\r\n\r\nexport interface SmartFormProps {\r\n metadata: SmartFormMetadata;\r\n ctx: SmartRuntimeContext;\r\n}\r\n\r\nconst SUPPORTED_SCHEMA_MAJOR = 1;\r\n\r\nfunction isSupportedSchemaVersion(version: string): boolean {\r\n const major = Number(version.split(\".\")[0]);\r\n return Number.isFinite(major) && major === SUPPORTED_SCHEMA_MAJOR;\r\n}\r\n\r\n/**\r\n * A thin iteration helper over SmartField (doc §09/§15/§18 decision 4) —\r\n * it owns no field values, evaluates no business rule, and decides no\r\n * layout. Its only two responsibilities: fail the whole form closed on an\r\n * unsupported schema version instead of rendering a partially-understood\r\n * form (doc §12, reusing Alert rather than a bespoke error UI), and map\r\n * each field's metadata to a SmartField.\r\n *\r\n * A SmartField used standalone (outside SmartForm) is responsible for its\r\n * own schemaVersion check — this component is the only place that check\r\n * happens automatically.\r\n */\r\nexport function SmartForm({ metadata, ctx }: SmartFormProps) {\r\n if (!isSupportedSchemaVersion(metadata.schemaVersion)) {\r\n return (\r\n <Alert variant=\"danger\">\r\n Unsupported form schema version "{metadata.schemaVersion}" — this app understands schema version {SUPPORTED_SCHEMA_MAJOR}.x.\r\n </Alert>\r\n );\r\n }\r\n\r\n return (\r\n <>\r\n {metadata.fields.map((field) => (\r\n <SmartField key={field.name} metadata={field} ctx={ctx} />\r\n ))}\r\n </>\r\n );\r\n}\r\n","import { Button } from \"../base\";\r\nimport { resolveSmartActionMetadata } from \"./useSmartAction\";\r\nimport type { SmartRuntimeContext } from \"./runtime\";\r\nimport type { SmartActionMetadata } from \"./types\";\r\n\r\nexport interface SmartActionProps {\r\n metadata: SmartActionMetadata;\r\n ctx: Pick<SmartRuntimeContext, \"actions\" | \"translate\">;\r\n}\r\n\r\n/**\r\n * Composes Base Button, not a second button implementation (doc §16/§20) —\r\n * the only component-shaped thing action metadata currently resolves to.\r\n * Unlike field metadata, an action's `component: \"Button\"` never needs a\r\n * registry lookup: there is exactly one action UI shape, so there is\r\n * nothing to resolve between.\r\n */\r\nexport function SmartAction({ metadata, ctx }: SmartActionProps) {\r\n const resolved = resolveSmartActionMetadata(metadata, ctx);\r\n if (!resolved.visible) return null;\r\n\r\n return (\r\n <Button disabled={!resolved.enabled} onClick={() => resolved.handler?.()}>\r\n {resolved.label ?? metadata.id}\r\n </Button>\r\n );\r\n}\r\n","import { SmartAction } from \"./SmartAction\";\r\nimport type { SmartRuntimeContext } from \"./runtime\";\r\nimport type { SmartFormMetadata } from \"./types\";\r\n\r\nexport interface SmartActionsProps {\r\n metadata: SmartFormMetadata;\r\n ctx: Pick<SmartRuntimeContext, \"actions\" | \"translate\">;\r\n}\r\n\r\n/**\r\n * A thin iteration helper over SmartAction — the action-side counterpart\r\n * of SmartForm (doc §09/§15). Maps `metadata.actions` to SmartActions and\r\n * nothing else: no layout, no spacing, no handler logic of its own. The\r\n * consuming screen wraps this in whatever layout (Stack, a form footer,\r\n * a toolbar) it needs.\r\n */\r\nexport function SmartActions({ metadata, ctx }: SmartActionsProps) {\r\n if (!metadata.actions || metadata.actions.length === 0) return null;\r\n\r\n return (\r\n <>\r\n {metadata.actions.map((action) => (\r\n <SmartAction key={action.id} metadata={action} ctx={ctx} />\r\n ))}\r\n </>\r\n );\r\n}\r\n"],"names":["cx","values","Label","htmlFor","required","className","children","jsxs","jsx","ValidationMessage","error","helpText","FieldShell","id","label","useControllableState","value","defaultValue","onChange","isControlled","isControlledRef","useRef","internalValue","setInternalValue","useState","currentValue","setValue","useCallback","next","Input","props","name","disabled","readOnly","placeholder","onBlur","type","maxLength","autoFocus","inputProps","endAdornment","generatedId","useId","fieldId","control","event","TextArea","rows","NumberInput","min","max","step","rest","raw","parsed","PasswordInput","visible","setVisible","prev","FileInput","accept","multiple","BooleanFieldControl","wrapperClassName","role","checked","CheckBox","setChecked","Switch","RadioButton","RadioGroup","options","inline","groupName","option","Select","loading","matched","useEscapeKey","active","onEscape","useEffect","handleKeyDown","Popup","open","onClose","anchorRef","popupRef","handlePointerDown","target","_a","_b","useListNavigation","itemCount","isOpen","onSelect","activeIndex","setActiveIndex","MultiSelect","defaultValues","emptyText","currentValues","setValues","setOpen","selectedSet","close","toggleIndex","index","v","summary","toDateInputValue","date","year","month","day","fromDateInputValue","parts","DatePicker","toTimeInputValue","hours","minutes","fromTimeInputValue","TimePicker","combine","datePart","timePart","time","DateTimePicker","ComboBox","selectedOption","selectIndex","defaultFilter","query","AutoComplete","inputValue","onInputValueChange","filter","internalText","setInternalText","matchFilter","filteredOptions","text","FormField","Modal","title","footer","Fragment","getPageList","current","total","siblingCount","pages","start","end","page","Pagination","currentPage","pageSize","totalItems","onPageChange","totalPages","dataGridFormatters","amount","nextSortDirection","key","columnKeyOf","column","columnValueOf","row","accessor","renderCell","alignClass","align","DataGrid","columns","rowKey","selectedRowKeys","onSelectionChange","sort","onSortChange","totalCount","selectable","paginated","toggleAll","toggleRow","Spinner","size","variant","Button","onClick","isDisabled","Alert","dismissible","onDismiss","ToastContext","createContext","DEFAULT_DURATION","ToastProvider","toasts","setToasts","nextId","timers","activeTimers","dismiss","timer","toast","show","message","duration","api","useMemo","useToast","context","useContext","ConfirmContext","ConfirmProvider","pending","setPending","confirm","resolve","settle","result","useConfirm","Badge","appearance","pill","SIZE_EM","Icon","navClass","SIZE_CLASS","Tabs","items","activeKey","defaultActiveKey","orientation","stretch","currentKey","setKey","activeItem","item","isButtonVariant","isVertical","tabRefs","activate","focus","findEnabled","from","i","currentIndex","nextKey","prevKey","first","tabList","buttonContent","button","node","panel","Accordion","openKeys","defaultOpenKeys","currentOpenKeys","setOpenKeys","openSet","toggle","k","Tooltip","content","placement","tooltipId","Popover","Skeleton","width","height","circle","Stack","direction","gap","justify","wrap","SIZE_REM","WEIGHT_CLASS","TONE_CLASS","Text","as","weight","tone","truncate","Component","DefaultHeader","subtitle","icon","avatar","actions","Card","header","resolvedHeader","Divider","vertical","Container","fluid","Row","Col","span","sm","md","lg","xl","Breadcrumb","isLast","isInteractive","Menu","Stepper","steps","currentStep","status","getInitials","last","DIMENSION","Avatar","src","dimension","Tag","onRemove","Slider","Rating","_","n","ProgressBar","clamped","Navbar","brand","COLOR_SCHEME_TOKEN_KEYS","isValidColorScheme","candidate","tokens","createColorScheme","seed","primary","primaryActive","primaryLight","primaryInverse","primaryRgb","swatch","BUILT_IN_SCHEMES","DEFAULT_COLOR_SCHEME_ID","registry","scheme","registerColorScheme","getColorScheme","listColorSchemes","resolveColorScheme","colorSchemeCssVariables","t","THEME_MODES","SIDEBAR_PRESENTATIONS","SIDEBAR_TONES","AppearanceContext","isThemeMode","isSidebarPresentation","isSidebarTone","readStoredSettings","storage","source","settings","AppearanceProvider","mode","defaultMode","onModeChange","sidebarPresentation","defaultSidebarPresentation","onSidebarPresentationChange","sidebarTone","defaultSidebarTone","onSidebarToneChange","colorSchemeId","defaultColorSchemeId","onColorSchemeIdChange","storageKey","applyTo","themeAttribute","currentMode","setMode","currentPresentation","setSidebarPresentation","currentTone","setSidebarTone","currentSchemeId","setColorSchemeId","systemTheme","setSystemTheme","handleChange","persistenceEnabled","hydrated","setHydrated","controlledRef","settersRef","stored","controlled","setters","resolvedTheme","colorScheme","cssVariables","previousTheme","appearanceProps","useAppearance","useOptionalAppearance","createAppearanceInitScript","literal","attribute","fallback","element","isSidebarParent","isSidebarExpandable","isLegacyGroup","section","toSidebarItems","sections","legacyGroupToItem","legacyLeafToItem","group","leaf","shared","legacyDefaultExpandedKeys","legacyActiveKey","child","buildSidebarTree","byKey","order","duplicateKeys","walk","list","depth","ancestors","nodes","sortKeysByTreeOrder","keys","wanted","sorted","known","toggleExpandedKey","tree","descendant","descendantKeys","ancestor","expandPath","path","sameExpandedKeys","a","b","activeAncestorKeys","activeExpandablePath","useIsomorphicLayoutEffect","useLayoutEffect","UNRESOLVED","accessibleNameOf","panelId","idPrefix","RowContent","expandable","CollapsedRowTooltip","measureRailTooltipAnchor","anchor","rect","edge","rtl","viewportWidth","railTooltipAnchorProps","collapsed","measure","SidebarRow","ctx","flyoutRef","flyoutOpen","setFlyoutOpen","closeFlyout","place","depthStyle","isActive","isActiveAncestor","isExpanded","controlsId","rowClass","handleClick","linkProps","titleId","submenu","iconOnlyBranch","toggleExpanded","previous","toggleButton","DefaultCollapseControl","Sidebar","expandActivePath","activePathExpansion","expandedKeys","defaultExpandedKeys","onExpandedKeysChange","expandMode","defaultCollapsed","onCollapsedChange","collapsible","renderCollapseControl","collapseLabel","expandLabel","mobileOpen","defaultMobileOpen","onMobileOpenChange","mobileLabel","closeMobileOnSelect","collapsedFooter","navLabel","renderLink","legacySections","resolvedItems","duplicates","legacyDefaults","resolvedActiveKeyForInit","expansionStrategy","initialExpandedRef","base","currentExpanded","setExpanded","currentCollapsed","setCollapsed","currentMobileOpen","setMobileOpen","resolvedActiveKey","activeAncestors","expandedSet","set","expandedRef","previousActiveKeyRef","closeMobile","openerRef","opener","select","resolvedVariant","resolvedTone","effectiveCollapsed","collapseControlProps","resolvedFooter","aside","PageHeader","description","breadcrumbItems","GAP_TOKEN","resolveGap","Flex","grow","shrink","fullWidth","IconButton","ariaLabel","iconSize","tooltip","ListItem","leading","trailing","dense","rowClassName","buildLinePoints","data","padding","range","innerWidth","innerHeight","x","y","LineOrArea","strokeWidth","points","linePoints","Bars","barWidth","barHeight","Sparkline","TREND_TONE","TREND_ICON","formatValue","precision","Statistic","prefix","suffix","trend","delta","AppearanceRadioGroup","refs","move","selected","AppearanceMenu","labels","colorSchemes","changeMode","changePresentation","changeTone","changeScheme","schemes","HttpError","statusText","url","serializeParams","params","searchParams","rawValue","createHttpClient","baseUrl","fetcher","buildRequestInit","requestOptions","fullUrl","init","response","defaultHttpClient","sortKeys","obj","acc","useRemoteData","client","mapResponse","enabled","state","setState","setItems","setError","reloadToken","setReloadToken","paramsKey","latestRequestId","mapResponseRef","requestId","controller","mapped","err","reload","token","useDebouncedValue","delayMs","debounced","setDebounced","defaultArrayNormalization","toSelectOption","valueMember","displayMember","record","RemoteComboBox","comboBoxProps","resolvedError","RemoteAutoComplete","searchParam","minSearchLength","debounceMs","autoCompleteProps","internalSearchText","setInternalSearchText","debouncedSearchText","searchReady","RemoteDataGrid","getTotalCount","dataGridProps","setPage","setSort","isFirstRender","requestParams","lastResponseRef","explicitTotalCount","inferredTotalCount","RemoteSelect","selectProps","RemoteMultiSelect","multiSelectProps","createSmartComponentRegistry","resolvers","warned","component","resolver","metadata","createSmartDataSourceRegistry","initial","definitions","definition","createSmartActionRegistry","handlers","handler","hasDataSource","resolveParams","paramDefs","resolved","def","resolveText","translate","resolveSmartFieldMetadata","useSmartField","formMetadata","field","NO_DEPENDENCIES","pick","useSmartDependencies","dependsOn","onMetadataRefreshNeeded","watched","watchedSnapshot","watchedKey","previousRef","onRefreshRef","resolveSmartActionMetadata","useSmartAction","action","comboBoxResolver","dataSourceDef","resolveColumn","isLocalizedBoolean","dataGridResolver","totalCountField","parseIsoDate","datePickerResolver","inputResolver","registerBuiltInResolvers","SmartField","notifyRefresh","changedField","SUPPORTED_SCHEMA_MAJOR","isSupportedSchemaVersion","version","major","SmartForm","SmartAction","SmartActions"],"mappings":"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"}
|