rich-react-component 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","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/shared/useIsomorphicLayoutEffect.ts","../src/base/shared/useElementResize.ts","../src/base/dataGridResponsive.ts","../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/chart/ChartStatus.tsx","../src/base/chart/useChartDimensions.ts","../src/base/Chart.tsx","../src/base/chart/chartColors.ts","../src/base/ChartLegend.tsx","../src/base/chart/ChartTooltip.tsx","../src/base/chart/chartScales.ts","../src/base/chart/CartesianChart.tsx","../src/base/LineChart.tsx","../src/base/AreaChart.tsx","../src/base/BarChart.tsx","../src/base/StackedBarChart.tsx","../src/base/chart/ChartSliceSummary.tsx","../src/base/chart/useChartIndexNavigation.ts","../src/base/chart/CircularChartBase.tsx","../src/base/DonutChart.tsx","../src/base/PieChart.tsx","../src/base/Calendar.tsx","../src/base/DocumentViewer.tsx","../src/base/AppearanceMenu.tsx","../src/base/shared/composeRefs.ts","../src/base/shared/Portal.tsx","../src/base/contextMenuModel.ts","../src/base/contextMenuPosition.ts","../src/base/ContextMenu.tsx","../src/base/RichComponentBase.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 { useEffect, useLayoutEffect } from \"react\";\r\n\r\n/**\r\n * `useLayoutEffect` in the browser, `useEffect` on the server.\r\n *\r\n * Measurement has to happen after layout but before paint, which is what\r\n * `useLayoutEffect` is for — but React warns when it runs during server\r\n * rendering, where there is no layout to read. The `typeof window` test never\r\n * touches a browser global (it cannot throw) and is evaluated once, so the\r\n * choice is constant for the lifetime of the module and the rules of hooks\r\n * still hold.\r\n */\r\nexport const useIsomorphicLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\r\n","import { useEffect, useRef, type RefObject } from \"react\";\r\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect\";\r\n\r\n/**\r\n * Calls `onResize` whenever the observed element's box changes.\r\n *\r\n * The element's *own* box, not the viewport: a grid can sit in a narrow\r\n * dashboard panel, a modal, a split view or a resizable container, and a\r\n * global breakpoint knows nothing about any of those.\r\n *\r\n * `ResizeObserver` is used when the environment has it, and only then; the\r\n * window-resize listener is a fallback for environments without it, so a\r\n * modern browser never gets a permanent global listener per grid. Nothing is\r\n * touched during module initialization or during render, so importing this on\r\n * a server is inert, and the observer is disconnected on cleanup — which is\r\n * also what makes it safe under React Strict Mode's double mount.\r\n */\r\nexport function useElementResize(ref: RefObject<Element | null>, enabled: boolean, onResize: () => void): void {\r\n const handlerRef = useRef(onResize);\r\n\r\n // Kept in a ref so a new inline callback never re-subscribes the observer.\r\n useIsomorphicLayoutEffect(() => {\r\n handlerRef.current = onResize;\r\n });\r\n\r\n useEffect(() => {\r\n if (!enabled) return;\r\n const element = ref.current;\r\n if (!element) return;\r\n\r\n const notify = () => handlerRef.current();\r\n\r\n if (typeof ResizeObserver !== \"undefined\") {\r\n const observer = new ResizeObserver(notify);\r\n observer.observe(element);\r\n return () => observer.disconnect();\r\n }\r\n\r\n if (typeof window === \"undefined\") return;\r\n window.addEventListener(\"resize\", notify);\r\n return () => window.removeEventListener(\"resize\", notify);\r\n }, [ref, enabled]);\r\n}\r\n","import { useCallback, useEffect, useRef, useState, type RefObject } from \"react\";\r\nimport { useElementResize } from \"./shared/useElementResize\";\r\nimport { useIsomorphicLayoutEffect } from \"./shared/useIsomorphicLayoutEffect\";\r\n\r\n/**\r\n * Responsive column model for grid-like components.\r\n *\r\n * The problem: when a grid's *actual available width* is too small for its\r\n * visible columns, rows stop being readable. The answer here is an ordered\r\n * list of rules that progressively take columns out of the tabular layout —\r\n * either relocating them into the row's own label/value detail area\r\n * (`\"Responsive\"`) or dropping them entirely (`\"Hide\"`) — while one primary\r\n * column always stays in the normal row.\r\n *\r\n * This module owns the whole algorithm: column classification, primary-column\r\n * resolution, rule normalization, development-time validation and the\r\n * width-driven fit loop. `DataGrid` is its only consumer, and `RemoteDataGrid`\r\n * and the Smart `dataGridResolver` inherit the behavior by composing\r\n * `DataGrid` — the algorithm exists exactly once.\r\n *\r\n * It is deliberately React-only-at-the-edges: everything above\r\n * `useResponsiveColumnFit` is a pure function of a structural column model,\r\n * so it is unit-testable without rendering a grid, and it never imports the\r\n * grid itself (no cycle, and the grid stays the sole owner of its column type).\r\n */\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Public contract\r\n * ------------------------------------------------------------------ */\r\n\r\n/**\r\n * What happens to a column when the grid runs out of room for it.\r\n *\r\n * - `\"Responsive\"` — leaves the tabular row and is shown as a label/value pair\r\n * in that same row's detail area.\r\n * - `\"Hide\"` — leaves the tabular row and is not shown anywhere.\r\n *\r\n * Capitalized, unlike this library's other string unions (`\"asc\"`, `\"text\"`,\r\n * `\"auto\"`, …), because these two are a specified external contract. One\r\n * representation only: the lower-case spellings are deliberately *not*\r\n * accepted, so there is never a second competing form of the same concept.\r\n */\r\nexport type ResponsiveColumnBehavior = \"Responsive\" | \"Hide\";\r\n\r\n/**\r\n * One entry of the ordered rule list. Position in the array is the priority —\r\n * there is no separate priority number to keep in sync with it.\r\n */\r\nexport interface ResponsiveColumnRule<TField> {\r\n field: TField;\r\n behavior: ResponsiveColumnBehavior;\r\n}\r\n\r\nexport interface GridResponsiveOptions<TField> {\r\n /**\r\n * The column that carries the row's identity in a narrow layout. It always\r\n * stays in the tabular row: it is never relocated to the detail area and\r\n * never removed by a `\"Hide\"` rule.\r\n */\r\n primaryColumn?: TField;\r\n /**\r\n * Ordered rules. The first is processed first as width shrinks, and the last\r\n * processed is the first restored as width grows. Columns not listed here\r\n * are still handled — see `buildResponsiveColumnPlan`.\r\n */\r\n columns?: readonly ResponsiveColumnRule<TField>[];\r\n}\r\n\r\n/**\r\n * The parts of a grid column this model needs, as a structural shape.\r\n *\r\n * `isData` / `isUtility` / `isTextual` are classifications the grid derives\r\n * from its own column type, so this module never has to know what a\r\n * `DataGridColumn` is.\r\n */\r\nexport interface ResponsiveColumnModel {\r\n /** The grid's own column identity. */\r\n key: string;\r\n /** Reads a value out of the row (as opposed to a command/action column). */\r\n isData: boolean;\r\n /** A command/action/control column: renders arbitrary content, reads no value. */\r\n isUtility: boolean;\r\n /** A data column whose value is textual, so it reads well as a row title. */\r\n isTextual: boolean;\r\n}\r\n\r\nexport type ResponsiveProblemKind =\r\n | \"unknown-column\"\r\n | \"duplicate-rule\"\r\n | \"primary-column-rule\"\r\n | \"invalid-behavior\"\r\n | \"utility-column-responsive\"\r\n | \"invalid-primary-column\";\r\n\r\n/** One development-time diagnostic, in the same shape the demo registry uses. */\r\nexport interface ResponsiveProblem {\r\n kind: ResponsiveProblemKind;\r\n detail: string;\r\n}\r\n\r\n/** A rule after validation, addressed by the grid's resolved column key. */\r\nexport interface NormalizedResponsiveRule {\r\n key: string;\r\n behavior: ResponsiveColumnBehavior;\r\n}\r\n\r\nexport interface ResponsiveColumnPlan {\r\n /** Resolved primary column, or `undefined` when no column is eligible. */\r\n primaryKey: string | undefined;\r\n /** The single ordered list the fit loop walks. */\r\n rules: readonly NormalizedResponsiveRule[];\r\n problems: readonly ResponsiveProblem[];\r\n}\r\n\r\nconst BEHAVIORS: readonly ResponsiveColumnBehavior[] = [\"Responsive\", \"Hide\"];\r\n\r\nfunction isBehavior(value: unknown): value is ResponsiveColumnBehavior {\r\n return typeof value === \"string\" && BEHAVIORS.includes(value as ResponsiveColumnBehavior);\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Primary column resolution\r\n * ------------------------------------------------------------------ */\r\n\r\n/**\r\n * Deterministic resolution, in order:\r\n *\r\n * 1. the configured `primaryColumn`, when it names an eligible column;\r\n * 2. otherwise the first textual data column in declared column order;\r\n * 3. otherwise the first data column in declared column order;\r\n * 4. otherwise `undefined` — the grid keeps its existing behavior.\r\n *\r\n * Utility columns (selection, row number, expanders, actions, command and\r\n * drag-handle columns) are never chosen automatically, and a configured one is\r\n * rejected: a checkbox or a button is not a row's identity.\r\n *\r\n * A configured column that is absent from the current column set — because it\r\n * was filtered out upstream by a column chooser, by a permission check or by\r\n * Smart metadata — cannot be the *visible* primary column, so resolution falls\r\n * through to the automatic rules. Nothing about the upstream decision is\r\n * touched or written back.\r\n */\r\nexport function resolvePrimaryColumnKey(\r\n columns: readonly ResponsiveColumnModel[],\r\n configured: string | undefined\r\n): string | undefined {\r\n const eligible = columns.filter((column) => column.isData && !column.isUtility);\r\n\r\n if (configured !== undefined) {\r\n const match = eligible.find((column) => column.key === configured);\r\n if (match) return match.key;\r\n }\r\n\r\n return eligible.find((column) => column.isTextual)?.key ?? eligible[0]?.key;\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Rule normalization\r\n * ------------------------------------------------------------------ */\r\n\r\n/**\r\n * Turns the configured options into one ordered, validated rule list.\r\n *\r\n * Configured rules come first, in their declared order. Every remaining\r\n * eligible data column is then appended in *declared column order* with the\r\n * default `\"Responsive\"` behavior, so responsive layout works without asking\r\n * a consumer to describe every column — and nothing is hidden by default.\r\n *\r\n * Skipped, each with a diagnostic: a rule for an unknown column, a duplicate\r\n * rule, a rule for the primary column, a rule with an invalid behavior, and a\r\n * `\"Responsive\"` rule for a utility column (an action cell has no meaningful\r\n * label/value form). A `\"Hide\"` rule for a utility column is honored — that is\r\n * an explicit instruction to drop a control when space runs out, not a silent\r\n * loss of data. Utility columns are never added by default.\r\n */\r\nexport function buildResponsiveColumnPlan(\r\n columns: readonly ResponsiveColumnModel[],\r\n options: GridResponsiveOptions<string> | undefined\r\n): ResponsiveColumnPlan {\r\n const problems: ResponsiveProblem[] = [];\r\n const byKey = new Map(columns.map((column) => [column.key, column]));\r\n const primaryKey = resolvePrimaryColumnKey(columns, options?.primaryColumn);\r\n\r\n if (options?.primaryColumn !== undefined && options.primaryColumn !== primaryKey) {\r\n problems.push({\r\n kind: \"invalid-primary-column\",\r\n detail: `\"${options.primaryColumn}\" is not an eligible data column; ${\r\n primaryKey === undefined ? \"no primary column could be resolved\" : `\"${primaryKey}\" was resolved instead`\r\n }`,\r\n });\r\n }\r\n\r\n const rules: NormalizedResponsiveRule[] = [];\r\n const claimed = new Set<string>();\r\n\r\n for (const rule of options?.columns ?? []) {\r\n const column = byKey.get(rule.field);\r\n if (!column) {\r\n problems.push({ kind: \"unknown-column\", detail: rule.field });\r\n continue;\r\n }\r\n if (claimed.has(rule.field)) {\r\n problems.push({ kind: \"duplicate-rule\", detail: rule.field });\r\n continue;\r\n }\r\n if (!isBehavior(rule.behavior)) {\r\n problems.push({ kind: \"invalid-behavior\", detail: `${rule.field} -> ${String(rule.behavior)}` });\r\n continue;\r\n }\r\n if (rule.field === primaryKey) {\r\n problems.push({ kind: \"primary-column-rule\", detail: rule.field });\r\n // Claimed so the default pass does not add it back either.\r\n claimed.add(rule.field);\r\n continue;\r\n }\r\n if (column.isUtility && rule.behavior === \"Responsive\") {\r\n problems.push({ kind: \"utility-column-responsive\", detail: rule.field });\r\n claimed.add(rule.field);\r\n continue;\r\n }\r\n\r\n claimed.add(rule.field);\r\n rules.push({ key: rule.field, behavior: rule.behavior });\r\n }\r\n\r\n for (const column of columns) {\r\n if (claimed.has(column.key)) continue;\r\n if (column.key === primaryKey) continue;\r\n if (!column.isData || column.isUtility) continue;\r\n rules.push({ key: column.key, behavior: \"Responsive\" });\r\n }\r\n\r\n return { primaryKey, rules, problems };\r\n}\r\n\r\n/**\r\n * A stable string identity for one plan. Used to reset the fit loop and to\r\n * report diagnostics once per configuration rather than once per render or —\r\n * far worse — once per resize.\r\n */\r\nexport function responsivePlanSignature(plan: ResponsiveColumnPlan): string {\r\n const rules = plan.rules.map((rule) => `${rule.key}:${rule.behavior}`).join(\",\");\r\n const problems = plan.problems.map((problem) => `${problem.kind}:${problem.detail}`).join(\",\");\r\n return `${plan.primaryKey ?? \"\"}|${rules}|${problems}`;\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Width-driven fit loop\r\n * ------------------------------------------------------------------ */\r\n\r\n/** Sub-pixel slack, so a rounding artifact is never read as an overflow. */\r\nconst OVERFLOW_TOLERANCE = 1;\r\n\r\n/**\r\n * A column is restored only once the container is meaningfully wider than the\r\n * width at which it last failed to fit. Without this, a width sitting exactly\r\n * on a threshold would remove and restore the same column forever.\r\n */\r\nconst RESTORE_HYSTERESIS = 16;\r\n\r\nexport interface ResponsiveColumnFitOptions {\r\n enabled: boolean;\r\n /** The grid's own scroll container — the element whose width actually matters. */\r\n containerRef: RefObject<HTMLElement | null>;\r\n ruleCount: number;\r\n /** Resets the loop when the columns or the rules themselves change. */\r\n signature: string;\r\n}\r\n\r\n/**\r\n * How many rules are currently applied.\r\n *\r\n * Overflow is read from the grid's existing scroll container\r\n * (`scrollWidth` vs `clientWidth`) rather than from a re-implementation of\r\n * column sizing, so the browser's own table layout — fixed, minimum and\r\n * maximum column widths, measured content, `white-space` — remains the single\r\n * sizing authority. Two DOM reads per pass, independent of row count: the\r\n * algorithm is O(1) in rows and never scans cells.\r\n *\r\n * Shrinking applies one more rule per pass and records the width at which the\r\n * previous count did not fit. Growing releases one rule per pass, but only\r\n * once the container is wider than that recorded width plus the hysteresis, so\r\n * a restore that would immediately overflow again is not attempted. Passes are\r\n * capped per width, so a pathological layout cannot loop forever.\r\n */\r\nexport function useResponsiveColumnFit({\r\n enabled,\r\n containerRef,\r\n ruleCount,\r\n signature,\r\n}: ResponsiveColumnFitOptions): number {\r\n const [processedCount, setProcessedCount] = useState(0);\r\n const countRef = useRef(0);\r\n const blockedWidthRef = useRef<number | null>(null);\r\n const lastWidthRef = useRef(-1);\r\n const passesRef = useRef(0);\r\n\r\n useEffect(() => {\r\n countRef.current = 0;\r\n blockedWidthRef.current = null;\r\n lastWidthRef.current = -1;\r\n passesRef.current = 0;\r\n setProcessedCount(0);\r\n }, [signature, enabled]);\r\n\r\n const evaluate = useCallback(() => {\r\n if (!enabled) return;\r\n const element = containerRef.current;\r\n if (!element) return;\r\n\r\n const available = element.clientWidth;\r\n // Zero means \"no layout to read\": a server render, a detached node, a\r\n // `display: none` ancestor, or a test environment without layout. Leaving\r\n // the plan untouched keeps the grid exactly as it was.\r\n if (available <= 0) return;\r\n\r\n if (available !== lastWidthRef.current) {\r\n lastWidthRef.current = available;\r\n passesRef.current = 0;\r\n }\r\n if (passesRef.current > ruleCount + 2) return;\r\n\r\n const overflowing = element.scrollWidth - available > OVERFLOW_TOLERANCE;\r\n const current = countRef.current;\r\n let next = current;\r\n\r\n if (overflowing) {\r\n if (current < ruleCount) {\r\n next = current + 1;\r\n blockedWidthRef.current = available;\r\n }\r\n } else if (current > 0) {\r\n const blocked = blockedWidthRef.current;\r\n if (blocked === null || available > blocked + RESTORE_HYSTERESIS) next = current - 1;\r\n }\r\n\r\n if (next === current) return;\r\n passesRef.current += 1;\r\n countRef.current = next;\r\n setProcessedCount(next);\r\n }, [enabled, containerRef, ruleCount]);\r\n\r\n // After every commit: the loop converges across renders, all before paint,\r\n // so a transient step is never painted.\r\n useIsomorphicLayoutEffect(evaluate);\r\n useElementResize(containerRef, enabled, evaluate);\r\n\r\n return enabled ? processedCount : 0;\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Development-time validation\r\n * ------------------------------------------------------------------ */\r\n\r\nconst PROBLEM_MESSAGES: Record<ResponsiveProblemKind, string> = {\r\n \"unknown-column\": \"names a column that does not exist and was ignored\",\r\n \"duplicate-rule\": \"is listed more than once; only the first rule was kept\",\r\n \"primary-column-rule\": \"targets the primary column, which never leaves the row, and was ignored\",\r\n \"invalid-behavior\": 'has an unsupported behavior; use \"Responsive\" or \"Hide\"',\r\n \"utility-column-responsive\":\r\n 'is an action/command column and has no meaningful label/value form, so its \"Responsive\" rule was ignored — use \"Hide\" to drop it instead',\r\n \"invalid-primary-column\": \"is not usable as the primary column\",\r\n};\r\n\r\n/**\r\n * Reports configuration problems once per configuration.\r\n *\r\n * Follows the library's existing development-time validation convention\r\n * (`useControllableState`, `Sidebar`): `NODE_ENV`-guarded, `console.error`\r\n * with the `[react-components]` prefix, from an effect keyed on a stable\r\n * signature — so it never throws during render and never logs on resize.\r\n * Production fails safe: the malformed rule is skipped, and no data is hidden\r\n * because of it.\r\n */\r\nexport function useResponsivePlanDiagnostics(plan: ResponsiveColumnPlan, signature: string): void {\r\n const { problems } = plan;\r\n\r\n useEffect(() => {\r\n if (process.env.NODE_ENV === \"production\") return;\r\n if (problems.length === 0) return;\r\n\r\n for (const problem of problems) {\r\n // eslint-disable-next-line no-console\r\n console.error(\r\n `[react-components] DataGrid responsive configuration: \"${problem.detail}\" ${PROBLEM_MESSAGES[problem.kind]}.`\r\n );\r\n }\r\n // `signature` encodes the problems, so this fires once per configuration —\r\n // never per render, and never per resize.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [signature]);\r\n}\r\n","import { Fragment, useMemo, useRef, type ReactNode } from \"react\";\r\nimport { Pagination } from \"./Pagination\";\r\nimport {\r\n buildResponsiveColumnPlan,\r\n responsivePlanSignature,\r\n useResponsiveColumnFit,\r\n useResponsivePlanDiagnostics,\r\n type GridResponsiveOptions,\r\n type ResponsiveColumnModel,\r\n type ResponsiveColumnPlan,\r\n} from \"./dataGridResponsive\";\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\n/**\r\n * A column's identity as the grid resolves it: `key ?? field ?? header`.\r\n *\r\n * The row's own field names are offered as suggestions — they are what most\r\n * columns are keyed by — while an explicit `key` (a `render`-only column, a\r\n * command column) is still accepted. `string & {}` is what keeps the literal\r\n * suggestions from collapsing into bare `string`.\r\n */\r\nexport type DataGridColumnKey<TRow> = (keyof TRow & string) | (string & {});\r\n\r\n/** Responsive options for one grid, keyed by that grid's column identities. */\r\nexport type DataGridResponsiveOptions<TRow> = GridResponsiveOptions<DataGridColumnKey<TRow>>;\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\n * Progressive column reduction for narrow containers. Presence of this\r\n * object is what enables the behavior — there is no second boolean to\r\n * disagree with it. Omitted (the default), the grid is byte-for-byte what it\r\n * was: every column stays in the row and a wide table scrolls horizontally\r\n * inside its own container.\r\n *\r\n * Enabled, columns leave the tabular layout one at a time as the *grid's own\r\n * container* gets too narrow for them, in the order of `columns`, and come\r\n * back in the exact reverse order as it widens. `primaryColumn` always stays.\r\n * With no `columns` list, every eligible data column is processed in declared\r\n * order with `\"Responsive\"` behavior, so nothing is hidden by default.\r\n */\r\n responsive?: DataGridResponsiveOptions<TRow>;\r\n}\r\n\r\nconst EMPTY_RESPONSIVE_PLAN: ResponsiveColumnPlan = { primaryKey: undefined, rules: [], problems: [] };\r\nconst EMPTY_COLUMNS: never[] = [];\r\n\r\n/**\r\n * Classifies one column for the responsive model.\r\n *\r\n * A *utility* column is the library's existing shape for a command/action\r\n * cell: a `render` callback with no `field` to read (the demo's row-action\r\n * column is exactly this). Those are never chosen as the primary column and\r\n * never relocated into a label/value detail area, because a button has no\r\n * meaningful label/value form. The built-in selection checkbox column is not a\r\n * `DataGridColumn` at all, so it is outside this model entirely and always\r\n * stays in the row.\r\n */\r\nfunction toResponsiveColumnModel<TRow>(column: DataGridColumn<TRow>): ResponsiveColumnModel {\r\n const accessor = column.field ?? column.key;\r\n const isUtility = column.render !== undefined && column.field === undefined;\r\n const isData = !isUtility && accessor !== undefined;\r\n\r\n return {\r\n key: columnKeyOf(column),\r\n isData,\r\n isUtility,\r\n // Deterministic and data-independent: derived from the column model, never\r\n // by sampling row values, so the primary column cannot change between the\r\n // loading and loaded states of the same grid.\r\n isTextual: isData && (column.format === undefined || column.format === \"text\"),\r\n };\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 responsive,\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 /* ---- responsive column plan ----\r\n Purely derived presentation state. The `columns` prop is never rewritten,\r\n so a column hidden by a chooser, by a permission check or by Smart\r\n metadata was already gone before it got here and stays gone; and a column\r\n the responsive pass removed comes back on its own when there is room,\r\n without anything being persisted. */\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const responsiveEnabled = responsive !== undefined;\r\n\r\n const columnModels = useMemo(() => columns.map(toResponsiveColumnModel), [columns]);\r\n const plan = useMemo(\r\n () => (responsive === undefined ? EMPTY_RESPONSIVE_PLAN : buildResponsiveColumnPlan(columnModels, responsive)),\r\n [columnModels, responsive]\r\n );\r\n const signature = responsivePlanSignature(plan);\r\n\r\n useResponsivePlanDiagnostics(plan, signature);\r\n const processedCount = useResponsiveColumnFit({\r\n enabled: responsiveEnabled,\r\n containerRef,\r\n ruleCount: plan.rules.length,\r\n signature,\r\n });\r\n\r\n const processedRules = plan.rules.slice(0, processedCount);\r\n let visibleColumns = columns;\r\n let detailColumns: DataGridColumn<TRow>[] = EMPTY_COLUMNS;\r\n\r\n if (processedRules.length > 0) {\r\n const removedKeys = new Set(processedRules.map((rule) => rule.key));\r\n visibleColumns = columns.filter((column) => !removedKeys.has(columnKeyOf(column)));\r\n\r\n const columnsByKey = new Map(columns.map((column) => [columnKeyOf(column), column] as const));\r\n // Relocated columns keep the order in which their rules were processed.\r\n // `\"Hide\"` rules are absent here by construction, so a hidden column\r\n // reaches neither the row nor the detail area.\r\n detailColumns = processedRules\r\n .filter((rule) => rule.behavior === \"Responsive\")\r\n .map((rule) => columnsByKey.get(rule.key))\r\n .filter((column): column is DataGridColumn<TRow> => column !== undefined);\r\n }\r\n\r\n // `colSpan={0}` means \"every remaining column\" in HTML, which is not what a\r\n // state row wants; one is the floor even in the degenerate case where a\r\n // consumer explicitly hid every column.\r\n const spanCount = Math.max(1, visibleColumns.length + (selectable ? 1 : 0));\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\r\n ref={containerRef}\r\n className={cx(\"table-responsive\", \"rrc-data-grid\", responsiveEnabled && \"rrc-data-grid--responsive\", className)}\r\n >\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 {visibleColumns.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={spanCount} 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={spanCount} 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={spanCount} 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 // One Fragment per row, keyed by the row's own identity: the\r\n // detail row cannot collide with any other row's React key,\r\n // whatever `rowKey` returns.\r\n <Fragment key={key}>\r\n <tr>\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 {visibleColumns.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 {detailColumns.length > 0 && (\r\n // A real table row with the right colSpan, so the table DOM\r\n // stays valid, the detail belongs to its own row, and the\r\n // row's context menu / click scope is unchanged. Always\r\n // visible: these columns were removed by layout, not\r\n // collapsed by the user, so they need no expander.\r\n <tr className=\"rrc-data-grid__detail-row\">\r\n <td colSpan={spanCount} className=\"rrc-data-grid__detail-cell\">\r\n <dl className=\"rrc-data-grid__details\">\r\n {detailColumns.map((column) => (\r\n <div key={columnKeyOf(column)} className=\"rrc-data-grid__detail-item\">\r\n <dt className=\"rrc-data-grid__detail-term\">{column.header}</dt>\r\n {/* Same value pipeline as the normal cell — render,\r\n formatter, format, null convention — and the\r\n column is *moved*, never duplicated, so no cell\r\n renders or fetches twice. */}\r\n <dd className=\"rrc-data-grid__detail-value\">{renderCell(column, row)}</dd>\r\n </div>\r\n ))}\r\n </dl>\r\n </td>\r\n </tr>\r\n )}\r\n </Fragment>\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 type { ReactNode } from \"react\";\r\nimport { Alert } from \"../Alert\";\r\nimport { Skeleton } from \"../Skeleton\";\r\nimport { cx } from \"../shared/classNames\";\r\nimport type { ChartStatusProps } from \"./chartTypes\";\r\n\r\nexport interface ChartStatusOverlayProps extends ChartStatusProps {\r\n height: number;\r\n emptyMessage?: ReactNode;\r\n}\r\n\r\n/**\r\n * Loading/error/empty presentation shared by every chart (doc: \"Chart,\r\n * ChartLegend, ChartTooltip, ChartEmptyState\" common infrastructure — kept as\r\n * one internal piece rather than three, since none of the three states is\r\n * ever shown without the others in this family).\r\n *\r\n * Not part of the public surface: each concrete chart decides when to render\r\n * it, so there is nothing here a consumer would use standalone.\r\n */\r\nexport function ChartStatusOverlay({ loading, error, emptyMessage, height }: ChartStatusOverlayProps) {\r\n if (loading) {\r\n return (\r\n <div className=\"rrc-chart__status\" style={{ height }} aria-busy=\"true\">\r\n <Skeleton height=\"100%\" width=\"100%\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"rrc-chart__status\" style={{ height }}>\r\n <Alert variant=\"danger\" className=\"mb-0 h-100 d-flex align-items-center\">\r\n {error}\r\n </Alert>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={cx(\"rrc-chart__status\", \"rrc-chart__empty\")} style={{ height }}>\r\n {emptyMessage ?? \"No data to display\"}\r\n </div>\r\n );\r\n}\r\n","import { useRef, useState } from \"react\";\r\nimport { useElementResize } from \"../shared/useElementResize\";\r\nimport { useIsomorphicLayoutEffect } from \"../shared/useIsomorphicLayoutEffect\";\r\n\r\n/**\r\n * Measures the chart's own container width (doc: responsive width, no global\r\n * breakpoint). Reuses `useElementResize` (ResizeObserver with a window-resize\r\n * fallback, already SSR-safe) instead of a second measurement strategy.\r\n *\r\n * Starts at 0 so the very first server/client render emits no SVG at all\r\n * (avoids a divide-by-zero layout before the real width is known); the\r\n * measured width lands on the next paint, which is invisible to the user.\r\n */\r\nexport function useChartDimensions(): { containerRef: React.RefObject<HTMLDivElement>; width: number } {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const [width, setWidth] = useState(0);\r\n\r\n const measure = () => {\r\n const next = containerRef.current?.clientWidth ?? 0;\r\n setWidth((prev) => (prev === next ? prev : next));\r\n };\r\n\r\n useIsomorphicLayoutEffect(measure, []);\r\n useElementResize(containerRef, true, measure);\r\n\r\n return { containerRef, width };\r\n}\r\n","import { useId, type ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { ChartStatusOverlay } from \"./chart/ChartStatus\";\r\nimport { useChartDimensions } from \"./chart/useChartDimensions\";\r\nimport type { ChartCommonProps } from \"./chart/chartTypes\";\r\n\r\nexport interface ChartProps extends ChartCommonProps {\r\n /** Render prop — receives the measured surface size once a real width is known (never called at width 0). */\r\n children: (size: { width: number; height: number }) => ReactNode;\r\n /** No data to plot (distinct from `loading`/`error`) — renders `emptyMessage` instead of an empty SVG. */\r\n isEmpty?: boolean;\r\n legend?: ReactNode;\r\n /** Visually-hidden textual/table fallback for screen reader and keyboard users who don't perceive the SVG (doc: chart data needs a non-visual summary). */\r\n summary?: ReactNode;\r\n}\r\n\r\n/**\r\n * Low-level responsive shell every concrete chart (LineChart, BarChart, ...)\r\n * composes for sizing + loading/empty/error chrome (doc: \"Chart\" is part of\r\n * the public surface in its own right, for a consumer building a custom\r\n * visualization without reimplementing that infrastructure).\r\n *\r\n * Deliberately not `role=\"img\"`: a chart's data points are individually\r\n * focusable (keyboard navigation between them), and `img` tells assistive\r\n * tech to ignore all descendants. `group` plus the visually-hidden `summary`\r\n * is what stays correct for an interactive chart.\r\n */\r\nexport function Chart({\r\n title,\r\n height = 320,\r\n loading,\r\n error,\r\n emptyMessage,\r\n disabled,\r\n className,\r\n animate = true,\r\n \"aria-label\": ariaLabel,\r\n isEmpty,\r\n legend,\r\n summary,\r\n children,\r\n}: ChartProps) {\r\n const { containerRef, width } = useChartDimensions();\r\n const summaryId = useId();\r\n const showStatus = loading || !!error || isEmpty;\r\n\r\n return (\r\n <div className={cx(\"rrc-chart\", !animate && \"rrc-chart--no-animate\", className)}>\r\n {title && <div className=\"rrc-chart__title\">{title}</div>}\r\n <div\r\n ref={containerRef}\r\n className={cx(\"rrc-chart__surface\", disabled && \"rrc-chart__surface--disabled\")}\r\n style={{ height }}\r\n role=\"group\"\r\n aria-label={ariaLabel ?? title}\r\n aria-describedby={summary ? summaryId : undefined}\r\n aria-busy={loading || undefined}\r\n >\r\n {showStatus ? (\r\n <ChartStatusOverlay loading={loading} error={error} emptyMessage={emptyMessage} height={height} />\r\n ) : (\r\n width > 0 && children({ width, height })\r\n )}\r\n </div>\r\n {!showStatus && legend}\r\n {summary && (\r\n <div id={summaryId} className=\"visually-hidden\">\r\n {summary}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import type { ChartSeries } from \"./chartTypes\";\r\n\r\n/**\r\n * Chart palette — five `--rrc-chart-N` tokens (doc: colors come from theme\r\n * tokens, never hardcoded hex in a component). A series/slice with an\r\n * explicit `color` wins; otherwise the palette assigns one by index, cycling\r\n * if there are more series than palette slots.\r\n */\r\nconst PALETTE_SIZE = 5;\r\n\r\nexport function resolveChartColor(index: number, explicit: string | undefined, overrides: string[] | undefined): string {\r\n if (explicit) return explicit;\r\n if (overrides && overrides.length > 0) return overrides[index % overrides.length]!;\r\n return `var(--rrc-chart-${(index % PALETTE_SIZE) + 1})`;\r\n}\r\n\r\n/** Resolves a color for every series in order — the shape `ChartLegend` and every concrete chart need. */\r\nexport function chartSeriesColorList(series: readonly ChartSeries[], overrides: string[] | undefined): string[] {\r\n return series.map((item, index) => resolveChartColor(index, item.color, overrides));\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\nimport { chartSeriesColorList } from \"./chart/chartColors\";\r\nimport type { ChartSeries } from \"./chart/chartTypes\";\r\n\r\nexport interface ChartLegendItem {\r\n key: string;\r\n label: string;\r\n color: string;\r\n hidden?: boolean;\r\n}\r\n\r\nexport interface ChartLegendProps {\r\n items: readonly ChartLegendItem[];\r\n /** Toggles one series' visibility. Omit to render a read-only legend. */\r\n onToggle?: (key: string) => void;\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Series swatches + labels, shared by every chart (doc section 5 — public,\r\n * reused rather than reimplemented per chart type). Each item is a real\r\n * `<button>` when `onToggle` is supplied, so toggling a series is keyboard-\r\n * and screen-reader-accessible, not a `<div onClick>`.\r\n */\r\nexport function ChartLegend({ items, onToggle, className }: ChartLegendProps) {\r\n return (\r\n <ul className={cx(\"rrc-chart-legend\", className)} role=\"list\">\r\n {items.map((item) => (\r\n <li key={item.key} className=\"rrc-chart-legend__item\">\r\n {onToggle ? (\r\n <button\r\n type=\"button\"\r\n className={cx(\"rrc-chart-legend__button\", item.hidden && \"rrc-chart-legend__button--hidden\")}\r\n aria-pressed={!item.hidden}\r\n onClick={() => onToggle(item.key)}\r\n >\r\n <span className=\"rrc-chart-legend__swatch\" style={{ backgroundColor: item.color }} aria-hidden=\"true\" />\r\n {item.label}\r\n </button>\r\n ) : (\r\n <span className=\"rrc-chart-legend__label\">\r\n <span className=\"rrc-chart-legend__swatch\" style={{ backgroundColor: item.color }} aria-hidden=\"true\" />\r\n {item.label}\r\n </span>\r\n )}\r\n </li>\r\n ))}\r\n </ul>\r\n );\r\n}\r\n\r\n/** Convenience: builds legend items straight from a chart's series list + resolved colors — the shape every concrete chart needs. */\r\nexport function legendItemsFromSeries(series: readonly ChartSeries[], colorOverrides: string[] | undefined, hiddenKeys: ReadonlySet<string>): ChartLegendItem[] {\r\n const colors = chartSeriesColorList(series, colorOverrides);\r\n return series.map((item, index) => ({ key: item.key, label: item.label, color: colors[index]!, hidden: hiddenKeys.has(item.key) }));\r\n}\r\n","import { cx } from \"../shared/classNames\";\r\n\r\nexport interface ChartTooltipPayloadItem {\r\n key: string;\r\n label: string;\r\n value: string;\r\n color: string;\r\n}\r\n\r\nexport interface ChartTooltipPayload {\r\n label: string;\r\n items: ChartTooltipPayloadItem[];\r\n}\r\n\r\nexport interface ChartTooltipProps {\r\n payload: ChartTooltipPayload;\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Summary of the currently focused/hovered data point (doc: tooltip).\r\n * Deliberately not a cursor-following floating panel: that would need its own\r\n * portal/collision-avoidance system duplicating `Popup`'s, for marginal gain —\r\n * a fixed slot next to the chart (positioned by CSS, `.rrc-chart__tooltip`) is\r\n * equally readable and stays keyboard- and touch-friendly without one.\r\n */\r\nexport function ChartTooltip({ payload, className }: ChartTooltipProps) {\r\n return (\r\n <div className={cx(\"rrc-chart__tooltip\", className)}>\r\n <div className=\"rrc-chart__tooltip-title\">{payload.label}</div>\r\n {payload.items.map((item) => (\r\n <div key={item.key} className=\"rrc-chart__tooltip-row\">\r\n <span className=\"rrc-chart__tooltip-swatch\" style={{ backgroundColor: item.color }} aria-hidden=\"true\" />\r\n <span className=\"rrc-chart__tooltip-label\">{item.label}</span>\r\n <span className=\"rrc-chart__tooltip-value\">{item.value}</span>\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * Minimal scale/tick math, written in-house rather than adding a dependency\r\n * (d3-scale et al.) — the same call this repo already made for `Sparkline`.\r\n * A handful of pure functions is enough for a band + linear axis and stays\r\n * inside the library's zero-runtime-dependency footprint for the Base layer.\r\n */\r\n\r\nexport function linearScale(domain: [number, number], range: [number, number]): (value: number) => number {\r\n const [d0, d1] = domain;\r\n const [r0, r1] = range;\r\n const span = d1 - d0 || 1;\r\n return (value: number) => r0 + ((value - d0) / span) * (r1 - r0);\r\n}\r\n\r\n/** \"Nice\" round tick values spanning at least [min, max] — the standard d3-style rounding step. */\r\nexport function niceTicks(min: number, max: number, count = 5): number[] {\r\n if (min === max) {\r\n min -= 1;\r\n max += 1;\r\n }\r\n const range = max - min;\r\n const rawStep = range / Math.max(count, 1);\r\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));\r\n const residual = rawStep / magnitude;\r\n const step = residual > 5 ? 10 * magnitude : residual > 2 ? 5 * magnitude : residual > 1 ? 2 * magnitude : magnitude;\r\n const niceMin = Math.floor(min / step) * step;\r\n const niceMax = Math.ceil(max / step) * step;\r\n\r\n const ticks: number[] = [];\r\n for (let value = niceMin; value <= niceMax + step * 0.5; value += step) {\r\n ticks.push(Math.round(value / step) * step);\r\n }\r\n return ticks;\r\n}\r\n\r\n/** Evenly divides `size` into `count` bands, returning each band's start offset and width. */\r\nexport function bandScale(count: number, size: number, paddingRatio = 0.2): { bandWidth: number; offset: (index: number) => number } {\r\n if (count <= 0) return { bandWidth: size, offset: () => 0 };\r\n const step = size / count;\r\n const bandWidth = step * (1 - paddingRatio);\r\n const padding = (step - bandWidth) / 2;\r\n return { bandWidth, offset: (index: number) => index * step + padding };\r\n}\r\n\r\nexport function defaultNumberFormatter(locale?: string): (value: number) => string {\r\n const formatter = new Intl.NumberFormat(locale, { maximumFractionDigits: 2 });\r\n return (value: number) => formatter.format(value);\r\n}\r\n","import { useId, useMemo, useState, type KeyboardEvent, type ReactNode } from \"react\";\r\nimport { cx } from \"../shared/classNames\";\r\nimport { ChartLegend, type ChartLegendItem } from \"../ChartLegend\";\r\nimport { ChartStatusOverlay } from \"./ChartStatus\";\r\nimport { ChartTooltip, type ChartTooltipPayload } from \"./ChartTooltip\";\r\nimport { resolveChartColor } from \"./chartColors\";\r\nimport { bandScale, defaultNumberFormatter, linearScale, niceTicks } from \"./chartScales\";\r\nimport type { ChartCommonProps, ChartDatum, ChartInteraction, ChartSeries, ChartValue } from \"./chartTypes\";\r\nimport { useChartDimensions } from \"./useChartDimensions\";\r\n\r\nexport interface CartesianChartCoreProps extends ChartCommonProps {\r\n kind: \"line\" | \"area\" | \"bar\";\r\n data: ChartDatum[];\r\n xKey: string;\r\n series: ChartSeries[];\r\n xAxisLabel?: string;\r\n yAxisLabel?: string;\r\n showGrid?: boolean;\r\n showDataLabels?: boolean;\r\n xFormatter?: (value: ChartValue) => string;\r\n yFormatter?: (value: number) => string;\r\n /** Bar/StackedBar only. */\r\n orientation?: \"vertical\" | \"horizontal\";\r\n /** Bar only — StackedBarChart always passes `true` and hides the prop from its own public API. */\r\n stacked?: boolean;\r\n onDataPointClick?: (interaction: ChartInteraction) => void;\r\n onLegendItemClick?: (seriesKey: string, hidden: boolean) => void;\r\n locale?: string;\r\n}\r\n\r\nconst MARGIN = { top: 16, right: 16, bottom: 32, left: 48 };\r\n\r\nfunction toNumber(value: ChartValue | null | undefined): number {\r\n if (value == null) return 0;\r\n if (value instanceof Date) return value.getTime();\r\n return typeof value === \"number\" ? value : Number(value) || 0;\r\n}\r\n\r\nfunction formatXLabel(value: ChartValue, formatter?: (value: ChartValue) => string): string {\r\n if (formatter) return formatter(value);\r\n if (value instanceof Date) return value.toLocaleDateString();\r\n return String(value);\r\n}\r\n\r\n/**\r\n * Shared renderer behind LineChart/AreaChart/BarChart/StackedBarChart (doc:\r\n * compose, don't reimplement per chart type — the only real differences\r\n * between them are the mark shape and, for bars, orientation/stacking).\r\n *\r\n * Plain SVG, no charting dependency (the same call already made for\r\n * `Sparkline`): a public API shaped around `data`/`xKey`/`series` stays\r\n * implementation-agnostic, and the repository's Base layer has zero runtime\r\n * dependencies today.\r\n */\r\nexport function CartesianChart({\r\n kind,\r\n title,\r\n data,\r\n xKey,\r\n series,\r\n height = 320,\r\n loading,\r\n error,\r\n emptyMessage,\r\n disabled,\r\n showLegend = true,\r\n showTooltip = true,\r\n showGrid = true,\r\n showDataLabels = false,\r\n animate = true,\r\n xAxisLabel,\r\n yAxisLabel,\r\n xFormatter,\r\n yFormatter,\r\n orientation = \"vertical\",\r\n stacked = false,\r\n colors,\r\n className,\r\n onDataPointClick,\r\n onLegendItemClick,\r\n locale,\r\n \"aria-label\": ariaLabel,\r\n}: CartesianChartCoreProps) {\r\n const { containerRef, width } = useChartDimensions();\r\n const titleId = useId();\r\n const tooltipId = useId();\r\n const [hidden, setHidden] = useState<Set<string>>(() => new Set(series.filter((s) => s.hidden).map((s) => s.key)));\r\n const [activeIndex, setActiveIndex] = useState<number>(-1);\r\n\r\n const visibleSeries = useMemo(() => series.filter((s) => !hidden.has(s.key)), [series, hidden]);\r\n const numberFormatter = useMemo(() => yFormatter ?? defaultNumberFormatter(locale), [yFormatter, locale]);\r\n\r\n const isEmpty = data.length === 0 || series.length === 0;\r\n const isMeasuring = width === 0;\r\n const showOverlay = loading || !!error || isEmpty || isMeasuring;\r\n\r\n const toggleSeries = (key: string) => {\r\n setHidden((prev) => {\r\n const next = new Set(prev);\r\n const willHide = !next.has(key);\r\n if (willHide) next.add(key);\r\n else next.delete(key);\r\n onLegendItemClick?.(key, willHide);\r\n return next;\r\n });\r\n };\r\n\r\n const legendItems: ChartLegendItem[] = series.map((s, index) => ({\r\n key: s.key,\r\n label: s.label,\r\n color: resolveChartColor(index, s.color, colors),\r\n hidden: hidden.has(s.key),\r\n }));\r\n\r\n const innerWidth = Math.max(width - MARGIN.left - MARGIN.right, 0);\r\n const innerHeight = Math.max(height - MARGIN.top - MARGIN.bottom, 0);\r\n const isHorizontal = kind === \"bar\" && orientation === \"horizontal\";\r\n\r\n const { bandWidth, offset } = bandScale(data.length, isHorizontal ? innerHeight : innerWidth, kind === \"bar\" ? 0.3 : 0);\r\n\r\n const values = data.flatMap((row) =>\r\n visibleSeries.map((s) => {\r\n const raw = toNumber(row[s.key] as ChartValue);\r\n return raw;\r\n })\r\n );\r\n const stackedTotals =\r\n kind === \"bar\" && stacked\r\n ? data.map((row) => visibleSeries.reduce((sum, s) => sum + Math.max(toNumber(row[s.key] as ChartValue), 0), 0))\r\n : [];\r\n const domainValues = kind === \"bar\" && stacked ? stackedTotals : values;\r\n const min = Math.min(0, ...domainValues, 0);\r\n const max = Math.max(0, ...domainValues, 1);\r\n const ticks = niceTicks(min, max, 4);\r\n const domainMin = ticks[0] ?? min;\r\n const domainMax = ticks[ticks.length - 1] ?? max;\r\n\r\n const valueScale = linearScale([domainMin, domainMax], isHorizontal ? [0, innerWidth] : [innerHeight, 0]);\r\n const zeroY = valueScale(0);\r\n\r\n const tooltip: ChartTooltipPayload | null =\r\n showTooltip && activeIndex >= 0 && data[activeIndex]\r\n ? {\r\n label: formatXLabel(data[activeIndex]![xKey] as ChartValue, xFormatter),\r\n items: visibleSeries.map((s, seriesIndex) => {\r\n const raw = toNumber(data[activeIndex]![s.key] as ChartValue);\r\n const format = s.valueFormatter ?? numberFormatter;\r\n return {\r\n key: s.key,\r\n label: s.label,\r\n value: format(raw),\r\n color: resolveChartColor(series.indexOf(s), s.color, colors),\r\n };\r\n }),\r\n }\r\n : null;\r\n\r\n const emitClick = (index: number) => {\r\n for (const s of visibleSeries) {\r\n onDataPointClick?.({ seriesKey: s.key, datum: data[index]!, value: toNumber(data[index]![s.key] as ChartValue), index });\r\n }\r\n };\r\n\r\n const handleColumnKeyDown = (event: KeyboardEvent<SVGGElement>, index: number) => {\r\n if (disabled) return;\r\n switch (event.key) {\r\n case \"ArrowRight\":\r\n event.preventDefault();\r\n setActiveIndex(Math.min(index + 1, data.length - 1));\r\n break;\r\n case \"ArrowLeft\":\r\n event.preventDefault();\r\n setActiveIndex(Math.max(index - 1, 0));\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n setActiveIndex(0);\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n setActiveIndex(data.length - 1);\r\n break;\r\n case \"Enter\":\r\n case \" \":\r\n event.preventDefault();\r\n emitClick(index);\r\n break;\r\n default:\r\n break;\r\n }\r\n };\r\n\r\n const columnLabel = (index: number) => {\r\n const row = data[index]!;\r\n const parts = visibleSeries.map((s) => {\r\n const format = s.valueFormatter ?? numberFormatter;\r\n return `${s.label} ${format(toNumber(row[s.key] as ChartValue))}`;\r\n });\r\n return `${formatXLabel(row[xKey] as ChartValue, xFormatter)}: ${parts.join(\", \")}`;\r\n };\r\n\r\n function renderMarks(): ReactNode {\r\n if (kind === \"line\" || kind === \"area\") {\r\n return visibleSeries.map((s, seriesIndex) => {\r\n const color = resolveChartColor(series.indexOf(s), s.color, colors);\r\n const points = data.map((row, index) => {\r\n const x = offset(index) + bandWidth / 2;\r\n const y = valueScale(toNumber(row[s.key] as ChartValue));\r\n return [x, y] as const;\r\n });\r\n const linePath = points.map(([x, y]) => `${x},${y}`).join(\" \");\r\n return (\r\n <g key={s.key}>\r\n {kind === \"area\" && (\r\n <polygon\r\n className={cx(\"rrc-chart__mark\", \"rrc-chart__area\", animate && \"rrc-chart__mark--animate\")}\r\n points={`${points[0]?.[0] ?? 0},${zeroY} ${linePath} ${points[points.length - 1]?.[0] ?? 0},${zeroY}`}\r\n fill={color}\r\n opacity={0.18}\r\n stroke=\"none\"\r\n />\r\n )}\r\n <polyline\r\n className={cx(\"rrc-chart__mark\", \"rrc-chart__line\", animate && \"rrc-chart__mark--animate\")}\r\n points={linePath}\r\n fill=\"none\"\r\n stroke={color}\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n />\r\n {points.map(([x, y], index) => (\r\n <circle\r\n key={index}\r\n cx={x}\r\n cy={y}\r\n r={activeIndex === index ? 5 : 3}\r\n fill={color}\r\n className=\"rrc-chart__point\"\r\n onClick={() => onDataPointClick?.({ seriesKey: s.key, datum: data[index]!, value: toNumber(data[index]![s.key] as ChartValue), index })}\r\n />\r\n ))}\r\n {showDataLabels &&\r\n points.map(([x, y], index) => (\r\n <text key={index} x={x} y={y - 8} textAnchor=\"middle\" className=\"rrc-chart__data-label\">\r\n {(s.valueFormatter ?? numberFormatter)(toNumber(data[index]![s.key] as ChartValue))}\r\n </text>\r\n ))}\r\n </g>\r\n );\r\n });\r\n }\r\n\r\n // bar / stacked bar\r\n const stackOffsets = new Array(data.length).fill(0);\r\n return visibleSeries.map((s, seriesIndex) => {\r\n const color = resolveChartColor(series.indexOf(s), s.color, colors);\r\n const groupWidth = stacked ? bandWidth : bandWidth / Math.max(visibleSeries.length, 1);\r\n return (\r\n <g key={s.key}>\r\n {data.map((row, index) => {\r\n const raw = toNumber(row[s.key] as ChartValue);\r\n const bandStart = offset(index);\r\n if (isHorizontal) {\r\n const barLength = Math.abs(valueScale(raw) - zeroY);\r\n const y = stacked ? stackOffsets[index] : bandStart + seriesIndex * groupWidth;\r\n const x = raw >= 0 ? zeroY : zeroY - barLength;\r\n if (stacked) stackOffsets[index] += barLength;\r\n return (\r\n <rect\r\n key={index}\r\n x={x}\r\n y={y}\r\n width={barLength}\r\n height={Math.max(groupWidth, 1)}\r\n fill={color}\r\n rx={2}\r\n className={cx(\"rrc-chart__mark\", \"rrc-chart__bar\", animate && \"rrc-chart__mark--animate\")}\r\n onClick={() => onDataPointClick?.({ seriesKey: s.key, datum: row, value: raw, index })}\r\n />\r\n );\r\n }\r\n const barHeight = Math.abs(valueScale(raw) - zeroY);\r\n const x = stacked ? bandStart : bandStart + seriesIndex * groupWidth;\r\n const y = stacked ? stackOffsets[index] - (raw >= 0 ? barHeight : 0) : raw >= 0 ? zeroY - barHeight : zeroY;\r\n if (stacked) stackOffsets[index] += raw >= 0 ? -barHeight : barHeight;\r\n return (\r\n <rect\r\n key={index}\r\n x={x}\r\n y={stacked ? (raw >= 0 ? y : zeroY) : y}\r\n width={Math.max(groupWidth, 1)}\r\n height={barHeight}\r\n fill={color}\r\n rx={2}\r\n className={cx(\"rrc-chart__mark\", \"rrc-chart__bar\", animate && \"rrc-chart__mark--animate\")}\r\n onClick={() => onDataPointClick?.({ seriesKey: s.key, datum: row, value: raw, index })}\r\n />\r\n );\r\n })}\r\n </g>\r\n );\r\n });\r\n }\r\n\r\n return (\r\n <div className={cx(\"rrc-chart\", disabled && \"rrc-chart--disabled\", className)} aria-disabled={disabled || undefined}>\r\n {title && (\r\n <div id={titleId} className=\"rrc-chart__title\">\r\n {title}\r\n </div>\r\n )}\r\n\r\n <div\r\n ref={containerRef}\r\n className=\"rrc-chart__canvas\"\r\n style={{ height }}\r\n role=\"group\"\r\n aria-labelledby={title ? titleId : undefined}\r\n aria-label={!title ? ariaLabel ?? \"Chart\" : undefined}\r\n >\r\n {showOverlay ? (\r\n <ChartStatusOverlay loading={loading || isMeasuring} error={error} emptyMessage={emptyMessage} height={height} />\r\n ) : (\r\n <>\r\n {/*\r\n Deliberately no `role=\"img\"` here (or on this svg at all): each\r\n data column below is its own focusable `role=\"button\"` target\r\n (doc: keyboard navigation between data points), and `img` — like\r\n `aria-hidden` — would tell assistive tech to ignore all\r\n descendants, exactly the access this chart needs to keep. The\r\n accessible name lives on the wrapping `role=\"group\"` above; the\r\n visually-hidden `<table>` at the end is the non-visual data\r\n summary.\r\n */}\r\n <svg width=\"100%\" height={height} viewBox={`0 0 ${width} ${height}`}>\r\n <g transform={`translate(${MARGIN.left},${MARGIN.top})`}>\r\n {showGrid &&\r\n ticks.map((tick) => {\r\n const y = isHorizontal ? undefined : valueScale(tick);\r\n const x = isHorizontal ? valueScale(tick) : undefined;\r\n return isHorizontal ? (\r\n <line key={tick} x1={x} x2={x} y1={0} y2={innerHeight} className=\"rrc-chart__grid-line\" />\r\n ) : (\r\n <line key={tick} x1={0} x2={innerWidth} y1={y} y2={y} className=\"rrc-chart__grid-line\" />\r\n );\r\n })}\r\n\r\n {!isHorizontal &&\r\n ticks.map((tick) => (\r\n <text key={tick} x={-8} y={valueScale(tick)} textAnchor=\"end\" dominantBaseline=\"middle\" className=\"rrc-chart__axis-label\">\r\n {numberFormatter(tick)}\r\n </text>\r\n ))}\r\n {isHorizontal &&\r\n ticks.map((tick) => (\r\n <text key={tick} x={valueScale(tick)} y={innerHeight + 16} textAnchor=\"middle\" className=\"rrc-chart__axis-label\">\r\n {numberFormatter(tick)}\r\n </text>\r\n ))}\r\n\r\n {!isHorizontal &&\r\n data.map((row, index) => (\r\n <text\r\n key={index}\r\n x={offset(index) + bandWidth / 2}\r\n y={innerHeight + 16}\r\n textAnchor=\"middle\"\r\n className=\"rrc-chart__axis-label\"\r\n >\r\n {formatXLabel(row[xKey] as ChartValue, xFormatter)}\r\n </text>\r\n ))}\r\n {isHorizontal &&\r\n data.map((row, index) => (\r\n <text\r\n key={index}\r\n x={-8}\r\n y={offset(index) + bandWidth / 2}\r\n textAnchor=\"end\"\r\n dominantBaseline=\"middle\"\r\n className=\"rrc-chart__axis-label\"\r\n >\r\n {formatXLabel(row[xKey] as ChartValue, xFormatter)}\r\n </text>\r\n ))}\r\n\r\n {renderMarks()}\r\n\r\n {/* Keyboard-navigable, invisible column targets — roving tabindex across data points (doc: keyboard + screen-reader access). */}\r\n {data.map((_, index) => (\r\n <rect\r\n key={index}\r\n x={isHorizontal ? 0 : offset(index)}\r\n y={isHorizontal ? offset(index) : 0}\r\n width={isHorizontal ? innerWidth : bandWidth}\r\n height={isHorizontal ? bandWidth : innerHeight}\r\n fill=\"transparent\"\r\n role=\"button\"\r\n tabIndex={disabled ? -1 : index === Math.max(activeIndex, 0) ? 0 : -1}\r\n aria-label={columnLabel(index)}\r\n aria-describedby={showTooltip && activeIndex === index ? tooltipId : undefined}\r\n className=\"rrc-chart__column-target\"\r\n onFocus={() => setActiveIndex(index)}\r\n onMouseEnter={() => setActiveIndex(index)}\r\n onMouseLeave={() => setActiveIndex(-1)}\r\n onKeyDown={(event) => handleColumnKeyDown(event, index)}\r\n onClick={() => emitClick(index)}\r\n />\r\n ))}\r\n </g>\r\n </svg>\r\n\r\n {showTooltip && tooltip && (\r\n <div id={tooltipId} role=\"tooltip\">\r\n <ChartTooltip payload={tooltip} />\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n\r\n {(xAxisLabel || yAxisLabel) && (\r\n <div className=\"rrc-chart__axis-titles\">\r\n {yAxisLabel && <span className=\"rrc-chart__axis-title rrc-chart__axis-title--y\">{yAxisLabel}</span>}\r\n {xAxisLabel && <span className=\"rrc-chart__axis-title rrc-chart__axis-title--x\">{xAxisLabel}</span>}\r\n </div>\r\n )}\r\n\r\n {showLegend && !isEmpty && <ChartLegend items={legendItems} onToggle={toggleSeries} />}\r\n\r\n <table className=\"visually-hidden\">\r\n <caption>{title ?? \"Chart data\"}</caption>\r\n <thead>\r\n <tr>\r\n <th scope=\"col\">{xAxisLabel ?? xKey}</th>\r\n {series.map((s) => (\r\n <th key={s.key} scope=\"col\">\r\n {s.label}\r\n </th>\r\n ))}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {data.map((row, index) => (\r\n <tr key={index}>\r\n <th scope=\"row\">{formatXLabel(row[xKey] as ChartValue, xFormatter)}</th>\r\n {series.map((s) => (\r\n <td key={s.key}>{(s.valueFormatter ?? numberFormatter)(toNumber(row[s.key] as ChartValue))}</td>\r\n ))}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n}\r\n","import { CartesianChart, type CartesianChartCoreProps } from \"./chart/CartesianChart\";\r\n\r\nexport type LineChartProps = Omit<CartesianChartCoreProps, \"kind\" | \"orientation\" | \"stacked\">;\r\n\r\n/**\r\n * `<LineChart title=\"...\" data={data} xKey=\"month\" series={[...]} />` — a\r\n * consumer never touches SVG, ResizeObserver or a tooltip portal (doc section\r\n * 5). Composes the shared `CartesianChart` renderer with `AreaChart`,\r\n * `BarChart` and `StackedBarChart`.\r\n */\r\nexport function LineChart(props: LineChartProps) {\r\n return <CartesianChart {...props} kind=\"line\" />;\r\n}\r\n","import { CartesianChart, type CartesianChartCoreProps } from \"./chart/CartesianChart\";\r\n\r\nexport type AreaChartProps = Omit<CartesianChartCoreProps, \"kind\" | \"orientation\" | \"stacked\">;\r\n\r\n/** Same API and interaction model as `LineChart`, filled to its baseline. See `CartesianChart`. */\r\nexport function AreaChart(props: AreaChartProps) {\r\n return <CartesianChart {...props} kind=\"area\" />;\r\n}\r\n","import { CartesianChart, type CartesianChartCoreProps } from \"./chart/CartesianChart\";\r\n\r\nexport type BarChartProps = Omit<CartesianChartCoreProps, \"kind\" | \"stacked\">;\r\n\r\n/** Grouped bars — each series in a category sits side by side. For stacked segments, use `StackedBarChart`. */\r\nexport function BarChart(props: BarChartProps) {\r\n return <CartesianChart {...props} kind=\"bar\" stacked={false} />;\r\n}\r\n","import { CartesianChart, type CartesianChartCoreProps } from \"./chart/CartesianChart\";\r\n\r\nexport type StackedBarChartProps = Omit<CartesianChartCoreProps, \"kind\" | \"stacked\">;\r\n\r\n/** Every visible series stacks into one column per category. See `BarChart` for grouped bars. */\r\nexport function StackedBarChart(props: StackedBarChartProps) {\r\n return <CartesianChart {...props} kind=\"bar\" stacked={true} />;\r\n}\r\n","export interface ChartSliceSummaryProps {\n items: readonly { label: string; value: number }[];\n}\n\n/**\n * Visually-hidden textual/table fallback of a circular chart's data (doc:\n * \"ekran okuyucu için tablo veya metinsel veri özeti\") — name/value pairs,\n * the shape Donut/Pie slices actually have (`CartesianChart` builds its own\n * equivalent table inline, since its shape — a series per column — differs).\n */\nexport function ChartSliceSummary({ items }: ChartSliceSummaryProps) {\n return (\n <table>\n <caption>Chart data</caption>\n <thead>\n <tr>\n <th scope=\"col\">Category</th>\n <th scope=\"col\">Value</th>\n </tr>\n </thead>\n <tbody>\n {items.map((item, index) => (\n <tr key={index}>\n <th scope=\"row\">{item.label}</th>\n <td>{item.value}</td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n","import { useCallback, useState, type KeyboardEvent } from \"react\";\r\n\r\nexport interface UseChartIndexNavigationOptions {\r\n count: number;\r\n disabled?: boolean;\r\n onActivate?: (index: number) => void;\r\n onSelect?: (index: number) => void;\r\n}\r\n\r\nexport interface ChartIndexNavigation {\r\n activeIndex: number;\r\n setActiveIndex: (index: number) => void;\r\n clearActive: () => void;\r\n handleKeyDown: (event: KeyboardEvent) => void;\r\n}\r\n\r\n/**\r\n * Roving index navigation shared by every chart shape: Left/Right (or the\r\n * next/previous data point) moves the focused/hover point, Home/End jump to\r\n * the ends, Enter/Space fires the same callback a mouse click on that point\r\n * would (doc: \"veri noktasına tıklama\" and \"klavye ile veri noktaları arasında\r\n * hareket\" are one interaction model, not two). Used for x-categories in the\r\n * cartesian charts (Line/Area/Bar/StackedBar) and for slices in the circular\r\n * ones (Donut/Pie) — the math is identical, only what \"index\" means differs.\r\n */\r\nexport function useChartIndexNavigation({ count, disabled, onActivate, onSelect }: UseChartIndexNavigationOptions): ChartIndexNavigation {\r\n const [activeIndex, setActiveIndexState] = useState(-1);\r\n\r\n const setActiveIndex = useCallback(\r\n (index: number) => {\r\n setActiveIndexState(index);\r\n if (index >= 0) onActivate?.(index);\r\n },\r\n [onActivate]\r\n );\r\n\r\n const clearActive = useCallback(() => setActiveIndexState(-1), []);\r\n\r\n const handleKeyDown = useCallback(\r\n (event: KeyboardEvent) => {\r\n if (disabled || count === 0) return;\r\n switch (event.key) {\r\n case \"ArrowRight\":\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n setActiveIndex(activeIndex < 0 ? 0 : Math.min(activeIndex + 1, count - 1));\r\n break;\r\n case \"ArrowLeft\":\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n setActiveIndex(activeIndex < 0 ? count - 1 : Math.max(activeIndex - 1, 0));\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n setActiveIndex(0);\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n setActiveIndex(count - 1);\r\n break;\r\n case \"Enter\":\r\n case \" \":\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 [disabled, count, activeIndex, setActiveIndex, onSelect]\r\n );\r\n\r\n return { activeIndex, setActiveIndex, clearActive, handleKeyDown };\r\n}\r\n","import { useMemo, type ReactNode } from \"react\";\r\nimport { Chart } from \"../Chart\";\r\nimport { ChartLegend, type ChartLegendItem } from \"../ChartLegend\";\r\nimport { resolveChartColor } from \"./chartColors\";\r\nimport { ChartSliceSummary } from \"./ChartSliceSummary\";\r\nimport { ChartTooltip } from \"./ChartTooltip\";\r\nimport { useChartIndexNavigation } from \"./useChartIndexNavigation\";\r\nimport type { ChartCommonProps, ChartDatum, ChartSliceInteraction } from \"./chartTypes\";\r\n\r\nexport interface CircularChartBaseProps extends ChartCommonProps {\r\n variant: \"donut\" | \"pie\";\r\n data: ChartDatum[];\r\n nameKey: string;\r\n valueKey: string;\r\n /** Donut only — ratio of the inner cutout radius to the outer radius. Ignored (forced to 0) for `variant=\"pie\"`. */\r\n innerRadiusRatio?: number;\r\n /** Donut only — rendered in the center cutout. */\r\n centerLabel?: ReactNode;\r\n centerValue?: ReactNode;\r\n valueFormatter?: (value: number) => string;\r\n showDataLabels?: boolean;\r\n onSliceClick?: (interaction: ChartSliceInteraction) => void;\r\n}\r\n\r\ninterface Slice {\r\n key: string;\r\n label: string;\r\n value: number;\r\n percent: number;\r\n startAngle: number;\r\n endAngle: number;\r\n color: string;\r\n datum: ChartDatum;\r\n index: number;\r\n}\r\n\r\nfunction polar(cx: number, cy: number, r: number, angle: number): [number, number] {\r\n const rad = (angle - 90) * (Math.PI / 180);\r\n return [cx + r * Math.cos(rad), cy + r * Math.sin(rad)];\r\n}\r\n\r\n/** SVG path for one pie/donut wedge. A full circle (100%) is special-cased since an arc command can't describe 360deg. */\r\nfunction slicePath(cx: number, cy: number, outerR: number, innerR: number, startAngle: number, endAngle: number): string {\r\n const isFullCircle = endAngle - startAngle >= 359.999;\r\n const large = endAngle - startAngle > 180 ? 1 : 0;\r\n\r\n if (isFullCircle) {\r\n const [ox] = polar(cx, cy, outerR, 0);\r\n const [ox2] = polar(cx, cy, outerR, 180);\r\n if (innerR <= 0) {\r\n return `M ${ox},${cy} A ${outerR} ${outerR} 0 1 1 ${ox2},${cy} A ${outerR} ${outerR} 0 1 1 ${ox},${cy} Z`;\r\n }\r\n const [ix] = polar(cx, cy, innerR, 0);\r\n const [ix2] = polar(cx, cy, innerR, 180);\r\n return (\r\n `M ${ox},${cy} A ${outerR} ${outerR} 0 1 1 ${ox2},${cy} A ${outerR} ${outerR} 0 1 1 ${ox},${cy} Z ` +\r\n `M ${ix},${cy} A ${innerR} ${innerR} 0 1 0 ${ix2},${cy} A ${innerR} ${innerR} 0 1 0 ${ix},${cy} Z`\r\n );\r\n }\r\n\r\n const [x1, y1] = polar(cx, cy, outerR, startAngle);\r\n const [x2, y2] = polar(cx, cy, outerR, endAngle);\r\n\r\n if (innerR <= 0) {\r\n return `M ${cx},${cy} L ${x1},${y1} A ${outerR} ${outerR} 0 ${large} 1 ${x2},${y2} Z`;\r\n }\r\n\r\n const [x3, y3] = polar(cx, cy, innerR, endAngle);\r\n const [x4, y4] = polar(cx, cy, innerR, startAngle);\r\n return `M ${x1},${y1} A ${outerR} ${outerR} 0 ${large} 1 ${x2},${y2} L ${x3},${y3} A ${innerR} ${innerR} 0 ${large} 0 ${x4},${y4} Z`;\r\n}\r\n\r\n/** Shared renderer for DonutChart and PieChart. */\r\nexport function CircularChartBase({\r\n variant,\r\n data,\r\n nameKey,\r\n valueKey,\r\n innerRadiusRatio = variant === \"donut\" ? 0.62 : 0,\r\n centerLabel,\r\n centerValue,\r\n valueFormatter,\r\n showDataLabels,\r\n showLegend = true,\r\n colors,\r\n onSliceClick,\r\n ...chartProps\r\n}: CircularChartBaseProps) {\r\n const isEmpty = data.length === 0 || data.every((row) => Number(row[valueKey] ?? 0) <= 0);\r\n const formatValue = valueFormatter ?? ((value: number) => new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value));\r\n\r\n const slices = useMemo<Slice[]>(() => {\r\n const total = data.reduce((sum, row) => sum + Math.max(Number(row[valueKey] ?? 0), 0), 0);\r\n let angle = 0;\r\n return data.map((row, index) => {\r\n const value = Math.max(Number(row[valueKey] ?? 0), 0);\r\n const percent = total > 0 ? value / total : 0;\r\n const startAngle = angle;\r\n const endAngle = angle + percent * 360;\r\n angle = endAngle;\r\n return {\r\n key: String(row[nameKey] ?? index),\r\n label: String(row[nameKey] ?? `#${index + 1}`),\r\n value,\r\n percent,\r\n startAngle,\r\n endAngle,\r\n color: resolveChartColor(index, row.color as string | undefined, colors),\r\n datum: row,\r\n index,\r\n };\r\n });\r\n }, [data, nameKey, valueKey, colors]);\r\n\r\n const nav = useChartIndexNavigation({\r\n count: slices.length,\r\n onSelect: (index) => {\r\n const slice = slices[index];\r\n if (slice) onSliceClick?.({ key: slice.key, label: slice.label, value: slice.value, index, datum: slice.datum });\r\n },\r\n });\r\n\r\n const legendItems: ChartLegendItem[] = slices.map((slice) => ({ key: slice.key, label: slice.label, color: slice.color }));\r\n\r\n return (\r\n <Chart\r\n {...chartProps}\r\n isEmpty={isEmpty}\r\n legend={showLegend ? <ChartLegend items={legendItems} /> : undefined}\r\n summary={<ChartSliceSummary items={slices.map((slice) => ({ label: slice.label, value: slice.value }))} />}\r\n >\r\n {({ width, height }) => (\r\n <CircularSurface\r\n width={width}\r\n height={height}\r\n slices={slices}\r\n innerRadiusRatio={variant === \"pie\" ? 0 : innerRadiusRatio}\r\n centerLabel={centerLabel}\r\n centerValue={centerValue}\r\n formatValue={formatValue}\r\n showDataLabels={showDataLabels}\r\n nav={nav}\r\n onSliceClick={onSliceClick}\r\n />\r\n )}\r\n </Chart>\r\n );\r\n}\r\n\r\ninterface CircularSurfaceProps {\r\n width: number;\r\n height: number;\r\n slices: Slice[];\r\n innerRadiusRatio: number;\r\n centerLabel?: ReactNode;\r\n centerValue?: ReactNode;\r\n formatValue: (value: number) => string;\r\n showDataLabels?: boolean;\r\n nav: ReturnType<typeof useChartIndexNavigation>;\r\n onSliceClick?: (interaction: ChartSliceInteraction) => void;\r\n}\r\n\r\nfunction CircularSurface({ width, height, slices, innerRadiusRatio, centerLabel, centerValue, formatValue, showDataLabels, nav, onSliceClick }: CircularSurfaceProps) {\r\n const cx = width / 2;\r\n const cy = height / 2;\r\n const outerR = Math.max(Math.min(width, height) / 2 - 16, 1);\r\n const innerR = outerR * innerRadiusRatio;\r\n const activeIndex = nav.activeIndex;\r\n const activeSlice = activeIndex >= 0 ? slices[activeIndex] : undefined;\r\n\r\n const percentFormat = (value: number) => new Intl.NumberFormat(undefined, { style: \"percent\", maximumFractionDigits: 1 }).format(value);\r\n const tabbableIndex = activeIndex >= 0 ? activeIndex : 0;\r\n\r\n return (\r\n <div className=\"rrc-chart__plot-wrap\">\r\n {/*\r\n Deliberately no `role=\"img\"`/single tabIndex on the `<svg>`: each slice\r\n below is its own focusable `role=\"button\"` target with a real\r\n accessible name (doc: keyboard navigation between data points +\r\n \"tooltip içeriğinin klavye kullanıcılarına erişilebilir olması\"),\r\n following the same roving-tabindex pattern as `CartesianChart`'s\r\n column targets. The visually-hidden `<table>` (`ChartSliceSummary`) is\r\n the non-visual data summary.\r\n */}\r\n <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} className=\"rrc-chart__plot\">\r\n {slices.map((slice) => {\r\n const isActive = activeIndex === slice.index;\r\n const labelAngle = (slice.startAngle + slice.endAngle) / 2;\r\n const [labelX, labelY] = polar(cx, cy, (outerR + innerR) / 2, labelAngle);\r\n return (\r\n <g key={slice.key}>\r\n <path\r\n d={slicePath(cx, cy, isActive ? outerR + 4 : outerR, innerR, slice.startAngle, slice.endAngle)}\r\n fill={slice.color}\r\n className=\"rrc-chart__slice\"\r\n role=\"button\"\r\n tabIndex={slice.index === tabbableIndex ? 0 : -1}\r\n aria-label={`${slice.label}: ${formatValue(slice.value)} (${percentFormat(slice.percent)})`}\r\n onKeyDown={nav.handleKeyDown}\r\n onMouseEnter={() => nav.setActiveIndex(slice.index)}\r\n onFocus={() => nav.setActiveIndex(slice.index)}\r\n onClick={() => onSliceClick?.({ key: slice.key, label: slice.label, value: slice.value, index: slice.index, datum: slice.datum })}\r\n />\r\n {showDataLabels && slice.percent > 0.03 && (\r\n <text x={labelX} y={labelY} textAnchor=\"middle\" dominantBaseline=\"middle\" className=\"rrc-chart__data-label\">\r\n {percentFormat(slice.percent)}\r\n </text>\r\n )}\r\n </g>\r\n );\r\n })}\r\n\r\n {innerR > 0 && (centerLabel || centerValue) && (\r\n <g>\r\n {centerValue && (\r\n <text x={cx} y={cy - (centerLabel ? 8 : 0)} textAnchor=\"middle\" dominantBaseline=\"middle\" className=\"rrc-chart__center-value\">\r\n {centerValue}\r\n </text>\r\n )}\r\n {centerLabel && (\r\n <text x={cx} y={cy + (centerValue ? 14 : 0)} textAnchor=\"middle\" dominantBaseline=\"middle\" className=\"rrc-chart__center-label\">\r\n {centerLabel}\r\n </text>\r\n )}\r\n </g>\r\n )}\r\n </svg>\r\n\r\n {activeSlice && (\r\n <ChartTooltip\r\n payload={{\r\n label: activeSlice.label,\r\n items: [{ key: activeSlice.key, label: percentFormat(activeSlice.percent), value: formatValue(activeSlice.value), color: activeSlice.color }],\r\n }}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { CircularChartBase, type CircularChartBaseProps } from \"./chart/CircularChartBase\";\r\n\r\nexport type DonutChartProps = Omit<CircularChartBaseProps, \"variant\">;\r\n\r\n/** A `PieChart` with a cutout center — `centerLabel`/`centerValue` render inside it. */\r\nexport function DonutChart(props: DonutChartProps) {\r\n return <CircularChartBase {...props} variant=\"donut\" />;\r\n}\r\n","import { CircularChartBase, type CircularChartBaseProps } from \"./chart/CircularChartBase\";\r\n\r\nexport type PieChartProps = Omit<CircularChartBaseProps, \"variant\" | \"innerRadiusRatio\" | \"centerLabel\" | \"centerValue\">;\r\n\r\n/** A single metric broken into categories (`nameKey`/`valueKey` over `data`). For a cutout center, use `DonutChart`. */\r\nexport function PieChart(props: PieChartProps) {\r\n return <CircularChartBase {...props} variant=\"pie\" innerRadiusRatio={0} />;\r\n}\r\n","import { useEffect, useId, useMemo, useRef, useState, type KeyboardEvent, type ReactNode } from \"react\";\r\nimport { Alert } from \"./Alert\";\r\nimport { Button } from \"./Button\";\r\nimport { IconButton } from \"./IconButton\";\r\nimport { Skeleton } from \"./Skeleton\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\n\r\nexport type CalendarView = \"month\" | \"week\" | \"day\" | \"agenda\" | \"scheduler\";\r\nexport type CalendarEventVariant = \"primary\" | \"success\" | \"warning\" | \"danger\" | \"info\" | \"secondary\";\r\n\r\nexport interface CalendarEvent {\r\n id: string;\r\n title: string;\r\n start: Date | string;\r\n end?: Date | string;\r\n allDay?: boolean;\r\n color?: string;\r\n variant?: CalendarEventVariant;\r\n description?: string;\r\n disabled?: boolean;\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\nexport interface CalendarProps {\r\n value?: Date | null;\r\n defaultValue?: Date | null;\r\n onDateChange?: (date: Date) => void;\r\n events?: CalendarEvent[];\r\n /**\r\n * Only `\"month\"` is implemented in this release. The type accepts the rest\r\n * of the family so a future release can add them without a breaking prop\r\n * change; passing one today falls back to `\"month\"` with a dev warning\r\n * (known limitation — no week/day/agenda/scheduler view yet).\r\n */\r\n view?: CalendarView;\r\n /** BCP 47 locale for month/weekday names via `Intl.DateTimeFormat`. */\r\n locale?: string;\r\n /** 0 = Sunday, 1 = Monday. */\r\n weekStartsOn?: 0 | 1;\r\n min?: Date;\r\n max?: Date;\r\n disabledDates?: (date: Date) => boolean;\r\n maxEventsPerDay?: number;\r\n loading?: boolean;\r\n error?: ReactNode;\r\n className?: string;\r\n \"aria-label\"?: string;\r\n todayLabel?: string;\r\n moreLabel?: (count: number) => string;\r\n noEventsLabel?: string;\r\n onMonthChange?: (year: number, month: number) => void;\r\n onEventClick?: (event: CalendarEvent) => void;\r\n}\r\n\r\n/**\r\n * Timezone contract: every comparison here uses the `Date` object's local\r\n * getters (`getFullYear`/`getMonth`/`getDate`) and never `Date.UTC`/ISO\r\n * parsing for day-bucketing, so a day never silently shifts across a\r\n * timezone or DST boundary. `start`/`end` strings are parsed once with\r\n * `new Date(...)` (same as the platform's own `Date` constructor rules) and\r\n * only ever compared by local calendar day, never by instant.\r\n */\r\nfunction toDate(value: Date | string): Date {\r\n return value instanceof Date ? value : new Date(value);\r\n}\r\n\r\nfunction startOfDay(date: Date): Date {\r\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\r\n}\r\n\r\nfunction isSameDay(a: Date, b: Date): boolean {\r\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\r\n}\r\n\r\nfunction addDays(date: Date, amount: number): Date {\r\n const next = new Date(date);\r\n next.setDate(next.getDate() + amount);\r\n return next;\r\n}\r\n\r\nfunction addMonths(date: Date, amount: number): Date {\r\n return new Date(date.getFullYear(), date.getMonth() + amount, 1);\r\n}\r\n\r\n/** Always 42 cells (6 full weeks) so the grid's row count never jumps between months. */\r\nfunction buildMonthGrid(viewDate: Date, weekStartsOn: 0 | 1): Date[] {\r\n const first = new Date(viewDate.getFullYear(), viewDate.getMonth(), 1);\r\n const offset = (first.getDay() - weekStartsOn + 7) % 7;\r\n const start = addDays(first, -offset);\r\n return Array.from({ length: 42 }, (_, index) => addDays(start, index));\r\n}\r\n\r\nfunction eventOccursOnDay(event: CalendarEvent, day: Date): boolean {\r\n const start = startOfDay(toDate(event.start));\r\n const end = event.end ? startOfDay(toDate(event.end)) : start;\r\n const target = startOfDay(day);\r\n return target >= start && target <= end;\r\n}\r\n\r\nfunction chunk<T>(items: T[], size: number): T[][] {\r\n const result: T[][] = [];\r\n for (let index = 0; index < items.length; index += size) result.push(items.slice(index, index + size));\r\n return result;\r\n}\r\n\r\n/**\r\n * Month-view event calendar. Composes `Button`/`IconButton`/`Skeleton`/`Alert`\r\n * for chrome rather than reimplementing them (doc: reuse, don't duplicate).\r\n *\r\n * Known limitations: only `view=\"month\"` renders; no week/day/agenda/\r\n * scheduler view and no drag-and-drop event moving yet — the `view` prop and\r\n * `CalendarEvent` shape are deliberately future-proof for both.\r\n */\r\nexport function Calendar({\r\n value,\r\n defaultValue = null,\r\n onDateChange,\r\n events = [],\r\n view = \"month\",\r\n locale = \"en-US\",\r\n weekStartsOn = 1,\r\n min,\r\n max,\r\n disabledDates,\r\n maxEventsPerDay = 3,\r\n loading,\r\n error,\r\n className,\r\n \"aria-label\": ariaLabel,\r\n todayLabel = \"Today\",\r\n moreLabel = (count) => `+${count} more`,\r\n noEventsLabel = \"No events\",\r\n onMonthChange,\r\n onEventClick,\r\n}: CalendarProps) {\r\n if (process.env.NODE_ENV !== \"production\" && view !== \"month\") {\r\n // eslint-disable-next-line no-console\r\n console.warn(`[react-components] Calendar view \"${view}\" is not implemented yet; falling back to \"month\".`);\r\n }\r\n\r\n const [selected, setSelected] = useControllableState<Date | null>({\r\n value,\r\n defaultValue,\r\n // `selectDay` never passes `null` — only a day cell click sets this — so the\r\n // public `onDateChange` can stay typed as `(date: Date) => void`, matching the\r\n // task's own usage example, without narrowing `useControllableState` itself.\r\n onChange: (next) => {\r\n if (next) onDateChange?.(next);\r\n },\r\n });\r\n const today = useMemo(() => new Date(), []);\r\n const [viewDate, setViewDate] = useState(() => startOfMonthOf(selected ?? today));\r\n\r\n function startOfMonthOf(date: Date): Date {\r\n return new Date(date.getFullYear(), date.getMonth(), 1);\r\n }\r\n\r\n useEffect(() => {\r\n onMonthChange?.(viewDate.getFullYear(), viewDate.getMonth());\r\n // Fires on mount (initial range) and on every subsequent navigation — deliberately not gated to skip the first call.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [viewDate]);\r\n\r\n const grid = useMemo(() => buildMonthGrid(viewDate, weekStartsOn), [viewDate, weekStartsOn]);\r\n const weeks = useMemo(() => chunk(grid, 7), [grid]);\r\n\r\n const weekdayFormatter = useMemo(() => new Intl.DateTimeFormat(locale, { weekday: \"short\" }), [locale]);\r\n const titleFormatter = useMemo(() => new Intl.DateTimeFormat(locale, { month: \"long\", year: \"numeric\" }), [locale]);\r\n const dayLabelFormatter = useMemo(() => new Intl.DateTimeFormat(locale, { dateStyle: \"full\" }), [locale]);\r\n const weekdayLabels = useMemo(() => grid.slice(0, 7).map((day) => weekdayFormatter.format(day)), [grid, weekdayFormatter]);\r\n\r\n const eventsByDayKey = useMemo(() => {\r\n const map = new Map<string, CalendarEvent[]>();\r\n for (const day of grid) {\r\n const key = dateKey(day);\r\n map.set(\r\n key,\r\n events.filter((event) => eventOccursOnDay(event, day))\r\n );\r\n }\r\n return map;\r\n }, [grid, events]);\r\n\r\n function dateKey(day: Date): string {\r\n return `${day.getFullYear()}-${day.getMonth()}-${day.getDate()}`;\r\n }\r\n\r\n function isDisabledDay(day: Date): boolean {\r\n const target = startOfDay(day);\r\n if (min && target < startOfDay(min)) return true;\r\n if (max && target > startOfDay(max)) return true;\r\n return disabledDates?.(day) ?? false;\r\n }\r\n\r\n /** Falls back to today (or the grid's first cell) so the roving tabindex always has exactly one home. */\r\n function focusIndexFor(gridDays: Date[], selectedDate: Date | null): number {\r\n const selectedIndex = selectedDate ? gridDays.findIndex((day) => isSameDay(day, selectedDate)) : -1;\r\n if (selectedIndex >= 0) return selectedIndex;\r\n const todayIndex = gridDays.findIndex((day) => isSameDay(day, today));\r\n return todayIndex >= 0 ? todayIndex : 0;\r\n }\r\n\r\n // Deliberately a plain `useState` with no reactive resync effect: every path that\r\n // changes the visible month (`goToMonth`, `selectDay`) also sets `focusedIndex`\r\n // itself, in the same synchronous update. A `useEffect` that re-derived it from\r\n // `grid` instead would fire one render after `setViewDate`, doubling the render\r\n // pass on every navigation for no behavioral gain.\r\n const [focusedIndex, setFocusedIndex] = useState(() => focusIndexFor(grid, selected));\r\n\r\n const cellRefs = useRef<Array<HTMLButtonElement | null>>([]);\r\n\r\n /**\r\n * Focuses synchronously, in the same handler that calls `setFocusedIndex`\r\n * (mirrors `Tabs`' `activate`) rather than in a `useEffect` keyed on\r\n * `focusedIndex`. The target button is already mounted at this DOM\r\n * position — React reuses the same 42 cell nodes across a month change, it\r\n * just repaints their content — so there's no need to wait for the next\r\n * commit before moving focus.\r\n */\r\n function focusCell(index: number) {\r\n cellRefs.current[index]?.focus();\r\n }\r\n\r\n function goToMonth(next: Date, keepSelected: Date | null = selected) {\r\n const targetMonth = startOfMonthOf(next);\r\n setViewDate(targetMonth);\r\n setFocusedIndex(focusIndexFor(buildMonthGrid(targetMonth, weekStartsOn), keepSelected));\r\n }\r\n\r\n function selectDay(day: Date, index: number) {\r\n if (isDisabledDay(day)) return;\r\n setSelected(day);\r\n if (day.getMonth() !== viewDate.getMonth() || day.getFullYear() !== viewDate.getFullYear()) {\r\n const targetIndex = buildMonthGrid(startOfMonthOf(day), weekStartsOn).findIndex((gridDay) => isSameDay(gridDay, day));\r\n goToMonth(day, day);\r\n focusCell(targetIndex >= 0 ? targetIndex : index);\r\n } else {\r\n setFocusedIndex(index);\r\n focusCell(index);\r\n }\r\n }\r\n\r\n function moveFocus(nextIndex: number) {\r\n const clamped = Math.max(0, Math.min(41, nextIndex));\r\n setFocusedIndex(clamped);\r\n focusCell(clamped);\r\n }\r\n\r\n function handleGridKeyDown(event: KeyboardEvent<HTMLDivElement>) {\r\n switch (event.key) {\r\n case \"ArrowRight\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex + 1);\r\n break;\r\n case \"ArrowLeft\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex - 1);\r\n break;\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex + 7);\r\n break;\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex - 7);\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex - (focusedIndex % 7));\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex - (focusedIndex % 7) + 6);\r\n break;\r\n case \"PageUp\":\r\n event.preventDefault();\r\n goToMonth(addMonths(viewDate, -1));\r\n break;\r\n case \"PageDown\":\r\n event.preventDefault();\r\n goToMonth(addMonths(viewDate, 1));\r\n break;\r\n case \"Enter\":\r\n case \" \":\r\n event.preventDefault();\r\n selectDay(grid[focusedIndex]!, focusedIndex);\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n const title = titleFormatter.format(viewDate);\r\n const disabled = Boolean(loading || error);\r\n const rootId = useId();\r\n\r\n return (\r\n <div className={cx(\"rrc-calendar\", className)} aria-label={ariaLabel ?? title}>\r\n <div className=\"rrc-calendar__header\">\r\n <IconButton icon=\"bi bi-chevron-left\" aria-label=\"Previous month\" onClick={() => goToMonth(addMonths(viewDate, -1))} disabled={disabled} size=\"sm\" variant=\"light-secondary\" />\r\n <Button size=\"sm\" variant=\"light-secondary\" onClick={() => goToMonth(today)} disabled={disabled}>\r\n {todayLabel}\r\n </Button>\r\n <div className=\"rrc-calendar__title\" aria-live=\"polite\" id={rootId}>\r\n {title}\r\n </div>\r\n <IconButton icon=\"bi bi-chevron-right\" aria-label=\"Next month\" onClick={() => goToMonth(addMonths(viewDate, 1))} disabled={disabled} size=\"sm\" variant=\"light-secondary\" />\r\n </div>\r\n\r\n {error ? (\r\n <Alert variant=\"danger\" className=\"mb-0\">\r\n {error}\r\n </Alert>\r\n ) : loading ? (\r\n <div className=\"rrc-calendar__skeleton\" aria-busy=\"true\">\r\n {Array.from({ length: 6 }, (_, index) => (\r\n <Skeleton key={index} height=\"4.5rem\" />\r\n ))}\r\n </div>\r\n ) : (\r\n <>\r\n <div className=\"rrc-calendar__weekdays\" role=\"row\">\r\n {weekdayLabels.map((label, index) => (\r\n <div key={index} className=\"rrc-calendar__weekday\" role=\"columnheader\" aria-label={label}>\r\n {label}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n <div className=\"rrc-calendar__grid\" role=\"grid\" aria-labelledby={rootId} onKeyDown={handleGridKeyDown}>\r\n {weeks.map((week, weekIndex) => (\r\n <div key={weekIndex} className=\"rrc-calendar__week\" role=\"row\">\r\n {week.map((day, dayIndex) => {\r\n const index = weekIndex * 7 + dayIndex;\r\n const isOutside = day.getMonth() !== viewDate.getMonth();\r\n const isToday = isSameDay(day, today);\r\n const isSelected = selected ? isSameDay(day, selected) : false;\r\n const dayDisabled = isDisabledDay(day);\r\n const dayEvents = eventsByDayKey.get(dateKey(day)) ?? [];\r\n const visibleEvents = dayEvents.slice(0, maxEventsPerDay);\r\n const overflowCount = dayEvents.length - visibleEvents.length;\r\n\r\n const dayAriaLabel = [dayLabelFormatter.format(day), isToday && \"today\", dayEvents.length > 0 && `${dayEvents.length} events`].filter(Boolean).join(\", \");\r\n\r\n return (\r\n <div\r\n key={index}\r\n role=\"gridcell\"\r\n aria-selected={isSelected || undefined}\r\n aria-current={isToday ? \"date\" : undefined}\r\n aria-disabled={dayDisabled || undefined}\r\n className={cx(\r\n \"rrc-calendar__day\",\r\n isOutside && \"rrc-calendar__day--outside\",\r\n isToday && \"rrc-calendar__day--today\",\r\n isSelected && \"rrc-calendar__day--selected\",\r\n dayDisabled && \"rrc-calendar__day--disabled\"\r\n )}\r\n >\r\n <button\r\n type=\"button\"\r\n ref={(element) => {\r\n cellRefs.current[index] = element;\r\n }}\r\n className=\"rrc-calendar__day-button\"\r\n tabIndex={index === focusedIndex ? 0 : -1}\r\n disabled={dayDisabled}\r\n aria-label={dayAriaLabel}\r\n onClick={() => selectDay(day, index)}\r\n >\r\n {day.getDate()}\r\n </button>\r\n {(visibleEvents.length > 0 || overflowCount > 0) && (\r\n <div className=\"rrc-calendar__events\">\r\n {visibleEvents.map((eventItem) => (\r\n <button\r\n key={eventItem.id}\r\n type=\"button\"\r\n className={cx(\"rrc-calendar__event\", `rrc-calendar__event--${eventItem.variant ?? \"primary\"}`)}\r\n style={eventItem.color ? { backgroundColor: eventItem.color } : undefined}\r\n disabled={eventItem.disabled}\r\n title={eventItem.title}\r\n onClick={(clickEvent) => {\r\n clickEvent.stopPropagation();\r\n if (!eventItem.disabled) onEventClick?.(eventItem);\r\n }}\r\n >\r\n {eventItem.title}\r\n </button>\r\n ))}\r\n {overflowCount > 0 && (\r\n <button\r\n type=\"button\"\r\n className=\"rrc-calendar__more\"\r\n onClick={(clickEvent) => {\r\n clickEvent.stopPropagation();\r\n selectDay(day, index);\r\n }}\r\n >\r\n {moreLabel(overflowCount)}\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n <div className=\"rrc-calendar__agenda d-md-none\">\r\n <div className=\"rrc-calendar__agenda-title\">{dayLabelFormatter.format(selected ?? today)}</div>\r\n {(eventsByDayKey.get(dateKey(selected ?? today)) ?? []).length === 0 ? (\r\n <div className=\"rrc-calendar__agenda-empty\">{noEventsLabel}</div>\r\n ) : (\r\n <ul className=\"rrc-calendar__agenda-list\">\r\n {(eventsByDayKey.get(dateKey(selected ?? today)) ?? []).map((eventItem) => (\r\n <li key={eventItem.id}>\r\n <button type=\"button\" className=\"rrc-calendar__agenda-item\" disabled={eventItem.disabled} onClick={() => !eventItem.disabled && onEventClick?.(eventItem)}>\r\n {eventItem.title}\r\n </button>\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useEffect, useRef, useState, type MouseEvent as ReactMouseEvent } from \"react\";\r\nimport { IconButton } from \"./IconButton\";\r\nimport { Icon } from \"./Icon\";\r\nimport { Modal } from \"./Modal\";\r\nimport { Spinner } from \"./Spinner\";\r\nimport { Text } from \"./Text\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { useElementResize } from \"./shared/useElementResize\";\r\n\r\nexport type DocumentViewerSource = string | Blob | ArrayBuffer;\r\n\r\nexport type DocumentViewerErrorKind = \"unsupported\" | \"password-protected\" | \"corrupted\" | \"network\" | \"unknown\";\r\n\r\nexport interface DocumentViewerError {\r\n kind: DocumentViewerErrorKind;\r\n message: string;\r\n}\r\n\r\nexport interface DocumentViewerLabels {\r\n loading?: string;\r\n unsupported?: string;\r\n passwordProtected?: string;\r\n corrupted?: string;\r\n networkError?: string;\r\n download?: string;\r\n zoomIn?: string;\r\n zoomOut?: string;\r\n fitToWidth?: string;\r\n fitToView?: string;\r\n rotate?: string;\r\n fullscreen?: string;\r\n exitFullscreen?: string;\r\n previousPage?: string;\r\n nextPage?: string;\r\n page?: string;\r\n of?: string;\r\n openInNewTab?: string;\r\n}\r\n\r\nexport interface DocumentViewerProps {\r\n source: DocumentViewerSource;\r\n fileName?: string;\r\n /** MIME type, when known. Falls back to a safe guess from `fileName`'s extension when omitted. */\r\n mimeType?: string;\r\n className?: string;\r\n /** Viewer surface height. Defaults to a fixed comfortable reading height rather than growing unbounded with page content. */\r\n height?: number | string;\r\n initialPage?: number;\r\n toolbar?: boolean;\r\n allowFullscreen?: boolean;\r\n allowNewTab?: boolean;\r\n /** No central i18n catalog lives in Base (doc: Smart owns the one exception) — override the visible strings here instead. */\r\n labels?: DocumentViewerLabels;\r\n /** Called instead of the built-in download behavior when supplied. */\r\n onDownload?: () => void;\r\n onError?: (error: DocumentViewerError) => void;\r\n onPageChange?: (page: number, totalPages: number) => void;\r\n}\r\n\r\ntype FileKind = \"pdf\" | \"image\" | \"unsupported\";\r\ntype ViewerStatus = \"loading\" | \"ready\" | \"error\";\r\ntype FitMode = \"none\" | \"width\" | \"view\";\r\n\r\nconst DEFAULT_LABELS: Required<DocumentViewerLabels> = {\r\n loading: \"Loading document…\",\r\n unsupported: \"This file type cannot be previewed.\",\r\n passwordProtected: \"This PDF is password protected and cannot be previewed.\",\r\n corrupted: \"This file appears to be corrupted and cannot be previewed.\",\r\n networkError: \"The document could not be loaded. Check your connection and try again.\",\r\n download: \"Download\",\r\n zoomIn: \"Zoom in\",\r\n zoomOut: \"Zoom out\",\r\n fitToWidth: \"Fit to width\",\r\n fitToView: \"Fit to view\",\r\n rotate: \"Rotate\",\r\n fullscreen: \"Fullscreen\",\r\n exitFullscreen: \"Exit fullscreen\",\r\n previousPage: \"Previous page\",\r\n nextPage: \"Next page\",\r\n page: \"Page\",\r\n of: \"of\",\r\n openInNewTab: \"Open in new tab\",\r\n};\r\n\r\nconst IMAGE_MIME_TYPES = new Set([\"image/png\", \"image/jpeg\", \"image/webp\", \"image/gif\"]);\r\n\r\nconst EXTENSION_MIME_TYPES: Record<string, string> = {\r\n pdf: \"application/pdf\",\r\n png: \"image/png\",\r\n jpg: \"image/jpeg\",\r\n jpeg: \"image/jpeg\",\r\n webp: \"image/webp\",\r\n gif: \"image/gif\",\r\n};\r\n\r\nfunction resolveMimeType(mimeType: string | undefined, fileName: string | undefined): string | undefined {\r\n if (mimeType) return mimeType;\r\n const ext = fileName?.split(\".\").pop()?.toLowerCase();\r\n return ext ? EXTENSION_MIME_TYPES[ext] : undefined;\r\n}\r\n\r\nfunction classifyMimeType(mime: string | undefined): FileKind {\r\n if (mime === \"application/pdf\") return \"pdf\";\r\n if (mime && IMAGE_MIME_TYPES.has(mime)) return \"image\";\r\n return \"unsupported\";\r\n}\r\n\r\nasync function toObjectUrl(source: Blob | ArrayBuffer, mime: string | undefined): Promise<string> {\r\n const blob = source instanceof Blob ? source : new Blob([source], mime ? { type: mime } : undefined);\r\n return URL.createObjectURL(blob);\r\n}\r\n\r\n/**\r\n * `<a download>` clicked synchronously, then the object URL is revoked on the\r\n * next tick — revoking immediately breaks the download in some browsers\r\n * because navigation to the blob URL hasn't started yet.\r\n */\r\nfunction triggerDownload(url: string, fileName: string | undefined, revoke: boolean) {\r\n const link = document.createElement(\"a\");\r\n link.href = url;\r\n if (fileName) link.download = fileName;\r\n link.rel = \"noopener\";\r\n document.body.appendChild(link);\r\n link.click();\r\n link.remove();\r\n if (revoke) setTimeout(() => URL.revokeObjectURL(url), 0);\r\n}\r\n\r\nlet workerConfigured = false;\r\n\r\n/**\r\n * Set once per page load — every PDF render after the first reuses the same\r\n * worker. The `?url` suffix is Vite's asset-URL import: it resolves at *this\r\n * library's own* build time, so `dist/` ships the worker file already copied\r\n * next to the bundle with a content-hashed name and this import already\r\n * rewritten to a plain string. A consumer's own bundler (Vite, webpack, or\r\n * otherwise) never has to understand `?url` itself or configure a worker path.\r\n */\r\nasync function configurePdfWorker(pdfjsLib: typeof import(\"pdfjs-dist\")): Promise<void> {\r\n if (workerConfigured) return;\r\n // `?url` has no ambient type without adding `vite/client` to the project-wide\r\n // tsconfig; the runtime shape is a plain `{ default: string }` module either way.\r\n // @ts-expect-error -- Vite-only asset-URL import, resolved at this library's own build time.\r\n const workerUrl = (await import(\"pdfjs-dist/build/pdf.worker.min.mjs?url\")) as { default: string };\r\n pdfjsLib.GlobalWorkerOptions.workerSrc = workerUrl.default;\r\n workerConfigured = true;\r\n}\r\n\r\nfunction classifyPdfError(error: unknown, labels: Required<DocumentViewerLabels>): DocumentViewerError {\r\n const name = (error as { name?: string } | null)?.name;\r\n if (name === \"PasswordException\") return { kind: \"password-protected\", message: labels.passwordProtected };\r\n if (name === \"InvalidPDFException\" || name === \"MissingPDFException\") return { kind: \"corrupted\", message: labels.corrupted };\r\n if (name === \"UnexpectedResponseException\" || error instanceof TypeError) return { kind: \"network\", message: labels.networkError };\r\n return { kind: \"unknown\", message: labels.corrupted };\r\n}\r\n\r\ninterface PdfDocumentLike {\r\n numPages: number;\r\n getPage(pageNumber: number): Promise<PdfPageLike>;\r\n destroy(): Promise<void> | void;\r\n}\r\n\r\ninterface PdfPageLike {\r\n getViewport(params: { scale: number; rotation?: number }): { width: number; height: number };\r\n render(params: { canvasContext: CanvasRenderingContext2D; viewport: unknown }): { promise: Promise<void>; cancel(): void };\r\n}\r\n\r\nfunction StatusPanel({ icon, title, message, fileName, showDownload, onDownload, downloadLabel }: {\r\n icon: string;\r\n title: string;\r\n message?: string;\r\n fileName?: string;\r\n showDownload: boolean;\r\n onDownload: () => void;\r\n downloadLabel: string;\r\n}) {\r\n return (\r\n <div className=\"rrc-document-viewer__status\">\r\n <Icon name={icon} size=\"xl\" className=\"rrc-document-viewer__status-icon\" />\r\n <Text as=\"div\" weight=\"semibold\" className=\"rrc-document-viewer__status-title\">\r\n {title}\r\n </Text>\r\n {message && (\r\n <Text as=\"div\" size=\"sm\" tone=\"muted\" className=\"rrc-document-viewer__status-message\">\r\n {message}\r\n </Text>\r\n )}\r\n {fileName && (\r\n <Text as=\"div\" size=\"sm\" tone=\"muted\" className=\"rrc-document-viewer__meta\">\r\n {fileName}\r\n </Text>\r\n )}\r\n {showDownload && (\r\n <button type=\"button\" className=\"btn btn-light-primary rrc-btn rrc-btn--light-primary mt-2\" onClick={onDownload}>\r\n {downloadLabel}\r\n </button>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * Previews PDF and common image formats without leaking SVG/canvas/portal\r\n * plumbing to the consumer — a document/file card, a native `<embed>`, a\r\n * third-party viewer, or a bespoke zoom/rotate/pagination toolbar are never\r\n * something a consumer of this library builds by hand.\r\n *\r\n * `pdfjs-dist` is imported lazily (only once a PDF `source` is actually\r\n * rendered), so an app that only ever previews images never pays for it.\r\n * SVG/HTML/script sources are never rendered directly — anything outside the\r\n * five supported formats below falls back to a file-info + download panel.\r\n */\r\nexport function DocumentViewer({\r\n source,\r\n fileName,\r\n mimeType,\r\n className,\r\n height = 480,\r\n initialPage = 1,\r\n toolbar = true,\r\n allowFullscreen = true,\r\n allowNewTab = true,\r\n labels,\r\n onDownload,\r\n onError,\r\n onPageChange,\r\n}: DocumentViewerProps) {\r\n const resolvedLabels: Required<DocumentViewerLabels> = { ...DEFAULT_LABELS, ...labels };\r\n\r\n const [kind, setKind] = useState<FileKind>(\"unsupported\");\r\n const [status, setStatus] = useState<ViewerStatus>(\"loading\");\r\n const [error, setError] = useState<DocumentViewerError | null>(null);\r\n const [imageUrl, setImageUrl] = useState<string | undefined>(undefined);\r\n const [totalPages, setTotalPages] = useState(0);\r\n const [currentPage, setCurrentPage] = useState(initialPage);\r\n const [fitMode, setFitMode] = useState<FitMode>(\"width\");\r\n const [manualScale, setManualScale] = useState(1);\r\n const [rotation, setRotation] = useState(0);\r\n const [fullscreen, setFullscreen] = useState(false);\r\n\r\n const pdfDocRef = useRef<PdfDocumentLike | null>(null);\r\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\r\n const containerRef = useRef<HTMLDivElement | null>(null);\r\n const [containerSize, setContainerSize] = useState({ width: 0, height: 0 });\r\n const onErrorRef = useRef(onError);\r\n onErrorRef.current = onError;\r\n const onPageChangeRef = useRef(onPageChange);\r\n onPageChangeRef.current = onPageChange;\r\n\r\n useElementResize(containerRef, true, () => {\r\n const rect = containerRef.current?.getBoundingClientRect();\r\n if (rect) setContainerSize({ width: rect.width, height: rect.height });\r\n });\r\n\r\n // Loads the document whenever its identity changes; tears down the loading\r\n // task / pdf handle / object URL from the *previous* source on every run,\r\n // including unmount, so nothing outlives the source it was created for.\r\n useEffect(() => {\r\n let cancelled = false;\r\n let objectUrl: string | undefined;\r\n let loadingTask: { promise: Promise<PdfDocumentLike>; destroy(): void } | undefined;\r\n\r\n setStatus(\"loading\");\r\n setError(null);\r\n setImageUrl(undefined);\r\n setTotalPages(0);\r\n setCurrentPage(initialPage);\r\n setFitMode(\"width\");\r\n setManualScale(1);\r\n setRotation(0);\r\n\r\n const mime = resolveMimeType(mimeType, fileName);\r\n const fileKind = classifyMimeType(mime);\r\n setKind(fileKind);\r\n\r\n async function load() {\r\n if (fileKind === \"unsupported\") {\r\n const info: DocumentViewerError = { kind: \"unsupported\", message: resolvedLabels.unsupported };\r\n if (!cancelled) {\r\n setError(info);\r\n setStatus(\"error\");\r\n }\r\n onErrorRef.current?.(info);\r\n return;\r\n }\r\n\r\n if (fileKind === \"image\") {\r\n const url = typeof source === \"string\" ? source : await toObjectUrl(source, mime);\r\n if (typeof source !== \"string\") objectUrl = url;\r\n if (cancelled) return;\r\n setImageUrl(url);\r\n // `status` flips to \"ready\" from the <img onLoad>/onError handlers below.\r\n return;\r\n }\r\n\r\n const pdfjsLib = await import(\"pdfjs-dist\");\r\n if (cancelled) return;\r\n await configurePdfWorker(pdfjsLib);\r\n\r\n const input =\r\n typeof source === \"string\"\r\n ? { url: source }\r\n : source instanceof Blob\r\n ? { data: new Uint8Array(await source.arrayBuffer()) }\r\n : { data: new Uint8Array(source) };\r\n\r\n loadingTask = pdfjsLib.getDocument(input as never) as unknown as { promise: Promise<PdfDocumentLike>; destroy(): void };\r\n try {\r\n const pdf = await loadingTask.promise;\r\n if (cancelled) {\r\n pdf.destroy();\r\n return;\r\n }\r\n pdfDocRef.current = pdf;\r\n setTotalPages(pdf.numPages);\r\n setCurrentPage((page) => Math.min(Math.max(page, 1), pdf.numPages));\r\n setStatus(\"ready\");\r\n } catch (err) {\r\n if (cancelled) return;\r\n const info = classifyPdfError(err, resolvedLabels);\r\n setError(info);\r\n setStatus(\"error\");\r\n onErrorRef.current?.(info);\r\n }\r\n }\r\n\r\n load();\r\n\r\n return () => {\r\n cancelled = true;\r\n loadingTask?.destroy();\r\n pdfDocRef.current?.destroy();\r\n pdfDocRef.current = null;\r\n if (objectUrl) URL.revokeObjectURL(objectUrl);\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [source, mimeType, fileName]);\r\n\r\n // Renders the current page to the canvas. Re-runs on page/zoom/rotation\r\n // changes and cancels the in-flight render task on cleanup so a fast zoom\r\n // or page flip never races an older render onto the canvas.\r\n useEffect(() => {\r\n if (kind !== \"pdf\" || status !== \"ready\" || !pdfDocRef.current) return;\r\n let cancelled = false;\r\n let task: { promise: Promise<void>; cancel(): void } | undefined;\r\n\r\n (async () => {\r\n const pdf = pdfDocRef.current;\r\n if (!pdf) return;\r\n const page = await pdf.getPage(currentPage);\r\n if (cancelled) return;\r\n\r\n const baseViewport = page.getViewport({ scale: 1, rotation });\r\n const width = containerSize.width || baseViewport.width;\r\n const height = containerSize.height || baseViewport.height;\r\n const scale =\r\n fitMode === \"width\"\r\n ? width / baseViewport.width\r\n : fitMode === \"view\"\r\n ? Math.min(width / baseViewport.width, height / baseViewport.height)\r\n : manualScale;\r\n\r\n const viewport = page.getViewport({ scale, rotation });\r\n const canvas = canvasRef.current;\r\n const ctx = canvas?.getContext(\"2d\");\r\n if (!canvas || !ctx || cancelled) return;\r\n\r\n canvas.width = viewport.width;\r\n canvas.height = viewport.height;\r\n task = page.render({ canvasContext: ctx, viewport });\r\n try {\r\n await task.promise;\r\n } catch (err) {\r\n if ((err as { name?: string } | null)?.name !== \"RenderingCancelledException\") throw err;\r\n }\r\n })().catch((err) => {\r\n if (cancelled) return;\r\n const info = classifyPdfError(err, resolvedLabels);\r\n setError(info);\r\n setStatus(\"error\");\r\n onErrorRef.current?.(info);\r\n });\r\n\r\n return () => {\r\n cancelled = true;\r\n task?.cancel();\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [kind, status, currentPage, rotation, fitMode, manualScale, containerSize.width, containerSize.height]);\r\n\r\n useEffect(() => {\r\n if (kind === \"pdf\" && status === \"ready\") onPageChangeRef.current?.(currentPage, totalPages);\r\n }, [kind, status, currentPage, totalPages]);\r\n\r\n function handleDownload() {\r\n if (onDownload) {\r\n onDownload();\r\n return;\r\n }\r\n if (typeof source === \"string\") {\r\n triggerDownload(source, fileName, false);\r\n return;\r\n }\r\n toObjectUrl(source, resolveMimeType(mimeType, fileName)).then((url) => triggerDownload(url, fileName, true));\r\n }\r\n\r\n function handleOpenInNewTab(event: ReactMouseEvent) {\r\n event.preventDefault();\r\n if (typeof source === \"string\") {\r\n window.open(source, \"_blank\", \"noopener\");\r\n return;\r\n }\r\n toObjectUrl(source, resolveMimeType(mimeType, fileName)).then((url) => {\r\n window.open(url, \"_blank\", \"noopener\");\r\n setTimeout(() => URL.revokeObjectURL(url), 60_000);\r\n });\r\n }\r\n\r\n function zoomIn() {\r\n setFitMode(\"none\");\r\n setManualScale((scale) => Math.min(scale * 1.25, 4));\r\n }\r\n function zoomOut() {\r\n setFitMode(\"none\");\r\n setManualScale((scale) => Math.max(scale / 1.25, 0.25));\r\n }\r\n function rotate() {\r\n setRotation((value) => (value + 90) % 360);\r\n }\r\n\r\n const isPreviewable = kind === \"pdf\" || kind === \"image\";\r\n\r\n function renderToolbar() {\r\n // The status panel is self-contained (it carries its own download action),\r\n // and paging/zoom/rotate/new-tab make no sense against a document that\r\n // failed to load, so the toolbar steps aside entirely rather than showing\r\n // a second, redundant \"Download\" control next to the panel's own.\r\n if (!toolbar || status === \"error\") return null;\r\n return (\r\n <div className=\"rrc-document-viewer__toolbar\">\r\n <div className=\"rrc-document-viewer__toolbar-group\">\r\n {kind === \"pdf\" && status === \"ready\" && (\r\n <>\r\n <IconButton\r\n icon=\"bi bi-chevron-left\"\r\n aria-label={resolvedLabels.previousPage}\r\n tooltip={resolvedLabels.previousPage}\r\n size=\"sm\"\r\n variant=\"light-secondary\"\r\n disabled={currentPage <= 1}\r\n onClick={() => setCurrentPage((page) => Math.max(1, page - 1))}\r\n />\r\n <span className=\"rrc-document-viewer__page-indicator\" aria-live=\"polite\">\r\n {resolvedLabels.page} {currentPage} {resolvedLabels.of} {totalPages}\r\n </span>\r\n <IconButton\r\n icon=\"bi bi-chevron-right\"\r\n aria-label={resolvedLabels.nextPage}\r\n tooltip={resolvedLabels.nextPage}\r\n size=\"sm\"\r\n variant=\"light-secondary\"\r\n disabled={currentPage >= totalPages}\r\n onClick={() => setCurrentPage((page) => Math.min(totalPages, page + 1))}\r\n />\r\n </>\r\n )}\r\n </div>\r\n <div className=\"rrc-document-viewer__toolbar-group\">\r\n {isPreviewable && status === \"ready\" && (\r\n <>\r\n <IconButton icon=\"bi bi-zoom-out\" aria-label={resolvedLabels.zoomOut} tooltip={resolvedLabels.zoomOut} size=\"sm\" variant=\"light-secondary\" onClick={zoomOut} />\r\n <IconButton icon=\"bi bi-zoom-in\" aria-label={resolvedLabels.zoomIn} tooltip={resolvedLabels.zoomIn} size=\"sm\" variant=\"light-secondary\" onClick={zoomIn} />\r\n <IconButton\r\n icon=\"bi bi-arrows-angle-expand\"\r\n aria-label={resolvedLabels.fitToWidth}\r\n tooltip={resolvedLabels.fitToWidth}\r\n size=\"sm\"\r\n variant={fitMode === \"width\" ? \"light-primary\" : \"light-secondary\"}\r\n onClick={() => setFitMode(\"width\")}\r\n />\r\n <IconButton\r\n icon=\"bi bi-aspect-ratio\"\r\n aria-label={resolvedLabels.fitToView}\r\n tooltip={resolvedLabels.fitToView}\r\n size=\"sm\"\r\n variant={fitMode === \"view\" ? \"light-primary\" : \"light-secondary\"}\r\n onClick={() => setFitMode(\"view\")}\r\n />\r\n <IconButton icon=\"bi bi-arrow-clockwise\" aria-label={resolvedLabels.rotate} tooltip={resolvedLabels.rotate} size=\"sm\" variant=\"light-secondary\" onClick={rotate} />\r\n </>\r\n )}\r\n {allowNewTab && (\r\n <IconButton\r\n icon=\"bi bi-box-arrow-up-right\"\r\n aria-label={resolvedLabels.openInNewTab}\r\n tooltip={resolvedLabels.openInNewTab}\r\n size=\"sm\"\r\n variant=\"light-secondary\"\r\n onClick={handleOpenInNewTab}\r\n />\r\n )}\r\n <IconButton icon=\"bi bi-download\" aria-label={resolvedLabels.download} tooltip={resolvedLabels.download} size=\"sm\" variant=\"light-secondary\" onClick={handleDownload} />\r\n {allowFullscreen && (\r\n <IconButton\r\n icon={fullscreen ? \"bi bi-fullscreen-exit\" : \"bi bi-arrows-fullscreen\"}\r\n aria-label={fullscreen ? resolvedLabels.exitFullscreen : resolvedLabels.fullscreen}\r\n tooltip={fullscreen ? resolvedLabels.exitFullscreen : resolvedLabels.fullscreen}\r\n size=\"sm\"\r\n variant=\"light-secondary\"\r\n onClick={() => setFullscreen((value) => !value)}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n function renderSurface() {\r\n if (status === \"error\" && error) {\r\n const icon =\r\n error.kind === \"password-protected\"\r\n ? \"bi bi-shield-lock\"\r\n : error.kind === \"network\"\r\n ? \"bi bi-wifi-off\"\r\n : error.kind === \"unsupported\"\r\n ? \"bi bi-file-earmark-x\"\r\n : \"bi bi-exclamation-triangle\";\r\n return (\r\n <StatusPanel\r\n icon={icon}\r\n title={error.message}\r\n fileName={fileName}\r\n showDownload\r\n onDownload={handleDownload}\r\n downloadLabel={resolvedLabels.download}\r\n />\r\n );\r\n }\r\n\r\n // The <img> mounts as soon as a URL is resolved, even while `status` is\r\n // still \"loading\" — its own onLoad/onError is what flips `status`, so it\r\n // has to already be in the DOM for that event to ever fire.\r\n if (kind === \"image\" && imageUrl) {\r\n const transform = `scale(${fitMode === \"none\" ? manualScale : 1}) rotate(${rotation}deg)`;\r\n return (\r\n <div className=\"rrc-document-viewer__surface\" ref={containerRef}>\r\n <img\r\n src={imageUrl}\r\n alt={fileName ?? \"Document preview\"}\r\n className={cx(\"rrc-document-viewer__image\", fitMode !== \"none\" && `rrc-document-viewer__image--fit-${fitMode}`)}\r\n style={{ transform }}\r\n onLoad={() => setStatus(\"ready\")}\r\n onError={() => {\r\n const info: DocumentViewerError = { kind: \"network\", message: resolvedLabels.networkError };\r\n setError(info);\r\n setStatus(\"error\");\r\n onErrorRef.current?.(info);\r\n }}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n if (status === \"loading\") {\r\n return (\r\n <div className=\"rrc-document-viewer__status\">\r\n <Spinner label={resolvedLabels.loading} />\r\n <Text as=\"div\" size=\"sm\" tone=\"muted\">\r\n {resolvedLabels.loading}\r\n </Text>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"rrc-document-viewer__surface\" ref={containerRef}>\r\n <canvas\r\n ref={canvasRef}\r\n className=\"rrc-document-viewer__page\"\r\n role=\"img\"\r\n aria-label={`${resolvedLabels.page} ${currentPage} ${resolvedLabels.of} ${totalPages}`}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n const body = (\r\n <div className={cx(\"rrc-document-viewer\", fullscreen && \"rrc-document-viewer--fullscreen\", className)} style={fullscreen ? undefined : { height }}>\r\n {renderToolbar()}\r\n {renderSurface()}\r\n </div>\r\n );\r\n\r\n if (fullscreen) {\r\n return (\r\n <Modal open onClose={() => setFullscreen(false)} title={fileName} className=\"rrc-document-viewer__modal\">\r\n {body}\r\n </Modal>\r\n );\r\n }\r\n\r\n return body;\r\n}\r\n","import { useId, useRef, type KeyboardEvent, type ReactNode } from \"react\";\r\nimport {\r\n SIDEBAR_PRESENTATIONS,\r\n SIDEBAR_TONES,\r\n THEME_MODES,\r\n useOptionalAppearance,\r\n type SidebarPresentation,\r\n type SidebarTone,\r\n type ThemeMode,\r\n} from \"./Appearance\";\r\nimport { DEFAULT_COLOR_SCHEME_ID, listColorSchemes, type ColorScheme } from \"./appearanceSchemes\";\r\nimport { cx } from \"./shared/classNames\";\r\n\r\n/**\r\n * Every visible string is supplied by the caller — this component ships no\r\n * built-in copy in any language, so it can be dropped into an application that\r\n * owns its own localization.\r\n */\r\nexport interface AppearanceMenuLabels {\r\n presentation: { title: string; compact: string; grouped: string };\r\n mode: { title: string; light: string; dark: string; system: string };\r\n tone: { title: string; light: string; dark: string; auto: string };\r\n /** `options` maps a registered scheme id to its display name. */\r\n colorScheme: { title: string; options: Record<string, string> };\r\n}\r\n\r\n/** Each section is hideable on its own. Omitted entries default to visible. */\r\nexport interface AppearanceMenuSections {\r\n presentation?: boolean;\r\n mode?: boolean;\r\n tone?: boolean;\r\n colorScheme?: boolean;\r\n}\r\n\r\nexport interface AppearanceMenuProps {\r\n labels: AppearanceMenuLabels;\r\n sections?: AppearanceMenuSections;\r\n className?: string;\r\n\r\n /** Controlled values. When given, the provider is not written to for that setting. */\r\n mode?: ThemeMode;\r\n onModeChange?: (mode: ThemeMode) => void;\r\n sidebarPresentation?: SidebarPresentation;\r\n onSidebarPresentationChange?: (presentation: SidebarPresentation) => void;\r\n sidebarTone?: SidebarTone;\r\n onSidebarToneChange?: (tone: SidebarTone) => void;\r\n colorSchemeId?: string;\r\n onColorSchemeIdChange?: (id: string) => void;\r\n\r\n /** Restrict/order the offered schemes. Defaults to every registered scheme. */\r\n colorSchemes?: ColorScheme[];\r\n}\r\n\r\ninterface RadioOption<T extends string> {\r\n value: T;\r\n label: string;\r\n /** Extra visual, e.g. a color swatch. Never the only indicator of selection. */\r\n adornment?: ReactNode;\r\n}\r\n\r\n/**\r\n * A settings radio group, deliberately not the Base `RadioGroup`.\r\n *\r\n * `RadioGroup` is a *form field*: it composes `FieldShell` (form label,\r\n * help text, validation message, `mb-3` field spacing), takes a form `name`,\r\n * and its options carry string-only labels. An appearance menu is not a form\r\n * field and needs `ReactNode` option content for the color swatches, so\r\n * reusing it would mean fighting its field semantics rather than sharing\r\n * behavior (doc section 19).\r\n */\r\nfunction AppearanceRadioGroup<T extends string>({\r\n title,\r\n options,\r\n value,\r\n onChange,\r\n className,\r\n}: {\r\n title: string;\r\n options: RadioOption<T>[];\r\n value: T;\r\n onChange: (value: T) => void;\r\n className?: string;\r\n}) {\r\n const titleId = useId();\r\n const refs = useRef<Array<HTMLButtonElement | null>>([]);\r\n\r\n function move(from: number, step: 1 | -1) {\r\n if (options.length === 0) return;\r\n const next = (from + step + options.length) % options.length;\r\n const option = options[next];\r\n if (!option) return;\r\n onChange(option.value);\r\n refs.current[next]?.focus();\r\n }\r\n\r\n /** Roving tabindex with automatic selection, per the WAI-ARIA radiogroup pattern. */\r\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\r\n const current = options.findIndex((option) => option.value === value);\r\n if (event.key === \"ArrowDown\" || event.key === \"ArrowRight\") {\r\n event.preventDefault();\r\n move(current, 1);\r\n } else if (event.key === \"ArrowUp\" || event.key === \"ArrowLeft\") {\r\n event.preventDefault();\r\n move(current, -1);\r\n }\r\n }\r\n\r\n return (\r\n <div className={cx(\"rrc-appearance__section\", className)}>\r\n <div className=\"rrc-appearance__title\" id={titleId}>\r\n {title}\r\n </div>\r\n <div className=\"rrc-appearance__options\" role=\"radiogroup\" aria-labelledby={titleId} onKeyDown={handleKeyDown}>\r\n {options.map((option, index) => {\r\n const selected = option.value === value;\r\n return (\r\n <button\r\n key={option.value}\r\n ref={(node) => {\r\n refs.current[index] = node;\r\n }}\r\n type=\"button\"\r\n role=\"radio\"\r\n aria-checked={selected}\r\n tabIndex={selected ? 0 : -1}\r\n className={cx(\"rrc-appearance__option\", selected && \"rrc-appearance__option--selected\")}\r\n onClick={() => onChange(option.value)}\r\n >\r\n {option.adornment}\r\n <span className=\"rrc-appearance__option-label\">{option.label}</span>\r\n {/* A shape, not a color — selection stays visible to color-blind users and in forced-colors mode. */}\r\n <span className=\"rrc-appearance__check\" aria-hidden=\"true\" />\r\n </button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * Composable appearance selector. Drop it into a `Navbar` slot, a `Popover`,\r\n * a `Menu` trigger's content, a settings drawer, or any application-owned\r\n * container.\r\n *\r\n * Deliberately NOT a Metronic Layout Builder: it exposes exactly four\r\n * independent settings and nothing else. It forces no persistence, mutates no\r\n * global DOM, and makes no decision about who is allowed to change branding —\r\n * those belong to the application.\r\n */\r\nexport function AppearanceMenu({\r\n labels,\r\n sections,\r\n className,\r\n mode,\r\n onModeChange,\r\n sidebarPresentation,\r\n onSidebarPresentationChange,\r\n sidebarTone,\r\n onSidebarToneChange,\r\n colorSchemeId,\r\n onColorSchemeIdChange,\r\n colorSchemes,\r\n}: AppearanceMenuProps) {\r\n const appearance = useOptionalAppearance();\r\n\r\n const show = {\r\n presentation: sections?.presentation ?? true,\r\n mode: sections?.mode ?? true,\r\n tone: sections?.tone ?? true,\r\n colorScheme: sections?.colorScheme ?? true,\r\n };\r\n\r\n const currentMode = mode ?? appearance?.mode ?? \"system\";\r\n const currentPresentation = sidebarPresentation ?? appearance?.sidebarPresentation ?? \"grouped\";\r\n const currentTone = sidebarTone ?? appearance?.sidebarTone ?? \"auto\";\r\n const currentSchemeId = colorSchemeId ?? appearance?.colorSchemeId ?? DEFAULT_COLOR_SCHEME_ID;\r\n\r\n // Each setting is written independently: changing one never re-writes another.\r\n const changeMode = (next: ThemeMode) => {\r\n onModeChange?.(next);\r\n if (mode === undefined) appearance?.setMode(next);\r\n };\r\n const changePresentation = (next: SidebarPresentation) => {\r\n onSidebarPresentationChange?.(next);\r\n if (sidebarPresentation === undefined) appearance?.setSidebarPresentation(next);\r\n };\r\n const changeTone = (next: SidebarTone) => {\r\n onSidebarToneChange?.(next);\r\n if (sidebarTone === undefined) appearance?.setSidebarTone(next);\r\n };\r\n const changeScheme = (next: string) => {\r\n onColorSchemeIdChange?.(next);\r\n if (colorSchemeId === undefined) appearance?.setColorSchemeId(next);\r\n };\r\n\r\n const schemes = colorSchemes ?? listColorSchemes();\r\n\r\n return (\r\n <div className={cx(\"rrc-appearance\", className)}>\r\n {show.presentation && (\r\n <AppearanceRadioGroup<SidebarPresentation>\r\n title={labels.presentation.title}\r\n value={currentPresentation}\r\n onChange={changePresentation}\r\n options={SIDEBAR_PRESENTATIONS.map((value) => ({ value, label: labels.presentation[value] }))}\r\n />\r\n )}\r\n\r\n {show.mode && (\r\n <AppearanceRadioGroup<ThemeMode>\r\n title={labels.mode.title}\r\n value={currentMode}\r\n onChange={changeMode}\r\n options={THEME_MODES.map((value) => ({ value, label: labels.mode[value] }))}\r\n />\r\n )}\r\n\r\n {show.tone && (\r\n <AppearanceRadioGroup<SidebarTone>\r\n title={labels.tone.title}\r\n value={currentTone}\r\n onChange={changeTone}\r\n options={SIDEBAR_TONES.map((value) => ({ value, label: labels.tone[value] }))}\r\n />\r\n )}\r\n\r\n {show.colorScheme && (\r\n <AppearanceRadioGroup<string>\r\n title={labels.colorScheme.title}\r\n value={currentSchemeId}\r\n onChange={changeScheme}\r\n className=\"rrc-appearance__section--schemes\"\r\n options={schemes.map((scheme) => ({\r\n value: scheme.id,\r\n // Falls back to the registered identifier rather than to invented\r\n // English copy, so a swatch always has a real accessible name.\r\n label: labels.colorScheme.options[scheme.id] ?? scheme.id,\r\n adornment: (\r\n <span\r\n className=\"rrc-appearance__swatch\"\r\n style={{ backgroundColor: scheme.swatch ?? scheme.tokens.primary }}\r\n aria-hidden=\"true\"\r\n />\r\n ),\r\n }))}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import type { Ref } from \"react\";\r\n\r\n/**\r\n * Ref plumbing for the slot path in `RichComponentBase`, where a consumer's\r\n * ref and a child's own ref both have to reach the same element.\r\n */\r\n\r\nfunction assignRef<T>(ref: Ref<T> | undefined | null, value: T | null): void {\r\n if (typeof ref === \"function\") {\r\n ref(value);\r\n return;\r\n }\r\n if (!ref || typeof ref !== \"object\") return;\r\n // `RefObject.current` is declared readonly for consumers, but writing it is\r\n // exactly what React itself does when it attaches an object ref. This is the\r\n // one place the library crosses that boundary, and it is confined to here.\r\n (ref as { current: T | null }).current = value;\r\n}\r\n\r\n/** Fans one element out to every supplied ref, ignoring the empty ones. */\r\nexport function composeRefs<T>(...refs: Array<Ref<T> | undefined | null>): Ref<T> {\r\n return (value: T | null) => {\r\n for (const ref of refs) assignRef(ref, value);\r\n };\r\n}\r\n","import { useEffect, useState, type ReactNode } from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\n\r\nexport interface PortalProps {\r\n children: ReactNode;\r\n /** Defaults to `document.body` once mounted on the client. */\r\n container?: Element | null;\r\n}\r\n\r\n/**\r\n * Minimal SSR-safe portal.\r\n *\r\n * The repository had no portal infrastructure before this (Popup positions\r\n * itself with plain CSS and Modal renders in place, both of which say so in\r\n * their own doc comments), so this is the smallest primitive that lets an\r\n * overlay escape an ancestor's `overflow`/`transform` clipping.\r\n *\r\n * `document` is never touched during module initialization or during render:\r\n * the host is resolved in an effect, so a server render produces nothing and\r\n * the first client render is identical to it. Intentionally internal — it is\r\n * plumbing for the context menu surface, not a second public overlay API.\r\n */\r\nexport function Portal({ children, container }: PortalProps) {\r\n const [host, setHost] = useState<Element | null>(null);\r\n\r\n useEffect(() => {\r\n if (container) {\r\n setHost(container);\r\n return;\r\n }\r\n setHost(typeof document === \"undefined\" ? null : document.body);\r\n }, [container]);\r\n\r\n if (!host) return null;\r\n return createPortal(children, host);\r\n}\r\n","import { Children, Fragment, isValidElement, type ReactElement, type ReactNode } from \"react\";\r\n\r\n/**\r\n * Identification of the declarative context-menu nodes.\r\n *\r\n * Recognition is by component *identity*, recorded in a module-private\r\n * WeakMap that is written once while this module initializes and never\r\n * mutated afterwards. Deliberately not `displayName`, not `Component.name`\r\n * and not a string on `props`: those are all rewritten or dropped by a\r\n * minifier, which would make the whole feature fail only in a production\r\n * bundle. A WeakMap keyed on the component reference survives minification\r\n * for exactly the same reason `type === Component` does, and needs no type\r\n * assertion to read back.\r\n */\r\n\r\nexport type ContextMenuNodeKind = \"menu\" | \"item\" | \"label\" | \"separator\" | \"submenu\";\r\n\r\nconst nodeKinds = new WeakMap<object, ContextMenuNodeKind>();\r\n\r\n/** Records what a component is. Called once per component at module scope. */\r\nexport function markContextMenuNode<TComponent extends object>(\r\n component: TComponent,\r\n kind: ContextMenuNodeKind\r\n): TComponent {\r\n nodeKinds.set(component, kind);\r\n return component;\r\n}\r\n\r\n/** The kind of a rendered node, or `undefined` for anything this module did not mark. */\r\nexport function contextMenuNodeKind(node: ReactNode): ContextMenuNodeKind | undefined {\r\n if (!isValidElement(node)) return undefined;\r\n const { type } = node;\r\n if (typeof type !== \"function\" && typeof type !== \"object\") return undefined;\r\n return nodeKinds.get(type);\r\n}\r\n\r\n/**\r\n * Flattens the direct children of a node one fragment level at a time.\r\n *\r\n * Fragments are handled deliberately rather than by accident: a\r\n * `<>{menu}{content}</>` child must not hide the menu declaration from the\r\n * partition below, and its visible children must not be dropped either.\r\n */\r\nexport function flattenMenuChildren(children: ReactNode): ReactNode[] {\r\n const flat: ReactNode[] = [];\r\n\r\n Children.forEach(children, (child) => {\r\n if (child === null || child === undefined || typeof child === \"boolean\") return;\r\n if (isValidElement(child) && child.type === Fragment) {\r\n const props: { children?: ReactNode } = child.props;\r\n flat.push(...flattenMenuChildren(props.children));\r\n return;\r\n }\r\n flat.push(child);\r\n });\r\n\r\n return flat;\r\n}\r\n\r\nexport interface RichComponentBaseChildren {\r\n /** The single `<ContextMenu>` declaration, if one was supplied. */\r\n menu?: ReactElement;\r\n /** Everything else, rendered as ordinary page content. */\r\n content: ReactNode[];\r\n}\r\n\r\n/**\r\n * Splits `RichComponentBase`'s children into the menu declaration and the\r\n * visible content. A second `<ContextMenu>` is ignored rather than rendered,\r\n * so a stray declaration can never leak into the page as content.\r\n */\r\nexport function partitionRichComponentBaseChildren(children: ReactNode): RichComponentBaseChildren {\r\n let menu: ReactElement | undefined;\r\n const content: ReactNode[] = [];\r\n\r\n for (const child of flattenMenuChildren(children)) {\r\n if (contextMenuNodeKind(child) === \"menu\" && isValidElement(child)) {\r\n if (!menu) menu = child;\r\n continue;\r\n }\r\n content.push(child);\r\n }\r\n\r\n return { menu, content };\r\n}\r\n\r\ninterface HideableProps {\r\n hidden?: boolean;\r\n}\r\n\r\n/**\r\n * Whether a declaration would put at least one selectable row on screen.\r\n *\r\n * This is what decides if the browser's own context menu is suppressed, so it\r\n * is answered from the declaration *before* anything is rendered. Labels and\r\n * separators do not count — a surface made only of those is \"effectively\r\n * empty\" and must leave native behavior alone. Anything this module did not\r\n * mark (a consumer's own wrapper component, arbitrary markup) counts as\r\n * content: guessing it away would silently disable a menu that does render.\r\n */\r\nexport function contextMenuHasContent(children: ReactNode): boolean {\r\n return flattenMenuChildren(children).some((child) => {\r\n const kind = contextMenuNodeKind(child);\r\n if (kind === \"label\" || kind === \"separator\") return false;\r\n if (kind === \"item\" || kind === \"submenu\") {\r\n if (!isValidElement(child)) return false;\r\n const props: HideableProps = child.props;\r\n return props.hidden !== true;\r\n }\r\n if (kind === \"menu\") return false;\r\n return true;\r\n });\r\n}\r\n","/**\r\n * Pure viewport placement math for the context menu surface.\r\n *\r\n * Kept free of React and of the DOM (the caller measures and passes plain\r\n * numbers) so the flip/clamp rules are unit-testable on their own, the same\r\n * split `sidebarModel.ts` uses for the Sidebar's navigation model.\r\n */\r\n\r\nexport interface ContextMenuPoint {\r\n x: number;\r\n y: number;\r\n}\r\n\r\nexport interface ContextMenuSize {\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport interface ContextMenuViewport {\r\n width: number;\r\n height: number;\r\n}\r\n\r\n/** Rect of a submenu's trigger row, in viewport coordinates. */\r\nexport interface ContextMenuTriggerBox {\r\n left: number;\r\n right: number;\r\n top: number;\r\n bottom: number;\r\n}\r\n\r\n/** Breathing room kept between the surface and the viewport edge. */\r\nexport const CONTEXT_MENU_VIEWPORT_MARGIN = 8;\r\n\r\nfunction clamp(value: number, min: number, max: number): number {\r\n if (max < min) return min;\r\n return Math.min(Math.max(value, min), max);\r\n}\r\n\r\n/**\r\n * Places the root surface at the pointer. Flips to the opposite side of the\r\n * pointer when the preferred side would overflow, then clamps, so a menu that\r\n * is simply larger than the viewport still starts inside it rather than\r\n * scrolling the page.\r\n */\r\nexport function placeContextMenuAtPoint(\r\n point: ContextMenuPoint,\r\n size: ContextMenuSize,\r\n viewport: ContextMenuViewport,\r\n margin: number = CONTEXT_MENU_VIEWPORT_MARGIN\r\n): ContextMenuPoint {\r\n const preferredX = point.x + size.width + margin > viewport.width ? point.x - size.width : point.x;\r\n const preferredY = point.y + size.height + margin > viewport.height ? point.y - size.height : point.y;\r\n\r\n return {\r\n x: clamp(preferredX, margin, viewport.width - size.width - margin),\r\n y: clamp(preferredY, margin, viewport.height - size.height - margin),\r\n };\r\n}\r\n\r\n/**\r\n * Places a submenu beside its trigger row: flush to the trigger's right edge\r\n * by default so the pointer can travel into it without crossing a gap, and\r\n * mirrored to the left when that would overflow.\r\n */\r\nexport function placeSubMenuBeside(\r\n trigger: ContextMenuTriggerBox,\r\n size: ContextMenuSize,\r\n viewport: ContextMenuViewport,\r\n margin: number = CONTEXT_MENU_VIEWPORT_MARGIN\r\n): ContextMenuPoint {\r\n const preferredX = trigger.right + size.width + margin > viewport.width ? trigger.left - size.width : trigger.right;\r\n const preferredY = trigger.top + size.height + margin > viewport.height ? trigger.bottom - size.height : trigger.top;\r\n\r\n return {\r\n x: clamp(preferredX, margin, viewport.width - size.width - margin),\r\n y: clamp(preferredY, margin, viewport.height - size.height - margin),\r\n };\r\n}\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useId,\r\n useLayoutEffect,\r\n useRef,\r\n useState,\r\n type CSSProperties,\r\n type KeyboardEvent as ReactKeyboardEvent,\r\n type ReactElement,\r\n type ReactNode,\r\n type RefObject,\r\n} from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { Portal } from \"./shared/Portal\";\r\nimport { markContextMenuNode } from \"./contextMenuModel\";\r\nimport { placeContextMenuAtPoint, placeSubMenuBeside, type ContextMenuPoint } from \"./contextMenuPosition\";\r\n\r\n/**\r\n * Declarative context menu.\r\n *\r\n * `<ContextMenu>` is a *declaration*, not page content: on its own it renders\r\n * nothing at all. `RichComponentBase` lifts the declaration out of its\r\n * children and re-renders it inside a surface context when the user invokes\r\n * the menu, which is why a stray `<ContextMenu>` anywhere else in a tree can\r\n * never leak markup into the page.\r\n *\r\n * Layer: Base. It performs no HTTP and knows nothing about metadata, so\r\n * Remote and Smart can compose it without inverting the dependency direction.\r\n */\r\n\r\nexport type ContextMenuCloseReason = \"select\" | \"escape\" | \"dismiss\";\r\n\r\nexport interface ContextMenuSurfaceValue {\r\n /** Viewport coordinates the menu was invoked at. */\r\n point: ContextMenuPoint;\r\n /** Changes on every invocation, so a repeated right-click re-measures. */\r\n openId: number;\r\n close: (reason: ContextMenuCloseReason) => void;\r\n}\r\n\r\n/**\r\n * Internal wiring between `RichComponentBase` and the surface. Deliberately\r\n * not part of the package's public exports — open/close state and positioning\r\n * are implementation details, not API.\r\n */\r\nexport const ContextMenuSurfaceContext = createContext<ContextMenuSurfaceValue | null>(null);\r\n\r\n/**\r\n * Dynamic viewport coordinates are the one thing a class cannot express, so\r\n * they travel as two narrowly scoped custom properties rather than as a pile\r\n * of inline layout declarations. Typed, not asserted.\r\n */\r\ninterface ContextMenuStyle extends CSSProperties {\r\n [key: `--${string}`]: string | number | undefined;\r\n}\r\n\r\nfunction positionStyle(position: ContextMenuPoint): ContextMenuStyle {\r\n return {\r\n \"--rrc-context-menu-x\": `${position.x}px`,\r\n \"--rrc-context-menu-y\": `${position.y}px`,\r\n };\r\n}\r\n\r\nfunction viewportSize() {\r\n return { width: window.innerWidth, height: window.innerHeight };\r\n}\r\n\r\nfunction isDisabledItem(item: HTMLElement): boolean {\r\n if (item instanceof HTMLButtonElement && item.disabled) return true;\r\n return item.getAttribute(\"aria-disabled\") === \"true\";\r\n}\r\n\r\n/**\r\n * The enabled rows of one menu level. Reading the level's own DOM is what\r\n * makes hidden items (never rendered), separators and labels (never\r\n * `menuitem`) and disabled items drop out of keyboard navigation, without a\r\n * second registration protocol that could drift from what is on screen.\r\n */\r\nfunction menuItemsOf(panel: HTMLElement): HTMLElement[] {\r\n return Array.from(panel.querySelectorAll<HTMLElement>('[role=\"menuitem\"]')).filter(\r\n (item) => item.closest('[role=\"menu\"]') === panel && !isDisabledItem(item)\r\n );\r\n}\r\n\r\nfunction focusFirstItem(panel: HTMLElement): void {\r\n const first = menuItemsOf(panel)[0];\r\n (first ?? panel).focus();\r\n}\r\n\r\ninterface MenuLevelKeyOptions {\r\n panelRef: RefObject<HTMLElement>;\r\n /** Escape (and Tab) at this level. */\r\n onEscape: () => void;\r\n /** Present only on a submenu level: ArrowLeft steps back to the trigger. */\r\n onStepOut?: () => void;\r\n}\r\n\r\n/**\r\n * Roving keyboard navigation for one menu level. A submenu is a level of its\r\n * own, so every key it handles is stopped there and the parent level never\r\n * sees it — the innermost menu always wins.\r\n */\r\nfunction useMenuLevelKeys({ panelRef, onEscape, onStepOut }: MenuLevelKeyOptions) {\r\n return useCallback(\r\n (event: ReactKeyboardEvent<HTMLElement>) => {\r\n const panel = panelRef.current;\r\n if (!panel) return;\r\n\r\n const items = menuItemsOf(panel);\r\n const currentIndex = items.findIndex((item) => item === document.activeElement);\r\n const focusAt = (index: number) => {\r\n const item = items[index];\r\n if (item) item.focus();\r\n };\r\n const handled = () => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n };\r\n\r\n switch (event.key) {\r\n case \"ArrowDown\":\r\n handled();\r\n if (items.length > 0) focusAt((currentIndex + 1) % items.length);\r\n return;\r\n case \"ArrowUp\":\r\n handled();\r\n if (items.length > 0) focusAt(currentIndex <= 0 ? items.length - 1 : currentIndex - 1);\r\n return;\r\n case \"Home\":\r\n handled();\r\n if (items.length > 0) focusAt(0);\r\n return;\r\n case \"End\":\r\n handled();\r\n if (items.length > 0) focusAt(items.length - 1);\r\n return;\r\n case \"ArrowLeft\":\r\n if (!onStepOut) return;\r\n handled();\r\n onStepOut();\r\n return;\r\n case \"Escape\":\r\n case \"Tab\":\r\n handled();\r\n onEscape();\r\n return;\r\n default:\r\n return;\r\n }\r\n },\r\n [panelRef, onEscape, onStepOut]\r\n );\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Root surface\r\n * ------------------------------------------------------------------ */\r\n\r\ninterface ContextMenuPanelProps {\r\n surface: ContextMenuSurfaceValue;\r\n label?: string;\r\n className?: string;\r\n children?: ReactNode;\r\n}\r\n\r\nfunction ContextMenuPanel({ surface, label, className, children }: ContextMenuPanelProps) {\r\n const { point, openId, close } = surface;\r\n const panelRef = useRef<HTMLDivElement>(null);\r\n const [position, setPosition] = useState<ContextMenuPoint>(point);\r\n\r\n // Measure, then flip/clamp into the viewport before the browser paints.\r\n useLayoutEffect(() => {\r\n const panel = panelRef.current;\r\n if (!panel) return;\r\n const rect = panel.getBoundingClientRect();\r\n setPosition(placeContextMenuAtPoint(point, { width: rect.width, height: rect.height }, viewportSize()));\r\n }, [point, openId]);\r\n\r\n useLayoutEffect(() => {\r\n const panel = panelRef.current;\r\n if (panel) focusFirstItem(panel);\r\n }, [openId]);\r\n\r\n // The only global listeners this feature installs, and only while a surface\r\n // is actually on screen: nothing is registered per mounted RichComponentBase.\r\n useEffect(() => {\r\n function isInsidePanel(target: EventTarget | null): boolean {\r\n const panel = panelRef.current;\r\n return Boolean(panel && target instanceof Node && panel.contains(target));\r\n }\r\n function handlePointerDown(event: MouseEvent) {\r\n if (isInsidePanel(event.target)) return;\r\n close(\"dismiss\");\r\n }\r\n function handleViewportChange(event: Event) {\r\n if (isInsidePanel(event.target)) return;\r\n close(\"dismiss\");\r\n }\r\n\r\n document.addEventListener(\"mousedown\", handlePointerDown);\r\n window.addEventListener(\"resize\", handleViewportChange);\r\n document.addEventListener(\"scroll\", handleViewportChange, true);\r\n return () => {\r\n document.removeEventListener(\"mousedown\", handlePointerDown);\r\n window.removeEventListener(\"resize\", handleViewportChange);\r\n document.removeEventListener(\"scroll\", handleViewportChange, true);\r\n };\r\n }, [close]);\r\n\r\n const onEscape = useCallback(() => close(\"escape\"), [close]);\r\n const handleKeyDown = useMenuLevelKeys({ panelRef, onEscape });\r\n\r\n return (\r\n <div\r\n ref={panelRef}\r\n role=\"menu\"\r\n aria-label={label}\r\n tabIndex={-1}\r\n className={cx(\"rrc-context-menu\", className)}\r\n style={positionStyle(position)}\r\n onKeyDown={(event) => {\r\n handleKeyDown(event);\r\n // A portal still propagates through the React tree, so without this a\r\n // key pressed inside the surface would reach the trigger it belongs to.\r\n event.stopPropagation();\r\n }}\r\n onClick={(event) => event.stopPropagation()}\r\n onContextMenu={(event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport interface ContextMenuProps {\r\n children?: ReactNode;\r\n /**\r\n * Leaves the browser's own context menu intact without removing the\r\n * declaration — the menu is switched off, not deleted.\r\n */\r\n disabled?: boolean;\r\n /** Accessible name for the surface, when the rows alone are not enough. */\r\n \"aria-label\"?: string;\r\n className?: string;\r\n}\r\n\r\nfunction ContextMenuRoot({ children, className, \"aria-label\": ariaLabel }: ContextMenuProps): ReactElement | null {\r\n const surface = useContext(ContextMenuSurfaceContext);\r\n // Declaration only: outside a surface this renders nothing, so it can never\r\n // appear as ordinary page content.\r\n if (!surface) return null;\r\n\r\n return (\r\n <Portal>\r\n <ContextMenuPanel surface={surface} label={ariaLabel} className={className}>\r\n {children}\r\n </ContextMenuPanel>\r\n </Portal>\r\n );\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Rows\r\n * ------------------------------------------------------------------ */\r\n\r\nfunction reportSelectError(error: unknown): void {\r\n // Reported, never swallowed, and never left as an unhandled rejection — the\r\n // console convention useControllableState and Sidebar already use for a\r\n // contract violation this library cannot recover from.\r\n console.error(\"[rich-react-component] ContextMenu.Item onSelect failed:\", error);\r\n}\r\n\r\nfunction runSelectHandler(onSelect: (() => void | Promise<void>) | undefined): void {\r\n if (!onSelect) return;\r\n const result = onSelect();\r\n if (result !== undefined) Promise.resolve(result).then(undefined, reportSelectError);\r\n}\r\n\r\nexport interface ContextMenuItemProps {\r\n children?: ReactNode;\r\n /** Optional stable identifier; emitted as the row's DOM id. */\r\n id?: string;\r\n disabled?: boolean;\r\n /** Not rendered at all, and so skipped by keyboard navigation. */\r\n hidden?: boolean;\r\n /** Destructive emphasis — the same semantic name `Menu`'s item model uses. */\r\n danger?: boolean;\r\n /** Icon content, e.g. `<Icon name=\"bi bi-pencil\" />`. No icon set is bundled. */\r\n icon?: ReactNode;\r\n /** Accessible name, for a row whose visible text is not sufficient. */\r\n \"aria-label\"?: string;\r\n className?: string;\r\n onSelect?: () => void | Promise<void>;\r\n}\r\n\r\nfunction ContextMenuItem({\r\n children,\r\n id,\r\n disabled,\r\n hidden,\r\n danger,\r\n icon,\r\n className,\r\n \"aria-label\": ariaLabel,\r\n onSelect,\r\n}: ContextMenuItemProps): ReactElement | null {\r\n const surface = useContext(ContextMenuSurfaceContext);\r\n\r\n const handleClick = useCallback(() => {\r\n runSelectHandler(onSelect);\r\n surface?.close(\"select\");\r\n }, [onSelect, surface]);\r\n\r\n if (hidden) return null;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n role=\"menuitem\"\r\n id={id}\r\n tabIndex={-1}\r\n disabled={disabled}\r\n aria-disabled={disabled || undefined}\r\n aria-label={ariaLabel}\r\n className={cx(\"rrc-context-menu__item\", danger && \"rrc-context-menu__item--danger\", className)}\r\n onClick={handleClick}\r\n >\r\n {icon !== undefined && <span className=\"rrc-context-menu__item-icon\">{icon}</span>}\r\n <span className=\"rrc-context-menu__item-label\">{children}</span>\r\n </button>\r\n );\r\n}\r\n\r\nexport interface ContextMenuLabelProps {\r\n children?: ReactNode;\r\n className?: string;\r\n}\r\n\r\nfunction ContextMenuLabel({ children, className }: ContextMenuLabelProps): ReactElement {\r\n // `presentation` keeps a caption out of the menu's child structure, so it is\r\n // neither announced as a row nor reachable by keyboard.\r\n return (\r\n <div role=\"presentation\" className={cx(\"rrc-context-menu__label\", className)}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport interface ContextMenuSeparatorProps {\r\n className?: string;\r\n}\r\n\r\nfunction ContextMenuSeparator({ className }: ContextMenuSeparatorProps): ReactElement {\r\n return <div role=\"separator\" className={cx(\"rrc-context-menu__separator\", className)} />;\r\n}\r\n\r\nexport interface ContextMenuSubMenuProps {\r\n /** Visible text of the row that opens the submenu. */\r\n label: ReactNode;\r\n children?: ReactNode;\r\n id?: string;\r\n disabled?: boolean;\r\n hidden?: boolean;\r\n icon?: ReactNode;\r\n /** Accessible name, for a trigger whose visible text is not sufficient. */\r\n \"aria-label\"?: string;\r\n className?: string;\r\n}\r\n\r\nfunction ContextMenuSubMenu({\r\n label,\r\n children,\r\n id,\r\n disabled,\r\n hidden,\r\n icon,\r\n className,\r\n \"aria-label\": ariaLabel,\r\n}: ContextMenuSubMenuProps): ReactElement | null {\r\n const [open, setOpen] = useState(false);\r\n const [position, setPosition] = useState<ContextMenuPoint>({ x: 0, y: 0 });\r\n const triggerRef = useRef<HTMLButtonElement>(null);\r\n const panelRef = useRef<HTMLDivElement>(null);\r\n const focusOnOpen = useRef(false);\r\n\r\n const generatedId = useId();\r\n const triggerId = id ?? `${generatedId}trigger`;\r\n const panelId = `${generatedId}panel`;\r\n\r\n const closeLevel = useCallback(() => {\r\n setOpen(false);\r\n triggerRef.current?.focus();\r\n }, []);\r\n\r\n useLayoutEffect(() => {\r\n if (!open) {\r\n // A toggle that closed the level must not leave a pending focus request\r\n // behind for the next hover to consume.\r\n focusOnOpen.current = false;\r\n return;\r\n }\r\n const trigger = triggerRef.current;\r\n const panel = panelRef.current;\r\n if (!trigger || !panel) return;\r\n\r\n const triggerRect = trigger.getBoundingClientRect();\r\n const panelRect = panel.getBoundingClientRect();\r\n setPosition(\r\n placeSubMenuBeside(\r\n { left: triggerRect.left, right: triggerRect.right, top: triggerRect.top, bottom: triggerRect.bottom },\r\n { width: panelRect.width, height: panelRect.height },\r\n viewportSize()\r\n )\r\n );\r\n\r\n if (focusOnOpen.current) {\r\n focusOnOpen.current = false;\r\n focusFirstItem(panel);\r\n }\r\n }, [open]);\r\n\r\n const handlePanelKeys = useMenuLevelKeys({ panelRef, onEscape: closeLevel, onStepOut: closeLevel });\r\n\r\n if (hidden) return null;\r\n\r\n return (\r\n <div\r\n role=\"presentation\"\r\n className=\"rrc-context-menu__submenu\"\r\n onMouseEnter={() => {\r\n if (!disabled) setOpen(true);\r\n }}\r\n onMouseLeave={() => setOpen(false)}\r\n >\r\n <button\r\n ref={triggerRef}\r\n type=\"button\"\r\n role=\"menuitem\"\r\n id={triggerId}\r\n tabIndex={-1}\r\n disabled={disabled}\r\n aria-disabled={disabled || undefined}\r\n aria-haspopup=\"menu\"\r\n aria-expanded={open}\r\n aria-controls={open ? panelId : undefined}\r\n aria-label={ariaLabel}\r\n className={cx(\"rrc-context-menu__item\", \"rrc-context-menu__item--submenu\", className)}\r\n onClick={() => {\r\n focusOnOpen.current = true;\r\n setOpen((previous) => !previous);\r\n }}\r\n onKeyDown={(event) => {\r\n if (event.key !== \"ArrowRight\") return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n focusOnOpen.current = true;\r\n setOpen(true);\r\n }}\r\n >\r\n {icon !== undefined && <span className=\"rrc-context-menu__item-icon\">{icon}</span>}\r\n <span className=\"rrc-context-menu__item-label\">{label}</span>\r\n <span className=\"rrc-context-menu__item-arrow\" aria-hidden=\"true\" />\r\n </button>\r\n\r\n {open && (\r\n <div\r\n ref={panelRef}\r\n id={panelId}\r\n role=\"menu\"\r\n aria-labelledby={triggerId}\r\n tabIndex={-1}\r\n className=\"rrc-context-menu rrc-context-menu--sub\"\r\n style={positionStyle(position)}\r\n onKeyDown={handlePanelKeys}\r\n >\r\n {children}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Compound export\r\n * ------------------------------------------------------------------ */\r\n\r\nmarkContextMenuNode(ContextMenuRoot, \"menu\");\r\nmarkContextMenuNode(ContextMenuItem, \"item\");\r\nmarkContextMenuNode(ContextMenuLabel, \"label\");\r\nmarkContextMenuNode(ContextMenuSeparator, \"separator\");\r\nmarkContextMenuNode(ContextMenuSubMenu, \"submenu\");\r\n\r\nexport interface ContextMenuComponent {\r\n (props: ContextMenuProps): ReactElement | null;\r\n Item: (props: ContextMenuItemProps) => ReactElement | null;\r\n Separator: (props: ContextMenuSeparatorProps) => ReactElement;\r\n Label: (props: ContextMenuLabelProps) => ReactElement;\r\n SubMenu: (props: ContextMenuSubMenuProps) => ReactElement | null;\r\n}\r\n\r\n/**\r\n * The compound is annotated explicitly rather than inferred from\r\n * `Object.assign`, so the generated declaration file names only exported\r\n * types and never a private local one.\r\n */\r\nexport const ContextMenu: ContextMenuComponent = Object.assign(ContextMenuRoot, {\r\n Item: ContextMenuItem,\r\n Separator: ContextMenuSeparator,\r\n Label: ContextMenuLabel,\r\n SubMenu: ContextMenuSubMenu,\r\n});\r\n","import {\r\n Children,\r\n cloneElement,\r\n createElement,\r\n forwardRef,\r\n isValidElement,\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useMemo,\r\n useRef,\r\n useState,\r\n type CSSProperties,\r\n type HTMLAttributes,\r\n type KeyboardEventHandler,\r\n type MouseEventHandler,\r\n type ReactElement,\r\n type ReactHTML,\r\n type ReactNode,\r\n type Ref,\r\n} from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { composeRefs } from \"./shared/composeRefs\";\r\nimport {\r\n ContextMenuSurfaceContext,\r\n type ContextMenuCloseReason,\r\n type ContextMenuProps,\r\n type ContextMenuSurfaceValue,\r\n} from \"./ContextMenu\";\r\nimport { contextMenuHasContent, partitionRichComponentBaseChildren } from \"./contextMenuModel\";\r\nimport type { ContextMenuPoint } from \"./contextMenuPosition\";\r\n\r\n/**\r\n * `RichComponentBase` — the one place the context-menu behavior lives.\r\n *\r\n * Composition, never inheritance: it wraps content it does not know anything\r\n * about, so no existing component gained a `contextMenu` prop and none of them\r\n * carries a copy of this logic.\r\n *\r\n * <RichComponentBase>\r\n * <ContextMenu>\r\n * <ContextMenu.Item onSelect={handleEdit}>Düzenle</ContextMenu.Item>\r\n * <ContextMenu.Separator />\r\n * <ContextMenu.Item danger onSelect={handleDelete}>Sil</ContextMenu.Item>\r\n * </ContextMenu>\r\n *\r\n * <Button>İşlem</Button>\r\n * </RichComponentBase>\r\n *\r\n * Without a `<ContextMenu>` child it is transparent: no listeners, no ARIA, no\r\n * interception of the browser's own menu.\r\n *\r\n * ## How the trigger attaches (`trigger`)\r\n *\r\n * `\"auto\"` (default) attaches to the child itself — no extra DOM — when the\r\n * single visible child is a *host element* (`<div>`, `<table>`, `<button>`,\r\n * …), because a host element is the only child guaranteed to forward\r\n * `onContextMenu`, `onKeyDown` and a ref. Most Base components in this\r\n * repository deliberately keep a small prop surface and do not spread unknown\r\n * props onto their root, so injecting handlers into them would fail silently.\r\n * For those, and for multiple or non-element children, `auto` falls back to a\r\n * wrapper element that is `display: contents` — it generates no layout box, so\r\n * flex and grid placement, width/height resolution, positioning and\r\n * scroll containers all behave as if it were not there.\r\n *\r\n * `\"child\"` forces the slot path for a component the caller knows forwards its\r\n * props (e.g. `Button`, which extends `ButtonHTMLAttributes`). `\"wrapper\"`\r\n * forces the wrapper. `as` picks the wrapper's element, for the places a\r\n * `<div>` would be invalid markup (`as=\"tbody\"`, `as=\"li\"`, …).\r\n *\r\n * ## Event composition policy (documented, tested)\r\n *\r\n * 1. the child's / the caller's own `onContextMenu` runs first;\r\n * 2. if it called `preventDefault()`, this base does nothing at all — it does\r\n * not open, and it does not stop propagation, so an outer\r\n * `RichComponentBase` still gets its chance;\r\n * 3. otherwise, and only when an enabled non-empty menu exists, the native\r\n * menu is suppressed, propagation is stopped (nearest base wins) and the\r\n * surface opens at the pointer.\r\n *\r\n * The trigger carries no ARIA of its own. `aria-haspopup` is not a supported\r\n * attribute on `role=\"generic\"`, which is what a wrapper `<div>` and most host\r\n * elements resolve to, so emitting it would be an authoring error rather than\r\n * a hint; a context-menu target is not a menu button. The accessibility work\r\n * is in the surface (`role=\"menu\"`, real focus management, real keyboard\r\n * navigation) and in the submenu triggers, where `role=\"menuitem\"` does\r\n * support `aria-haspopup`/`aria-expanded`/`aria-controls`.\r\n */\r\n\r\n/** Broadcast on `document` when a menu opens, so any other open menu closes itself. */\r\nconst CONTEXT_MENU_OPEN_EVENT = \"rrc:context-menu-open\";\r\n\r\ninterface ContextMenuOpenDetail {\r\n id: string;\r\n}\r\n\r\nfunction isOpenDetail(detail: unknown): detail is ContextMenuOpenDetail {\r\n return typeof detail === \"object\" && detail !== null && typeof Reflect.get(detail, \"id\") === \"string\";\r\n}\r\n\r\nconst FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\");\r\nconst MEMO_TYPE = Symbol.for(\"react.memo\");\r\n\r\n/**\r\n * Whether attaching a ref to this element is safe. Passing a ref to a plain\r\n * function component produces a React warning and no node, so the slot path\r\n * only forwards one to a host element or to something that really is a\r\n * `forwardRef` (possibly behind `memo`). Checked structurally — `$$typeof`\r\n * survives minification, a display name does not.\r\n */\r\nfunction acceptsRef(element: ReactElement): boolean {\r\n const { type } = element;\r\n if (typeof type === \"string\") return true;\r\n if (typeof type !== \"object\" || type === null) return false;\r\n\r\n const marker: unknown = Reflect.get(type, \"$$typeof\");\r\n if (marker === FORWARD_REF_TYPE) return true;\r\n if (marker !== MEMO_TYPE) return false;\r\n\r\n const inner: unknown = Reflect.get(type, \"type\");\r\n if (typeof inner !== \"object\" || inner === null) return false;\r\n return Reflect.get(inner, \"$$typeof\") === FORWARD_REF_TYPE;\r\n}\r\n\r\nfunction composeMouseHandlers(\r\n ...handlers: Array<MouseEventHandler<HTMLElement> | undefined>\r\n): MouseEventHandler<HTMLElement> {\r\n return (event) => {\r\n for (const handler of handlers) handler?.(event);\r\n };\r\n}\r\n\r\nfunction composeKeyboardHandlers(\r\n ...handlers: Array<KeyboardEventHandler<HTMLElement> | undefined>\r\n): KeyboardEventHandler<HTMLElement> {\r\n return (event) => {\r\n for (const handler of handlers) handler?.(event);\r\n };\r\n}\r\n\r\n/** How the context-menu trigger is attached to the visible content. */\r\nexport type RichComponentBaseTrigger = \"auto\" | \"child\" | \"wrapper\";\r\n\r\nexport interface RichComponentBaseProps extends Omit<HTMLAttributes<HTMLElement>, \"children\"> {\r\n /** A single optional `<ContextMenu>` declaration plus the visible content. */\r\n children?: ReactNode;\r\n /** See the component doc comment. Defaults to `\"auto\"`. */\r\n trigger?: RichComponentBaseTrigger;\r\n /** Wrapper element used by the wrapper path. Defaults to `\"div\"`. */\r\n as?: keyof ReactHTML;\r\n}\r\n\r\ntype ResolvedTrigger = { mode: \"child\"; child: ReactElement } | { mode: \"wrapper\" };\r\n\r\nfunction resolveTrigger(trigger: RichComponentBaseTrigger, content: ReactNode[]): ResolvedTrigger {\r\n if (trigger === \"wrapper\") return { mode: \"wrapper\" };\r\n\r\n const only = content.length === 1 ? content[0] : undefined;\r\n if (only === undefined || !isValidElement(only)) return { mode: \"wrapper\" };\r\n if (trigger === \"child\") return { mode: \"child\", child: only };\r\n\r\n return typeof only.type === \"string\" ? { mode: \"child\", child: only } : { mode: \"wrapper\" };\r\n}\r\n\r\n/** The child props the slot path has to merge with rather than replace. */\r\ninterface SlotChildProps {\r\n className?: string;\r\n style?: CSSProperties;\r\n onContextMenu?: MouseEventHandler<HTMLElement>;\r\n onKeyDown?: KeyboardEventHandler<HTMLElement>;\r\n}\r\n\r\nexport const RichComponentBase = forwardRef<HTMLElement, RichComponentBaseProps>(function RichComponentBase(\r\n { children, trigger = \"auto\", as = \"div\", className, style, onContextMenu, onKeyDown, ...rest },\r\n forwardedRef\r\n) {\r\n const instanceId = useId();\r\n const { menu, content } = useMemo(() => partitionRichComponentBaseChildren(children), [children]);\r\n\r\n const menuEnabled = useMemo(() => {\r\n if (!menu) return false;\r\n const menuProps: ContextMenuProps = menu.props;\r\n if (menuProps.disabled === true) return false;\r\n return contextMenuHasContent(menuProps.children);\r\n }, [menu]);\r\n\r\n const [openState, setOpenState] = useState<{ point: ContextMenuPoint; openId: number } | null>(null);\r\n const openCounter = useRef(0);\r\n const restoreFocusRef = useRef<HTMLElement | null>(null);\r\n\r\n const close = useCallback((reason: ContextMenuCloseReason) => {\r\n setOpenState(null);\r\n const target = restoreFocusRef.current;\r\n restoreFocusRef.current = null;\r\n // An outside click is already moving focus somewhere the user chose, so\r\n // only a deliberate close hands focus back to where it came from.\r\n if (reason === \"dismiss\") return;\r\n if (target && target.isConnected) target.focus();\r\n }, []);\r\n\r\n const openAt = useCallback(\r\n (x: number, y: number) => {\r\n if (openState === null) {\r\n const active = document.activeElement;\r\n restoreFocusRef.current = active instanceof HTMLElement ? active : null;\r\n }\r\n // No module-level registry: the opener announces itself and every other\r\n // open surface closes itself in response.\r\n document.dispatchEvent(\r\n new CustomEvent(CONTEXT_MENU_OPEN_EVENT, { detail: { id: instanceId } satisfies ContextMenuOpenDetail })\r\n );\r\n openCounter.current += 1;\r\n setOpenState({ point: { x, y }, openId: openCounter.current });\r\n },\r\n [instanceId, openState]\r\n );\r\n\r\n // Registered only while this instance's surface is open.\r\n useEffect(() => {\r\n if (!openState) return;\r\n function handleOtherOpen(event: Event) {\r\n if (!(event instanceof CustomEvent)) return;\r\n const detail: unknown = event.detail;\r\n if (isOpenDetail(detail) && detail.id !== instanceId) close(\"dismiss\");\r\n }\r\n document.addEventListener(CONTEXT_MENU_OPEN_EVENT, handleOtherOpen);\r\n return () => document.removeEventListener(CONTEXT_MENU_OPEN_EVENT, handleOtherOpen);\r\n }, [openState, instanceId, close]);\r\n\r\n // A menu that is removed or disabled while open must not stay on screen.\r\n useEffect(() => {\r\n if (!menuEnabled && openState) close(\"dismiss\");\r\n }, [menuEnabled, openState, close]);\r\n\r\n const triggerContextMenu = useCallback<MouseEventHandler<HTMLElement>>(\r\n (event) => {\r\n if (event.defaultPrevented) return;\r\n if (!menuEnabled) return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n openAt(event.clientX, event.clientY);\r\n },\r\n [menuEnabled, openAt]\r\n );\r\n\r\n const triggerKeyDown = useCallback<KeyboardEventHandler<HTMLElement>>(\r\n (event) => {\r\n if (event.defaultPrevented) return;\r\n if (!menuEnabled) return;\r\n const invokes = event.key === \"ContextMenu\" || (event.shiftKey && event.key === \"F10\");\r\n if (!invokes) return;\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n const anchor = event.target instanceof HTMLElement ? event.target : event.currentTarget;\r\n const rect = anchor.getBoundingClientRect();\r\n openAt(rect.left, rect.bottom);\r\n },\r\n [menuEnabled, openAt]\r\n );\r\n\r\n const surfaceValue = useMemo<ContextMenuSurfaceValue | null>(\r\n () => (openState ? { point: openState.point, openId: openState.openId, close } : null),\r\n [openState, close]\r\n );\r\n\r\n const resolved = resolveTrigger(trigger, content);\r\n\r\n let triggerNode: ReactNode;\r\n if (resolved.mode === \"child\") {\r\n const { child } = resolved;\r\n const childProps: SlotChildProps = child.props;\r\n const childRef: Ref<HTMLElement> | undefined = Reflect.get(child, \"ref\") ?? undefined;\r\n const mergedClassName = cx(className, childProps.className);\r\n const hasStyle = style !== undefined || childProps.style !== undefined;\r\n\r\n triggerNode = cloneElement(child, {\r\n ...rest,\r\n // The child's own props win over this base's. Only `className`, `style`\r\n // and the two trigger handlers are merged rather than replaced; every\r\n // other prop the child declares, accessibility props included, is left\r\n // exactly as it was.\r\n ...child.props,\r\n className: mergedClassName || undefined,\r\n ...(hasStyle ? { style: { ...style, ...childProps.style } } : null),\r\n onContextMenu: composeMouseHandlers(childProps.onContextMenu, onContextMenu, triggerContextMenu),\r\n onKeyDown: composeKeyboardHandlers(childProps.onKeyDown, onKeyDown, triggerKeyDown),\r\n ...(acceptsRef(child) ? { ref: composeRefs<HTMLElement>(childRef, forwardedRef) } : null),\r\n });\r\n } else {\r\n triggerNode = createElement(\r\n as,\r\n {\r\n ...rest,\r\n ref: forwardedRef,\r\n className: cx(\"rrc-rich-base\", className) || undefined,\r\n style,\r\n onContextMenu: composeMouseHandlers(onContextMenu, triggerContextMenu),\r\n onKeyDown: composeKeyboardHandlers(onKeyDown, triggerKeyDown),\r\n },\r\n // Spread as separate arguments, the way JSX does, so React treats them\r\n // as static children and no synthetic keys are needed.\r\n ...Children.toArray(content)\r\n );\r\n }\r\n\r\n return (\r\n <>\r\n {triggerNode}\r\n {menu && surfaceValue && (\r\n <ContextMenuSurfaceContext.Provider value={surfaceValue}>{menu}</ContextMenuSurfaceContext.Provider>\r\n )}\r\n </>\r\n );\r\n});\r\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","useIsomorphicLayoutEffect","useLayoutEffect","useElementResize","ref","enabled","onResize","handlerRef","element","notify","observer","BEHAVIORS","isBehavior","resolvePrimaryColumnKey","columns","configured","eligible","column","match","buildResponsiveColumnPlan","problems","byKey","primaryKey","rules","claimed","rule","responsivePlanSignature","plan","problem","OVERFLOW_TOLERANCE","RESTORE_HYSTERESIS","useResponsiveColumnFit","containerRef","ruleCount","signature","processedCount","setProcessedCount","countRef","blockedWidthRef","lastWidthRef","passesRef","evaluate","available","overflowing","blocked","PROBLEM_MESSAGES","useResponsivePlanDiagnostics","dataGridFormatters","amount","EMPTY_RESPONSIVE_PLAN","EMPTY_COLUMNS","toResponsiveColumnModel","accessor","isUtility","isData","columnKeyOf","nextSortDirection","key","columnValueOf","row","renderCell","alignClass","align","DataGrid","rowKey","selectedRowKeys","onSelectionChange","sort","onSortChange","totalCount","responsive","selectable","paginated","responsiveEnabled","columnModels","useMemo","processedRules","visibleColumns","detailColumns","removedKeys","columnsByKey","spanCount","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","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","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","isSidebarParent","isSidebarExpandable","isLegacyGroup","section","toSidebarItems","sections","legacyGroupToItem","legacyLeafToItem","group","leaf","shared","legacyDefaultExpandedKeys","legacyActiveKey","child","buildSidebarTree","order","duplicateKeys","walk","list","depth","ancestors","nodes","sortKeysByTreeOrder","keys","wanted","sorted","known","toggleExpandedKey","tree","descendant","descendantKeys","ancestor","expandPath","path","sameExpandedKeys","a","b","activeAncestorKeys","activeExpandablePath","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","ChartStatusOverlay","emptyMessage","useChartDimensions","setWidth","Chart","animate","isEmpty","legend","summaryId","showStatus","PALETTE_SIZE","resolveChartColor","explicit","overrides","chartSeriesColorList","series","ChartLegend","onToggle","legendItemsFromSeries","colorOverrides","hiddenKeys","colors","ChartTooltip","payload","linearScale","domain","d0","d1","r0","r1","niceTicks","count","rawStep","magnitude","residual","niceMin","niceMax","ticks","bandScale","paddingRatio","bandWidth","defaultNumberFormatter","locale","formatter","MARGIN","toNumber","formatXLabel","CartesianChart","kind","xKey","showLegend","showTooltip","showGrid","showDataLabels","xAxisLabel","yAxisLabel","xFormatter","yFormatter","stacked","onDataPointClick","onLegendItemClick","hidden","setHidden","s","visibleSeries","numberFormatter","isMeasuring","showOverlay","toggleSeries","willHide","legendItems","isHorizontal","offset","stackedTotals","sum","domainValues","domainMin","domainMax","valueScale","zeroY","seriesIndex","format","emitClick","handleColumnKeyDown","columnLabel","renderMarks","color","linePath","stackOffsets","groupWidth","bandStart","barLength","tick","LineChart","AreaChart","BarChart","StackedBarChart","ChartSliceSummary","useChartIndexNavigation","onActivate","setActiveIndexState","clearActive","polar","cy","r","angle","rad","slicePath","outerR","innerR","startAngle","endAngle","isFullCircle","large","ox","ox2","ix","ix2","x1","y1","x2","y2","x3","y3","x4","y4","CircularChartBase","nameKey","valueKey","innerRadiusRatio","centerLabel","centerValue","valueFormatter","onSliceClick","chartProps","slices","percent","nav","slice","CircularSurface","activeSlice","percentFormat","tabbableIndex","labelAngle","labelX","labelY","DonutChart","PieChart","toDate","startOfDay","isSameDay","addDays","addMonths","buildMonthGrid","viewDate","weekStartsOn","eventOccursOnDay","chunk","Calendar","onDateChange","events","view","disabledDates","maxEventsPerDay","todayLabel","moreLabel","noEventsLabel","onMonthChange","onEventClick","selected","setSelected","today","setViewDate","startOfMonthOf","grid","weeks","weekdayFormatter","titleFormatter","dayLabelFormatter","weekdayLabels","eventsByDayKey","map","dateKey","isDisabledDay","focusIndexFor","gridDays","selectedDate","selectedIndex","todayIndex","focusedIndex","setFocusedIndex","cellRefs","focusCell","goToMonth","keepSelected","targetMonth","selectDay","targetIndex","gridDay","moveFocus","nextIndex","handleGridKeyDown","rootId","week","weekIndex","dayIndex","isOutside","isToday","isSelected","dayDisabled","dayEvents","visibleEvents","overflowCount","dayAriaLabel","eventItem","clickEvent","DEFAULT_LABELS","IMAGE_MIME_TYPES","EXTENSION_MIME_TYPES","resolveMimeType","mimeType","fileName","ext","classifyMimeType","mime","toObjectUrl","blob","triggerDownload","url","revoke","link","workerConfigured","configurePdfWorker","pdfjsLib","workerUrl","classifyPdfError","labels","StatusPanel","showDownload","onDownload","downloadLabel","DocumentViewer","initialPage","toolbar","allowFullscreen","allowNewTab","onError","resolvedLabels","setKind","setStatus","setError","imageUrl","setImageUrl","setTotalPages","setCurrentPage","fitMode","setFitMode","manualScale","setManualScale","rotation","setRotation","fullscreen","setFullscreen","pdfDocRef","canvasRef","containerSize","setContainerSize","onErrorRef","onPageChangeRef","cancelled","objectUrl","loadingTask","fileKind","load","info","input","pdf","err","task","baseViewport","scale","viewport","canvas","handleDownload","handleOpenInNewTab","zoomIn","zoomOut","rotate","isPreviewable","renderToolbar","renderSurface","transform","body","AppearanceRadioGroup","refs","move","AppearanceMenu","colorSchemes","changeMode","changePresentation","changeTone","changeScheme","schemes","assignRef","composeRefs","Portal","container","host","setHost","createPortal","nodeKinds","markContextMenuNode","component","contextMenuNodeKind","isValidElement","flattenMenuChildren","flat","Children","partitionRichComponentBaseChildren","menu","contextMenuHasContent","CONTEXT_MENU_VIEWPORT_MARGIN","clamp","placeContextMenuAtPoint","point","margin","preferredX","preferredY","placeSubMenuBeside","trigger","ContextMenuSurfaceContext","positionStyle","position","viewportSize","isDisabledItem","menuItemsOf","focusFirstItem","useMenuLevelKeys","panelRef","onStepOut","focusAt","handled","ContextMenuPanel","surface","openId","setPosition","isInsidePanel","handleViewportChange","ContextMenuRoot","reportSelectError","runSelectHandler","ContextMenuItem","danger","ContextMenuLabel","ContextMenuSeparator","ContextMenuSubMenu","triggerRef","focusOnOpen","triggerId","closeLevel","triggerRect","panelRect","handlePanelKeys","ContextMenu","CONTEXT_MENU_OPEN_EVENT","isOpenDetail","detail","FORWARD_REF_TYPE","MEMO_TYPE","acceptsRef","marker","inner","composeMouseHandlers","handlers","handler","composeKeyboardHandlers","resolveTrigger","only","RichComponentBase","forwardRef","style","onContextMenu","onKeyDown","forwardedRef","instanceId","menuEnabled","menuProps","openState","setOpenState","openCounter","restoreFocusRef","reason","openAt","handleOtherOpen","triggerContextMenu","triggerKeyDown","surfaceValue","resolved","triggerNode","childProps","childRef","mergedClassName","hasStyle","cloneElement","createElement","HttpError","statusText","serializeParams","params","searchParams","rawValue","createHttpClient","baseUrl","fetcher","buildRequestInit","requestOptions","fullUrl","init","response","defaultHttpClient","sortKeys","obj","acc","useRemoteData","client","mapResponse","state","setState","setItems","reloadToken","setReloadToken","paramsKey","latestRequestId","mapResponseRef","requestId","controller","mapped","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","resolver","metadata","createSmartDataSourceRegistry","initial","definitions","definition","createSmartActionRegistry","hasDataSource","resolveParams","paramDefs","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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"}
|
|
1
|
+
{"version":3,"file":"index.js","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/shared/useIsomorphicLayoutEffect.ts","../src/base/shared/useElementResize.ts","../src/base/dataGridResponsive.ts","../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/chart/ChartStatus.tsx","../src/base/chart/useChartDimensions.ts","../src/base/Chart.tsx","../src/base/chart/chartColors.ts","../src/base/ChartLegend.tsx","../src/base/chart/ChartTooltip.tsx","../src/base/chart/chartScales.ts","../src/base/chart/CartesianChart.tsx","../src/base/LineChart.tsx","../src/base/AreaChart.tsx","../src/base/BarChart.tsx","../src/base/StackedBarChart.tsx","../src/base/chart/ChartSliceSummary.tsx","../src/base/chart/useChartIndexNavigation.ts","../src/base/chart/CircularChartBase.tsx","../src/base/DonutChart.tsx","../src/base/PieChart.tsx","../src/base/Calendar.tsx","../src/base/DocumentViewer.tsx","../src/base/AppearanceMenu.tsx","../src/base/shared/composeRefs.ts","../src/base/shared/Portal.tsx","../src/base/contextMenuModel.ts","../src/base/contextMenuPosition.ts","../src/base/ContextMenu.tsx","../src/base/RichComponentBase.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 { useEffect, useLayoutEffect } from \"react\";\r\n\r\n/**\r\n * `useLayoutEffect` in the browser, `useEffect` on the server.\r\n *\r\n * Measurement has to happen after layout but before paint, which is what\r\n * `useLayoutEffect` is for — but React warns when it runs during server\r\n * rendering, where there is no layout to read. The `typeof window` test never\r\n * touches a browser global (it cannot throw) and is evaluated once, so the\r\n * choice is constant for the lifetime of the module and the rules of hooks\r\n * still hold.\r\n */\r\nexport const useIsomorphicLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\r\n","import { useEffect, useRef, type RefObject } from \"react\";\r\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect\";\r\n\r\n/**\r\n * Calls `onResize` whenever the observed element's box changes.\r\n *\r\n * The element's *own* box, not the viewport: a grid can sit in a narrow\r\n * dashboard panel, a modal, a split view or a resizable container, and a\r\n * global breakpoint knows nothing about any of those.\r\n *\r\n * `ResizeObserver` is used when the environment has it, and only then; the\r\n * window-resize listener is a fallback for environments without it, so a\r\n * modern browser never gets a permanent global listener per grid. Nothing is\r\n * touched during module initialization or during render, so importing this on\r\n * a server is inert, and the observer is disconnected on cleanup — which is\r\n * also what makes it safe under React Strict Mode's double mount.\r\n */\r\nexport function useElementResize(ref: RefObject<Element | null>, enabled: boolean, onResize: () => void): void {\r\n const handlerRef = useRef(onResize);\r\n\r\n // Kept in a ref so a new inline callback never re-subscribes the observer.\r\n useIsomorphicLayoutEffect(() => {\r\n handlerRef.current = onResize;\r\n });\r\n\r\n useEffect(() => {\r\n if (!enabled) return;\r\n const element = ref.current;\r\n if (!element) return;\r\n\r\n const notify = () => handlerRef.current();\r\n\r\n if (typeof ResizeObserver !== \"undefined\") {\r\n const observer = new ResizeObserver(notify);\r\n observer.observe(element);\r\n return () => observer.disconnect();\r\n }\r\n\r\n if (typeof window === \"undefined\") return;\r\n window.addEventListener(\"resize\", notify);\r\n return () => window.removeEventListener(\"resize\", notify);\r\n }, [ref, enabled]);\r\n}\r\n","import { useCallback, useEffect, useRef, useState, type RefObject } from \"react\";\r\nimport { useElementResize } from \"./shared/useElementResize\";\r\nimport { useIsomorphicLayoutEffect } from \"./shared/useIsomorphicLayoutEffect\";\r\n\r\n/**\r\n * Responsive column model for grid-like components.\r\n *\r\n * The problem: when a grid's *actual available width* is too small for its\r\n * visible columns, rows stop being readable. The answer here is an ordered\r\n * list of rules that progressively take columns out of the tabular layout —\r\n * either relocating them into the row's own label/value detail area\r\n * (`\"Responsive\"`) or dropping them entirely (`\"Hide\"`) — while one primary\r\n * column always stays in the normal row.\r\n *\r\n * This module owns the whole algorithm: column classification, primary-column\r\n * resolution, rule normalization, development-time validation and the\r\n * width-driven fit loop. `DataGrid` is its only consumer, and `RemoteDataGrid`\r\n * and the Smart `dataGridResolver` inherit the behavior by composing\r\n * `DataGrid` — the algorithm exists exactly once.\r\n *\r\n * It is deliberately React-only-at-the-edges: everything above\r\n * `useResponsiveColumnFit` is a pure function of a structural column model,\r\n * so it is unit-testable without rendering a grid, and it never imports the\r\n * grid itself (no cycle, and the grid stays the sole owner of its column type).\r\n */\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Public contract\r\n * ------------------------------------------------------------------ */\r\n\r\n/**\r\n * What happens to a column when the grid runs out of room for it.\r\n *\r\n * - `\"Responsive\"` — leaves the tabular row and is shown as a label/value pair\r\n * in that same row's detail area.\r\n * - `\"Hide\"` — leaves the tabular row and is not shown anywhere.\r\n *\r\n * Capitalized, unlike this library's other string unions (`\"asc\"`, `\"text\"`,\r\n * `\"auto\"`, …), because these two are a specified external contract. One\r\n * representation only: the lower-case spellings are deliberately *not*\r\n * accepted, so there is never a second competing form of the same concept.\r\n */\r\nexport type ResponsiveColumnBehavior = \"Responsive\" | \"Hide\";\r\n\r\n/**\r\n * One entry of the ordered rule list. Position in the array is the priority —\r\n * there is no separate priority number to keep in sync with it.\r\n */\r\nexport interface ResponsiveColumnRule<TField> {\r\n field: TField;\r\n behavior: ResponsiveColumnBehavior;\r\n}\r\n\r\nexport interface GridResponsiveOptions<TField> {\r\n /**\r\n * The column that carries the row's identity in a narrow layout. It always\r\n * stays in the tabular row: it is never relocated to the detail area and\r\n * never removed by a `\"Hide\"` rule.\r\n */\r\n primaryColumn?: TField;\r\n /**\r\n * Ordered rules. The first is processed first as width shrinks, and the last\r\n * processed is the first restored as width grows. Columns not listed here\r\n * are still handled — see `buildResponsiveColumnPlan`.\r\n */\r\n columns?: readonly ResponsiveColumnRule<TField>[];\r\n}\r\n\r\n/**\r\n * The parts of a grid column this model needs, as a structural shape.\r\n *\r\n * `isData` / `isUtility` / `isTextual` are classifications the grid derives\r\n * from its own column type, so this module never has to know what a\r\n * `DataGridColumn` is.\r\n */\r\nexport interface ResponsiveColumnModel {\r\n /** The grid's own column identity. */\r\n key: string;\r\n /** Reads a value out of the row (as opposed to a command/action column). */\r\n isData: boolean;\r\n /** A command/action/control column: renders arbitrary content, reads no value. */\r\n isUtility: boolean;\r\n /** A data column whose value is textual, so it reads well as a row title. */\r\n isTextual: boolean;\r\n}\r\n\r\nexport type ResponsiveProblemKind =\r\n | \"unknown-column\"\r\n | \"duplicate-rule\"\r\n | \"primary-column-rule\"\r\n | \"invalid-behavior\"\r\n | \"utility-column-responsive\"\r\n | \"invalid-primary-column\";\r\n\r\n/** One development-time diagnostic, in the same shape the demo registry uses. */\r\nexport interface ResponsiveProblem {\r\n kind: ResponsiveProblemKind;\r\n detail: string;\r\n}\r\n\r\n/** A rule after validation, addressed by the grid's resolved column key. */\r\nexport interface NormalizedResponsiveRule {\r\n key: string;\r\n behavior: ResponsiveColumnBehavior;\r\n}\r\n\r\nexport interface ResponsiveColumnPlan {\r\n /** Resolved primary column, or `undefined` when no column is eligible. */\r\n primaryKey: string | undefined;\r\n /** The single ordered list the fit loop walks. */\r\n rules: readonly NormalizedResponsiveRule[];\r\n problems: readonly ResponsiveProblem[];\r\n}\r\n\r\nconst BEHAVIORS: readonly ResponsiveColumnBehavior[] = [\"Responsive\", \"Hide\"];\r\n\r\nfunction isBehavior(value: unknown): value is ResponsiveColumnBehavior {\r\n return typeof value === \"string\" && BEHAVIORS.includes(value as ResponsiveColumnBehavior);\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Primary column resolution\r\n * ------------------------------------------------------------------ */\r\n\r\n/**\r\n * Deterministic resolution, in order:\r\n *\r\n * 1. the configured `primaryColumn`, when it names an eligible column;\r\n * 2. otherwise the first textual data column in declared column order;\r\n * 3. otherwise the first data column in declared column order;\r\n * 4. otherwise `undefined` — the grid keeps its existing behavior.\r\n *\r\n * Utility columns (selection, row number, expanders, actions, command and\r\n * drag-handle columns) are never chosen automatically, and a configured one is\r\n * rejected: a checkbox or a button is not a row's identity.\r\n *\r\n * A configured column that is absent from the current column set — because it\r\n * was filtered out upstream by a column chooser, by a permission check or by\r\n * Smart metadata — cannot be the *visible* primary column, so resolution falls\r\n * through to the automatic rules. Nothing about the upstream decision is\r\n * touched or written back.\r\n */\r\nexport function resolvePrimaryColumnKey(\r\n columns: readonly ResponsiveColumnModel[],\r\n configured: string | undefined\r\n): string | undefined {\r\n const eligible = columns.filter((column) => column.isData && !column.isUtility);\r\n\r\n if (configured !== undefined) {\r\n const match = eligible.find((column) => column.key === configured);\r\n if (match) return match.key;\r\n }\r\n\r\n return eligible.find((column) => column.isTextual)?.key ?? eligible[0]?.key;\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Rule normalization\r\n * ------------------------------------------------------------------ */\r\n\r\n/**\r\n * Turns the configured options into one ordered, validated rule list.\r\n *\r\n * Configured rules come first, in their declared order. Every remaining\r\n * eligible data column is then appended in *declared column order* with the\r\n * default `\"Responsive\"` behavior, so responsive layout works without asking\r\n * a consumer to describe every column — and nothing is hidden by default.\r\n *\r\n * Skipped, each with a diagnostic: a rule for an unknown column, a duplicate\r\n * rule, a rule for the primary column, a rule with an invalid behavior, and a\r\n * `\"Responsive\"` rule for a utility column (an action cell has no meaningful\r\n * label/value form). A `\"Hide\"` rule for a utility column is honored — that is\r\n * an explicit instruction to drop a control when space runs out, not a silent\r\n * loss of data. Utility columns are never added by default.\r\n */\r\nexport function buildResponsiveColumnPlan(\r\n columns: readonly ResponsiveColumnModel[],\r\n options: GridResponsiveOptions<string> | undefined\r\n): ResponsiveColumnPlan {\r\n const problems: ResponsiveProblem[] = [];\r\n const byKey = new Map(columns.map((column) => [column.key, column]));\r\n const primaryKey = resolvePrimaryColumnKey(columns, options?.primaryColumn);\r\n\r\n if (options?.primaryColumn !== undefined && options.primaryColumn !== primaryKey) {\r\n problems.push({\r\n kind: \"invalid-primary-column\",\r\n detail: `\"${options.primaryColumn}\" is not an eligible data column; ${\r\n primaryKey === undefined ? \"no primary column could be resolved\" : `\"${primaryKey}\" was resolved instead`\r\n }`,\r\n });\r\n }\r\n\r\n const rules: NormalizedResponsiveRule[] = [];\r\n const claimed = new Set<string>();\r\n\r\n for (const rule of options?.columns ?? []) {\r\n const column = byKey.get(rule.field);\r\n if (!column) {\r\n problems.push({ kind: \"unknown-column\", detail: rule.field });\r\n continue;\r\n }\r\n if (claimed.has(rule.field)) {\r\n problems.push({ kind: \"duplicate-rule\", detail: rule.field });\r\n continue;\r\n }\r\n if (!isBehavior(rule.behavior)) {\r\n problems.push({ kind: \"invalid-behavior\", detail: `${rule.field} -> ${String(rule.behavior)}` });\r\n continue;\r\n }\r\n if (rule.field === primaryKey) {\r\n problems.push({ kind: \"primary-column-rule\", detail: rule.field });\r\n // Claimed so the default pass does not add it back either.\r\n claimed.add(rule.field);\r\n continue;\r\n }\r\n if (column.isUtility && rule.behavior === \"Responsive\") {\r\n problems.push({ kind: \"utility-column-responsive\", detail: rule.field });\r\n claimed.add(rule.field);\r\n continue;\r\n }\r\n\r\n claimed.add(rule.field);\r\n rules.push({ key: rule.field, behavior: rule.behavior });\r\n }\r\n\r\n for (const column of columns) {\r\n if (claimed.has(column.key)) continue;\r\n if (column.key === primaryKey) continue;\r\n if (!column.isData || column.isUtility) continue;\r\n rules.push({ key: column.key, behavior: \"Responsive\" });\r\n }\r\n\r\n return { primaryKey, rules, problems };\r\n}\r\n\r\n/**\r\n * A stable string identity for one plan. Used to reset the fit loop and to\r\n * report diagnostics once per configuration rather than once per render or —\r\n * far worse — once per resize.\r\n */\r\nexport function responsivePlanSignature(plan: ResponsiveColumnPlan): string {\r\n const rules = plan.rules.map((rule) => `${rule.key}:${rule.behavior}`).join(\",\");\r\n const problems = plan.problems.map((problem) => `${problem.kind}:${problem.detail}`).join(\",\");\r\n return `${plan.primaryKey ?? \"\"}|${rules}|${problems}`;\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Width-driven fit loop\r\n * ------------------------------------------------------------------ */\r\n\r\n/** Sub-pixel slack, so a rounding artifact is never read as an overflow. */\r\nconst OVERFLOW_TOLERANCE = 1;\r\n\r\n/**\r\n * A column is restored only once the container is meaningfully wider than the\r\n * width at which it last failed to fit. Without this, a width sitting exactly\r\n * on a threshold would remove and restore the same column forever.\r\n */\r\nconst RESTORE_HYSTERESIS = 16;\r\n\r\nexport interface ResponsiveColumnFitOptions {\r\n enabled: boolean;\r\n /** The grid's own scroll container — the element whose width actually matters. */\r\n containerRef: RefObject<HTMLElement | null>;\r\n ruleCount: number;\r\n /** Resets the loop when the columns or the rules themselves change. */\r\n signature: string;\r\n}\r\n\r\n/**\r\n * How many rules are currently applied.\r\n *\r\n * Overflow is read from the grid's existing scroll container\r\n * (`scrollWidth` vs `clientWidth`) rather than from a re-implementation of\r\n * column sizing, so the browser's own table layout — fixed, minimum and\r\n * maximum column widths, measured content, `white-space` — remains the single\r\n * sizing authority. Two DOM reads per pass, independent of row count: the\r\n * algorithm is O(1) in rows and never scans cells.\r\n *\r\n * Shrinking applies one more rule per pass and records the width at which the\r\n * previous count did not fit. Growing releases one rule per pass, but only\r\n * once the container is wider than that recorded width plus the hysteresis, so\r\n * a restore that would immediately overflow again is not attempted. Passes are\r\n * capped per width, so a pathological layout cannot loop forever.\r\n */\r\nexport function useResponsiveColumnFit({\r\n enabled,\r\n containerRef,\r\n ruleCount,\r\n signature,\r\n}: ResponsiveColumnFitOptions): number {\r\n const [processedCount, setProcessedCount] = useState(0);\r\n const countRef = useRef(0);\r\n const blockedWidthRef = useRef<number | null>(null);\r\n const lastWidthRef = useRef(-1);\r\n const passesRef = useRef(0);\r\n\r\n useEffect(() => {\r\n countRef.current = 0;\r\n blockedWidthRef.current = null;\r\n lastWidthRef.current = -1;\r\n passesRef.current = 0;\r\n setProcessedCount(0);\r\n }, [signature, enabled]);\r\n\r\n const evaluate = useCallback(() => {\r\n if (!enabled) return;\r\n const element = containerRef.current;\r\n if (!element) return;\r\n\r\n const available = element.clientWidth;\r\n // Zero means \"no layout to read\": a server render, a detached node, a\r\n // `display: none` ancestor, or a test environment without layout. Leaving\r\n // the plan untouched keeps the grid exactly as it was.\r\n if (available <= 0) return;\r\n\r\n if (available !== lastWidthRef.current) {\r\n lastWidthRef.current = available;\r\n passesRef.current = 0;\r\n }\r\n if (passesRef.current > ruleCount + 2) return;\r\n\r\n const overflowing = element.scrollWidth - available > OVERFLOW_TOLERANCE;\r\n const current = countRef.current;\r\n let next = current;\r\n\r\n if (overflowing) {\r\n if (current < ruleCount) {\r\n next = current + 1;\r\n blockedWidthRef.current = available;\r\n }\r\n } else if (current > 0) {\r\n const blocked = blockedWidthRef.current;\r\n if (blocked === null || available > blocked + RESTORE_HYSTERESIS) next = current - 1;\r\n }\r\n\r\n if (next === current) return;\r\n passesRef.current += 1;\r\n countRef.current = next;\r\n setProcessedCount(next);\r\n }, [enabled, containerRef, ruleCount]);\r\n\r\n // After every commit: the loop converges across renders, all before paint,\r\n // so a transient step is never painted.\r\n useIsomorphicLayoutEffect(evaluate);\r\n useElementResize(containerRef, enabled, evaluate);\r\n\r\n return enabled ? processedCount : 0;\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Development-time validation\r\n * ------------------------------------------------------------------ */\r\n\r\nconst PROBLEM_MESSAGES: Record<ResponsiveProblemKind, string> = {\r\n \"unknown-column\": \"names a column that does not exist and was ignored\",\r\n \"duplicate-rule\": \"is listed more than once; only the first rule was kept\",\r\n \"primary-column-rule\": \"targets the primary column, which never leaves the row, and was ignored\",\r\n \"invalid-behavior\": 'has an unsupported behavior; use \"Responsive\" or \"Hide\"',\r\n \"utility-column-responsive\":\r\n 'is an action/command column and has no meaningful label/value form, so its \"Responsive\" rule was ignored — use \"Hide\" to drop it instead',\r\n \"invalid-primary-column\": \"is not usable as the primary column\",\r\n};\r\n\r\n/**\r\n * Reports configuration problems once per configuration.\r\n *\r\n * Follows the library's existing development-time validation convention\r\n * (`useControllableState`, `Sidebar`): `NODE_ENV`-guarded, `console.error`\r\n * with the `[react-components]` prefix, from an effect keyed on a stable\r\n * signature — so it never throws during render and never logs on resize.\r\n * Production fails safe: the malformed rule is skipped, and no data is hidden\r\n * because of it.\r\n */\r\nexport function useResponsivePlanDiagnostics(plan: ResponsiveColumnPlan, signature: string): void {\r\n const { problems } = plan;\r\n\r\n useEffect(() => {\r\n if (process.env.NODE_ENV === \"production\") return;\r\n if (problems.length === 0) return;\r\n\r\n for (const problem of problems) {\r\n // eslint-disable-next-line no-console\r\n console.error(\r\n `[react-components] DataGrid responsive configuration: \"${problem.detail}\" ${PROBLEM_MESSAGES[problem.kind]}.`\r\n );\r\n }\r\n // `signature` encodes the problems, so this fires once per configuration —\r\n // never per render, and never per resize.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [signature]);\r\n}\r\n","import { Fragment, useMemo, useRef, type ReactNode } from \"react\";\r\nimport { Pagination } from \"./Pagination\";\r\nimport {\r\n buildResponsiveColumnPlan,\r\n responsivePlanSignature,\r\n useResponsiveColumnFit,\r\n useResponsivePlanDiagnostics,\r\n type GridResponsiveOptions,\r\n type ResponsiveColumnModel,\r\n type ResponsiveColumnPlan,\r\n} from \"./dataGridResponsive\";\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\n/**\r\n * A column's identity as the grid resolves it: `key ?? field ?? header`.\r\n *\r\n * The row's own field names are offered as suggestions — they are what most\r\n * columns are keyed by — while an explicit `key` (a `render`-only column, a\r\n * command column) is still accepted. `string & {}` is what keeps the literal\r\n * suggestions from collapsing into bare `string`.\r\n */\r\nexport type DataGridColumnKey<TRow> = (keyof TRow & string) | (string & {});\r\n\r\n/** Responsive options for one grid, keyed by that grid's column identities. */\r\nexport type DataGridResponsiveOptions<TRow> = GridResponsiveOptions<DataGridColumnKey<TRow>>;\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\n * Progressive column reduction for narrow containers. Presence of this\r\n * object is what enables the behavior — there is no second boolean to\r\n * disagree with it. Omitted (the default), the grid is byte-for-byte what it\r\n * was: every column stays in the row and a wide table scrolls horizontally\r\n * inside its own container.\r\n *\r\n * Enabled, columns leave the tabular layout one at a time as the *grid's own\r\n * container* gets too narrow for them, in the order of `columns`, and come\r\n * back in the exact reverse order as it widens. `primaryColumn` always stays.\r\n * With no `columns` list, every eligible data column is processed in declared\r\n * order with `\"Responsive\"` behavior, so nothing is hidden by default.\r\n */\r\n responsive?: DataGridResponsiveOptions<TRow>;\r\n}\r\n\r\nconst EMPTY_RESPONSIVE_PLAN: ResponsiveColumnPlan = { primaryKey: undefined, rules: [], problems: [] };\r\nconst EMPTY_COLUMNS: never[] = [];\r\n\r\n/**\r\n * Classifies one column for the responsive model.\r\n *\r\n * A *utility* column is the library's existing shape for a command/action\r\n * cell: a `render` callback with no `field` to read (the demo's row-action\r\n * column is exactly this). Those are never chosen as the primary column and\r\n * never relocated into a label/value detail area, because a button has no\r\n * meaningful label/value form. The built-in selection checkbox column is not a\r\n * `DataGridColumn` at all, so it is outside this model entirely and always\r\n * stays in the row.\r\n */\r\nfunction toResponsiveColumnModel<TRow>(column: DataGridColumn<TRow>): ResponsiveColumnModel {\r\n const accessor = column.field ?? column.key;\r\n const isUtility = column.render !== undefined && column.field === undefined;\r\n const isData = !isUtility && accessor !== undefined;\r\n\r\n return {\r\n key: columnKeyOf(column),\r\n isData,\r\n isUtility,\r\n // Deterministic and data-independent: derived from the column model, never\r\n // by sampling row values, so the primary column cannot change between the\r\n // loading and loaded states of the same grid.\r\n isTextual: isData && (column.format === undefined || column.format === \"text\"),\r\n };\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 responsive,\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 /* ---- responsive column plan ----\r\n Purely derived presentation state. The `columns` prop is never rewritten,\r\n so a column hidden by a chooser, by a permission check or by Smart\r\n metadata was already gone before it got here and stays gone; and a column\r\n the responsive pass removed comes back on its own when there is room,\r\n without anything being persisted. */\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const responsiveEnabled = responsive !== undefined;\r\n\r\n const columnModels = useMemo(() => columns.map(toResponsiveColumnModel), [columns]);\r\n const plan = useMemo(\r\n () => (responsive === undefined ? EMPTY_RESPONSIVE_PLAN : buildResponsiveColumnPlan(columnModels, responsive)),\r\n [columnModels, responsive]\r\n );\r\n const signature = responsivePlanSignature(plan);\r\n\r\n useResponsivePlanDiagnostics(plan, signature);\r\n const processedCount = useResponsiveColumnFit({\r\n enabled: responsiveEnabled,\r\n containerRef,\r\n ruleCount: plan.rules.length,\r\n signature,\r\n });\r\n\r\n const processedRules = plan.rules.slice(0, processedCount);\r\n let visibleColumns = columns;\r\n let detailColumns: DataGridColumn<TRow>[] = EMPTY_COLUMNS;\r\n\r\n if (processedRules.length > 0) {\r\n const removedKeys = new Set(processedRules.map((rule) => rule.key));\r\n visibleColumns = columns.filter((column) => !removedKeys.has(columnKeyOf(column)));\r\n\r\n const columnsByKey = new Map(columns.map((column) => [columnKeyOf(column), column] as const));\r\n // Relocated columns keep the order in which their rules were processed.\r\n // `\"Hide\"` rules are absent here by construction, so a hidden column\r\n // reaches neither the row nor the detail area.\r\n detailColumns = processedRules\r\n .filter((rule) => rule.behavior === \"Responsive\")\r\n .map((rule) => columnsByKey.get(rule.key))\r\n .filter((column): column is DataGridColumn<TRow> => column !== undefined);\r\n }\r\n\r\n // `colSpan={0}` means \"every remaining column\" in HTML, which is not what a\r\n // state row wants; one is the floor even in the degenerate case where a\r\n // consumer explicitly hid every column.\r\n const spanCount = Math.max(1, visibleColumns.length + (selectable ? 1 : 0));\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\r\n ref={containerRef}\r\n className={cx(\"table-responsive\", \"rrc-data-grid\", responsiveEnabled && \"rrc-data-grid--responsive\", className)}\r\n >\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 {visibleColumns.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={spanCount} 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={spanCount} 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={spanCount} 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 // One Fragment per row, keyed by the row's own identity: the\r\n // detail row cannot collide with any other row's React key,\r\n // whatever `rowKey` returns.\r\n <Fragment key={key}>\r\n <tr>\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 {visibleColumns.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 {detailColumns.length > 0 && (\r\n // A real table row with the right colSpan, so the table DOM\r\n // stays valid, the detail belongs to its own row, and the\r\n // row's context menu / click scope is unchanged. Always\r\n // visible: these columns were removed by layout, not\r\n // collapsed by the user, so they need no expander.\r\n <tr className=\"rrc-data-grid__detail-row\">\r\n <td colSpan={spanCount} className=\"rrc-data-grid__detail-cell\">\r\n <dl className=\"rrc-data-grid__details\">\r\n {detailColumns.map((column) => (\r\n <div key={columnKeyOf(column)} className=\"rrc-data-grid__detail-item\">\r\n <dt className=\"rrc-data-grid__detail-term\">{column.header}</dt>\r\n {/* Same value pipeline as the normal cell — render,\r\n formatter, format, null convention — and the\r\n column is *moved*, never duplicated, so no cell\r\n renders or fetches twice. */}\r\n <dd className=\"rrc-data-grid__detail-value\">{renderCell(column, row)}</dd>\r\n </div>\r\n ))}\r\n </dl>\r\n </td>\r\n </tr>\r\n )}\r\n </Fragment>\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 type { ReactNode } from \"react\";\r\nimport { Alert } from \"../Alert\";\r\nimport { Skeleton } from \"../Skeleton\";\r\nimport { cx } from \"../shared/classNames\";\r\nimport type { ChartStatusProps } from \"./chartTypes\";\r\n\r\nexport interface ChartStatusOverlayProps extends ChartStatusProps {\r\n height: number;\r\n emptyMessage?: ReactNode;\r\n}\r\n\r\n/**\r\n * Loading/error/empty presentation shared by every chart (doc: \"Chart,\r\n * ChartLegend, ChartTooltip, ChartEmptyState\" common infrastructure — kept as\r\n * one internal piece rather than three, since none of the three states is\r\n * ever shown without the others in this family).\r\n *\r\n * Not part of the public surface: each concrete chart decides when to render\r\n * it, so there is nothing here a consumer would use standalone.\r\n */\r\nexport function ChartStatusOverlay({ loading, error, emptyMessage, height }: ChartStatusOverlayProps) {\r\n if (loading) {\r\n return (\r\n <div className=\"rrc-chart__status\" style={{ height }} aria-busy=\"true\">\r\n <Skeleton height=\"100%\" width=\"100%\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"rrc-chart__status\" style={{ height }}>\r\n <Alert variant=\"danger\" className=\"mb-0 h-100 d-flex align-items-center\">\r\n {error}\r\n </Alert>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={cx(\"rrc-chart__status\", \"rrc-chart__empty\")} style={{ height }}>\r\n {emptyMessage ?? \"No data to display\"}\r\n </div>\r\n );\r\n}\r\n","import { useRef, useState } from \"react\";\r\nimport { useElementResize } from \"../shared/useElementResize\";\r\nimport { useIsomorphicLayoutEffect } from \"../shared/useIsomorphicLayoutEffect\";\r\n\r\n/**\r\n * Measures the chart's own container width (doc: responsive width, no global\r\n * breakpoint). Reuses `useElementResize` (ResizeObserver with a window-resize\r\n * fallback, already SSR-safe) instead of a second measurement strategy.\r\n *\r\n * Starts at 0 so the very first server/client render emits no SVG at all\r\n * (avoids a divide-by-zero layout before the real width is known); the\r\n * measured width lands on the next paint, which is invisible to the user.\r\n */\r\nexport function useChartDimensions(): { containerRef: React.RefObject<HTMLDivElement>; width: number } {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const [width, setWidth] = useState(0);\r\n\r\n const measure = () => {\r\n const next = containerRef.current?.clientWidth ?? 0;\r\n setWidth((prev) => (prev === next ? prev : next));\r\n };\r\n\r\n useIsomorphicLayoutEffect(measure, []);\r\n useElementResize(containerRef, true, measure);\r\n\r\n return { containerRef, width };\r\n}\r\n","import { useId, type ReactNode } from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { ChartStatusOverlay } from \"./chart/ChartStatus\";\r\nimport { useChartDimensions } from \"./chart/useChartDimensions\";\r\nimport type { ChartCommonProps } from \"./chart/chartTypes\";\r\n\r\nexport interface ChartProps extends ChartCommonProps {\r\n /** Render prop — receives the measured surface size once a real width is known (never called at width 0). */\r\n children: (size: { width: number; height: number }) => ReactNode;\r\n /** No data to plot (distinct from `loading`/`error`) — renders `emptyMessage` instead of an empty SVG. */\r\n isEmpty?: boolean;\r\n legend?: ReactNode;\r\n /** Visually-hidden textual/table fallback for screen reader and keyboard users who don't perceive the SVG (doc: chart data needs a non-visual summary). */\r\n summary?: ReactNode;\r\n}\r\n\r\n/**\r\n * Low-level responsive shell every concrete chart (LineChart, BarChart, ...)\r\n * composes for sizing + loading/empty/error chrome (doc: \"Chart\" is part of\r\n * the public surface in its own right, for a consumer building a custom\r\n * visualization without reimplementing that infrastructure).\r\n *\r\n * Deliberately not `role=\"img\"`: a chart's data points are individually\r\n * focusable (keyboard navigation between them), and `img` tells assistive\r\n * tech to ignore all descendants. `group` plus the visually-hidden `summary`\r\n * is what stays correct for an interactive chart.\r\n */\r\nexport function Chart({\r\n title,\r\n height = 320,\r\n loading,\r\n error,\r\n emptyMessage,\r\n disabled,\r\n className,\r\n animate = true,\r\n \"aria-label\": ariaLabel,\r\n isEmpty,\r\n legend,\r\n summary,\r\n children,\r\n}: ChartProps) {\r\n const { containerRef, width } = useChartDimensions();\r\n const summaryId = useId();\r\n const showStatus = loading || !!error || isEmpty;\r\n\r\n return (\r\n <div className={cx(\"rrc-chart\", !animate && \"rrc-chart--no-animate\", className)}>\r\n {title && <div className=\"rrc-chart__title\">{title}</div>}\r\n <div\r\n ref={containerRef}\r\n className={cx(\"rrc-chart__surface\", disabled && \"rrc-chart__surface--disabled\")}\r\n style={{ height }}\r\n role=\"group\"\r\n aria-label={ariaLabel ?? title}\r\n aria-describedby={summary ? summaryId : undefined}\r\n aria-busy={loading || undefined}\r\n >\r\n {showStatus ? (\r\n <ChartStatusOverlay loading={loading} error={error} emptyMessage={emptyMessage} height={height} />\r\n ) : (\r\n width > 0 && children({ width, height })\r\n )}\r\n </div>\r\n {!showStatus && legend}\r\n {summary && (\r\n <div id={summaryId} className=\"visually-hidden\">\r\n {summary}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import type { ChartSeries } from \"./chartTypes\";\r\n\r\n/**\r\n * Chart palette — five `--rrc-chart-N` tokens (doc: colors come from theme\r\n * tokens, never hardcoded hex in a component). A series/slice with an\r\n * explicit `color` wins; otherwise the palette assigns one by index, cycling\r\n * if there are more series than palette slots.\r\n */\r\nconst PALETTE_SIZE = 5;\r\n\r\nexport function resolveChartColor(index: number, explicit: string | undefined, overrides: string[] | undefined): string {\r\n if (explicit) return explicit;\r\n if (overrides && overrides.length > 0) return overrides[index % overrides.length]!;\r\n return `var(--rrc-chart-${(index % PALETTE_SIZE) + 1})`;\r\n}\r\n\r\n/** Resolves a color for every series in order — the shape `ChartLegend` and every concrete chart need. */\r\nexport function chartSeriesColorList(series: readonly ChartSeries[], overrides: string[] | undefined): string[] {\r\n return series.map((item, index) => resolveChartColor(index, item.color, overrides));\r\n}\r\n","import { cx } from \"./shared/classNames\";\r\nimport { chartSeriesColorList } from \"./chart/chartColors\";\r\nimport type { ChartSeries } from \"./chart/chartTypes\";\r\n\r\nexport interface ChartLegendItem {\r\n key: string;\r\n label: string;\r\n color: string;\r\n hidden?: boolean;\r\n}\r\n\r\nexport interface ChartLegendProps {\r\n items: readonly ChartLegendItem[];\r\n /** Toggles one series' visibility. Omit to render a read-only legend. */\r\n onToggle?: (key: string) => void;\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Series swatches + labels, shared by every chart (doc section 5 — public,\r\n * reused rather than reimplemented per chart type). Each item is a real\r\n * `<button>` when `onToggle` is supplied, so toggling a series is keyboard-\r\n * and screen-reader-accessible, not a `<div onClick>`.\r\n */\r\nexport function ChartLegend({ items, onToggle, className }: ChartLegendProps) {\r\n return (\r\n <ul className={cx(\"rrc-chart-legend\", className)} role=\"list\">\r\n {items.map((item) => (\r\n <li key={item.key} className=\"rrc-chart-legend__item\">\r\n {onToggle ? (\r\n <button\r\n type=\"button\"\r\n className={cx(\"rrc-chart-legend__button\", item.hidden && \"rrc-chart-legend__button--hidden\")}\r\n aria-pressed={!item.hidden}\r\n onClick={() => onToggle(item.key)}\r\n >\r\n <span className=\"rrc-chart-legend__swatch\" style={{ backgroundColor: item.color }} aria-hidden=\"true\" />\r\n {item.label}\r\n </button>\r\n ) : (\r\n <span className=\"rrc-chart-legend__label\">\r\n <span className=\"rrc-chart-legend__swatch\" style={{ backgroundColor: item.color }} aria-hidden=\"true\" />\r\n {item.label}\r\n </span>\r\n )}\r\n </li>\r\n ))}\r\n </ul>\r\n );\r\n}\r\n\r\n/** Convenience: builds legend items straight from a chart's series list + resolved colors — the shape every concrete chart needs. */\r\nexport function legendItemsFromSeries(series: readonly ChartSeries[], colorOverrides: string[] | undefined, hiddenKeys: ReadonlySet<string>): ChartLegendItem[] {\r\n const colors = chartSeriesColorList(series, colorOverrides);\r\n return series.map((item, index) => ({ key: item.key, label: item.label, color: colors[index]!, hidden: hiddenKeys.has(item.key) }));\r\n}\r\n","import { cx } from \"../shared/classNames\";\r\n\r\nexport interface ChartTooltipPayloadItem {\r\n key: string;\r\n label: string;\r\n value: string;\r\n color: string;\r\n}\r\n\r\nexport interface ChartTooltipPayload {\r\n label: string;\r\n items: ChartTooltipPayloadItem[];\r\n}\r\n\r\nexport interface ChartTooltipProps {\r\n payload: ChartTooltipPayload;\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Summary of the currently focused/hovered data point (doc: tooltip).\r\n * Deliberately not a cursor-following floating panel: that would need its own\r\n * portal/collision-avoidance system duplicating `Popup`'s, for marginal gain —\r\n * a fixed slot next to the chart (positioned by CSS, `.rrc-chart__tooltip`) is\r\n * equally readable and stays keyboard- and touch-friendly without one.\r\n */\r\nexport function ChartTooltip({ payload, className }: ChartTooltipProps) {\r\n return (\r\n <div className={cx(\"rrc-chart__tooltip\", className)}>\r\n <div className=\"rrc-chart__tooltip-title\">{payload.label}</div>\r\n {payload.items.map((item) => (\r\n <div key={item.key} className=\"rrc-chart__tooltip-row\">\r\n <span className=\"rrc-chart__tooltip-swatch\" style={{ backgroundColor: item.color }} aria-hidden=\"true\" />\r\n <span className=\"rrc-chart__tooltip-label\">{item.label}</span>\r\n <span className=\"rrc-chart__tooltip-value\">{item.value}</span>\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * Minimal scale/tick math, written in-house rather than adding a dependency\r\n * (d3-scale et al.) — the same call this repo already made for `Sparkline`.\r\n * A handful of pure functions is enough for a band + linear axis and stays\r\n * inside the library's zero-runtime-dependency footprint for the Base layer.\r\n */\r\n\r\nexport function linearScale(domain: [number, number], range: [number, number]): (value: number) => number {\r\n const [d0, d1] = domain;\r\n const [r0, r1] = range;\r\n const span = d1 - d0 || 1;\r\n return (value: number) => r0 + ((value - d0) / span) * (r1 - r0);\r\n}\r\n\r\n/** \"Nice\" round tick values spanning at least [min, max] — the standard d3-style rounding step. */\r\nexport function niceTicks(min: number, max: number, count = 5): number[] {\r\n if (min === max) {\r\n min -= 1;\r\n max += 1;\r\n }\r\n const range = max - min;\r\n const rawStep = range / Math.max(count, 1);\r\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));\r\n const residual = rawStep / magnitude;\r\n const step = residual > 5 ? 10 * magnitude : residual > 2 ? 5 * magnitude : residual > 1 ? 2 * magnitude : magnitude;\r\n const niceMin = Math.floor(min / step) * step;\r\n const niceMax = Math.ceil(max / step) * step;\r\n\r\n const ticks: number[] = [];\r\n for (let value = niceMin; value <= niceMax + step * 0.5; value += step) {\r\n ticks.push(Math.round(value / step) * step);\r\n }\r\n return ticks;\r\n}\r\n\r\n/** Evenly divides `size` into `count` bands, returning each band's start offset and width. */\r\nexport function bandScale(count: number, size: number, paddingRatio = 0.2): { bandWidth: number; offset: (index: number) => number } {\r\n if (count <= 0) return { bandWidth: size, offset: () => 0 };\r\n const step = size / count;\r\n const bandWidth = step * (1 - paddingRatio);\r\n const padding = (step - bandWidth) / 2;\r\n return { bandWidth, offset: (index: number) => index * step + padding };\r\n}\r\n\r\nexport function defaultNumberFormatter(locale?: string): (value: number) => string {\r\n const formatter = new Intl.NumberFormat(locale, { maximumFractionDigits: 2 });\r\n return (value: number) => formatter.format(value);\r\n}\r\n","import { useId, useMemo, useState, type KeyboardEvent, type ReactNode } from \"react\";\r\nimport { cx } from \"../shared/classNames\";\r\nimport { ChartLegend, type ChartLegendItem } from \"../ChartLegend\";\r\nimport { ChartStatusOverlay } from \"./ChartStatus\";\r\nimport { ChartTooltip, type ChartTooltipPayload } from \"./ChartTooltip\";\r\nimport { resolveChartColor } from \"./chartColors\";\r\nimport { bandScale, defaultNumberFormatter, linearScale, niceTicks } from \"./chartScales\";\r\nimport type { ChartCommonProps, ChartDatum, ChartInteraction, ChartSeries, ChartValue } from \"./chartTypes\";\r\nimport { useChartDimensions } from \"./useChartDimensions\";\r\n\r\nexport interface CartesianChartCoreProps extends ChartCommonProps {\r\n kind: \"line\" | \"area\" | \"bar\";\r\n data: ChartDatum[];\r\n xKey: string;\r\n series: ChartSeries[];\r\n xAxisLabel?: string;\r\n yAxisLabel?: string;\r\n showGrid?: boolean;\r\n showDataLabels?: boolean;\r\n xFormatter?: (value: ChartValue) => string;\r\n yFormatter?: (value: number) => string;\r\n /** Bar/StackedBar only. */\r\n orientation?: \"vertical\" | \"horizontal\";\r\n /** Bar only — StackedBarChart always passes `true` and hides the prop from its own public API. */\r\n stacked?: boolean;\r\n onDataPointClick?: (interaction: ChartInteraction) => void;\r\n onLegendItemClick?: (seriesKey: string, hidden: boolean) => void;\r\n locale?: string;\r\n}\r\n\r\nconst MARGIN = { top: 16, right: 16, bottom: 32, left: 48 };\r\n\r\nfunction toNumber(value: ChartValue | null | undefined): number {\r\n if (value == null) return 0;\r\n if (value instanceof Date) return value.getTime();\r\n return typeof value === \"number\" ? value : Number(value) || 0;\r\n}\r\n\r\nfunction formatXLabel(value: ChartValue, formatter?: (value: ChartValue) => string): string {\r\n if (formatter) return formatter(value);\r\n if (value instanceof Date) return value.toLocaleDateString();\r\n return String(value);\r\n}\r\n\r\n/**\r\n * Shared renderer behind LineChart/AreaChart/BarChart/StackedBarChart (doc:\r\n * compose, don't reimplement per chart type — the only real differences\r\n * between them are the mark shape and, for bars, orientation/stacking).\r\n *\r\n * Plain SVG, no charting dependency (the same call already made for\r\n * `Sparkline`): a public API shaped around `data`/`xKey`/`series` stays\r\n * implementation-agnostic, and the repository's Base layer has zero runtime\r\n * dependencies today.\r\n */\r\nexport function CartesianChart({\r\n kind,\r\n title,\r\n data,\r\n xKey,\r\n series,\r\n height = 320,\r\n loading,\r\n error,\r\n emptyMessage,\r\n disabled,\r\n showLegend = true,\r\n showTooltip = true,\r\n showGrid = true,\r\n showDataLabels = false,\r\n animate = true,\r\n xAxisLabel,\r\n yAxisLabel,\r\n xFormatter,\r\n yFormatter,\r\n orientation = \"vertical\",\r\n stacked = false,\r\n colors,\r\n className,\r\n onDataPointClick,\r\n onLegendItemClick,\r\n locale,\r\n \"aria-label\": ariaLabel,\r\n}: CartesianChartCoreProps) {\r\n const { containerRef, width } = useChartDimensions();\r\n const titleId = useId();\r\n const tooltipId = useId();\r\n const [hidden, setHidden] = useState<Set<string>>(() => new Set(series.filter((s) => s.hidden).map((s) => s.key)));\r\n const [activeIndex, setActiveIndex] = useState<number>(-1);\r\n\r\n const visibleSeries = useMemo(() => series.filter((s) => !hidden.has(s.key)), [series, hidden]);\r\n const numberFormatter = useMemo(() => yFormatter ?? defaultNumberFormatter(locale), [yFormatter, locale]);\r\n\r\n const isEmpty = data.length === 0 || series.length === 0;\r\n const isMeasuring = width === 0;\r\n const showOverlay = loading || !!error || isEmpty || isMeasuring;\r\n\r\n const toggleSeries = (key: string) => {\r\n setHidden((prev) => {\r\n const next = new Set(prev);\r\n const willHide = !next.has(key);\r\n if (willHide) next.add(key);\r\n else next.delete(key);\r\n onLegendItemClick?.(key, willHide);\r\n return next;\r\n });\r\n };\r\n\r\n const legendItems: ChartLegendItem[] = series.map((s, index) => ({\r\n key: s.key,\r\n label: s.label,\r\n color: resolveChartColor(index, s.color, colors),\r\n hidden: hidden.has(s.key),\r\n }));\r\n\r\n const innerWidth = Math.max(width - MARGIN.left - MARGIN.right, 0);\r\n const innerHeight = Math.max(height - MARGIN.top - MARGIN.bottom, 0);\r\n const isHorizontal = kind === \"bar\" && orientation === \"horizontal\";\r\n\r\n const { bandWidth, offset } = bandScale(data.length, isHorizontal ? innerHeight : innerWidth, kind === \"bar\" ? 0.3 : 0);\r\n\r\n const values = data.flatMap((row) =>\r\n visibleSeries.map((s) => {\r\n const raw = toNumber(row[s.key] as ChartValue);\r\n return raw;\r\n })\r\n );\r\n const stackedTotals =\r\n kind === \"bar\" && stacked\r\n ? data.map((row) => visibleSeries.reduce((sum, s) => sum + Math.max(toNumber(row[s.key] as ChartValue), 0), 0))\r\n : [];\r\n const domainValues = kind === \"bar\" && stacked ? stackedTotals : values;\r\n const min = Math.min(0, ...domainValues, 0);\r\n const max = Math.max(0, ...domainValues, 1);\r\n const ticks = niceTicks(min, max, 4);\r\n const domainMin = ticks[0] ?? min;\r\n const domainMax = ticks[ticks.length - 1] ?? max;\r\n\r\n const valueScale = linearScale([domainMin, domainMax], isHorizontal ? [0, innerWidth] : [innerHeight, 0]);\r\n const zeroY = valueScale(0);\r\n\r\n const tooltip: ChartTooltipPayload | null =\r\n showTooltip && activeIndex >= 0 && data[activeIndex]\r\n ? {\r\n label: formatXLabel(data[activeIndex]![xKey] as ChartValue, xFormatter),\r\n items: visibleSeries.map((s, seriesIndex) => {\r\n const raw = toNumber(data[activeIndex]![s.key] as ChartValue);\r\n const format = s.valueFormatter ?? numberFormatter;\r\n return {\r\n key: s.key,\r\n label: s.label,\r\n value: format(raw),\r\n color: resolveChartColor(series.indexOf(s), s.color, colors),\r\n };\r\n }),\r\n }\r\n : null;\r\n\r\n const emitClick = (index: number) => {\r\n for (const s of visibleSeries) {\r\n onDataPointClick?.({ seriesKey: s.key, datum: data[index]!, value: toNumber(data[index]![s.key] as ChartValue), index });\r\n }\r\n };\r\n\r\n const handleColumnKeyDown = (event: KeyboardEvent<SVGGElement>, index: number) => {\r\n if (disabled) return;\r\n switch (event.key) {\r\n case \"ArrowRight\":\r\n event.preventDefault();\r\n setActiveIndex(Math.min(index + 1, data.length - 1));\r\n break;\r\n case \"ArrowLeft\":\r\n event.preventDefault();\r\n setActiveIndex(Math.max(index - 1, 0));\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n setActiveIndex(0);\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n setActiveIndex(data.length - 1);\r\n break;\r\n case \"Enter\":\r\n case \" \":\r\n event.preventDefault();\r\n emitClick(index);\r\n break;\r\n default:\r\n break;\r\n }\r\n };\r\n\r\n const columnLabel = (index: number) => {\r\n const row = data[index]!;\r\n const parts = visibleSeries.map((s) => {\r\n const format = s.valueFormatter ?? numberFormatter;\r\n return `${s.label} ${format(toNumber(row[s.key] as ChartValue))}`;\r\n });\r\n return `${formatXLabel(row[xKey] as ChartValue, xFormatter)}: ${parts.join(\", \")}`;\r\n };\r\n\r\n function renderMarks(): ReactNode {\r\n if (kind === \"line\" || kind === \"area\") {\r\n return visibleSeries.map((s, seriesIndex) => {\r\n const color = resolveChartColor(series.indexOf(s), s.color, colors);\r\n const points = data.map((row, index) => {\r\n const x = offset(index) + bandWidth / 2;\r\n const y = valueScale(toNumber(row[s.key] as ChartValue));\r\n return [x, y] as const;\r\n });\r\n const linePath = points.map(([x, y]) => `${x},${y}`).join(\" \");\r\n return (\r\n <g key={s.key}>\r\n {kind === \"area\" && (\r\n <polygon\r\n className={cx(\"rrc-chart__mark\", \"rrc-chart__area\", animate && \"rrc-chart__mark--animate\")}\r\n points={`${points[0]?.[0] ?? 0},${zeroY} ${linePath} ${points[points.length - 1]?.[0] ?? 0},${zeroY}`}\r\n fill={color}\r\n opacity={0.18}\r\n stroke=\"none\"\r\n />\r\n )}\r\n <polyline\r\n className={cx(\"rrc-chart__mark\", \"rrc-chart__line\", animate && \"rrc-chart__mark--animate\")}\r\n points={linePath}\r\n fill=\"none\"\r\n stroke={color}\r\n strokeWidth={2}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n />\r\n {points.map(([x, y], index) => (\r\n <circle\r\n key={index}\r\n cx={x}\r\n cy={y}\r\n r={activeIndex === index ? 5 : 3}\r\n fill={color}\r\n className=\"rrc-chart__point\"\r\n onClick={() => onDataPointClick?.({ seriesKey: s.key, datum: data[index]!, value: toNumber(data[index]![s.key] as ChartValue), index })}\r\n />\r\n ))}\r\n {showDataLabels &&\r\n points.map(([x, y], index) => (\r\n <text key={index} x={x} y={y - 8} textAnchor=\"middle\" className=\"rrc-chart__data-label\">\r\n {(s.valueFormatter ?? numberFormatter)(toNumber(data[index]![s.key] as ChartValue))}\r\n </text>\r\n ))}\r\n </g>\r\n );\r\n });\r\n }\r\n\r\n // bar / stacked bar\r\n const stackOffsets = new Array(data.length).fill(0);\r\n return visibleSeries.map((s, seriesIndex) => {\r\n const color = resolveChartColor(series.indexOf(s), s.color, colors);\r\n const groupWidth = stacked ? bandWidth : bandWidth / Math.max(visibleSeries.length, 1);\r\n return (\r\n <g key={s.key}>\r\n {data.map((row, index) => {\r\n const raw = toNumber(row[s.key] as ChartValue);\r\n const bandStart = offset(index);\r\n if (isHorizontal) {\r\n const barLength = Math.abs(valueScale(raw) - zeroY);\r\n const y = stacked ? stackOffsets[index] : bandStart + seriesIndex * groupWidth;\r\n const x = raw >= 0 ? zeroY : zeroY - barLength;\r\n if (stacked) stackOffsets[index] += barLength;\r\n return (\r\n <rect\r\n key={index}\r\n x={x}\r\n y={y}\r\n width={barLength}\r\n height={Math.max(groupWidth, 1)}\r\n fill={color}\r\n rx={2}\r\n className={cx(\"rrc-chart__mark\", \"rrc-chart__bar\", animate && \"rrc-chart__mark--animate\")}\r\n onClick={() => onDataPointClick?.({ seriesKey: s.key, datum: row, value: raw, index })}\r\n />\r\n );\r\n }\r\n const barHeight = Math.abs(valueScale(raw) - zeroY);\r\n const x = stacked ? bandStart : bandStart + seriesIndex * groupWidth;\r\n const y = stacked ? stackOffsets[index] - (raw >= 0 ? barHeight : 0) : raw >= 0 ? zeroY - barHeight : zeroY;\r\n if (stacked) stackOffsets[index] += raw >= 0 ? -barHeight : barHeight;\r\n return (\r\n <rect\r\n key={index}\r\n x={x}\r\n y={stacked ? (raw >= 0 ? y : zeroY) : y}\r\n width={Math.max(groupWidth, 1)}\r\n height={barHeight}\r\n fill={color}\r\n rx={2}\r\n className={cx(\"rrc-chart__mark\", \"rrc-chart__bar\", animate && \"rrc-chart__mark--animate\")}\r\n onClick={() => onDataPointClick?.({ seriesKey: s.key, datum: row, value: raw, index })}\r\n />\r\n );\r\n })}\r\n </g>\r\n );\r\n });\r\n }\r\n\r\n return (\r\n <div className={cx(\"rrc-chart\", disabled && \"rrc-chart--disabled\", className)} aria-disabled={disabled || undefined}>\r\n {title && (\r\n <div id={titleId} className=\"rrc-chart__title\">\r\n {title}\r\n </div>\r\n )}\r\n\r\n <div\r\n ref={containerRef}\r\n className=\"rrc-chart__canvas\"\r\n style={{ height }}\r\n role=\"group\"\r\n aria-labelledby={title ? titleId : undefined}\r\n aria-label={!title ? ariaLabel ?? \"Chart\" : undefined}\r\n >\r\n {showOverlay ? (\r\n <ChartStatusOverlay loading={loading || isMeasuring} error={error} emptyMessage={emptyMessage} height={height} />\r\n ) : (\r\n <>\r\n {/*\r\n Deliberately no `role=\"img\"` here (or on this svg at all): each\r\n data column below is its own focusable `role=\"button\"` target\r\n (doc: keyboard navigation between data points), and `img` — like\r\n `aria-hidden` — would tell assistive tech to ignore all\r\n descendants, exactly the access this chart needs to keep. The\r\n accessible name lives on the wrapping `role=\"group\"` above; the\r\n visually-hidden `<table>` at the end is the non-visual data\r\n summary.\r\n */}\r\n <svg width=\"100%\" height={height} viewBox={`0 0 ${width} ${height}`}>\r\n <g transform={`translate(${MARGIN.left},${MARGIN.top})`}>\r\n {showGrid &&\r\n ticks.map((tick) => {\r\n const y = isHorizontal ? undefined : valueScale(tick);\r\n const x = isHorizontal ? valueScale(tick) : undefined;\r\n return isHorizontal ? (\r\n <line key={tick} x1={x} x2={x} y1={0} y2={innerHeight} className=\"rrc-chart__grid-line\" />\r\n ) : (\r\n <line key={tick} x1={0} x2={innerWidth} y1={y} y2={y} className=\"rrc-chart__grid-line\" />\r\n );\r\n })}\r\n\r\n {!isHorizontal &&\r\n ticks.map((tick) => (\r\n <text key={tick} x={-8} y={valueScale(tick)} textAnchor=\"end\" dominantBaseline=\"middle\" className=\"rrc-chart__axis-label\">\r\n {numberFormatter(tick)}\r\n </text>\r\n ))}\r\n {isHorizontal &&\r\n ticks.map((tick) => (\r\n <text key={tick} x={valueScale(tick)} y={innerHeight + 16} textAnchor=\"middle\" className=\"rrc-chart__axis-label\">\r\n {numberFormatter(tick)}\r\n </text>\r\n ))}\r\n\r\n {!isHorizontal &&\r\n data.map((row, index) => (\r\n <text\r\n key={index}\r\n x={offset(index) + bandWidth / 2}\r\n y={innerHeight + 16}\r\n textAnchor=\"middle\"\r\n className=\"rrc-chart__axis-label\"\r\n >\r\n {formatXLabel(row[xKey] as ChartValue, xFormatter)}\r\n </text>\r\n ))}\r\n {isHorizontal &&\r\n data.map((row, index) => (\r\n <text\r\n key={index}\r\n x={-8}\r\n y={offset(index) + bandWidth / 2}\r\n textAnchor=\"end\"\r\n dominantBaseline=\"middle\"\r\n className=\"rrc-chart__axis-label\"\r\n >\r\n {formatXLabel(row[xKey] as ChartValue, xFormatter)}\r\n </text>\r\n ))}\r\n\r\n {renderMarks()}\r\n\r\n {/* Keyboard-navigable, invisible column targets — roving tabindex across data points (doc: keyboard + screen-reader access). */}\r\n {data.map((_, index) => (\r\n <rect\r\n key={index}\r\n x={isHorizontal ? 0 : offset(index)}\r\n y={isHorizontal ? offset(index) : 0}\r\n width={isHorizontal ? innerWidth : bandWidth}\r\n height={isHorizontal ? bandWidth : innerHeight}\r\n fill=\"transparent\"\r\n role=\"button\"\r\n tabIndex={disabled ? -1 : index === Math.max(activeIndex, 0) ? 0 : -1}\r\n aria-label={columnLabel(index)}\r\n aria-describedby={showTooltip && activeIndex === index ? tooltipId : undefined}\r\n className=\"rrc-chart__column-target\"\r\n onFocus={() => setActiveIndex(index)}\r\n onMouseEnter={() => setActiveIndex(index)}\r\n onMouseLeave={() => setActiveIndex(-1)}\r\n onKeyDown={(event) => handleColumnKeyDown(event, index)}\r\n onClick={() => emitClick(index)}\r\n />\r\n ))}\r\n </g>\r\n </svg>\r\n\r\n {showTooltip && tooltip && (\r\n <div id={tooltipId} role=\"tooltip\">\r\n <ChartTooltip payload={tooltip} />\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n\r\n {(xAxisLabel || yAxisLabel) && (\r\n <div className=\"rrc-chart__axis-titles\">\r\n {yAxisLabel && <span className=\"rrc-chart__axis-title rrc-chart__axis-title--y\">{yAxisLabel}</span>}\r\n {xAxisLabel && <span className=\"rrc-chart__axis-title rrc-chart__axis-title--x\">{xAxisLabel}</span>}\r\n </div>\r\n )}\r\n\r\n {showLegend && !isEmpty && <ChartLegend items={legendItems} onToggle={toggleSeries} />}\r\n\r\n <table className=\"visually-hidden\">\r\n <caption>{title ?? \"Chart data\"}</caption>\r\n <thead>\r\n <tr>\r\n <th scope=\"col\">{xAxisLabel ?? xKey}</th>\r\n {series.map((s) => (\r\n <th key={s.key} scope=\"col\">\r\n {s.label}\r\n </th>\r\n ))}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {data.map((row, index) => (\r\n <tr key={index}>\r\n <th scope=\"row\">{formatXLabel(row[xKey] as ChartValue, xFormatter)}</th>\r\n {series.map((s) => (\r\n <td key={s.key}>{(s.valueFormatter ?? numberFormatter)(toNumber(row[s.key] as ChartValue))}</td>\r\n ))}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n}\r\n","import { CartesianChart, type CartesianChartCoreProps } from \"./chart/CartesianChart\";\r\n\r\nexport type LineChartProps = Omit<CartesianChartCoreProps, \"kind\" | \"orientation\" | \"stacked\">;\r\n\r\n/**\r\n * `<LineChart title=\"...\" data={data} xKey=\"month\" series={[...]} />` — a\r\n * consumer never touches SVG, ResizeObserver or a tooltip portal (doc section\r\n * 5). Composes the shared `CartesianChart` renderer with `AreaChart`,\r\n * `BarChart` and `StackedBarChart`.\r\n */\r\nexport function LineChart(props: LineChartProps) {\r\n return <CartesianChart {...props} kind=\"line\" />;\r\n}\r\n","import { CartesianChart, type CartesianChartCoreProps } from \"./chart/CartesianChart\";\r\n\r\nexport type AreaChartProps = Omit<CartesianChartCoreProps, \"kind\" | \"orientation\" | \"stacked\">;\r\n\r\n/** Same API and interaction model as `LineChart`, filled to its baseline. See `CartesianChart`. */\r\nexport function AreaChart(props: AreaChartProps) {\r\n return <CartesianChart {...props} kind=\"area\" />;\r\n}\r\n","import { CartesianChart, type CartesianChartCoreProps } from \"./chart/CartesianChart\";\r\n\r\nexport type BarChartProps = Omit<CartesianChartCoreProps, \"kind\" | \"stacked\">;\r\n\r\n/** Grouped bars — each series in a category sits side by side. For stacked segments, use `StackedBarChart`. */\r\nexport function BarChart(props: BarChartProps) {\r\n return <CartesianChart {...props} kind=\"bar\" stacked={false} />;\r\n}\r\n","import { CartesianChart, type CartesianChartCoreProps } from \"./chart/CartesianChart\";\r\n\r\nexport type StackedBarChartProps = Omit<CartesianChartCoreProps, \"kind\" | \"stacked\">;\r\n\r\n/** Every visible series stacks into one column per category. See `BarChart` for grouped bars. */\r\nexport function StackedBarChart(props: StackedBarChartProps) {\r\n return <CartesianChart {...props} kind=\"bar\" stacked={true} />;\r\n}\r\n","export interface ChartSliceSummaryProps {\r\n items: readonly { label: string; value: number }[];\r\n}\r\n\r\n/**\r\n * Visually-hidden textual/table fallback of a circular chart's data (doc:\r\n * \"ekran okuyucu için tablo veya metinsel veri özeti\") — name/value pairs,\r\n * the shape Donut/Pie slices actually have (`CartesianChart` builds its own\r\n * equivalent table inline, since its shape — a series per column — differs).\r\n */\r\nexport function ChartSliceSummary({ items }: ChartSliceSummaryProps) {\r\n return (\r\n <table>\r\n <caption>Chart data</caption>\r\n <thead>\r\n <tr>\r\n <th scope=\"col\">Category</th>\r\n <th scope=\"col\">Value</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {items.map((item, index) => (\r\n <tr key={index}>\r\n <th scope=\"row\">{item.label}</th>\r\n <td>{item.value}</td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n );\r\n}\r\n","import { useCallback, useState, type KeyboardEvent } from \"react\";\r\n\r\nexport interface UseChartIndexNavigationOptions {\r\n count: number;\r\n disabled?: boolean;\r\n onActivate?: (index: number) => void;\r\n onSelect?: (index: number) => void;\r\n}\r\n\r\nexport interface ChartIndexNavigation {\r\n activeIndex: number;\r\n setActiveIndex: (index: number) => void;\r\n clearActive: () => void;\r\n handleKeyDown: (event: KeyboardEvent) => void;\r\n}\r\n\r\n/**\r\n * Roving index navigation shared by every chart shape: Left/Right (or the\r\n * next/previous data point) moves the focused/hover point, Home/End jump to\r\n * the ends, Enter/Space fires the same callback a mouse click on that point\r\n * would (doc: \"veri noktasına tıklama\" and \"klavye ile veri noktaları arasında\r\n * hareket\" are one interaction model, not two). Used for x-categories in the\r\n * cartesian charts (Line/Area/Bar/StackedBar) and for slices in the circular\r\n * ones (Donut/Pie) — the math is identical, only what \"index\" means differs.\r\n */\r\nexport function useChartIndexNavigation({ count, disabled, onActivate, onSelect }: UseChartIndexNavigationOptions): ChartIndexNavigation {\r\n const [activeIndex, setActiveIndexState] = useState(-1);\r\n\r\n const setActiveIndex = useCallback(\r\n (index: number) => {\r\n setActiveIndexState(index);\r\n if (index >= 0) onActivate?.(index);\r\n },\r\n [onActivate]\r\n );\r\n\r\n const clearActive = useCallback(() => setActiveIndexState(-1), []);\r\n\r\n const handleKeyDown = useCallback(\r\n (event: KeyboardEvent) => {\r\n if (disabled || count === 0) return;\r\n switch (event.key) {\r\n case \"ArrowRight\":\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n setActiveIndex(activeIndex < 0 ? 0 : Math.min(activeIndex + 1, count - 1));\r\n break;\r\n case \"ArrowLeft\":\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n setActiveIndex(activeIndex < 0 ? count - 1 : Math.max(activeIndex - 1, 0));\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n setActiveIndex(0);\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n setActiveIndex(count - 1);\r\n break;\r\n case \"Enter\":\r\n case \" \":\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 [disabled, count, activeIndex, setActiveIndex, onSelect]\r\n );\r\n\r\n return { activeIndex, setActiveIndex, clearActive, handleKeyDown };\r\n}\r\n","import { useMemo, type ReactNode } from \"react\";\r\nimport { Chart } from \"../Chart\";\r\nimport { ChartLegend, type ChartLegendItem } from \"../ChartLegend\";\r\nimport { resolveChartColor } from \"./chartColors\";\r\nimport { ChartSliceSummary } from \"./ChartSliceSummary\";\r\nimport { ChartTooltip } from \"./ChartTooltip\";\r\nimport { useChartIndexNavigation } from \"./useChartIndexNavigation\";\r\nimport type { ChartCommonProps, ChartDatum, ChartSliceInteraction } from \"./chartTypes\";\r\n\r\nexport interface CircularChartBaseProps extends ChartCommonProps {\r\n variant: \"donut\" | \"pie\";\r\n data: ChartDatum[];\r\n nameKey: string;\r\n valueKey: string;\r\n /** Donut only — ratio of the inner cutout radius to the outer radius. Ignored (forced to 0) for `variant=\"pie\"`. */\r\n innerRadiusRatio?: number;\r\n /** Donut only — rendered in the center cutout. */\r\n centerLabel?: ReactNode;\r\n centerValue?: ReactNode;\r\n valueFormatter?: (value: number) => string;\r\n showDataLabels?: boolean;\r\n onSliceClick?: (interaction: ChartSliceInteraction) => void;\r\n}\r\n\r\ninterface Slice {\r\n key: string;\r\n label: string;\r\n value: number;\r\n percent: number;\r\n startAngle: number;\r\n endAngle: number;\r\n color: string;\r\n datum: ChartDatum;\r\n index: number;\r\n}\r\n\r\nfunction polar(cx: number, cy: number, r: number, angle: number): [number, number] {\r\n const rad = (angle - 90) * (Math.PI / 180);\r\n return [cx + r * Math.cos(rad), cy + r * Math.sin(rad)];\r\n}\r\n\r\n/** SVG path for one pie/donut wedge. A full circle (100%) is special-cased since an arc command can't describe 360deg. */\r\nfunction slicePath(cx: number, cy: number, outerR: number, innerR: number, startAngle: number, endAngle: number): string {\r\n const isFullCircle = endAngle - startAngle >= 359.999;\r\n const large = endAngle - startAngle > 180 ? 1 : 0;\r\n\r\n if (isFullCircle) {\r\n const [ox] = polar(cx, cy, outerR, 0);\r\n const [ox2] = polar(cx, cy, outerR, 180);\r\n if (innerR <= 0) {\r\n return `M ${ox},${cy} A ${outerR} ${outerR} 0 1 1 ${ox2},${cy} A ${outerR} ${outerR} 0 1 1 ${ox},${cy} Z`;\r\n }\r\n const [ix] = polar(cx, cy, innerR, 0);\r\n const [ix2] = polar(cx, cy, innerR, 180);\r\n return (\r\n `M ${ox},${cy} A ${outerR} ${outerR} 0 1 1 ${ox2},${cy} A ${outerR} ${outerR} 0 1 1 ${ox},${cy} Z ` +\r\n `M ${ix},${cy} A ${innerR} ${innerR} 0 1 0 ${ix2},${cy} A ${innerR} ${innerR} 0 1 0 ${ix},${cy} Z`\r\n );\r\n }\r\n\r\n const [x1, y1] = polar(cx, cy, outerR, startAngle);\r\n const [x2, y2] = polar(cx, cy, outerR, endAngle);\r\n\r\n if (innerR <= 0) {\r\n return `M ${cx},${cy} L ${x1},${y1} A ${outerR} ${outerR} 0 ${large} 1 ${x2},${y2} Z`;\r\n }\r\n\r\n const [x3, y3] = polar(cx, cy, innerR, endAngle);\r\n const [x4, y4] = polar(cx, cy, innerR, startAngle);\r\n return `M ${x1},${y1} A ${outerR} ${outerR} 0 ${large} 1 ${x2},${y2} L ${x3},${y3} A ${innerR} ${innerR} 0 ${large} 0 ${x4},${y4} Z`;\r\n}\r\n\r\n/** Shared renderer for DonutChart and PieChart. */\r\nexport function CircularChartBase({\r\n variant,\r\n data,\r\n nameKey,\r\n valueKey,\r\n innerRadiusRatio = variant === \"donut\" ? 0.62 : 0,\r\n centerLabel,\r\n centerValue,\r\n valueFormatter,\r\n showDataLabels,\r\n showLegend = true,\r\n colors,\r\n onSliceClick,\r\n ...chartProps\r\n}: CircularChartBaseProps) {\r\n const isEmpty = data.length === 0 || data.every((row) => Number(row[valueKey] ?? 0) <= 0);\r\n const formatValue = valueFormatter ?? ((value: number) => new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value));\r\n\r\n const slices = useMemo<Slice[]>(() => {\r\n const total = data.reduce((sum, row) => sum + Math.max(Number(row[valueKey] ?? 0), 0), 0);\r\n let angle = 0;\r\n return data.map((row, index) => {\r\n const value = Math.max(Number(row[valueKey] ?? 0), 0);\r\n const percent = total > 0 ? value / total : 0;\r\n const startAngle = angle;\r\n const endAngle = angle + percent * 360;\r\n angle = endAngle;\r\n return {\r\n key: String(row[nameKey] ?? index),\r\n label: String(row[nameKey] ?? `#${index + 1}`),\r\n value,\r\n percent,\r\n startAngle,\r\n endAngle,\r\n color: resolveChartColor(index, row.color as string | undefined, colors),\r\n datum: row,\r\n index,\r\n };\r\n });\r\n }, [data, nameKey, valueKey, colors]);\r\n\r\n const nav = useChartIndexNavigation({\r\n count: slices.length,\r\n onSelect: (index) => {\r\n const slice = slices[index];\r\n if (slice) onSliceClick?.({ key: slice.key, label: slice.label, value: slice.value, index, datum: slice.datum });\r\n },\r\n });\r\n\r\n const legendItems: ChartLegendItem[] = slices.map((slice) => ({ key: slice.key, label: slice.label, color: slice.color }));\r\n\r\n return (\r\n <Chart\r\n {...chartProps}\r\n isEmpty={isEmpty}\r\n legend={showLegend ? <ChartLegend items={legendItems} /> : undefined}\r\n summary={<ChartSliceSummary items={slices.map((slice) => ({ label: slice.label, value: slice.value }))} />}\r\n >\r\n {({ width, height }) => (\r\n <CircularSurface\r\n width={width}\r\n height={height}\r\n slices={slices}\r\n innerRadiusRatio={variant === \"pie\" ? 0 : innerRadiusRatio}\r\n centerLabel={centerLabel}\r\n centerValue={centerValue}\r\n formatValue={formatValue}\r\n showDataLabels={showDataLabels}\r\n nav={nav}\r\n onSliceClick={onSliceClick}\r\n />\r\n )}\r\n </Chart>\r\n );\r\n}\r\n\r\ninterface CircularSurfaceProps {\r\n width: number;\r\n height: number;\r\n slices: Slice[];\r\n innerRadiusRatio: number;\r\n centerLabel?: ReactNode;\r\n centerValue?: ReactNode;\r\n formatValue: (value: number) => string;\r\n showDataLabels?: boolean;\r\n nav: ReturnType<typeof useChartIndexNavigation>;\r\n onSliceClick?: (interaction: ChartSliceInteraction) => void;\r\n}\r\n\r\nfunction CircularSurface({ width, height, slices, innerRadiusRatio, centerLabel, centerValue, formatValue, showDataLabels, nav, onSliceClick }: CircularSurfaceProps) {\r\n const cx = width / 2;\r\n const cy = height / 2;\r\n const outerR = Math.max(Math.min(width, height) / 2 - 16, 1);\r\n const innerR = outerR * innerRadiusRatio;\r\n const activeIndex = nav.activeIndex;\r\n const activeSlice = activeIndex >= 0 ? slices[activeIndex] : undefined;\r\n\r\n const percentFormat = (value: number) => new Intl.NumberFormat(undefined, { style: \"percent\", maximumFractionDigits: 1 }).format(value);\r\n const tabbableIndex = activeIndex >= 0 ? activeIndex : 0;\r\n\r\n return (\r\n <div className=\"rrc-chart__plot-wrap\">\r\n {/*\r\n Deliberately no `role=\"img\"`/single tabIndex on the `<svg>`: each slice\r\n below is its own focusable `role=\"button\"` target with a real\r\n accessible name (doc: keyboard navigation between data points +\r\n \"tooltip içeriğinin klavye kullanıcılarına erişilebilir olması\"),\r\n following the same roving-tabindex pattern as `CartesianChart`'s\r\n column targets. The visually-hidden `<table>` (`ChartSliceSummary`) is\r\n the non-visual data summary.\r\n */}\r\n <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} className=\"rrc-chart__plot\">\r\n {slices.map((slice) => {\r\n const isActive = activeIndex === slice.index;\r\n const labelAngle = (slice.startAngle + slice.endAngle) / 2;\r\n const [labelX, labelY] = polar(cx, cy, (outerR + innerR) / 2, labelAngle);\r\n return (\r\n <g key={slice.key}>\r\n <path\r\n d={slicePath(cx, cy, isActive ? outerR + 4 : outerR, innerR, slice.startAngle, slice.endAngle)}\r\n fill={slice.color}\r\n className=\"rrc-chart__slice\"\r\n role=\"button\"\r\n tabIndex={slice.index === tabbableIndex ? 0 : -1}\r\n aria-label={`${slice.label}: ${formatValue(slice.value)} (${percentFormat(slice.percent)})`}\r\n onKeyDown={nav.handleKeyDown}\r\n onMouseEnter={() => nav.setActiveIndex(slice.index)}\r\n onFocus={() => nav.setActiveIndex(slice.index)}\r\n onClick={() => onSliceClick?.({ key: slice.key, label: slice.label, value: slice.value, index: slice.index, datum: slice.datum })}\r\n />\r\n {showDataLabels && slice.percent > 0.03 && (\r\n <text x={labelX} y={labelY} textAnchor=\"middle\" dominantBaseline=\"middle\" className=\"rrc-chart__data-label\">\r\n {percentFormat(slice.percent)}\r\n </text>\r\n )}\r\n </g>\r\n );\r\n })}\r\n\r\n {innerR > 0 && (centerLabel || centerValue) && (\r\n <g>\r\n {centerValue && (\r\n <text x={cx} y={cy - (centerLabel ? 8 : 0)} textAnchor=\"middle\" dominantBaseline=\"middle\" className=\"rrc-chart__center-value\">\r\n {centerValue}\r\n </text>\r\n )}\r\n {centerLabel && (\r\n <text x={cx} y={cy + (centerValue ? 14 : 0)} textAnchor=\"middle\" dominantBaseline=\"middle\" className=\"rrc-chart__center-label\">\r\n {centerLabel}\r\n </text>\r\n )}\r\n </g>\r\n )}\r\n </svg>\r\n\r\n {activeSlice && (\r\n <ChartTooltip\r\n payload={{\r\n label: activeSlice.label,\r\n items: [{ key: activeSlice.key, label: percentFormat(activeSlice.percent), value: formatValue(activeSlice.value), color: activeSlice.color }],\r\n }}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { CircularChartBase, type CircularChartBaseProps } from \"./chart/CircularChartBase\";\r\n\r\nexport type DonutChartProps = Omit<CircularChartBaseProps, \"variant\">;\r\n\r\n/** A `PieChart` with a cutout center — `centerLabel`/`centerValue` render inside it. */\r\nexport function DonutChart(props: DonutChartProps) {\r\n return <CircularChartBase {...props} variant=\"donut\" />;\r\n}\r\n","import { CircularChartBase, type CircularChartBaseProps } from \"./chart/CircularChartBase\";\r\n\r\nexport type PieChartProps = Omit<CircularChartBaseProps, \"variant\" | \"innerRadiusRatio\" | \"centerLabel\" | \"centerValue\">;\r\n\r\n/** A single metric broken into categories (`nameKey`/`valueKey` over `data`). For a cutout center, use `DonutChart`. */\r\nexport function PieChart(props: PieChartProps) {\r\n return <CircularChartBase {...props} variant=\"pie\" innerRadiusRatio={0} />;\r\n}\r\n","import { useEffect, useId, useMemo, useRef, useState, type KeyboardEvent, type ReactNode } from \"react\";\r\nimport { Alert } from \"./Alert\";\r\nimport { Button } from \"./Button\";\r\nimport { IconButton } from \"./IconButton\";\r\nimport { Skeleton } from \"./Skeleton\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { useControllableState } from \"./shared/useControllableState\";\r\n\r\nexport type CalendarView = \"month\" | \"week\" | \"day\" | \"agenda\" | \"scheduler\";\r\nexport type CalendarEventVariant = \"primary\" | \"success\" | \"warning\" | \"danger\" | \"info\" | \"secondary\";\r\n\r\nexport interface CalendarEvent {\r\n id: string;\r\n title: string;\r\n start: Date | string;\r\n end?: Date | string;\r\n allDay?: boolean;\r\n color?: string;\r\n variant?: CalendarEventVariant;\r\n description?: string;\r\n disabled?: boolean;\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\nexport interface CalendarProps {\r\n value?: Date | null;\r\n defaultValue?: Date | null;\r\n onDateChange?: (date: Date) => void;\r\n events?: CalendarEvent[];\r\n /**\r\n * Only `\"month\"` is implemented in this release. The type accepts the rest\r\n * of the family so a future release can add them without a breaking prop\r\n * change; passing one today falls back to `\"month\"` with a dev warning\r\n * (known limitation — no week/day/agenda/scheduler view yet).\r\n */\r\n view?: CalendarView;\r\n /** BCP 47 locale for month/weekday names via `Intl.DateTimeFormat`. */\r\n locale?: string;\r\n /** 0 = Sunday, 1 = Monday. */\r\n weekStartsOn?: 0 | 1;\r\n min?: Date;\r\n max?: Date;\r\n disabledDates?: (date: Date) => boolean;\r\n maxEventsPerDay?: number;\r\n loading?: boolean;\r\n error?: ReactNode;\r\n className?: string;\r\n \"aria-label\"?: string;\r\n todayLabel?: string;\r\n moreLabel?: (count: number) => string;\r\n noEventsLabel?: string;\r\n onMonthChange?: (year: number, month: number) => void;\r\n onEventClick?: (event: CalendarEvent) => void;\r\n}\r\n\r\n/**\r\n * Timezone contract: every comparison here uses the `Date` object's local\r\n * getters (`getFullYear`/`getMonth`/`getDate`) and never `Date.UTC`/ISO\r\n * parsing for day-bucketing, so a day never silently shifts across a\r\n * timezone or DST boundary. `start`/`end` strings are parsed once with\r\n * `new Date(...)` (same as the platform's own `Date` constructor rules) and\r\n * only ever compared by local calendar day, never by instant.\r\n */\r\nfunction toDate(value: Date | string): Date {\r\n return value instanceof Date ? value : new Date(value);\r\n}\r\n\r\nfunction startOfDay(date: Date): Date {\r\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\r\n}\r\n\r\nfunction isSameDay(a: Date, b: Date): boolean {\r\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\r\n}\r\n\r\nfunction addDays(date: Date, amount: number): Date {\r\n const next = new Date(date);\r\n next.setDate(next.getDate() + amount);\r\n return next;\r\n}\r\n\r\nfunction addMonths(date: Date, amount: number): Date {\r\n return new Date(date.getFullYear(), date.getMonth() + amount, 1);\r\n}\r\n\r\n/** Always 42 cells (6 full weeks) so the grid's row count never jumps between months. */\r\nfunction buildMonthGrid(viewDate: Date, weekStartsOn: 0 | 1): Date[] {\r\n const first = new Date(viewDate.getFullYear(), viewDate.getMonth(), 1);\r\n const offset = (first.getDay() - weekStartsOn + 7) % 7;\r\n const start = addDays(first, -offset);\r\n return Array.from({ length: 42 }, (_, index) => addDays(start, index));\r\n}\r\n\r\nfunction eventOccursOnDay(event: CalendarEvent, day: Date): boolean {\r\n const start = startOfDay(toDate(event.start));\r\n const end = event.end ? startOfDay(toDate(event.end)) : start;\r\n const target = startOfDay(day);\r\n return target >= start && target <= end;\r\n}\r\n\r\nfunction chunk<T>(items: T[], size: number): T[][] {\r\n const result: T[][] = [];\r\n for (let index = 0; index < items.length; index += size) result.push(items.slice(index, index + size));\r\n return result;\r\n}\r\n\r\n/**\r\n * Month-view event calendar. Composes `Button`/`IconButton`/`Skeleton`/`Alert`\r\n * for chrome rather than reimplementing them (doc: reuse, don't duplicate).\r\n *\r\n * Known limitations: only `view=\"month\"` renders; no week/day/agenda/\r\n * scheduler view and no drag-and-drop event moving yet — the `view` prop and\r\n * `CalendarEvent` shape are deliberately future-proof for both.\r\n */\r\nexport function Calendar({\r\n value,\r\n defaultValue = null,\r\n onDateChange,\r\n events = [],\r\n view = \"month\",\r\n locale = \"en-US\",\r\n weekStartsOn = 1,\r\n min,\r\n max,\r\n disabledDates,\r\n maxEventsPerDay = 3,\r\n loading,\r\n error,\r\n className,\r\n \"aria-label\": ariaLabel,\r\n todayLabel = \"Today\",\r\n moreLabel = (count) => `+${count} more`,\r\n noEventsLabel = \"No events\",\r\n onMonthChange,\r\n onEventClick,\r\n}: CalendarProps) {\r\n if (process.env.NODE_ENV !== \"production\" && view !== \"month\") {\r\n // eslint-disable-next-line no-console\r\n console.warn(`[react-components] Calendar view \"${view}\" is not implemented yet; falling back to \"month\".`);\r\n }\r\n\r\n const [selected, setSelected] = useControllableState<Date | null>({\r\n value,\r\n defaultValue,\r\n // `selectDay` never passes `null` — only a day cell click sets this — so the\r\n // public `onDateChange` can stay typed as `(date: Date) => void`, matching the\r\n // task's own usage example, without narrowing `useControllableState` itself.\r\n onChange: (next) => {\r\n if (next) onDateChange?.(next);\r\n },\r\n });\r\n const today = useMemo(() => new Date(), []);\r\n const [viewDate, setViewDate] = useState(() => startOfMonthOf(selected ?? today));\r\n\r\n function startOfMonthOf(date: Date): Date {\r\n return new Date(date.getFullYear(), date.getMonth(), 1);\r\n }\r\n\r\n useEffect(() => {\r\n onMonthChange?.(viewDate.getFullYear(), viewDate.getMonth());\r\n // Fires on mount (initial range) and on every subsequent navigation — deliberately not gated to skip the first call.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [viewDate]);\r\n\r\n const grid = useMemo(() => buildMonthGrid(viewDate, weekStartsOn), [viewDate, weekStartsOn]);\r\n const weeks = useMemo(() => chunk(grid, 7), [grid]);\r\n\r\n const weekdayFormatter = useMemo(() => new Intl.DateTimeFormat(locale, { weekday: \"short\" }), [locale]);\r\n const titleFormatter = useMemo(() => new Intl.DateTimeFormat(locale, { month: \"long\", year: \"numeric\" }), [locale]);\r\n const dayLabelFormatter = useMemo(() => new Intl.DateTimeFormat(locale, { dateStyle: \"full\" }), [locale]);\r\n const weekdayLabels = useMemo(() => grid.slice(0, 7).map((day) => weekdayFormatter.format(day)), [grid, weekdayFormatter]);\r\n\r\n const eventsByDayKey = useMemo(() => {\r\n const map = new Map<string, CalendarEvent[]>();\r\n for (const day of grid) {\r\n const key = dateKey(day);\r\n map.set(\r\n key,\r\n events.filter((event) => eventOccursOnDay(event, day))\r\n );\r\n }\r\n return map;\r\n }, [grid, events]);\r\n\r\n function dateKey(day: Date): string {\r\n return `${day.getFullYear()}-${day.getMonth()}-${day.getDate()}`;\r\n }\r\n\r\n function isDisabledDay(day: Date): boolean {\r\n const target = startOfDay(day);\r\n if (min && target < startOfDay(min)) return true;\r\n if (max && target > startOfDay(max)) return true;\r\n return disabledDates?.(day) ?? false;\r\n }\r\n\r\n /** Falls back to today (or the grid's first cell) so the roving tabindex always has exactly one home. */\r\n function focusIndexFor(gridDays: Date[], selectedDate: Date | null): number {\r\n const selectedIndex = selectedDate ? gridDays.findIndex((day) => isSameDay(day, selectedDate)) : -1;\r\n if (selectedIndex >= 0) return selectedIndex;\r\n const todayIndex = gridDays.findIndex((day) => isSameDay(day, today));\r\n return todayIndex >= 0 ? todayIndex : 0;\r\n }\r\n\r\n // Deliberately a plain `useState` with no reactive resync effect: every path that\r\n // changes the visible month (`goToMonth`, `selectDay`) also sets `focusedIndex`\r\n // itself, in the same synchronous update. A `useEffect` that re-derived it from\r\n // `grid` instead would fire one render after `setViewDate`, doubling the render\r\n // pass on every navigation for no behavioral gain.\r\n const [focusedIndex, setFocusedIndex] = useState(() => focusIndexFor(grid, selected));\r\n\r\n const cellRefs = useRef<Array<HTMLButtonElement | null>>([]);\r\n\r\n /**\r\n * Focuses synchronously, in the same handler that calls `setFocusedIndex`\r\n * (mirrors `Tabs`' `activate`) rather than in a `useEffect` keyed on\r\n * `focusedIndex`. The target button is already mounted at this DOM\r\n * position — React reuses the same 42 cell nodes across a month change, it\r\n * just repaints their content — so there's no need to wait for the next\r\n * commit before moving focus.\r\n */\r\n function focusCell(index: number) {\r\n cellRefs.current[index]?.focus();\r\n }\r\n\r\n function goToMonth(next: Date, keepSelected: Date | null = selected) {\r\n const targetMonth = startOfMonthOf(next);\r\n setViewDate(targetMonth);\r\n setFocusedIndex(focusIndexFor(buildMonthGrid(targetMonth, weekStartsOn), keepSelected));\r\n }\r\n\r\n function selectDay(day: Date, index: number) {\r\n if (isDisabledDay(day)) return;\r\n setSelected(day);\r\n if (day.getMonth() !== viewDate.getMonth() || day.getFullYear() !== viewDate.getFullYear()) {\r\n const targetIndex = buildMonthGrid(startOfMonthOf(day), weekStartsOn).findIndex((gridDay) => isSameDay(gridDay, day));\r\n goToMonth(day, day);\r\n focusCell(targetIndex >= 0 ? targetIndex : index);\r\n } else {\r\n setFocusedIndex(index);\r\n focusCell(index);\r\n }\r\n }\r\n\r\n function moveFocus(nextIndex: number) {\r\n const clamped = Math.max(0, Math.min(41, nextIndex));\r\n setFocusedIndex(clamped);\r\n focusCell(clamped);\r\n }\r\n\r\n function handleGridKeyDown(event: KeyboardEvent<HTMLDivElement>) {\r\n switch (event.key) {\r\n case \"ArrowRight\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex + 1);\r\n break;\r\n case \"ArrowLeft\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex - 1);\r\n break;\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex + 7);\r\n break;\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex - 7);\r\n break;\r\n case \"Home\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex - (focusedIndex % 7));\r\n break;\r\n case \"End\":\r\n event.preventDefault();\r\n moveFocus(focusedIndex - (focusedIndex % 7) + 6);\r\n break;\r\n case \"PageUp\":\r\n event.preventDefault();\r\n goToMonth(addMonths(viewDate, -1));\r\n break;\r\n case \"PageDown\":\r\n event.preventDefault();\r\n goToMonth(addMonths(viewDate, 1));\r\n break;\r\n case \"Enter\":\r\n case \" \":\r\n event.preventDefault();\r\n selectDay(grid[focusedIndex]!, focusedIndex);\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n const title = titleFormatter.format(viewDate);\r\n const disabled = Boolean(loading || error);\r\n const rootId = useId();\r\n\r\n return (\r\n <div className={cx(\"rrc-calendar\", className)} aria-label={ariaLabel ?? title}>\r\n <div className=\"rrc-calendar__header\">\r\n <IconButton icon=\"bi bi-chevron-left\" aria-label=\"Previous month\" onClick={() => goToMonth(addMonths(viewDate, -1))} disabled={disabled} size=\"sm\" variant=\"light-secondary\" />\r\n <Button size=\"sm\" variant=\"light-secondary\" onClick={() => goToMonth(today)} disabled={disabled}>\r\n {todayLabel}\r\n </Button>\r\n <div className=\"rrc-calendar__title\" aria-live=\"polite\" id={rootId}>\r\n {title}\r\n </div>\r\n <IconButton icon=\"bi bi-chevron-right\" aria-label=\"Next month\" onClick={() => goToMonth(addMonths(viewDate, 1))} disabled={disabled} size=\"sm\" variant=\"light-secondary\" />\r\n </div>\r\n\r\n {error ? (\r\n <Alert variant=\"danger\" className=\"mb-0\">\r\n {error}\r\n </Alert>\r\n ) : loading ? (\r\n <div className=\"rrc-calendar__skeleton\" aria-busy=\"true\">\r\n {Array.from({ length: 6 }, (_, index) => (\r\n <Skeleton key={index} height=\"4.5rem\" />\r\n ))}\r\n </div>\r\n ) : (\r\n <>\r\n <div className=\"rrc-calendar__weekdays\" role=\"row\">\r\n {weekdayLabels.map((label, index) => (\r\n <div key={index} className=\"rrc-calendar__weekday\" role=\"columnheader\" aria-label={label}>\r\n {label}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n <div className=\"rrc-calendar__grid\" role=\"grid\" aria-labelledby={rootId} onKeyDown={handleGridKeyDown}>\r\n {weeks.map((week, weekIndex) => (\r\n <div key={weekIndex} className=\"rrc-calendar__week\" role=\"row\">\r\n {week.map((day, dayIndex) => {\r\n const index = weekIndex * 7 + dayIndex;\r\n const isOutside = day.getMonth() !== viewDate.getMonth();\r\n const isToday = isSameDay(day, today);\r\n const isSelected = selected ? isSameDay(day, selected) : false;\r\n const dayDisabled = isDisabledDay(day);\r\n const dayEvents = eventsByDayKey.get(dateKey(day)) ?? [];\r\n const visibleEvents = dayEvents.slice(0, maxEventsPerDay);\r\n const overflowCount = dayEvents.length - visibleEvents.length;\r\n\r\n const dayAriaLabel = [dayLabelFormatter.format(day), isToday && \"today\", dayEvents.length > 0 && `${dayEvents.length} events`].filter(Boolean).join(\", \");\r\n\r\n return (\r\n <div\r\n key={index}\r\n role=\"gridcell\"\r\n aria-selected={isSelected || undefined}\r\n aria-current={isToday ? \"date\" : undefined}\r\n aria-disabled={dayDisabled || undefined}\r\n className={cx(\r\n \"rrc-calendar__day\",\r\n isOutside && \"rrc-calendar__day--outside\",\r\n isToday && \"rrc-calendar__day--today\",\r\n isSelected && \"rrc-calendar__day--selected\",\r\n dayDisabled && \"rrc-calendar__day--disabled\"\r\n )}\r\n >\r\n <button\r\n type=\"button\"\r\n ref={(element) => {\r\n cellRefs.current[index] = element;\r\n }}\r\n className=\"rrc-calendar__day-button\"\r\n tabIndex={index === focusedIndex ? 0 : -1}\r\n disabled={dayDisabled}\r\n aria-label={dayAriaLabel}\r\n onClick={() => selectDay(day, index)}\r\n >\r\n {day.getDate()}\r\n </button>\r\n {(visibleEvents.length > 0 || overflowCount > 0) && (\r\n <div className=\"rrc-calendar__events\">\r\n {visibleEvents.map((eventItem) => (\r\n <button\r\n key={eventItem.id}\r\n type=\"button\"\r\n className={cx(\"rrc-calendar__event\", `rrc-calendar__event--${eventItem.variant ?? \"primary\"}`)}\r\n style={eventItem.color ? { backgroundColor: eventItem.color } : undefined}\r\n disabled={eventItem.disabled}\r\n title={eventItem.title}\r\n onClick={(clickEvent) => {\r\n clickEvent.stopPropagation();\r\n if (!eventItem.disabled) onEventClick?.(eventItem);\r\n }}\r\n >\r\n {eventItem.title}\r\n </button>\r\n ))}\r\n {overflowCount > 0 && (\r\n <button\r\n type=\"button\"\r\n className=\"rrc-calendar__more\"\r\n onClick={(clickEvent) => {\r\n clickEvent.stopPropagation();\r\n selectDay(day, index);\r\n }}\r\n >\r\n {moreLabel(overflowCount)}\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n <div className=\"rrc-calendar__agenda d-md-none\">\r\n <div className=\"rrc-calendar__agenda-title\">{dayLabelFormatter.format(selected ?? today)}</div>\r\n {(eventsByDayKey.get(dateKey(selected ?? today)) ?? []).length === 0 ? (\r\n <div className=\"rrc-calendar__agenda-empty\">{noEventsLabel}</div>\r\n ) : (\r\n <ul className=\"rrc-calendar__agenda-list\">\r\n {(eventsByDayKey.get(dateKey(selected ?? today)) ?? []).map((eventItem) => (\r\n <li key={eventItem.id}>\r\n <button type=\"button\" className=\"rrc-calendar__agenda-item\" disabled={eventItem.disabled} onClick={() => !eventItem.disabled && onEventClick?.(eventItem)}>\r\n {eventItem.title}\r\n </button>\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useEffect, useRef, useState, type MouseEvent as ReactMouseEvent } from \"react\";\r\nimport { IconButton } from \"./IconButton\";\r\nimport { Icon } from \"./Icon\";\r\nimport { Modal } from \"./Modal\";\r\nimport { Spinner } from \"./Spinner\";\r\nimport { Text } from \"./Text\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { useElementResize } from \"./shared/useElementResize\";\r\n\r\nexport type DocumentViewerSource = string | Blob | ArrayBuffer;\r\n\r\nexport type DocumentViewerErrorKind = \"unsupported\" | \"password-protected\" | \"corrupted\" | \"network\" | \"unknown\";\r\n\r\nexport interface DocumentViewerError {\r\n kind: DocumentViewerErrorKind;\r\n message: string;\r\n}\r\n\r\nexport interface DocumentViewerLabels {\r\n loading?: string;\r\n unsupported?: string;\r\n passwordProtected?: string;\r\n corrupted?: string;\r\n networkError?: string;\r\n download?: string;\r\n zoomIn?: string;\r\n zoomOut?: string;\r\n fitToWidth?: string;\r\n fitToView?: string;\r\n rotate?: string;\r\n fullscreen?: string;\r\n exitFullscreen?: string;\r\n previousPage?: string;\r\n nextPage?: string;\r\n page?: string;\r\n of?: string;\r\n openInNewTab?: string;\r\n}\r\n\r\nexport interface DocumentViewerProps {\r\n source: DocumentViewerSource;\r\n fileName?: string;\r\n /** MIME type, when known. Falls back to a safe guess from `fileName`'s extension when omitted. */\r\n mimeType?: string;\r\n className?: string;\r\n /** Viewer surface height. Defaults to a fixed comfortable reading height rather than growing unbounded with page content. */\r\n height?: number | string;\r\n initialPage?: number;\r\n toolbar?: boolean;\r\n allowFullscreen?: boolean;\r\n allowNewTab?: boolean;\r\n /** No central i18n catalog lives in Base (doc: Smart owns the one exception) — override the visible strings here instead. */\r\n labels?: DocumentViewerLabels;\r\n /** Called instead of the built-in download behavior when supplied. */\r\n onDownload?: () => void;\r\n onError?: (error: DocumentViewerError) => void;\r\n onPageChange?: (page: number, totalPages: number) => void;\r\n}\r\n\r\ntype FileKind = \"pdf\" | \"image\" | \"unsupported\";\r\ntype ViewerStatus = \"loading\" | \"ready\" | \"error\";\r\ntype FitMode = \"none\" | \"width\" | \"view\";\r\n\r\nconst DEFAULT_LABELS: Required<DocumentViewerLabels> = {\r\n loading: \"Loading document…\",\r\n unsupported: \"This file type cannot be previewed.\",\r\n passwordProtected: \"This PDF is password protected and cannot be previewed.\",\r\n corrupted: \"This file appears to be corrupted and cannot be previewed.\",\r\n networkError: \"The document could not be loaded. Check your connection and try again.\",\r\n download: \"Download\",\r\n zoomIn: \"Zoom in\",\r\n zoomOut: \"Zoom out\",\r\n fitToWidth: \"Fit to width\",\r\n fitToView: \"Fit to view\",\r\n rotate: \"Rotate\",\r\n fullscreen: \"Fullscreen\",\r\n exitFullscreen: \"Exit fullscreen\",\r\n previousPage: \"Previous page\",\r\n nextPage: \"Next page\",\r\n page: \"Page\",\r\n of: \"of\",\r\n openInNewTab: \"Open in new tab\",\r\n};\r\n\r\nconst IMAGE_MIME_TYPES = new Set([\"image/png\", \"image/jpeg\", \"image/webp\", \"image/gif\"]);\r\n\r\nconst EXTENSION_MIME_TYPES: Record<string, string> = {\r\n pdf: \"application/pdf\",\r\n png: \"image/png\",\r\n jpg: \"image/jpeg\",\r\n jpeg: \"image/jpeg\",\r\n webp: \"image/webp\",\r\n gif: \"image/gif\",\r\n};\r\n\r\nfunction resolveMimeType(mimeType: string | undefined, fileName: string | undefined): string | undefined {\r\n if (mimeType) return mimeType;\r\n const ext = fileName?.split(\".\").pop()?.toLowerCase();\r\n return ext ? EXTENSION_MIME_TYPES[ext] : undefined;\r\n}\r\n\r\nfunction classifyMimeType(mime: string | undefined): FileKind {\r\n if (mime === \"application/pdf\") return \"pdf\";\r\n if (mime && IMAGE_MIME_TYPES.has(mime)) return \"image\";\r\n return \"unsupported\";\r\n}\r\n\r\nasync function toObjectUrl(source: Blob | ArrayBuffer, mime: string | undefined): Promise<string> {\r\n const blob = source instanceof Blob ? source : new Blob([source], mime ? { type: mime } : undefined);\r\n return URL.createObjectURL(blob);\r\n}\r\n\r\n/**\r\n * `<a download>` clicked synchronously, then the object URL is revoked on the\r\n * next tick — revoking immediately breaks the download in some browsers\r\n * because navigation to the blob URL hasn't started yet.\r\n */\r\nfunction triggerDownload(url: string, fileName: string | undefined, revoke: boolean) {\r\n const link = document.createElement(\"a\");\r\n link.href = url;\r\n if (fileName) link.download = fileName;\r\n link.rel = \"noopener\";\r\n document.body.appendChild(link);\r\n link.click();\r\n link.remove();\r\n if (revoke) setTimeout(() => URL.revokeObjectURL(url), 0);\r\n}\r\n\r\nlet workerConfigured = false;\r\n\r\n/**\r\n * Set once per page load — every PDF render after the first reuses the same\r\n * worker. The `?url` suffix is Vite's asset-URL import: it resolves at *this\r\n * library's own* build time, so `dist/` ships the worker file already copied\r\n * next to the bundle with a content-hashed name and this import already\r\n * rewritten to a plain string. A consumer's own bundler (Vite, webpack, or\r\n * otherwise) never has to understand `?url` itself or configure a worker path.\r\n */\r\nasync function configurePdfWorker(pdfjsLib: typeof import(\"pdfjs-dist\")): Promise<void> {\r\n if (workerConfigured) return;\r\n // `?url` has no ambient type without adding `vite/client` to the project-wide\r\n // tsconfig; the runtime shape is a plain `{ default: string }` module either way.\r\n // @ts-expect-error -- Vite-only asset-URL import, resolved at this library's own build time.\r\n const workerUrl = (await import(\"pdfjs-dist/build/pdf.worker.min.mjs?url\")) as { default: string };\r\n pdfjsLib.GlobalWorkerOptions.workerSrc = workerUrl.default;\r\n workerConfigured = true;\r\n}\r\n\r\nfunction classifyPdfError(error: unknown, labels: Required<DocumentViewerLabels>): DocumentViewerError {\r\n const name = (error as { name?: string } | null)?.name;\r\n if (name === \"PasswordException\") return { kind: \"password-protected\", message: labels.passwordProtected };\r\n if (name === \"InvalidPDFException\" || name === \"MissingPDFException\") return { kind: \"corrupted\", message: labels.corrupted };\r\n if (name === \"UnexpectedResponseException\" || error instanceof TypeError) return { kind: \"network\", message: labels.networkError };\r\n return { kind: \"unknown\", message: labels.corrupted };\r\n}\r\n\r\ninterface PdfDocumentLike {\r\n numPages: number;\r\n getPage(pageNumber: number): Promise<PdfPageLike>;\r\n destroy(): Promise<void> | void;\r\n}\r\n\r\ninterface PdfPageLike {\r\n getViewport(params: { scale: number; rotation?: number }): { width: number; height: number };\r\n render(params: { canvasContext: CanvasRenderingContext2D; viewport: unknown }): { promise: Promise<void>; cancel(): void };\r\n}\r\n\r\nfunction StatusPanel({ icon, title, message, fileName, showDownload, onDownload, downloadLabel }: {\r\n icon: string;\r\n title: string;\r\n message?: string;\r\n fileName?: string;\r\n showDownload: boolean;\r\n onDownload: () => void;\r\n downloadLabel: string;\r\n}) {\r\n return (\r\n <div className=\"rrc-document-viewer__status\">\r\n <Icon name={icon} size=\"xl\" className=\"rrc-document-viewer__status-icon\" />\r\n <Text as=\"div\" weight=\"semibold\" className=\"rrc-document-viewer__status-title\">\r\n {title}\r\n </Text>\r\n {message && (\r\n <Text as=\"div\" size=\"sm\" tone=\"muted\" className=\"rrc-document-viewer__status-message\">\r\n {message}\r\n </Text>\r\n )}\r\n {fileName && (\r\n <Text as=\"div\" size=\"sm\" tone=\"muted\" className=\"rrc-document-viewer__meta\">\r\n {fileName}\r\n </Text>\r\n )}\r\n {showDownload && (\r\n <button type=\"button\" className=\"btn btn-light-primary rrc-btn rrc-btn--light-primary mt-2\" onClick={onDownload}>\r\n {downloadLabel}\r\n </button>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * Previews PDF and common image formats without leaking SVG/canvas/portal\r\n * plumbing to the consumer — a document/file card, a native `<embed>`, a\r\n * third-party viewer, or a bespoke zoom/rotate/pagination toolbar are never\r\n * something a consumer of this library builds by hand.\r\n *\r\n * `pdfjs-dist` is imported lazily (only once a PDF `source` is actually\r\n * rendered), so an app that only ever previews images never pays for it.\r\n * SVG/HTML/script sources are never rendered directly — anything outside the\r\n * five supported formats below falls back to a file-info + download panel.\r\n */\r\nexport function DocumentViewer({\r\n source,\r\n fileName,\r\n mimeType,\r\n className,\r\n height = 480,\r\n initialPage = 1,\r\n toolbar = true,\r\n allowFullscreen = true,\r\n allowNewTab = true,\r\n labels,\r\n onDownload,\r\n onError,\r\n onPageChange,\r\n}: DocumentViewerProps) {\r\n const resolvedLabels: Required<DocumentViewerLabels> = { ...DEFAULT_LABELS, ...labels };\r\n\r\n const [kind, setKind] = useState<FileKind>(\"unsupported\");\r\n const [status, setStatus] = useState<ViewerStatus>(\"loading\");\r\n const [error, setError] = useState<DocumentViewerError | null>(null);\r\n const [imageUrl, setImageUrl] = useState<string | undefined>(undefined);\r\n const [totalPages, setTotalPages] = useState(0);\r\n const [currentPage, setCurrentPage] = useState(initialPage);\r\n const [fitMode, setFitMode] = useState<FitMode>(\"width\");\r\n const [manualScale, setManualScale] = useState(1);\r\n const [rotation, setRotation] = useState(0);\r\n const [fullscreen, setFullscreen] = useState(false);\r\n\r\n const pdfDocRef = useRef<PdfDocumentLike | null>(null);\r\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\r\n const containerRef = useRef<HTMLDivElement | null>(null);\r\n const [containerSize, setContainerSize] = useState({ width: 0, height: 0 });\r\n const onErrorRef = useRef(onError);\r\n onErrorRef.current = onError;\r\n const onPageChangeRef = useRef(onPageChange);\r\n onPageChangeRef.current = onPageChange;\r\n\r\n useElementResize(containerRef, true, () => {\r\n const rect = containerRef.current?.getBoundingClientRect();\r\n if (rect) setContainerSize({ width: rect.width, height: rect.height });\r\n });\r\n\r\n // Loads the document whenever its identity changes; tears down the loading\r\n // task / pdf handle / object URL from the *previous* source on every run,\r\n // including unmount, so nothing outlives the source it was created for.\r\n useEffect(() => {\r\n let cancelled = false;\r\n let objectUrl: string | undefined;\r\n let loadingTask: { promise: Promise<PdfDocumentLike>; destroy(): void } | undefined;\r\n\r\n setStatus(\"loading\");\r\n setError(null);\r\n setImageUrl(undefined);\r\n setTotalPages(0);\r\n setCurrentPage(initialPage);\r\n setFitMode(\"width\");\r\n setManualScale(1);\r\n setRotation(0);\r\n\r\n const mime = resolveMimeType(mimeType, fileName);\r\n const fileKind = classifyMimeType(mime);\r\n setKind(fileKind);\r\n\r\n async function load() {\r\n if (fileKind === \"unsupported\") {\r\n const info: DocumentViewerError = { kind: \"unsupported\", message: resolvedLabels.unsupported };\r\n if (!cancelled) {\r\n setError(info);\r\n setStatus(\"error\");\r\n }\r\n onErrorRef.current?.(info);\r\n return;\r\n }\r\n\r\n if (fileKind === \"image\") {\r\n const url = typeof source === \"string\" ? source : await toObjectUrl(source, mime);\r\n if (typeof source !== \"string\") objectUrl = url;\r\n if (cancelled) return;\r\n setImageUrl(url);\r\n // `status` flips to \"ready\" from the <img onLoad>/onError handlers below.\r\n return;\r\n }\r\n\r\n const pdfjsLib = await import(\"pdfjs-dist\");\r\n if (cancelled) return;\r\n await configurePdfWorker(pdfjsLib);\r\n\r\n const input =\r\n typeof source === \"string\"\r\n ? { url: source }\r\n : source instanceof Blob\r\n ? { data: new Uint8Array(await source.arrayBuffer()) }\r\n : { data: new Uint8Array(source) };\r\n\r\n loadingTask = pdfjsLib.getDocument(input as never) as unknown as { promise: Promise<PdfDocumentLike>; destroy(): void };\r\n try {\r\n const pdf = await loadingTask.promise;\r\n if (cancelled) {\r\n pdf.destroy();\r\n return;\r\n }\r\n pdfDocRef.current = pdf;\r\n setTotalPages(pdf.numPages);\r\n setCurrentPage((page) => Math.min(Math.max(page, 1), pdf.numPages));\r\n setStatus(\"ready\");\r\n } catch (err) {\r\n if (cancelled) return;\r\n const info = classifyPdfError(err, resolvedLabels);\r\n setError(info);\r\n setStatus(\"error\");\r\n onErrorRef.current?.(info);\r\n }\r\n }\r\n\r\n load();\r\n\r\n return () => {\r\n cancelled = true;\r\n loadingTask?.destroy();\r\n pdfDocRef.current?.destroy();\r\n pdfDocRef.current = null;\r\n if (objectUrl) URL.revokeObjectURL(objectUrl);\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [source, mimeType, fileName]);\r\n\r\n // Renders the current page to the canvas. Re-runs on page/zoom/rotation\r\n // changes and cancels the in-flight render task on cleanup so a fast zoom\r\n // or page flip never races an older render onto the canvas.\r\n useEffect(() => {\r\n if (kind !== \"pdf\" || status !== \"ready\" || !pdfDocRef.current) return;\r\n let cancelled = false;\r\n let task: { promise: Promise<void>; cancel(): void } | undefined;\r\n\r\n (async () => {\r\n const pdf = pdfDocRef.current;\r\n if (!pdf) return;\r\n const page = await pdf.getPage(currentPage);\r\n if (cancelled) return;\r\n\r\n const baseViewport = page.getViewport({ scale: 1, rotation });\r\n const width = containerSize.width || baseViewport.width;\r\n const height = containerSize.height || baseViewport.height;\r\n const scale =\r\n fitMode === \"width\"\r\n ? width / baseViewport.width\r\n : fitMode === \"view\"\r\n ? Math.min(width / baseViewport.width, height / baseViewport.height)\r\n : manualScale;\r\n\r\n const viewport = page.getViewport({ scale, rotation });\r\n const canvas = canvasRef.current;\r\n const ctx = canvas?.getContext(\"2d\");\r\n if (!canvas || !ctx || cancelled) return;\r\n\r\n canvas.width = viewport.width;\r\n canvas.height = viewport.height;\r\n task = page.render({ canvasContext: ctx, viewport });\r\n try {\r\n await task.promise;\r\n } catch (err) {\r\n if ((err as { name?: string } | null)?.name !== \"RenderingCancelledException\") throw err;\r\n }\r\n })().catch((err) => {\r\n if (cancelled) return;\r\n const info = classifyPdfError(err, resolvedLabels);\r\n setError(info);\r\n setStatus(\"error\");\r\n onErrorRef.current?.(info);\r\n });\r\n\r\n return () => {\r\n cancelled = true;\r\n task?.cancel();\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [kind, status, currentPage, rotation, fitMode, manualScale, containerSize.width, containerSize.height]);\r\n\r\n useEffect(() => {\r\n if (kind === \"pdf\" && status === \"ready\") onPageChangeRef.current?.(currentPage, totalPages);\r\n }, [kind, status, currentPage, totalPages]);\r\n\r\n function handleDownload() {\r\n if (onDownload) {\r\n onDownload();\r\n return;\r\n }\r\n if (typeof source === \"string\") {\r\n triggerDownload(source, fileName, false);\r\n return;\r\n }\r\n toObjectUrl(source, resolveMimeType(mimeType, fileName)).then((url) => triggerDownload(url, fileName, true));\r\n }\r\n\r\n function handleOpenInNewTab(event: ReactMouseEvent) {\r\n event.preventDefault();\r\n if (typeof source === \"string\") {\r\n window.open(source, \"_blank\", \"noopener\");\r\n return;\r\n }\r\n toObjectUrl(source, resolveMimeType(mimeType, fileName)).then((url) => {\r\n window.open(url, \"_blank\", \"noopener\");\r\n setTimeout(() => URL.revokeObjectURL(url), 60_000);\r\n });\r\n }\r\n\r\n function zoomIn() {\r\n setFitMode(\"none\");\r\n setManualScale((scale) => Math.min(scale * 1.25, 4));\r\n }\r\n function zoomOut() {\r\n setFitMode(\"none\");\r\n setManualScale((scale) => Math.max(scale / 1.25, 0.25));\r\n }\r\n function rotate() {\r\n setRotation((value) => (value + 90) % 360);\r\n }\r\n\r\n const isPreviewable = kind === \"pdf\" || kind === \"image\";\r\n\r\n function renderToolbar() {\r\n // The status panel is self-contained (it carries its own download action),\r\n // and paging/zoom/rotate/new-tab make no sense against a document that\r\n // failed to load, so the toolbar steps aside entirely rather than showing\r\n // a second, redundant \"Download\" control next to the panel's own.\r\n if (!toolbar || status === \"error\") return null;\r\n return (\r\n <div className=\"rrc-document-viewer__toolbar\">\r\n <div className=\"rrc-document-viewer__toolbar-group\">\r\n {kind === \"pdf\" && status === \"ready\" && (\r\n <>\r\n <IconButton\r\n icon=\"bi bi-chevron-left\"\r\n aria-label={resolvedLabels.previousPage}\r\n tooltip={resolvedLabels.previousPage}\r\n size=\"sm\"\r\n variant=\"light-secondary\"\r\n disabled={currentPage <= 1}\r\n onClick={() => setCurrentPage((page) => Math.max(1, page - 1))}\r\n />\r\n <span className=\"rrc-document-viewer__page-indicator\" aria-live=\"polite\">\r\n {resolvedLabels.page} {currentPage} {resolvedLabels.of} {totalPages}\r\n </span>\r\n <IconButton\r\n icon=\"bi bi-chevron-right\"\r\n aria-label={resolvedLabels.nextPage}\r\n tooltip={resolvedLabels.nextPage}\r\n size=\"sm\"\r\n variant=\"light-secondary\"\r\n disabled={currentPage >= totalPages}\r\n onClick={() => setCurrentPage((page) => Math.min(totalPages, page + 1))}\r\n />\r\n </>\r\n )}\r\n </div>\r\n <div className=\"rrc-document-viewer__toolbar-group\">\r\n {isPreviewable && status === \"ready\" && (\r\n <>\r\n <IconButton icon=\"bi bi-zoom-out\" aria-label={resolvedLabels.zoomOut} tooltip={resolvedLabels.zoomOut} size=\"sm\" variant=\"light-secondary\" onClick={zoomOut} />\r\n <IconButton icon=\"bi bi-zoom-in\" aria-label={resolvedLabels.zoomIn} tooltip={resolvedLabels.zoomIn} size=\"sm\" variant=\"light-secondary\" onClick={zoomIn} />\r\n <IconButton\r\n icon=\"bi bi-arrows-angle-expand\"\r\n aria-label={resolvedLabels.fitToWidth}\r\n tooltip={resolvedLabels.fitToWidth}\r\n size=\"sm\"\r\n variant={fitMode === \"width\" ? \"light-primary\" : \"light-secondary\"}\r\n onClick={() => setFitMode(\"width\")}\r\n />\r\n <IconButton\r\n icon=\"bi bi-aspect-ratio\"\r\n aria-label={resolvedLabels.fitToView}\r\n tooltip={resolvedLabels.fitToView}\r\n size=\"sm\"\r\n variant={fitMode === \"view\" ? \"light-primary\" : \"light-secondary\"}\r\n onClick={() => setFitMode(\"view\")}\r\n />\r\n <IconButton icon=\"bi bi-arrow-clockwise\" aria-label={resolvedLabels.rotate} tooltip={resolvedLabels.rotate} size=\"sm\" variant=\"light-secondary\" onClick={rotate} />\r\n </>\r\n )}\r\n {allowNewTab && (\r\n <IconButton\r\n icon=\"bi bi-box-arrow-up-right\"\r\n aria-label={resolvedLabels.openInNewTab}\r\n tooltip={resolvedLabels.openInNewTab}\r\n size=\"sm\"\r\n variant=\"light-secondary\"\r\n onClick={handleOpenInNewTab}\r\n />\r\n )}\r\n <IconButton icon=\"bi bi-download\" aria-label={resolvedLabels.download} tooltip={resolvedLabels.download} size=\"sm\" variant=\"light-secondary\" onClick={handleDownload} />\r\n {allowFullscreen && (\r\n <IconButton\r\n icon={fullscreen ? \"bi bi-fullscreen-exit\" : \"bi bi-arrows-fullscreen\"}\r\n aria-label={fullscreen ? resolvedLabels.exitFullscreen : resolvedLabels.fullscreen}\r\n tooltip={fullscreen ? resolvedLabels.exitFullscreen : resolvedLabels.fullscreen}\r\n size=\"sm\"\r\n variant=\"light-secondary\"\r\n onClick={() => setFullscreen((value) => !value)}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n function renderSurface() {\r\n if (status === \"error\" && error) {\r\n const icon =\r\n error.kind === \"password-protected\"\r\n ? \"bi bi-shield-lock\"\r\n : error.kind === \"network\"\r\n ? \"bi bi-wifi-off\"\r\n : error.kind === \"unsupported\"\r\n ? \"bi bi-file-earmark-x\"\r\n : \"bi bi-exclamation-triangle\";\r\n return (\r\n <StatusPanel\r\n icon={icon}\r\n title={error.message}\r\n fileName={fileName}\r\n showDownload\r\n onDownload={handleDownload}\r\n downloadLabel={resolvedLabels.download}\r\n />\r\n );\r\n }\r\n\r\n // The <img> mounts as soon as a URL is resolved, even while `status` is\r\n // still \"loading\" — its own onLoad/onError is what flips `status`, so it\r\n // has to already be in the DOM for that event to ever fire.\r\n if (kind === \"image\" && imageUrl) {\r\n const transform = `scale(${fitMode === \"none\" ? manualScale : 1}) rotate(${rotation}deg)`;\r\n return (\r\n <div className=\"rrc-document-viewer__surface\" ref={containerRef}>\r\n <img\r\n src={imageUrl}\r\n alt={fileName ?? \"Document preview\"}\r\n className={cx(\"rrc-document-viewer__image\", fitMode !== \"none\" && `rrc-document-viewer__image--fit-${fitMode}`)}\r\n style={{ transform }}\r\n onLoad={() => setStatus(\"ready\")}\r\n onError={() => {\r\n const info: DocumentViewerError = { kind: \"network\", message: resolvedLabels.networkError };\r\n setError(info);\r\n setStatus(\"error\");\r\n onErrorRef.current?.(info);\r\n }}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n if (status === \"loading\") {\r\n return (\r\n <div className=\"rrc-document-viewer__status\">\r\n <Spinner label={resolvedLabels.loading} />\r\n <Text as=\"div\" size=\"sm\" tone=\"muted\">\r\n {resolvedLabels.loading}\r\n </Text>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"rrc-document-viewer__surface\" ref={containerRef}>\r\n <canvas\r\n ref={canvasRef}\r\n className=\"rrc-document-viewer__page\"\r\n role=\"img\"\r\n aria-label={`${resolvedLabels.page} ${currentPage} ${resolvedLabels.of} ${totalPages}`}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n const body = (\r\n <div className={cx(\"rrc-document-viewer\", fullscreen && \"rrc-document-viewer--fullscreen\", className)} style={fullscreen ? undefined : { height }}>\r\n {renderToolbar()}\r\n {renderSurface()}\r\n </div>\r\n );\r\n\r\n if (fullscreen) {\r\n return (\r\n <Modal open onClose={() => setFullscreen(false)} title={fileName} className=\"rrc-document-viewer__modal\">\r\n {body}\r\n </Modal>\r\n );\r\n }\r\n\r\n return body;\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","import type { Ref } from \"react\";\r\n\r\n/**\r\n * Ref plumbing for the slot path in `RichComponentBase`, where a consumer's\r\n * ref and a child's own ref both have to reach the same element.\r\n */\r\n\r\nfunction assignRef<T>(ref: Ref<T> | undefined | null, value: T | null): void {\r\n if (typeof ref === \"function\") {\r\n ref(value);\r\n return;\r\n }\r\n if (!ref || typeof ref !== \"object\") return;\r\n // `RefObject.current` is declared readonly for consumers, but writing it is\r\n // exactly what React itself does when it attaches an object ref. This is the\r\n // one place the library crosses that boundary, and it is confined to here.\r\n (ref as { current: T | null }).current = value;\r\n}\r\n\r\n/** Fans one element out to every supplied ref, ignoring the empty ones. */\r\nexport function composeRefs<T>(...refs: Array<Ref<T> | undefined | null>): Ref<T> {\r\n return (value: T | null) => {\r\n for (const ref of refs) assignRef(ref, value);\r\n };\r\n}\r\n","import { useEffect, useState, type ReactNode } from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\n\r\nexport interface PortalProps {\r\n children: ReactNode;\r\n /** Defaults to `document.body` once mounted on the client. */\r\n container?: Element | null;\r\n}\r\n\r\n/**\r\n * Minimal SSR-safe portal.\r\n *\r\n * The repository had no portal infrastructure before this (Popup positions\r\n * itself with plain CSS and Modal renders in place, both of which say so in\r\n * their own doc comments), so this is the smallest primitive that lets an\r\n * overlay escape an ancestor's `overflow`/`transform` clipping.\r\n *\r\n * `document` is never touched during module initialization or during render:\r\n * the host is resolved in an effect, so a server render produces nothing and\r\n * the first client render is identical to it. Intentionally internal — it is\r\n * plumbing for the context menu surface, not a second public overlay API.\r\n */\r\nexport function Portal({ children, container }: PortalProps) {\r\n const [host, setHost] = useState<Element | null>(null);\r\n\r\n useEffect(() => {\r\n if (container) {\r\n setHost(container);\r\n return;\r\n }\r\n setHost(typeof document === \"undefined\" ? null : document.body);\r\n }, [container]);\r\n\r\n if (!host) return null;\r\n return createPortal(children, host);\r\n}\r\n","import { Children, Fragment, isValidElement, type ReactElement, type ReactNode } from \"react\";\r\n\r\n/**\r\n * Identification of the declarative context-menu nodes.\r\n *\r\n * Recognition is by component *identity*, recorded in a module-private\r\n * WeakMap that is written once while this module initializes and never\r\n * mutated afterwards. Deliberately not `displayName`, not `Component.name`\r\n * and not a string on `props`: those are all rewritten or dropped by a\r\n * minifier, which would make the whole feature fail only in a production\r\n * bundle. A WeakMap keyed on the component reference survives minification\r\n * for exactly the same reason `type === Component` does, and needs no type\r\n * assertion to read back.\r\n */\r\n\r\nexport type ContextMenuNodeKind = \"menu\" | \"item\" | \"label\" | \"separator\" | \"submenu\";\r\n\r\nconst nodeKinds = new WeakMap<object, ContextMenuNodeKind>();\r\n\r\n/** Records what a component is. Called once per component at module scope. */\r\nexport function markContextMenuNode<TComponent extends object>(\r\n component: TComponent,\r\n kind: ContextMenuNodeKind\r\n): TComponent {\r\n nodeKinds.set(component, kind);\r\n return component;\r\n}\r\n\r\n/** The kind of a rendered node, or `undefined` for anything this module did not mark. */\r\nexport function contextMenuNodeKind(node: ReactNode): ContextMenuNodeKind | undefined {\r\n if (!isValidElement(node)) return undefined;\r\n const { type } = node;\r\n if (typeof type !== \"function\" && typeof type !== \"object\") return undefined;\r\n return nodeKinds.get(type);\r\n}\r\n\r\n/**\r\n * Flattens the direct children of a node one fragment level at a time.\r\n *\r\n * Fragments are handled deliberately rather than by accident: a\r\n * `<>{menu}{content}</>` child must not hide the menu declaration from the\r\n * partition below, and its visible children must not be dropped either.\r\n */\r\nexport function flattenMenuChildren(children: ReactNode): ReactNode[] {\r\n const flat: ReactNode[] = [];\r\n\r\n Children.forEach(children, (child) => {\r\n if (child === null || child === undefined || typeof child === \"boolean\") return;\r\n if (isValidElement(child) && child.type === Fragment) {\r\n const props: { children?: ReactNode } = child.props;\r\n flat.push(...flattenMenuChildren(props.children));\r\n return;\r\n }\r\n flat.push(child);\r\n });\r\n\r\n return flat;\r\n}\r\n\r\nexport interface RichComponentBaseChildren {\r\n /** The single `<ContextMenu>` declaration, if one was supplied. */\r\n menu?: ReactElement;\r\n /** Everything else, rendered as ordinary page content. */\r\n content: ReactNode[];\r\n}\r\n\r\n/**\r\n * Splits `RichComponentBase`'s children into the menu declaration and the\r\n * visible content. A second `<ContextMenu>` is ignored rather than rendered,\r\n * so a stray declaration can never leak into the page as content.\r\n */\r\nexport function partitionRichComponentBaseChildren(children: ReactNode): RichComponentBaseChildren {\r\n let menu: ReactElement | undefined;\r\n const content: ReactNode[] = [];\r\n\r\n for (const child of flattenMenuChildren(children)) {\r\n if (contextMenuNodeKind(child) === \"menu\" && isValidElement(child)) {\r\n if (!menu) menu = child;\r\n continue;\r\n }\r\n content.push(child);\r\n }\r\n\r\n return { menu, content };\r\n}\r\n\r\ninterface HideableProps {\r\n hidden?: boolean;\r\n}\r\n\r\n/**\r\n * Whether a declaration would put at least one selectable row on screen.\r\n *\r\n * This is what decides if the browser's own context menu is suppressed, so it\r\n * is answered from the declaration *before* anything is rendered. Labels and\r\n * separators do not count — a surface made only of those is \"effectively\r\n * empty\" and must leave native behavior alone. Anything this module did not\r\n * mark (a consumer's own wrapper component, arbitrary markup) counts as\r\n * content: guessing it away would silently disable a menu that does render.\r\n */\r\nexport function contextMenuHasContent(children: ReactNode): boolean {\r\n return flattenMenuChildren(children).some((child) => {\r\n const kind = contextMenuNodeKind(child);\r\n if (kind === \"label\" || kind === \"separator\") return false;\r\n if (kind === \"item\" || kind === \"submenu\") {\r\n if (!isValidElement(child)) return false;\r\n const props: HideableProps = child.props;\r\n return props.hidden !== true;\r\n }\r\n if (kind === \"menu\") return false;\r\n return true;\r\n });\r\n}\r\n","/**\r\n * Pure viewport placement math for the context menu surface.\r\n *\r\n * Kept free of React and of the DOM (the caller measures and passes plain\r\n * numbers) so the flip/clamp rules are unit-testable on their own, the same\r\n * split `sidebarModel.ts` uses for the Sidebar's navigation model.\r\n */\r\n\r\nexport interface ContextMenuPoint {\r\n x: number;\r\n y: number;\r\n}\r\n\r\nexport interface ContextMenuSize {\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport interface ContextMenuViewport {\r\n width: number;\r\n height: number;\r\n}\r\n\r\n/** Rect of a submenu's trigger row, in viewport coordinates. */\r\nexport interface ContextMenuTriggerBox {\r\n left: number;\r\n right: number;\r\n top: number;\r\n bottom: number;\r\n}\r\n\r\n/** Breathing room kept between the surface and the viewport edge. */\r\nexport const CONTEXT_MENU_VIEWPORT_MARGIN = 8;\r\n\r\nfunction clamp(value: number, min: number, max: number): number {\r\n if (max < min) return min;\r\n return Math.min(Math.max(value, min), max);\r\n}\r\n\r\n/**\r\n * Places the root surface at the pointer. Flips to the opposite side of the\r\n * pointer when the preferred side would overflow, then clamps, so a menu that\r\n * is simply larger than the viewport still starts inside it rather than\r\n * scrolling the page.\r\n */\r\nexport function placeContextMenuAtPoint(\r\n point: ContextMenuPoint,\r\n size: ContextMenuSize,\r\n viewport: ContextMenuViewport,\r\n margin: number = CONTEXT_MENU_VIEWPORT_MARGIN\r\n): ContextMenuPoint {\r\n const preferredX = point.x + size.width + margin > viewport.width ? point.x - size.width : point.x;\r\n const preferredY = point.y + size.height + margin > viewport.height ? point.y - size.height : point.y;\r\n\r\n return {\r\n x: clamp(preferredX, margin, viewport.width - size.width - margin),\r\n y: clamp(preferredY, margin, viewport.height - size.height - margin),\r\n };\r\n}\r\n\r\n/**\r\n * Places a submenu beside its trigger row: flush to the trigger's right edge\r\n * by default so the pointer can travel into it without crossing a gap, and\r\n * mirrored to the left when that would overflow.\r\n */\r\nexport function placeSubMenuBeside(\r\n trigger: ContextMenuTriggerBox,\r\n size: ContextMenuSize,\r\n viewport: ContextMenuViewport,\r\n margin: number = CONTEXT_MENU_VIEWPORT_MARGIN\r\n): ContextMenuPoint {\r\n const preferredX = trigger.right + size.width + margin > viewport.width ? trigger.left - size.width : trigger.right;\r\n const preferredY = trigger.top + size.height + margin > viewport.height ? trigger.bottom - size.height : trigger.top;\r\n\r\n return {\r\n x: clamp(preferredX, margin, viewport.width - size.width - margin),\r\n y: clamp(preferredY, margin, viewport.height - size.height - margin),\r\n };\r\n}\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useId,\r\n useLayoutEffect,\r\n useRef,\r\n useState,\r\n type CSSProperties,\r\n type KeyboardEvent as ReactKeyboardEvent,\r\n type ReactElement,\r\n type ReactNode,\r\n type RefObject,\r\n} from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { Portal } from \"./shared/Portal\";\r\nimport { markContextMenuNode } from \"./contextMenuModel\";\r\nimport { placeContextMenuAtPoint, placeSubMenuBeside, type ContextMenuPoint } from \"./contextMenuPosition\";\r\n\r\n/**\r\n * Declarative context menu.\r\n *\r\n * `<ContextMenu>` is a *declaration*, not page content: on its own it renders\r\n * nothing at all. `RichComponentBase` lifts the declaration out of its\r\n * children and re-renders it inside a surface context when the user invokes\r\n * the menu, which is why a stray `<ContextMenu>` anywhere else in a tree can\r\n * never leak markup into the page.\r\n *\r\n * Layer: Base. It performs no HTTP and knows nothing about metadata, so\r\n * Remote and Smart can compose it without inverting the dependency direction.\r\n */\r\n\r\nexport type ContextMenuCloseReason = \"select\" | \"escape\" | \"dismiss\";\r\n\r\nexport interface ContextMenuSurfaceValue {\r\n /** Viewport coordinates the menu was invoked at. */\r\n point: ContextMenuPoint;\r\n /** Changes on every invocation, so a repeated right-click re-measures. */\r\n openId: number;\r\n close: (reason: ContextMenuCloseReason) => void;\r\n}\r\n\r\n/**\r\n * Internal wiring between `RichComponentBase` and the surface. Deliberately\r\n * not part of the package's public exports — open/close state and positioning\r\n * are implementation details, not API.\r\n */\r\nexport const ContextMenuSurfaceContext = createContext<ContextMenuSurfaceValue | null>(null);\r\n\r\n/**\r\n * Dynamic viewport coordinates are the one thing a class cannot express, so\r\n * they travel as two narrowly scoped custom properties rather than as a pile\r\n * of inline layout declarations. Typed, not asserted.\r\n */\r\ninterface ContextMenuStyle extends CSSProperties {\r\n [key: `--${string}`]: string | number | undefined;\r\n}\r\n\r\nfunction positionStyle(position: ContextMenuPoint): ContextMenuStyle {\r\n return {\r\n \"--rrc-context-menu-x\": `${position.x}px`,\r\n \"--rrc-context-menu-y\": `${position.y}px`,\r\n };\r\n}\r\n\r\nfunction viewportSize() {\r\n return { width: window.innerWidth, height: window.innerHeight };\r\n}\r\n\r\nfunction isDisabledItem(item: HTMLElement): boolean {\r\n if (item instanceof HTMLButtonElement && item.disabled) return true;\r\n return item.getAttribute(\"aria-disabled\") === \"true\";\r\n}\r\n\r\n/**\r\n * The enabled rows of one menu level. Reading the level's own DOM is what\r\n * makes hidden items (never rendered), separators and labels (never\r\n * `menuitem`) and disabled items drop out of keyboard navigation, without a\r\n * second registration protocol that could drift from what is on screen.\r\n */\r\nfunction menuItemsOf(panel: HTMLElement): HTMLElement[] {\r\n return Array.from(panel.querySelectorAll<HTMLElement>('[role=\"menuitem\"]')).filter(\r\n (item) => item.closest('[role=\"menu\"]') === panel && !isDisabledItem(item)\r\n );\r\n}\r\n\r\nfunction focusFirstItem(panel: HTMLElement): void {\r\n const first = menuItemsOf(panel)[0];\r\n (first ?? panel).focus();\r\n}\r\n\r\ninterface MenuLevelKeyOptions {\r\n panelRef: RefObject<HTMLElement>;\r\n /** Escape (and Tab) at this level. */\r\n onEscape: () => void;\r\n /** Present only on a submenu level: ArrowLeft steps back to the trigger. */\r\n onStepOut?: () => void;\r\n}\r\n\r\n/**\r\n * Roving keyboard navigation for one menu level. A submenu is a level of its\r\n * own, so every key it handles is stopped there and the parent level never\r\n * sees it — the innermost menu always wins.\r\n */\r\nfunction useMenuLevelKeys({ panelRef, onEscape, onStepOut }: MenuLevelKeyOptions) {\r\n return useCallback(\r\n (event: ReactKeyboardEvent<HTMLElement>) => {\r\n const panel = panelRef.current;\r\n if (!panel) return;\r\n\r\n const items = menuItemsOf(panel);\r\n const currentIndex = items.findIndex((item) => item === document.activeElement);\r\n const focusAt = (index: number) => {\r\n const item = items[index];\r\n if (item) item.focus();\r\n };\r\n const handled = () => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n };\r\n\r\n switch (event.key) {\r\n case \"ArrowDown\":\r\n handled();\r\n if (items.length > 0) focusAt((currentIndex + 1) % items.length);\r\n return;\r\n case \"ArrowUp\":\r\n handled();\r\n if (items.length > 0) focusAt(currentIndex <= 0 ? items.length - 1 : currentIndex - 1);\r\n return;\r\n case \"Home\":\r\n handled();\r\n if (items.length > 0) focusAt(0);\r\n return;\r\n case \"End\":\r\n handled();\r\n if (items.length > 0) focusAt(items.length - 1);\r\n return;\r\n case \"ArrowLeft\":\r\n if (!onStepOut) return;\r\n handled();\r\n onStepOut();\r\n return;\r\n case \"Escape\":\r\n case \"Tab\":\r\n handled();\r\n onEscape();\r\n return;\r\n default:\r\n return;\r\n }\r\n },\r\n [panelRef, onEscape, onStepOut]\r\n );\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Root surface\r\n * ------------------------------------------------------------------ */\r\n\r\ninterface ContextMenuPanelProps {\r\n surface: ContextMenuSurfaceValue;\r\n label?: string;\r\n className?: string;\r\n children?: ReactNode;\r\n}\r\n\r\nfunction ContextMenuPanel({ surface, label, className, children }: ContextMenuPanelProps) {\r\n const { point, openId, close } = surface;\r\n const panelRef = useRef<HTMLDivElement>(null);\r\n const [position, setPosition] = useState<ContextMenuPoint>(point);\r\n\r\n // Measure, then flip/clamp into the viewport before the browser paints.\r\n useLayoutEffect(() => {\r\n const panel = panelRef.current;\r\n if (!panel) return;\r\n const rect = panel.getBoundingClientRect();\r\n setPosition(placeContextMenuAtPoint(point, { width: rect.width, height: rect.height }, viewportSize()));\r\n }, [point, openId]);\r\n\r\n useLayoutEffect(() => {\r\n const panel = panelRef.current;\r\n if (panel) focusFirstItem(panel);\r\n }, [openId]);\r\n\r\n // The only global listeners this feature installs, and only while a surface\r\n // is actually on screen: nothing is registered per mounted RichComponentBase.\r\n useEffect(() => {\r\n function isInsidePanel(target: EventTarget | null): boolean {\r\n const panel = panelRef.current;\r\n return Boolean(panel && target instanceof Node && panel.contains(target));\r\n }\r\n function handlePointerDown(event: MouseEvent) {\r\n if (isInsidePanel(event.target)) return;\r\n close(\"dismiss\");\r\n }\r\n function handleViewportChange(event: Event) {\r\n if (isInsidePanel(event.target)) return;\r\n close(\"dismiss\");\r\n }\r\n\r\n document.addEventListener(\"mousedown\", handlePointerDown);\r\n window.addEventListener(\"resize\", handleViewportChange);\r\n document.addEventListener(\"scroll\", handleViewportChange, true);\r\n return () => {\r\n document.removeEventListener(\"mousedown\", handlePointerDown);\r\n window.removeEventListener(\"resize\", handleViewportChange);\r\n document.removeEventListener(\"scroll\", handleViewportChange, true);\r\n };\r\n }, [close]);\r\n\r\n const onEscape = useCallback(() => close(\"escape\"), [close]);\r\n const handleKeyDown = useMenuLevelKeys({ panelRef, onEscape });\r\n\r\n return (\r\n <div\r\n ref={panelRef}\r\n role=\"menu\"\r\n aria-label={label}\r\n tabIndex={-1}\r\n className={cx(\"rrc-context-menu\", className)}\r\n style={positionStyle(position)}\r\n onKeyDown={(event) => {\r\n handleKeyDown(event);\r\n // A portal still propagates through the React tree, so without this a\r\n // key pressed inside the surface would reach the trigger it belongs to.\r\n event.stopPropagation();\r\n }}\r\n onClick={(event) => event.stopPropagation()}\r\n onContextMenu={(event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport interface ContextMenuProps {\r\n children?: ReactNode;\r\n /**\r\n * Leaves the browser's own context menu intact without removing the\r\n * declaration — the menu is switched off, not deleted.\r\n */\r\n disabled?: boolean;\r\n /** Accessible name for the surface, when the rows alone are not enough. */\r\n \"aria-label\"?: string;\r\n className?: string;\r\n}\r\n\r\nfunction ContextMenuRoot({ children, className, \"aria-label\": ariaLabel }: ContextMenuProps): ReactElement | null {\r\n const surface = useContext(ContextMenuSurfaceContext);\r\n // Declaration only: outside a surface this renders nothing, so it can never\r\n // appear as ordinary page content.\r\n if (!surface) return null;\r\n\r\n return (\r\n <Portal>\r\n <ContextMenuPanel surface={surface} label={ariaLabel} className={className}>\r\n {children}\r\n </ContextMenuPanel>\r\n </Portal>\r\n );\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Rows\r\n * ------------------------------------------------------------------ */\r\n\r\nfunction reportSelectError(error: unknown): void {\r\n // Reported, never swallowed, and never left as an unhandled rejection — the\r\n // console convention useControllableState and Sidebar already use for a\r\n // contract violation this library cannot recover from.\r\n console.error(\"[rich-react-component] ContextMenu.Item onSelect failed:\", error);\r\n}\r\n\r\nfunction runSelectHandler(onSelect: (() => void | Promise<void>) | undefined): void {\r\n if (!onSelect) return;\r\n const result = onSelect();\r\n if (result !== undefined) Promise.resolve(result).then(undefined, reportSelectError);\r\n}\r\n\r\nexport interface ContextMenuItemProps {\r\n children?: ReactNode;\r\n /** Optional stable identifier; emitted as the row's DOM id. */\r\n id?: string;\r\n disabled?: boolean;\r\n /** Not rendered at all, and so skipped by keyboard navigation. */\r\n hidden?: boolean;\r\n /** Destructive emphasis — the same semantic name `Menu`'s item model uses. */\r\n danger?: boolean;\r\n /** Icon content, e.g. `<Icon name=\"bi bi-pencil\" />`. No icon set is bundled. */\r\n icon?: ReactNode;\r\n /** Accessible name, for a row whose visible text is not sufficient. */\r\n \"aria-label\"?: string;\r\n className?: string;\r\n onSelect?: () => void | Promise<void>;\r\n}\r\n\r\nfunction ContextMenuItem({\r\n children,\r\n id,\r\n disabled,\r\n hidden,\r\n danger,\r\n icon,\r\n className,\r\n \"aria-label\": ariaLabel,\r\n onSelect,\r\n}: ContextMenuItemProps): ReactElement | null {\r\n const surface = useContext(ContextMenuSurfaceContext);\r\n\r\n const handleClick = useCallback(() => {\r\n runSelectHandler(onSelect);\r\n surface?.close(\"select\");\r\n }, [onSelect, surface]);\r\n\r\n if (hidden) return null;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n role=\"menuitem\"\r\n id={id}\r\n tabIndex={-1}\r\n disabled={disabled}\r\n aria-disabled={disabled || undefined}\r\n aria-label={ariaLabel}\r\n className={cx(\"rrc-context-menu__item\", danger && \"rrc-context-menu__item--danger\", className)}\r\n onClick={handleClick}\r\n >\r\n {icon !== undefined && <span className=\"rrc-context-menu__item-icon\">{icon}</span>}\r\n <span className=\"rrc-context-menu__item-label\">{children}</span>\r\n </button>\r\n );\r\n}\r\n\r\nexport interface ContextMenuLabelProps {\r\n children?: ReactNode;\r\n className?: string;\r\n}\r\n\r\nfunction ContextMenuLabel({ children, className }: ContextMenuLabelProps): ReactElement {\r\n // `presentation` keeps a caption out of the menu's child structure, so it is\r\n // neither announced as a row nor reachable by keyboard.\r\n return (\r\n <div role=\"presentation\" className={cx(\"rrc-context-menu__label\", className)}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport interface ContextMenuSeparatorProps {\r\n className?: string;\r\n}\r\n\r\nfunction ContextMenuSeparator({ className }: ContextMenuSeparatorProps): ReactElement {\r\n return <div role=\"separator\" className={cx(\"rrc-context-menu__separator\", className)} />;\r\n}\r\n\r\nexport interface ContextMenuSubMenuProps {\r\n /** Visible text of the row that opens the submenu. */\r\n label: ReactNode;\r\n children?: ReactNode;\r\n id?: string;\r\n disabled?: boolean;\r\n hidden?: boolean;\r\n icon?: ReactNode;\r\n /** Accessible name, for a trigger whose visible text is not sufficient. */\r\n \"aria-label\"?: string;\r\n className?: string;\r\n}\r\n\r\nfunction ContextMenuSubMenu({\r\n label,\r\n children,\r\n id,\r\n disabled,\r\n hidden,\r\n icon,\r\n className,\r\n \"aria-label\": ariaLabel,\r\n}: ContextMenuSubMenuProps): ReactElement | null {\r\n const [open, setOpen] = useState(false);\r\n const [position, setPosition] = useState<ContextMenuPoint>({ x: 0, y: 0 });\r\n const triggerRef = useRef<HTMLButtonElement>(null);\r\n const panelRef = useRef<HTMLDivElement>(null);\r\n const focusOnOpen = useRef(false);\r\n\r\n const generatedId = useId();\r\n const triggerId = id ?? `${generatedId}trigger`;\r\n const panelId = `${generatedId}panel`;\r\n\r\n const closeLevel = useCallback(() => {\r\n setOpen(false);\r\n triggerRef.current?.focus();\r\n }, []);\r\n\r\n useLayoutEffect(() => {\r\n if (!open) {\r\n // A toggle that closed the level must not leave a pending focus request\r\n // behind for the next hover to consume.\r\n focusOnOpen.current = false;\r\n return;\r\n }\r\n const trigger = triggerRef.current;\r\n const panel = panelRef.current;\r\n if (!trigger || !panel) return;\r\n\r\n const triggerRect = trigger.getBoundingClientRect();\r\n const panelRect = panel.getBoundingClientRect();\r\n setPosition(\r\n placeSubMenuBeside(\r\n { left: triggerRect.left, right: triggerRect.right, top: triggerRect.top, bottom: triggerRect.bottom },\r\n { width: panelRect.width, height: panelRect.height },\r\n viewportSize()\r\n )\r\n );\r\n\r\n if (focusOnOpen.current) {\r\n focusOnOpen.current = false;\r\n focusFirstItem(panel);\r\n }\r\n }, [open]);\r\n\r\n const handlePanelKeys = useMenuLevelKeys({ panelRef, onEscape: closeLevel, onStepOut: closeLevel });\r\n\r\n if (hidden) return null;\r\n\r\n return (\r\n <div\r\n role=\"presentation\"\r\n className=\"rrc-context-menu__submenu\"\r\n onMouseEnter={() => {\r\n if (!disabled) setOpen(true);\r\n }}\r\n onMouseLeave={() => setOpen(false)}\r\n >\r\n <button\r\n ref={triggerRef}\r\n type=\"button\"\r\n role=\"menuitem\"\r\n id={triggerId}\r\n tabIndex={-1}\r\n disabled={disabled}\r\n aria-disabled={disabled || undefined}\r\n aria-haspopup=\"menu\"\r\n aria-expanded={open}\r\n aria-controls={open ? panelId : undefined}\r\n aria-label={ariaLabel}\r\n className={cx(\"rrc-context-menu__item\", \"rrc-context-menu__item--submenu\", className)}\r\n onClick={() => {\r\n focusOnOpen.current = true;\r\n setOpen((previous) => !previous);\r\n }}\r\n onKeyDown={(event) => {\r\n if (event.key !== \"ArrowRight\") return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n focusOnOpen.current = true;\r\n setOpen(true);\r\n }}\r\n >\r\n {icon !== undefined && <span className=\"rrc-context-menu__item-icon\">{icon}</span>}\r\n <span className=\"rrc-context-menu__item-label\">{label}</span>\r\n <span className=\"rrc-context-menu__item-arrow\" aria-hidden=\"true\" />\r\n </button>\r\n\r\n {open && (\r\n <div\r\n ref={panelRef}\r\n id={panelId}\r\n role=\"menu\"\r\n aria-labelledby={triggerId}\r\n tabIndex={-1}\r\n className=\"rrc-context-menu rrc-context-menu--sub\"\r\n style={positionStyle(position)}\r\n onKeyDown={handlePanelKeys}\r\n >\r\n {children}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/* ------------------------------------------------------------------ *\r\n * Compound export\r\n * ------------------------------------------------------------------ */\r\n\r\nmarkContextMenuNode(ContextMenuRoot, \"menu\");\r\nmarkContextMenuNode(ContextMenuItem, \"item\");\r\nmarkContextMenuNode(ContextMenuLabel, \"label\");\r\nmarkContextMenuNode(ContextMenuSeparator, \"separator\");\r\nmarkContextMenuNode(ContextMenuSubMenu, \"submenu\");\r\n\r\nexport interface ContextMenuComponent {\r\n (props: ContextMenuProps): ReactElement | null;\r\n Item: (props: ContextMenuItemProps) => ReactElement | null;\r\n Separator: (props: ContextMenuSeparatorProps) => ReactElement;\r\n Label: (props: ContextMenuLabelProps) => ReactElement;\r\n SubMenu: (props: ContextMenuSubMenuProps) => ReactElement | null;\r\n}\r\n\r\n/**\r\n * The compound is annotated explicitly rather than inferred from\r\n * `Object.assign`, so the generated declaration file names only exported\r\n * types and never a private local one.\r\n */\r\nexport const ContextMenu: ContextMenuComponent = Object.assign(ContextMenuRoot, {\r\n Item: ContextMenuItem,\r\n Separator: ContextMenuSeparator,\r\n Label: ContextMenuLabel,\r\n SubMenu: ContextMenuSubMenu,\r\n});\r\n","import {\r\n Children,\r\n cloneElement,\r\n createElement,\r\n forwardRef,\r\n isValidElement,\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useMemo,\r\n useRef,\r\n useState,\r\n type CSSProperties,\r\n type HTMLAttributes,\r\n type KeyboardEventHandler,\r\n type MouseEventHandler,\r\n type ReactElement,\r\n type ReactHTML,\r\n type ReactNode,\r\n type Ref,\r\n} from \"react\";\r\nimport { cx } from \"./shared/classNames\";\r\nimport { composeRefs } from \"./shared/composeRefs\";\r\nimport {\r\n ContextMenuSurfaceContext,\r\n type ContextMenuCloseReason,\r\n type ContextMenuProps,\r\n type ContextMenuSurfaceValue,\r\n} from \"./ContextMenu\";\r\nimport { contextMenuHasContent, partitionRichComponentBaseChildren } from \"./contextMenuModel\";\r\nimport type { ContextMenuPoint } from \"./contextMenuPosition\";\r\n\r\n/**\r\n * `RichComponentBase` — the one place the context-menu behavior lives.\r\n *\r\n * Composition, never inheritance: it wraps content it does not know anything\r\n * about, so no existing component gained a `contextMenu` prop and none of them\r\n * carries a copy of this logic.\r\n *\r\n * <RichComponentBase>\r\n * <ContextMenu>\r\n * <ContextMenu.Item onSelect={handleEdit}>Düzenle</ContextMenu.Item>\r\n * <ContextMenu.Separator />\r\n * <ContextMenu.Item danger onSelect={handleDelete}>Sil</ContextMenu.Item>\r\n * </ContextMenu>\r\n *\r\n * <Button>İşlem</Button>\r\n * </RichComponentBase>\r\n *\r\n * Without a `<ContextMenu>` child it is transparent: no listeners, no ARIA, no\r\n * interception of the browser's own menu.\r\n *\r\n * ## How the trigger attaches (`trigger`)\r\n *\r\n * `\"auto\"` (default) attaches to the child itself — no extra DOM — when the\r\n * single visible child is a *host element* (`<div>`, `<table>`, `<button>`,\r\n * …), because a host element is the only child guaranteed to forward\r\n * `onContextMenu`, `onKeyDown` and a ref. Most Base components in this\r\n * repository deliberately keep a small prop surface and do not spread unknown\r\n * props onto their root, so injecting handlers into them would fail silently.\r\n * For those, and for multiple or non-element children, `auto` falls back to a\r\n * wrapper element that is `display: contents` — it generates no layout box, so\r\n * flex and grid placement, width/height resolution, positioning and\r\n * scroll containers all behave as if it were not there.\r\n *\r\n * `\"child\"` forces the slot path for a component the caller knows forwards its\r\n * props (e.g. `Button`, which extends `ButtonHTMLAttributes`). `\"wrapper\"`\r\n * forces the wrapper. `as` picks the wrapper's element, for the places a\r\n * `<div>` would be invalid markup (`as=\"tbody\"`, `as=\"li\"`, …).\r\n *\r\n * ## Event composition policy (documented, tested)\r\n *\r\n * 1. the child's / the caller's own `onContextMenu` runs first;\r\n * 2. if it called `preventDefault()`, this base does nothing at all — it does\r\n * not open, and it does not stop propagation, so an outer\r\n * `RichComponentBase` still gets its chance;\r\n * 3. otherwise, and only when an enabled non-empty menu exists, the native\r\n * menu is suppressed, propagation is stopped (nearest base wins) and the\r\n * surface opens at the pointer.\r\n *\r\n * The trigger carries no ARIA of its own. `aria-haspopup` is not a supported\r\n * attribute on `role=\"generic\"`, which is what a wrapper `<div>` and most host\r\n * elements resolve to, so emitting it would be an authoring error rather than\r\n * a hint; a context-menu target is not a menu button. The accessibility work\r\n * is in the surface (`role=\"menu\"`, real focus management, real keyboard\r\n * navigation) and in the submenu triggers, where `role=\"menuitem\"` does\r\n * support `aria-haspopup`/`aria-expanded`/`aria-controls`.\r\n */\r\n\r\n/** Broadcast on `document` when a menu opens, so any other open menu closes itself. */\r\nconst CONTEXT_MENU_OPEN_EVENT = \"rrc:context-menu-open\";\r\n\r\ninterface ContextMenuOpenDetail {\r\n id: string;\r\n}\r\n\r\nfunction isOpenDetail(detail: unknown): detail is ContextMenuOpenDetail {\r\n return typeof detail === \"object\" && detail !== null && typeof Reflect.get(detail, \"id\") === \"string\";\r\n}\r\n\r\nconst FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\");\r\nconst MEMO_TYPE = Symbol.for(\"react.memo\");\r\n\r\n/**\r\n * Whether attaching a ref to this element is safe. Passing a ref to a plain\r\n * function component produces a React warning and no node, so the slot path\r\n * only forwards one to a host element or to something that really is a\r\n * `forwardRef` (possibly behind `memo`). Checked structurally — `$$typeof`\r\n * survives minification, a display name does not.\r\n */\r\nfunction acceptsRef(element: ReactElement): boolean {\r\n const { type } = element;\r\n if (typeof type === \"string\") return true;\r\n if (typeof type !== \"object\" || type === null) return false;\r\n\r\n const marker: unknown = Reflect.get(type, \"$$typeof\");\r\n if (marker === FORWARD_REF_TYPE) return true;\r\n if (marker !== MEMO_TYPE) return false;\r\n\r\n const inner: unknown = Reflect.get(type, \"type\");\r\n if (typeof inner !== \"object\" || inner === null) return false;\r\n return Reflect.get(inner, \"$$typeof\") === FORWARD_REF_TYPE;\r\n}\r\n\r\nfunction composeMouseHandlers(\r\n ...handlers: Array<MouseEventHandler<HTMLElement> | undefined>\r\n): MouseEventHandler<HTMLElement> {\r\n return (event) => {\r\n for (const handler of handlers) handler?.(event);\r\n };\r\n}\r\n\r\nfunction composeKeyboardHandlers(\r\n ...handlers: Array<KeyboardEventHandler<HTMLElement> | undefined>\r\n): KeyboardEventHandler<HTMLElement> {\r\n return (event) => {\r\n for (const handler of handlers) handler?.(event);\r\n };\r\n}\r\n\r\n/** How the context-menu trigger is attached to the visible content. */\r\nexport type RichComponentBaseTrigger = \"auto\" | \"child\" | \"wrapper\";\r\n\r\nexport interface RichComponentBaseProps extends Omit<HTMLAttributes<HTMLElement>, \"children\"> {\r\n /** A single optional `<ContextMenu>` declaration plus the visible content. */\r\n children?: ReactNode;\r\n /** See the component doc comment. Defaults to `\"auto\"`. */\r\n trigger?: RichComponentBaseTrigger;\r\n /** Wrapper element used by the wrapper path. Defaults to `\"div\"`. */\r\n as?: keyof ReactHTML;\r\n}\r\n\r\ntype ResolvedTrigger = { mode: \"child\"; child: ReactElement } | { mode: \"wrapper\" };\r\n\r\nfunction resolveTrigger(trigger: RichComponentBaseTrigger, content: ReactNode[]): ResolvedTrigger {\r\n if (trigger === \"wrapper\") return { mode: \"wrapper\" };\r\n\r\n const only = content.length === 1 ? content[0] : undefined;\r\n if (only === undefined || !isValidElement(only)) return { mode: \"wrapper\" };\r\n if (trigger === \"child\") return { mode: \"child\", child: only };\r\n\r\n return typeof only.type === \"string\" ? { mode: \"child\", child: only } : { mode: \"wrapper\" };\r\n}\r\n\r\n/** The child props the slot path has to merge with rather than replace. */\r\ninterface SlotChildProps {\r\n className?: string;\r\n style?: CSSProperties;\r\n onContextMenu?: MouseEventHandler<HTMLElement>;\r\n onKeyDown?: KeyboardEventHandler<HTMLElement>;\r\n}\r\n\r\nexport const RichComponentBase = forwardRef<HTMLElement, RichComponentBaseProps>(function RichComponentBase(\r\n { children, trigger = \"auto\", as = \"div\", className, style, onContextMenu, onKeyDown, ...rest },\r\n forwardedRef\r\n) {\r\n const instanceId = useId();\r\n const { menu, content } = useMemo(() => partitionRichComponentBaseChildren(children), [children]);\r\n\r\n const menuEnabled = useMemo(() => {\r\n if (!menu) return false;\r\n const menuProps: ContextMenuProps = menu.props;\r\n if (menuProps.disabled === true) return false;\r\n return contextMenuHasContent(menuProps.children);\r\n }, [menu]);\r\n\r\n const [openState, setOpenState] = useState<{ point: ContextMenuPoint; openId: number } | null>(null);\r\n const openCounter = useRef(0);\r\n const restoreFocusRef = useRef<HTMLElement | null>(null);\r\n\r\n const close = useCallback((reason: ContextMenuCloseReason) => {\r\n setOpenState(null);\r\n const target = restoreFocusRef.current;\r\n restoreFocusRef.current = null;\r\n // An outside click is already moving focus somewhere the user chose, so\r\n // only a deliberate close hands focus back to where it came from.\r\n if (reason === \"dismiss\") return;\r\n if (target && target.isConnected) target.focus();\r\n }, []);\r\n\r\n const openAt = useCallback(\r\n (x: number, y: number) => {\r\n if (openState === null) {\r\n const active = document.activeElement;\r\n restoreFocusRef.current = active instanceof HTMLElement ? active : null;\r\n }\r\n // No module-level registry: the opener announces itself and every other\r\n // open surface closes itself in response.\r\n document.dispatchEvent(\r\n new CustomEvent(CONTEXT_MENU_OPEN_EVENT, { detail: { id: instanceId } satisfies ContextMenuOpenDetail })\r\n );\r\n openCounter.current += 1;\r\n setOpenState({ point: { x, y }, openId: openCounter.current });\r\n },\r\n [instanceId, openState]\r\n );\r\n\r\n // Registered only while this instance's surface is open.\r\n useEffect(() => {\r\n if (!openState) return;\r\n function handleOtherOpen(event: Event) {\r\n if (!(event instanceof CustomEvent)) return;\r\n const detail: unknown = event.detail;\r\n if (isOpenDetail(detail) && detail.id !== instanceId) close(\"dismiss\");\r\n }\r\n document.addEventListener(CONTEXT_MENU_OPEN_EVENT, handleOtherOpen);\r\n return () => document.removeEventListener(CONTEXT_MENU_OPEN_EVENT, handleOtherOpen);\r\n }, [openState, instanceId, close]);\r\n\r\n // A menu that is removed or disabled while open must not stay on screen.\r\n useEffect(() => {\r\n if (!menuEnabled && openState) close(\"dismiss\");\r\n }, [menuEnabled, openState, close]);\r\n\r\n const triggerContextMenu = useCallback<MouseEventHandler<HTMLElement>>(\r\n (event) => {\r\n if (event.defaultPrevented) return;\r\n if (!menuEnabled) return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n openAt(event.clientX, event.clientY);\r\n },\r\n [menuEnabled, openAt]\r\n );\r\n\r\n const triggerKeyDown = useCallback<KeyboardEventHandler<HTMLElement>>(\r\n (event) => {\r\n if (event.defaultPrevented) return;\r\n if (!menuEnabled) return;\r\n const invokes = event.key === \"ContextMenu\" || (event.shiftKey && event.key === \"F10\");\r\n if (!invokes) return;\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n const anchor = event.target instanceof HTMLElement ? event.target : event.currentTarget;\r\n const rect = anchor.getBoundingClientRect();\r\n openAt(rect.left, rect.bottom);\r\n },\r\n [menuEnabled, openAt]\r\n );\r\n\r\n const surfaceValue = useMemo<ContextMenuSurfaceValue | null>(\r\n () => (openState ? { point: openState.point, openId: openState.openId, close } : null),\r\n [openState, close]\r\n );\r\n\r\n const resolved = resolveTrigger(trigger, content);\r\n\r\n let triggerNode: ReactNode;\r\n if (resolved.mode === \"child\") {\r\n const { child } = resolved;\r\n const childProps: SlotChildProps = child.props;\r\n const childRef: Ref<HTMLElement> | undefined = Reflect.get(child, \"ref\") ?? undefined;\r\n const mergedClassName = cx(className, childProps.className);\r\n const hasStyle = style !== undefined || childProps.style !== undefined;\r\n\r\n triggerNode = cloneElement(child, {\r\n ...rest,\r\n // The child's own props win over this base's. Only `className`, `style`\r\n // and the two trigger handlers are merged rather than replaced; every\r\n // other prop the child declares, accessibility props included, is left\r\n // exactly as it was.\r\n ...child.props,\r\n className: mergedClassName || undefined,\r\n ...(hasStyle ? { style: { ...style, ...childProps.style } } : null),\r\n onContextMenu: composeMouseHandlers(childProps.onContextMenu, onContextMenu, triggerContextMenu),\r\n onKeyDown: composeKeyboardHandlers(childProps.onKeyDown, onKeyDown, triggerKeyDown),\r\n ...(acceptsRef(child) ? { ref: composeRefs<HTMLElement>(childRef, forwardedRef) } : null),\r\n });\r\n } else {\r\n triggerNode = createElement(\r\n as,\r\n {\r\n ...rest,\r\n ref: forwardedRef,\r\n className: cx(\"rrc-rich-base\", className) || undefined,\r\n style,\r\n onContextMenu: composeMouseHandlers(onContextMenu, triggerContextMenu),\r\n onKeyDown: composeKeyboardHandlers(onKeyDown, triggerKeyDown),\r\n },\r\n // Spread as separate arguments, the way JSX does, so React treats them\r\n // as static children and no synthetic keys are needed.\r\n ...Children.toArray(content)\r\n );\r\n }\r\n\r\n return (\r\n <>\r\n {triggerNode}\r\n {menu && surfaceValue && (\r\n <ContextMenuSurfaceContext.Provider value={surfaceValue}>{menu}</ContextMenuSurfaceContext.Provider>\r\n )}\r\n </>\r\n );\r\n});\r\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","useIsomorphicLayoutEffect","useLayoutEffect","useElementResize","ref","enabled","onResize","handlerRef","element","notify","observer","BEHAVIORS","isBehavior","resolvePrimaryColumnKey","columns","configured","eligible","column","match","buildResponsiveColumnPlan","problems","byKey","primaryKey","rules","claimed","rule","responsivePlanSignature","plan","problem","OVERFLOW_TOLERANCE","RESTORE_HYSTERESIS","useResponsiveColumnFit","containerRef","ruleCount","signature","processedCount","setProcessedCount","countRef","blockedWidthRef","lastWidthRef","passesRef","evaluate","available","overflowing","blocked","PROBLEM_MESSAGES","useResponsivePlanDiagnostics","dataGridFormatters","amount","EMPTY_RESPONSIVE_PLAN","EMPTY_COLUMNS","toResponsiveColumnModel","accessor","isUtility","isData","columnKeyOf","nextSortDirection","key","columnValueOf","row","renderCell","alignClass","align","DataGrid","rowKey","selectedRowKeys","onSelectionChange","sort","onSortChange","totalCount","responsive","selectable","paginated","responsiveEnabled","columnModels","useMemo","processedRules","visibleColumns","detailColumns","removedKeys","columnsByKey","spanCount","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","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","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","isSidebarParent","isSidebarExpandable","isLegacyGroup","section","toSidebarItems","sections","legacyGroupToItem","legacyLeafToItem","group","leaf","shared","legacyDefaultExpandedKeys","legacyActiveKey","child","buildSidebarTree","order","duplicateKeys","walk","list","depth","ancestors","nodes","sortKeysByTreeOrder","keys","wanted","sorted","known","toggleExpandedKey","tree","descendant","descendantKeys","ancestor","expandPath","path","sameExpandedKeys","a","b","activeAncestorKeys","activeExpandablePath","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","ChartStatusOverlay","emptyMessage","useChartDimensions","setWidth","Chart","animate","isEmpty","legend","summaryId","showStatus","PALETTE_SIZE","resolveChartColor","explicit","overrides","chartSeriesColorList","series","ChartLegend","onToggle","legendItemsFromSeries","colorOverrides","hiddenKeys","colors","ChartTooltip","payload","linearScale","domain","d0","d1","r0","r1","niceTicks","count","rawStep","magnitude","residual","niceMin","niceMax","ticks","bandScale","paddingRatio","bandWidth","defaultNumberFormatter","locale","formatter","MARGIN","toNumber","formatXLabel","CartesianChart","kind","xKey","showLegend","showTooltip","showGrid","showDataLabels","xAxisLabel","yAxisLabel","xFormatter","yFormatter","stacked","onDataPointClick","onLegendItemClick","hidden","setHidden","s","visibleSeries","numberFormatter","isMeasuring","showOverlay","toggleSeries","willHide","legendItems","isHorizontal","offset","stackedTotals","sum","domainValues","domainMin","domainMax","valueScale","zeroY","seriesIndex","format","emitClick","handleColumnKeyDown","columnLabel","renderMarks","color","linePath","stackOffsets","groupWidth","bandStart","barLength","tick","LineChart","AreaChart","BarChart","StackedBarChart","ChartSliceSummary","useChartIndexNavigation","onActivate","setActiveIndexState","clearActive","polar","cy","r","angle","rad","slicePath","outerR","innerR","startAngle","endAngle","isFullCircle","large","ox","ox2","ix","ix2","x1","y1","x2","y2","x3","y3","x4","y4","CircularChartBase","nameKey","valueKey","innerRadiusRatio","centerLabel","centerValue","valueFormatter","onSliceClick","chartProps","slices","percent","nav","slice","CircularSurface","activeSlice","percentFormat","tabbableIndex","labelAngle","labelX","labelY","DonutChart","PieChart","toDate","startOfDay","isSameDay","addDays","addMonths","buildMonthGrid","viewDate","weekStartsOn","eventOccursOnDay","chunk","Calendar","onDateChange","events","view","disabledDates","maxEventsPerDay","todayLabel","moreLabel","noEventsLabel","onMonthChange","onEventClick","selected","setSelected","today","setViewDate","startOfMonthOf","grid","weeks","weekdayFormatter","titleFormatter","dayLabelFormatter","weekdayLabels","eventsByDayKey","map","dateKey","isDisabledDay","focusIndexFor","gridDays","selectedDate","selectedIndex","todayIndex","focusedIndex","setFocusedIndex","cellRefs","focusCell","goToMonth","keepSelected","targetMonth","selectDay","targetIndex","gridDay","moveFocus","nextIndex","handleGridKeyDown","rootId","week","weekIndex","dayIndex","isOutside","isToday","isSelected","dayDisabled","dayEvents","visibleEvents","overflowCount","dayAriaLabel","eventItem","clickEvent","DEFAULT_LABELS","IMAGE_MIME_TYPES","EXTENSION_MIME_TYPES","resolveMimeType","mimeType","fileName","ext","classifyMimeType","mime","toObjectUrl","blob","triggerDownload","url","revoke","link","workerConfigured","configurePdfWorker","pdfjsLib","workerUrl","classifyPdfError","labels","StatusPanel","showDownload","onDownload","downloadLabel","DocumentViewer","initialPage","toolbar","allowFullscreen","allowNewTab","onError","resolvedLabels","setKind","setStatus","setError","imageUrl","setImageUrl","setTotalPages","setCurrentPage","fitMode","setFitMode","manualScale","setManualScale","rotation","setRotation","fullscreen","setFullscreen","pdfDocRef","canvasRef","containerSize","setContainerSize","onErrorRef","onPageChangeRef","cancelled","objectUrl","loadingTask","fileKind","load","info","input","pdf","err","task","baseViewport","scale","viewport","canvas","handleDownload","handleOpenInNewTab","zoomIn","zoomOut","rotate","isPreviewable","renderToolbar","renderSurface","transform","body","AppearanceRadioGroup","refs","move","AppearanceMenu","colorSchemes","changeMode","changePresentation","changeTone","changeScheme","schemes","assignRef","composeRefs","Portal","container","host","setHost","createPortal","nodeKinds","markContextMenuNode","component","contextMenuNodeKind","isValidElement","flattenMenuChildren","flat","Children","partitionRichComponentBaseChildren","menu","contextMenuHasContent","CONTEXT_MENU_VIEWPORT_MARGIN","clamp","placeContextMenuAtPoint","point","margin","preferredX","preferredY","placeSubMenuBeside","trigger","ContextMenuSurfaceContext","positionStyle","position","viewportSize","isDisabledItem","menuItemsOf","focusFirstItem","useMenuLevelKeys","panelRef","onStepOut","focusAt","handled","ContextMenuPanel","surface","openId","setPosition","isInsidePanel","handleViewportChange","ContextMenuRoot","reportSelectError","runSelectHandler","ContextMenuItem","danger","ContextMenuLabel","ContextMenuSeparator","ContextMenuSubMenu","triggerRef","focusOnOpen","triggerId","closeLevel","triggerRect","panelRect","handlePanelKeys","ContextMenu","CONTEXT_MENU_OPEN_EVENT","isOpenDetail","detail","FORWARD_REF_TYPE","MEMO_TYPE","acceptsRef","marker","inner","composeMouseHandlers","handlers","handler","composeKeyboardHandlers","resolveTrigger","only","RichComponentBase","forwardRef","style","onContextMenu","onKeyDown","forwardedRef","instanceId","menuEnabled","menuProps","openState","setOpenState","openCounter","restoreFocusRef","reason","openAt","handleOtherOpen","triggerContextMenu","triggerKeyDown","surfaceValue","resolved","triggerNode","childProps","childRef","mergedClassName","hasStyle","cloneElement","createElement","HttpError","statusText","serializeParams","params","searchParams","rawValue","createHttpClient","baseUrl","fetcher","buildRequestInit","requestOptions","fullUrl","init","response","defaultHttpClient","sortKeys","obj","acc","useRemoteData","client","mapResponse","state","setState","setItems","reloadToken","setReloadToken","paramsKey","latestRequestId","mapResponseRef","requestId","controller","mapped","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","resolver","metadata","createSmartDataSourceRegistry","initial","definitions","definition","createSmartActionRegistry","hasDataSource","resolveParams","paramDefs","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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"}
|