@bmsuisse/ui 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BMS Suisse
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # @bmsuisse/ui
2
+
3
+ Shared shadcn/ui-based React primitives and composed UI patterns: `Modal`,
4
+ `ConfirmDialog`, `FormModal`, `FormField`, `AlertBox`, `StatusBadge`,
5
+ `LoadingSpinner`/`LoadingOverlay`, `Combobox`, plus base primitives
6
+ (`Button`, `Input`, `Dialog`, `Popover`, `Select`, `Sheet`, `Tooltip`, …).
7
+
8
+ ## Install
9
+
10
+ ```
11
+ npm install @bmsuisse/ui
12
+ ```
13
+
14
+ Peer dependencies: `react` and `react-dom` (`^18` or `^19`).
15
+
16
+ ## Usage
17
+
18
+ ```tsx
19
+ import { Button, FormField, AlertBox } from "@bmsuisse/ui";
20
+
21
+ function Example() {
22
+ return (
23
+ <FormField label="Name">
24
+ <input />
25
+ </FormField>
26
+ );
27
+ }
28
+ ```
29
+
30
+ See [AGENTS.md](../../AGENTS.md) for the full design rationale, and
31
+ `packages/ui/demo` for a runnable example of every component.
32
+
33
+ ## License
34
+
35
+ [MIT](LICENSE)
@@ -0,0 +1,416 @@
1
+ import * as react from 'react';
2
+ import { ButtonHTMLAttributes, InputHTMLAttributes, LabelHTMLAttributes, TextareaHTMLAttributes, HTMLAttributes, ReactElement, ComponentPropsWithoutRef, TdHTMLAttributes, ThHTMLAttributes, ReactNode, ComponentProps } from 'react';
3
+ import * as class_variance_authority_types from 'class-variance-authority/types';
4
+ import { VariantProps } from 'class-variance-authority';
5
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
6
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
7
+ import * as SelectPrimitive from '@radix-ui/react-select';
8
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
9
+ import * as SwitchPrimitive from '@radix-ui/react-switch';
10
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
11
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
12
+ import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
13
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
14
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
15
+ import { ClassValue } from 'clsx';
16
+
17
+ declare const buttonVariants: (props?: ({
18
+ variant?: "default" | "outline" | "ghost" | "destructive" | "secondary" | "link" | "swiss-primary" | "swiss-secondary" | null | undefined;
19
+ size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
20
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
21
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
22
+ asChild?: boolean;
23
+ }
24
+ declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
25
+
26
+ type InputProps = InputHTMLAttributes<HTMLInputElement>;
27
+ declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
28
+
29
+ declare const Label: react.ForwardRefExoticComponent<LabelHTMLAttributes<HTMLLabelElement> & react.RefAttributes<HTMLLabelElement>>;
30
+
31
+ type TextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement>;
32
+ declare const Textarea: react.ForwardRefExoticComponent<TextareaProps & react.RefAttributes<HTMLTextAreaElement>>;
33
+
34
+ declare const Card: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
35
+ declare const CardHeader: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
36
+ declare const CardTitle: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
37
+ declare const CardDescription: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
38
+ declare const CardContent: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
39
+ declare const CardFooter: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
40
+
41
+ declare const badgeVariants: (props?: ({
42
+ variant?: "default" | "outline" | "destructive" | "secondary" | "warning" | null | undefined;
43
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
44
+ interface BadgeProps extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
45
+ }
46
+ declare const Badge: ({ className, variant, ...props }: BadgeProps) => ReactElement;
47
+
48
+ declare const Dialog: react.FC<DialogPrimitive.DialogProps>;
49
+ declare const DialogTrigger: react.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & react.RefAttributes<HTMLButtonElement>>;
50
+ declare const DialogContent: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
51
+ showCloseButton?: boolean;
52
+ /** data-testid for the built-in header close button, since it renders no DOM a caller controls directly. */
53
+ closeButtonTestId?: string;
54
+ } & react.RefAttributes<HTMLDivElement>>;
55
+ declare const DialogHeader: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
56
+ declare const DialogTitle: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & react.RefAttributes<HTMLHeadingElement>, "ref"> & react.RefAttributes<HTMLHeadingElement>>;
57
+ declare const DialogDescription: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>, "ref"> & react.RefAttributes<HTMLParagraphElement>>;
58
+ declare const DialogFooter: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
59
+
60
+ declare const Popover: react.FC<PopoverPrimitive.PopoverProps>;
61
+ declare const PopoverTrigger: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & react.RefAttributes<HTMLButtonElement>>;
62
+ declare const PopoverAnchor: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & react.RefAttributes<HTMLDivElement>>;
63
+ declare const PopoverContent: react.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
64
+ /** Portal target for the popover content. Defaults to `document.body` (Radix's
65
+ * own default) when omitted. Needed when the popover is opened from inside a
66
+ * modal Dialog/Sheet: Radix's Dialog `FocusScope` traps focus within its own
67
+ * content subtree, and a popover portaled to `document.body` sits outside that
68
+ * subtree — so pass the Dialog/Sheet content element here to portal into it
69
+ * instead. */
70
+ container?: ComponentPropsWithoutRef<typeof PopoverPrimitive.Portal>["container"];
71
+ } & react.RefAttributes<HTMLDivElement>>;
72
+
73
+ declare const Select: react.FC<SelectPrimitive.SelectProps>;
74
+ declare const SelectGroup: react.ForwardRefExoticComponent<SelectPrimitive.SelectGroupProps & react.RefAttributes<HTMLDivElement>>;
75
+ declare const SelectValue: react.ForwardRefExoticComponent<SelectPrimitive.SelectValueProps & react.RefAttributes<HTMLSpanElement>>;
76
+ interface SelectTriggerProps extends ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> {
77
+ size?: "sm" | "default";
78
+ }
79
+ declare const SelectTrigger: react.ForwardRefExoticComponent<SelectTriggerProps & react.RefAttributes<HTMLButtonElement>>;
80
+ declare const SelectContent: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
81
+ declare const SelectItem: react.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
82
+
83
+ declare const Skeleton: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
84
+
85
+ declare const Checkbox: react.ForwardRefExoticComponent<Omit<CheckboxPrimitive.CheckboxProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
86
+
87
+ interface SwitchProps extends ComponentPropsWithoutRef<typeof SwitchPrimitive.Root> {
88
+ size?: "sm" | "default";
89
+ }
90
+ declare const Switch: react.ForwardRefExoticComponent<SwitchProps & react.RefAttributes<HTMLButtonElement>>;
91
+
92
+ declare const Tabs: react.ForwardRefExoticComponent<TabsPrimitive.TabsProps & react.RefAttributes<HTMLDivElement>>;
93
+ declare const TabsList: react.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsListProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
94
+ declare const TabsTrigger: react.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsTriggerProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
95
+ declare const TabsContent: react.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
96
+
97
+ declare const Separator: react.ForwardRefExoticComponent<Omit<SeparatorPrimitive.SeparatorProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
98
+
99
+ declare const ScrollBar: react.ForwardRefExoticComponent<Omit<ScrollAreaPrimitive.ScrollAreaScrollbarProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
100
+ declare const ScrollArea: react.ForwardRefExoticComponent<Omit<ScrollAreaPrimitive.ScrollAreaProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
101
+
102
+ declare const Table: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableElement> & react.RefAttributes<HTMLTableElement>>;
103
+ declare const TableHeader: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableSectionElement> & react.RefAttributes<HTMLTableSectionElement>>;
104
+ declare const TableBody: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableSectionElement> & react.RefAttributes<HTMLTableSectionElement>>;
105
+ declare const TableFooter: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableSectionElement> & react.RefAttributes<HTMLTableSectionElement>>;
106
+ declare const TableRow: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableRowElement> & react.RefAttributes<HTMLTableRowElement>>;
107
+ declare const TableHead: react.ForwardRefExoticComponent<ThHTMLAttributes<HTMLTableCellElement> & react.RefAttributes<HTMLTableCellElement>>;
108
+ declare const TableCell: react.ForwardRefExoticComponent<TdHTMLAttributes<HTMLTableCellElement> & react.RefAttributes<HTMLTableCellElement>>;
109
+ declare const TableCaption: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableCaptionElement> & react.RefAttributes<HTMLTableCaptionElement>>;
110
+
111
+ declare const DropdownMenu: react.FC<DropdownMenuPrimitive.DropdownMenuProps>;
112
+ declare const DropdownMenuTrigger: react.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuTriggerProps & react.RefAttributes<HTMLButtonElement>>;
113
+ declare const DropdownMenuGroup: react.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuGroupProps & react.RefAttributes<HTMLDivElement>>;
114
+ declare const DropdownMenuPortal: react.FC<DropdownMenuPrimitive.DropdownMenuPortalProps>;
115
+ declare const DropdownMenuSub: react.FC<DropdownMenuPrimitive.DropdownMenuSubProps>;
116
+ declare const DropdownMenuRadioGroup: react.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuRadioGroupProps & react.RefAttributes<HTMLDivElement>>;
117
+ declare const DropdownMenuContent: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
118
+ declare const DropdownMenuItem: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
119
+ danger?: boolean;
120
+ } & react.RefAttributes<HTMLDivElement>>;
121
+ declare const DropdownMenuCheckboxItem: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuCheckboxItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
122
+ declare const DropdownMenuRadioItem: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuRadioItemProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
123
+ declare const DropdownMenuSeparator: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSeparatorProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
124
+ declare const DropdownMenuLabel: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuLabelProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
125
+ declare const DropdownMenuShortcut: ({ className, ...props }: HTMLAttributes<HTMLSpanElement>) => react.JSX.Element;
126
+ declare const DropdownMenuSubTrigger: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubTriggerProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
127
+ declare const DropdownMenuSubContent: react.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
128
+
129
+ declare const Sheet: react.FC<DialogPrimitive.DialogProps>;
130
+ declare const SheetTrigger: react.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & react.RefAttributes<HTMLButtonElement>>;
131
+ declare const SheetClose: react.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & react.RefAttributes<HTMLButtonElement>>;
132
+ declare const SheetPortal: react.FC<DialogPrimitive.DialogPortalProps>;
133
+ declare const sheetVariants: (props?: ({
134
+ side?: "top" | "right" | "bottom" | "left" | null | undefined;
135
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
136
+ interface SheetContentProps extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheetVariants> {
137
+ }
138
+ declare const SheetContent: react.ForwardRefExoticComponent<SheetContentProps & react.RefAttributes<HTMLDivElement>>;
139
+ declare const SheetHeader: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
140
+ declare const SheetFooter: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
141
+ declare const SheetTitle: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & react.RefAttributes<HTMLHeadingElement>, "ref"> & react.RefAttributes<HTMLHeadingElement>>;
142
+ declare const SheetDescription: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>, "ref"> & react.RefAttributes<HTMLParagraphElement>>;
143
+
144
+ declare const TooltipProvider: react.FC<TooltipPrimitive.TooltipProviderProps>;
145
+ declare const Tooltip: react.FC<TooltipPrimitive.TooltipProps>;
146
+ declare const TooltipTrigger: react.ForwardRefExoticComponent<TooltipPrimitive.TooltipTriggerProps & react.RefAttributes<HTMLButtonElement>>;
147
+ declare const TooltipContent: react.ForwardRefExoticComponent<Omit<TooltipPrimitive.TooltipContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
148
+
149
+ interface ModalProps {
150
+ /** Whether the modal is open. Modal is fully controlled — no internal open state. */
151
+ open: boolean;
152
+ /** Called when Radix wants to change the open state (backdrop click, Esc, close button). */
153
+ onOpenChange: (open: boolean) => void;
154
+ /** Dialog title, rendered in `DialogTitle`. */
155
+ title: string;
156
+ /** Optional supporting copy, rendered in `DialogDescription` under the title. */
157
+ description?: string;
158
+ /** Body content of the modal. */
159
+ children: ReactNode;
160
+ /** Optional footer content (typically action buttons), rendered in `DialogFooter`. */
161
+ footer?: ReactNode;
162
+ /** Extra classes applied to `DialogContent`, e.g. to override the default width. */
163
+ className?: string;
164
+ }
165
+ /**
166
+ * Base structural wrapper around the `@bmsuisse/ui` Dialog primitives: title,
167
+ * optional description, body, and an optional footer. Use this directly for
168
+ * modals that don't fit `ConfirmDialog` or `FormModal`; those two are built
169
+ * on top of the same shape.
170
+ */
171
+ declare const Modal: ({ open, onOpenChange, title, description, children, footer, className, }: ModalProps) => ReactElement;
172
+
173
+ interface ConfirmDialogProps {
174
+ /** Whether the dialog is open. Fully controlled — no internal open state. */
175
+ open: boolean;
176
+ /** Called when Radix wants to change the open state (backdrop click, Esc, close button). */
177
+ onOpenChange: (open: boolean) => void;
178
+ /** Dialog title. */
179
+ title: string;
180
+ /** Optional supporting copy shown under the title. */
181
+ description?: string;
182
+ /** Label for the confirm button. Defaults to `"Confirm"`. */
183
+ confirmLabel?: string;
184
+ /** Label for the cancel button. Defaults to `"Cancel"`. */
185
+ cancelLabel?: string;
186
+ /** Called when the user clicks confirm. May return a promise; the dialog waits for it. */
187
+ onConfirm: () => void | Promise<void>;
188
+ /** Visual style of the confirm button. Defaults to `"default"`. */
189
+ variant?: "default" | "destructive";
190
+ /** Forwarded to the confirm button, for test targeting (e.g. Playwright/Testing Library). */
191
+ confirmTestId?: string;
192
+ /** Forwarded to the cancel button, for test targeting. */
193
+ cancelTestId?: string;
194
+ }
195
+ /**
196
+ * "Are you sure?" confirmation dialog. Unlike `FormModal`, this DOES close
197
+ * itself automatically after a successful `onConfirm` — confirmations are a
198
+ * single yes/no action with no follow-up state to inspect, so there's nothing
199
+ * for the caller to decide. If `onConfirm` throws/rejects, the dialog stays
200
+ * open and the error is not swallowed, so a caller can surface its own error
201
+ * UI without the dialog disappearing out from under it.
202
+ */
203
+ declare const ConfirmDialog: ({ open, onOpenChange, title, description, confirmLabel, cancelLabel, onConfirm, variant, confirmTestId, cancelTestId, }: ConfirmDialogProps) => ReactElement;
204
+
205
+ interface FormModalProps {
206
+ /** Whether the modal is open. Fully controlled — no internal open state. */
207
+ open: boolean;
208
+ /** Called when Radix wants to change the open state (backdrop click, Esc, close button). */
209
+ onOpenChange: (open: boolean) => void;
210
+ /** Dialog title. */
211
+ title: string;
212
+ /** Optional supporting copy shown under the title. */
213
+ description?: string;
214
+ /** Form field content, rendered inside the `<form>`. */
215
+ children: ReactNode;
216
+ /** Called on submit (button click or Enter in a field). May return a promise. */
217
+ onSubmit: () => void | Promise<void>;
218
+ /** Label for the submit button. Defaults to `"Save"`. */
219
+ submitLabel?: string;
220
+ /** Label for the cancel button. Defaults to `"Cancel"`. */
221
+ cancelLabel?: string;
222
+ /**
223
+ * Disables the submit button (e.g. required fields still empty), on top of
224
+ * the automatic disable while `onSubmit`'s promise is pending. Cancel
225
+ * stays enabled either way. Defaults to `false`.
226
+ */
227
+ submitDisabled?: boolean;
228
+ /** Extra classes applied to `DialogContent`, e.g. to override the default width. */
229
+ className?: string;
230
+ /** Forwarded to the submit button, for test targeting (e.g. Playwright/Testing Library). */
231
+ submitTestId?: string;
232
+ /** Forwarded to the cancel button, for test targeting. */
233
+ cancelTestId?: string;
234
+ }
235
+ /**
236
+ * Modal wrapping a form. Unlike `ConfirmDialog`, this does NOT close itself
237
+ * after a successful `onSubmit` — forms commonly have server-side validation
238
+ * and shouldn't vanish on failure, so closing after success is left entirely
239
+ * to the caller (typically by calling `onOpenChange(false)` once its own
240
+ * submit handler resolves without error).
241
+ */
242
+ declare const FormModal: ({ open, onOpenChange, title, description, children, onSubmit, submitLabel, cancelLabel, submitDisabled, className, submitTestId, cancelTestId, }: FormModalProps) => ReactElement;
243
+
244
+ interface FormFieldProps {
245
+ /** Visible label text for the field. */
246
+ label: string;
247
+ /** Explicit id to associate the label with the child control. Auto-generated when omitted. */
248
+ htmlFor?: string;
249
+ /** Validation error text. When set, takes precedence over `description` and marks the child as invalid. */
250
+ error?: string;
251
+ /** Helper text shown below the child control when there's no `error`. */
252
+ description?: string;
253
+ /** Renders a visual "required" indicator next to the label. */
254
+ required?: boolean;
255
+ /** The single form control (e.g. `Input`, `Textarea`, `Select`) this field wraps. */
256
+ children: ReactElement;
257
+ /** Additional class names for the outer wrapper. */
258
+ className?: string;
259
+ }
260
+ /**
261
+ * Wraps a single form control with a `Label`, optional required indicator, and
262
+ * either an `error` or `description` message — the "label + input + error"
263
+ * pattern used throughout the consuming apps' forms.
264
+ *
265
+ * Handles id plumbing automatically: generates a stable id (via `useId`) for
266
+ * the label/control pair unless `htmlFor` or the child's own `id` is set, and
267
+ * wires up `aria-invalid` / `aria-describedby` so the error or description
268
+ * text is announced by assistive tech.
269
+ */
270
+ declare function FormField({ label, htmlFor, error, description, required, children, className, }: FormFieldProps): ReactElement;
271
+
272
+ interface ComboboxOption {
273
+ value: string;
274
+ label: string;
275
+ disabled?: boolean;
276
+ /** Groups this option under a header with the given key, rendered as a bold label
277
+ * (plus a tri-state "select all" checkbox in multi-select mode — see `groupLabels`
278
+ * on the base props). Options sharing a `group` must be contiguous in `options` —
279
+ * the component renders a header the first time a group key is seen and does not
280
+ * re-sort the list, so interleaved groups would render more than one header for the
281
+ * same key. Ungrouped options (no `group`) render individually, with no header. */
282
+ group?: string;
283
+ }
284
+ interface ComboboxBaseProps {
285
+ /** The full option list. Filtering happens client-side against `label`. */
286
+ options: ComboboxOption[];
287
+ /** Trigger text shown when nothing is selected. Defaults to `"Select…"`. */
288
+ placeholder?: string;
289
+ /** Placeholder for the search input inside the popover. Defaults to `"Search…"`. */
290
+ searchPlaceholder?: string;
291
+ /** Shown when the search term matches nothing. Defaults to `"No matches."`. */
292
+ emptyMessage?: string;
293
+ disabled?: boolean;
294
+ /** Shows `loadingMessage` on the trigger instead of the placeholder/selection, and
295
+ * disables the trigger and clear affordance alongside `disabled`. For a combobox whose
296
+ * `options` are still being fetched. Defaults to `false`. */
297
+ loading?: boolean;
298
+ /** Trigger text shown while `loading` is true. Defaults to `"Loading…"`. */
299
+ loadingMessage?: string;
300
+ /** Shows a clear ("x") affordance on the trigger when a value is selected. Defaults to `true`. */
301
+ clearable?: boolean;
302
+ className?: string;
303
+ id?: string;
304
+ /** Forwarded to the trigger button, for test targeting (e.g. Playwright/Testing Library). */
305
+ "data-testid"?: string;
306
+ /** Display label for a group key (`ComboboxOption.group`). Falls back to the raw key
307
+ * when an entry is missing. Only relevant when at least one option sets `group`. */
308
+ groupLabels?: Record<string, string>;
309
+ /** Portal target for the popover, forwarded to the underlying `PopoverContent`.
310
+ * Needed when the combobox is opened from inside a modal Dialog/Sheet — pass the
311
+ * Dialog/Sheet content element so the popover portals inside it instead of
312
+ * `document.body`, which would otherwise fight with the Dialog's focus trap. */
313
+ container?: ComponentProps<typeof PopoverContent>["container"];
314
+ /** Switches the search input to server-driven mode: called with the raw search
315
+ * text on every keystroke (and with `""` when the popover opens), and `options`
316
+ * is rendered as-is instead of being filtered locally against `label`. Omit for
317
+ * the default client-side filtering behavior. */
318
+ onSearchChange?: (search: string) => void;
319
+ /** Fallback trigger label used when the current selection's `value`(s) aren't
320
+ * present in `options` — the case in server-driven search mode where the
321
+ * selected option was found by an earlier query and isn't part of the current
322
+ * result page. Ignored once a matching option is found in `options`. */
323
+ selectedLabel?: string;
324
+ }
325
+ interface ComboboxSingleProps extends ComboboxBaseProps {
326
+ /** Omitted or `false` for the (default) single-select shape below. */
327
+ multiple?: false;
328
+ /** Selected option's `value`, or `null`/`undefined` for no selection. */
329
+ value?: string | null;
330
+ /** Called with the newly selected option's `value`, or `null` when cleared. */
331
+ onChange: (value: string | null) => void;
332
+ }
333
+ interface ComboboxMultiProps extends ComboboxBaseProps {
334
+ /** `true` selects the multi-select shape below. */
335
+ multiple: true;
336
+ /** Selected options' `value`s. */
337
+ value: string[];
338
+ /** Called with the full updated selection after a toggle, or `[]` when cleared. */
339
+ onChange: (value: string[]) => void;
340
+ }
341
+ /**
342
+ * Discriminated on `multiple`: the default (omitted/`false`) shape is the
343
+ * original single-select API, unchanged (`value: string | null`); passing
344
+ * `multiple: true` switches to the array-valued shape (`value: string[]`).
345
+ */
346
+ type ComboboxProps = ComboboxSingleProps | ComboboxMultiProps;
347
+ /**
348
+ * A searchable dropdown ("autocomplete box"), single- or multi-select
349
+ * depending on the `multiple` prop: a button trigger showing the current
350
+ * selection, opening a popover with a text filter above a scrollable option
351
+ * list. Deliberately built on the existing `Popover` + `Input` primitives
352
+ * rather than a `cmdk`-based `Command` component — this mirrors
353
+ * `@bmsuisse/datagrid`'s `EnumFilter` (plain substring filter over a manually
354
+ * rendered list), keeping the dependency footprint the same as the rest of
355
+ * this package instead of introducing a new list/command library.
356
+ */
357
+ declare function Combobox(props: ComboboxProps): ReactElement;
358
+
359
+ type AlertBoxVariant = "error" | "warning" | "info" | "success";
360
+ interface AlertBoxProps {
361
+ /** Determines the color scheme and the default icon. */
362
+ variant: AlertBoxVariant;
363
+ /** Optional bold heading line shown above the body content. */
364
+ title?: string;
365
+ /** Body text/content. Always rendered. */
366
+ children: ReactNode;
367
+ className?: string;
368
+ /**
369
+ * Overrides the default variant icon entirely. Pass `null` to hide the
370
+ * icon. Defaults to a variant-specific lucide-react icon.
371
+ */
372
+ icon?: ReactNode;
373
+ }
374
+ declare const AlertBox: ({ variant, title, children, className, icon }: AlertBoxProps) => ReactElement;
375
+
376
+ /** Semantic color intent for a {@link StatusBadge}. */
377
+ type StatusTone = "success" | "warning" | "error" | "info" | "neutral";
378
+ interface StatusBadgeProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
379
+ /** Raw status value from the caller's domain, e.g. `"pending"`, `"APPROVED"`, `"in_review"`. */
380
+ status: string;
381
+ /** Overrides the displayed text. Defaults to a title-cased, space-separated derivation of `status`. */
382
+ label?: string;
383
+ /** Explicit tone override. When provided, `toneMap` and the built-in default map are skipped entirely. */
384
+ tone?: StatusTone;
385
+ /** Caller-supplied status-to-tone mapping (case-insensitive keys), checked before the built-in default map. */
386
+ toneMap?: Record<string, StatusTone>;
387
+ }
388
+ /**
389
+ * A status-to-color badge, built on the shared `Badge` primitive.
390
+ *
391
+ * Centralizes the status->color mapping that's otherwise reimplemented ad hoc
392
+ * per app: callers can rely on the built-in English status vocabulary, supply
393
+ * their own `toneMap` for domain-specific statuses, or force a `tone`
394
+ * outright.
395
+ */
396
+ declare const StatusBadge: ({ status, label, tone, toneMap, className, ...props }: StatusBadgeProps) => ReactElement;
397
+
398
+ declare const loadingSpinnerIconVariants: (props?: ({
399
+ size?: "default" | "sm" | "lg" | null | undefined;
400
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
401
+ interface LoadingSpinnerProps extends HTMLAttributes<HTMLSpanElement>, VariantProps<typeof loadingSpinnerIconVariants> {
402
+ /** Optional text rendered next to the spinner. Omitted entirely renders an icon-only spinner. */
403
+ label?: string;
404
+ }
405
+ /** Inline loading indicator: a spinning icon with an optional label, e.g. `<LoadingSpinner label="Saving…" />`. */
406
+ declare const LoadingSpinner: ({ size, label, className, ...props }: LoadingSpinnerProps) => ReactElement;
407
+ interface LoadingOverlayProps extends HTMLAttributes<HTMLDivElement>, Pick<LoadingSpinnerProps, "label"> {
408
+ size?: LoadingSpinnerProps["size"];
409
+ }
410
+ /** Centers a larger `LoadingSpinner` inside a full container/page — use as a route or panel loading state. */
411
+ declare const LoadingOverlay: ({ size, label, className, ...props }: LoadingOverlayProps) => ReactElement;
412
+
413
+ /** Merges conditional class names, then dedupes conflicting Tailwind utility classes. */
414
+ declare function cn(...inputs: ClassValue[]): string;
415
+
416
+ export { AlertBox, type AlertBoxProps, type AlertBoxVariant, Badge, type BadgeProps, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Combobox, type ComboboxMultiProps, type ComboboxOption, type ComboboxProps, type ComboboxSingleProps, ConfirmDialog, type ConfirmDialogProps, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FormField, type FormFieldProps, FormModal, type FormModalProps, Input, type InputProps, Label, LoadingOverlay, type LoadingOverlayProps, LoadingSpinner, type LoadingSpinnerProps, Modal, type ModalProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, type SelectTriggerProps, SelectValue, Separator, Sheet, SheetClose, SheetContent, type SheetContentProps, SheetDescription, SheetFooter, SheetHeader, SheetPortal, SheetTitle, SheetTrigger, Skeleton, StatusBadge, type StatusBadgeProps, type StatusTone, Switch, type SwitchProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, cn, loadingSpinnerIconVariants, sheetVariants };