@bmsuisse/ui 0.8.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +216 -4
- package/dist/index.js +930 -152
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -134,6 +134,13 @@ declare const sheetVariants: (props?: ({
|
|
|
134
134
|
side?: "top" | "right" | "bottom" | "left" | null | undefined;
|
|
135
135
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
136
136
|
interface SheetContentProps extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheetVariants> {
|
|
137
|
+
/**
|
|
138
|
+
* Bottom sheets only: adds a drag handle so the user can pull the sheet
|
|
139
|
+
* taller (up to 95% of the viewport) or shorter (down to 30%) with the
|
|
140
|
+
* mouse/touch instead of being stuck with the height set by className.
|
|
141
|
+
* Ignored for other sides.
|
|
142
|
+
*/
|
|
143
|
+
resizable?: boolean;
|
|
137
144
|
}
|
|
138
145
|
declare const SheetContent: react.ForwardRefExoticComponent<SheetContentProps & react.RefAttributes<HTMLDivElement>>;
|
|
139
146
|
declare const SheetHeader: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
|
|
@@ -241,6 +248,71 @@ interface FormModalProps {
|
|
|
241
248
|
*/
|
|
242
249
|
declare const FormModal: ({ open, onOpenChange, title, description, children, onSubmit, submitLabel, cancelLabel, submitDisabled, className, submitTestId, cancelTestId, }: FormModalProps) => ReactElement;
|
|
243
250
|
|
|
251
|
+
declare const desktopSizeClasses: {
|
|
252
|
+
readonly sm: "max-w-md";
|
|
253
|
+
readonly md: "max-w-xl";
|
|
254
|
+
readonly lg: "max-w-2xl";
|
|
255
|
+
readonly xl: "max-w-7xl";
|
|
256
|
+
};
|
|
257
|
+
type ResponsivePanelSize = keyof typeof desktopSizeClasses;
|
|
258
|
+
interface ResponsivePanelProps {
|
|
259
|
+
/** Whether the panel is open. Fully controlled — no internal open state. */
|
|
260
|
+
open: boolean;
|
|
261
|
+
/** Called when Radix wants to change the open state (backdrop click, Esc, close button). */
|
|
262
|
+
onOpenChange: (open: boolean) => void;
|
|
263
|
+
/** Panel title. */
|
|
264
|
+
title: string;
|
|
265
|
+
/** Optional supporting copy shown under the title. */
|
|
266
|
+
description?: string;
|
|
267
|
+
/** Body content of the panel. */
|
|
268
|
+
children: ReactNode;
|
|
269
|
+
/** Optional footer content (typically action buttons). */
|
|
270
|
+
footer?: ReactNode;
|
|
271
|
+
/** Extra classes applied to the panel content, e.g. to override the default width/height. */
|
|
272
|
+
className?: string;
|
|
273
|
+
/**
|
|
274
|
+
* `matchMedia` query that decides desktop vs. mobile layout. Defaults to
|
|
275
|
+
* Tailwind's `lg` breakpoint, matching the rest of `@bmsuisse/ui`'s responsive patterns.
|
|
276
|
+
*/
|
|
277
|
+
breakpoint?: string;
|
|
278
|
+
/**
|
|
279
|
+
* Panel size, `sm`/`md`/`lg` (default)/`xl`. On desktop this is the dialog
|
|
280
|
+
* width (`max-w-md`/`max-w-xl`/`max-w-2xl`/`max-w-4xl`); on mobile — where
|
|
281
|
+
* width is always full-bleed — it's the drawer's max height instead
|
|
282
|
+
* (`50vh`/`70vh`/`90vh`/`96vh`).
|
|
283
|
+
*/
|
|
284
|
+
size?: ResponsivePanelSize;
|
|
285
|
+
/**
|
|
286
|
+
* Adds drag handles so the user can resize the panel with the mouse:
|
|
287
|
+
* on desktop, a grip on all four corners (each anchors the opposite
|
|
288
|
+
* corner, so `size` just becomes the starting size); on the mobile
|
|
289
|
+
* drawer, a handle at the top (drags height between 30vh and 95vh).
|
|
290
|
+
* Default `false`.
|
|
291
|
+
*/
|
|
292
|
+
resizable?: boolean;
|
|
293
|
+
/**
|
|
294
|
+
* Desktop only: lets the user drag the panel by its header to reposition
|
|
295
|
+
* it anywhere in the viewport. Default `false`. No effect on the mobile
|
|
296
|
+
* drawer, which is always docked to the bottom.
|
|
297
|
+
*/
|
|
298
|
+
draggable?: boolean;
|
|
299
|
+
/**
|
|
300
|
+
* Whether clicking/tapping outside the panel closes it. Default `true`.
|
|
301
|
+
* When `false`, only the header's close button (and Esc) can close it —
|
|
302
|
+
* use this for panels guarding unsaved work the user shouldn't lose to a
|
|
303
|
+
* stray click.
|
|
304
|
+
*/
|
|
305
|
+
closeOnOutsideClick?: boolean;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Like `Modal`, but uses the extra desktop space instead of a fixed small
|
|
309
|
+
* dialog, and becomes a native bottom-sheet drawer below `breakpoint` — a
|
|
310
|
+
* centered floating box with its own scroll region reads as a leftover
|
|
311
|
+
* desktop shape on a phone. Use this over `Modal` for content that benefits
|
|
312
|
+
* from more room (multi-section forms, longer lists) on both form factors.
|
|
313
|
+
*/
|
|
314
|
+
declare const ResponsivePanel: ({ open, onOpenChange, title, description, children, footer, className, breakpoint, size, resizable, draggable, closeOnOutsideClick, }: ResponsivePanelProps) => ReactElement;
|
|
315
|
+
|
|
244
316
|
interface FormFieldProps {
|
|
245
317
|
/** Visible label text for the field. */
|
|
246
318
|
label: string;
|
|
@@ -269,6 +341,15 @@ interface FormFieldProps {
|
|
|
269
341
|
*/
|
|
270
342
|
declare function FormField({ label, htmlFor, error, description, required, children, className, }: FormFieldProps): ReactElement;
|
|
271
343
|
|
|
344
|
+
/** A column shown in a grid-style option popup (see `renderGridOptions`). `key`
|
|
345
|
+
* selects what each row shows in that column: the literal string `"label"` reads
|
|
346
|
+
* the option's own `label`, anything else reads `option.data?.[key]`. */
|
|
347
|
+
interface GridColumn {
|
|
348
|
+
key: string;
|
|
349
|
+
header: string;
|
|
350
|
+
className?: string;
|
|
351
|
+
}
|
|
352
|
+
|
|
272
353
|
interface ComboboxOption {
|
|
273
354
|
value: string;
|
|
274
355
|
label: string;
|
|
@@ -278,8 +359,13 @@ interface ComboboxOption {
|
|
|
278
359
|
* on the base props). Options sharing a `group` must be contiguous in `options` —
|
|
279
360
|
* the component renders a header the first time a group key is seen and does not
|
|
280
361
|
* 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.
|
|
362
|
+
* same key. Ungrouped options (no `group`) render individually, with no header.
|
|
363
|
+
* Ignored when `columns` is set (see that prop's own doc). */
|
|
282
364
|
group?: string;
|
|
365
|
+
/** Extra fields for this option, surfaced as additional columns when the
|
|
366
|
+
* base props' `columns` is set — e.g. `{ email: "a@b.com", role: "Admin" }`.
|
|
367
|
+
* Ignored otherwise. */
|
|
368
|
+
data?: Record<string, ReactNode>;
|
|
283
369
|
}
|
|
284
370
|
interface ComboboxBaseProps {
|
|
285
371
|
/** The full option list. Filtering happens client-side against `label`. */
|
|
@@ -321,6 +407,15 @@ interface ComboboxBaseProps {
|
|
|
321
407
|
* selected option was found by an earlier query and isn't part of the current
|
|
322
408
|
* result page. Ignored once a matching option is found in `options`. */
|
|
323
409
|
selectedLabel?: string;
|
|
410
|
+
/** Renders the popup's option list as a multi-column grid instead of a flat
|
|
411
|
+
* label list — one column per entry here, each reading either the option's
|
|
412
|
+
* own `label` (`key: "label"`) or `option.data[key]`. Useful when users need
|
|
413
|
+
* more context than a label to tell options apart (e.g. an id/email/role
|
|
414
|
+
* table instead of a bare name). Mutually exclusive with `group` — a grid
|
|
415
|
+
* row has no natural place for a group header spanning several unrelated
|
|
416
|
+
* columns, so `group` is ignored on every option while this is set. The
|
|
417
|
+
* popup grows to fit the columns (at least as wide as the trigger). */
|
|
418
|
+
columns?: GridColumn[];
|
|
324
419
|
}
|
|
325
420
|
interface ComboboxSingleProps extends ComboboxBaseProps {
|
|
326
421
|
/** Omitted or `false` for the (default) single-select shape below. */
|
|
@@ -364,8 +459,13 @@ interface TagComboboxOption {
|
|
|
364
459
|
* plus a tri-state "select all" checkbox (unchecked/checked/indeterminate, reflecting
|
|
365
460
|
* how many of the group's members are selected — toggling it selects or clears the
|
|
366
461
|
* whole group). Options sharing a `group` must be contiguous in `options` — see
|
|
367
|
-
* `Combobox`'s own `group` doc for the same constraint and the reasoning behind it.
|
|
462
|
+
* `Combobox`'s own `group` doc for the same constraint and the reasoning behind it.
|
|
463
|
+
* Ignored when `columns` is set (see that prop's own doc). */
|
|
368
464
|
group?: string;
|
|
465
|
+
/** Extra fields for this option, surfaced as additional columns when
|
|
466
|
+
* `columns` is set — e.g. `{ email: "a@b.com", role: "Admin" }`. Ignored
|
|
467
|
+
* otherwise. */
|
|
468
|
+
data?: Record<string, ReactNode>;
|
|
369
469
|
}
|
|
370
470
|
interface TagComboboxProps {
|
|
371
471
|
/** The full option list. Filtering happens client-side against `label`,
|
|
@@ -403,6 +503,10 @@ interface TagComboboxProps {
|
|
|
403
503
|
/** Display label for a group key (`TagComboboxOption.group`). Falls back to the raw
|
|
404
504
|
* key when an entry is missing. Only relevant when at least one option sets `group`. */
|
|
405
505
|
groupLabels?: Record<string, string>;
|
|
506
|
+
/** Renders the popup's option list as a multi-column grid instead of a flat
|
|
507
|
+
* label list — see `Combobox`'s own `columns` doc for the full contract
|
|
508
|
+
* (including its interaction with `group`, and the widened popup). */
|
|
509
|
+
columns?: GridColumn[];
|
|
406
510
|
}
|
|
407
511
|
/**
|
|
408
512
|
* A tags-and-search multi-select: selected options render as removable chips
|
|
@@ -415,7 +519,7 @@ interface TagComboboxProps {
|
|
|
415
519
|
* built on the same `Popover`/keyboard-nav shape rather than forking it,
|
|
416
520
|
* so both patterns share one mental model.
|
|
417
521
|
*/
|
|
418
|
-
declare function TagCombobox({ options, value, onChange, placeholder, emptyMessage, disabled, loading, loadingMessage, className, id, onSearchChange, container, groupLabels, ...rest }: TagComboboxProps): ReactElement;
|
|
522
|
+
declare function TagCombobox({ options, value, onChange, placeholder, emptyMessage, disabled, loading, loadingMessage, className, id, onSearchChange, container, groupLabels, columns, ...rest }: TagComboboxProps): ReactElement;
|
|
419
523
|
|
|
420
524
|
type AlertBoxVariant = "error" | "warning" | "info" | "success";
|
|
421
525
|
interface AlertBoxProps {
|
|
@@ -526,6 +630,108 @@ interface SearchBarProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "ty
|
|
|
526
630
|
*/
|
|
527
631
|
declare function SearchBar({ value, onChange, isLoading, onClear, clearLabel, inputRef, className, ...props }: SearchBarProps): ReactElement;
|
|
528
632
|
|
|
633
|
+
interface KpiCardProps {
|
|
634
|
+
label: string;
|
|
635
|
+
value?: string | number | null;
|
|
636
|
+
icon?: ComponentType<{
|
|
637
|
+
className?: string;
|
|
638
|
+
}>;
|
|
639
|
+
badge?: {
|
|
640
|
+
text: string;
|
|
641
|
+
positive?: boolean;
|
|
642
|
+
};
|
|
643
|
+
badgeLabel?: string;
|
|
644
|
+
/** @default "default" */
|
|
645
|
+
variant?: "hero" | "mini" | "default" | "donut";
|
|
646
|
+
loading?: boolean;
|
|
647
|
+
sub?: string;
|
|
648
|
+
/** Colors `sub` on the mini variant — "warn"/"danger" flag something worth acting on (overdue, at-risk), "default" stays muted. */
|
|
649
|
+
subTone?: "default" | "warn" | "danger";
|
|
650
|
+
/** Makes the icon (mini variant) or the whole card clickable. */
|
|
651
|
+
href?: string;
|
|
652
|
+
sparkline?: number[];
|
|
653
|
+
/** @default "var(--color-primary, #3b82f6)" */
|
|
654
|
+
sparklineColor?: string;
|
|
655
|
+
/** Hero variant only: 0-100 achievement-vs-target bar rendered under `sub`. */
|
|
656
|
+
progress?: number;
|
|
657
|
+
progressLabel?: string;
|
|
658
|
+
/** Donut variant only: the proportions to render as a ring chart, with a legend listing each segment's share. */
|
|
659
|
+
segments?: DonutSegment[];
|
|
660
|
+
/** Donut variant only: big label centered in the ring. Defaults to the sum of `segments`' values. */
|
|
661
|
+
centerValue?: string;
|
|
662
|
+
/** For E2E tests to target a specific tile unambiguously when `label` also appears elsewhere on the page (e.g. a chart legend). */
|
|
663
|
+
testId?: string;
|
|
664
|
+
}
|
|
665
|
+
interface DonutSegment {
|
|
666
|
+
label: string;
|
|
667
|
+
value: number;
|
|
668
|
+
/** @default a color from the built-in palette, cycling by index */
|
|
669
|
+
color?: string;
|
|
670
|
+
}
|
|
671
|
+
declare function DonutChart({ data, size, thickness, centerValue, centerLabel, }: {
|
|
672
|
+
data: DonutSegment[];
|
|
673
|
+
size?: number;
|
|
674
|
+
thickness?: number;
|
|
675
|
+
centerValue?: string;
|
|
676
|
+
centerLabel?: string;
|
|
677
|
+
}): ReactElement | null;
|
|
678
|
+
declare function Sparkline({ data, color }: {
|
|
679
|
+
data: number[];
|
|
680
|
+
color: string;
|
|
681
|
+
}): ReactElement | null;
|
|
682
|
+
/**
|
|
683
|
+
* Dashboard KPI tile in three variants — `hero` (large, primary-colored,
|
|
684
|
+
* for the single headline metric), `default` (bordered card for a KPI
|
|
685
|
+
* grid), and `mini` (compact, for dense grids of secondary metrics).
|
|
686
|
+
* Optionally shows a badge, a trend sparkline, and (hero only) a
|
|
687
|
+
* progress-vs-target bar.
|
|
688
|
+
*/
|
|
689
|
+
declare const KpiCard: react.NamedExoticComponent<KpiCardProps>;
|
|
690
|
+
|
|
691
|
+
interface SearchPanelMode {
|
|
692
|
+
key: string;
|
|
693
|
+
label: string;
|
|
694
|
+
icon?: ComponentType<{
|
|
695
|
+
className?: string;
|
|
696
|
+
}>;
|
|
697
|
+
}
|
|
698
|
+
interface SearchPanelProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "value" | "onChange" | "size"> {
|
|
699
|
+
value: string;
|
|
700
|
+
onChange: (value: string) => void;
|
|
701
|
+
/** Swaps the leading search icon for a spinner while a search request is in flight. */
|
|
702
|
+
isLoading?: boolean;
|
|
703
|
+
/** Extra content after the input, e.g. a mic button. */
|
|
704
|
+
trailingSlot?: ReactNode;
|
|
705
|
+
/** Keyboard-shortcut hint rendered after `trailingSlot`, e.g. `"⌘K"`. Omit to hide it. */
|
|
706
|
+
shortcutHint?: string;
|
|
707
|
+
/** Mode-switcher pills rendered below the input row (e.g. "Search" / "Ask AI"). Omit to hide the row entirely. */
|
|
708
|
+
modes?: SearchPanelMode[];
|
|
709
|
+
activeMode?: string;
|
|
710
|
+
onModeChange?: (key: string) => void;
|
|
711
|
+
/** Squares the panel's bottom corners so a results dropdown anchored directly below it reads as one continuous surface. */
|
|
712
|
+
expanded?: boolean;
|
|
713
|
+
inputRef?: Ref<HTMLInputElement>;
|
|
714
|
+
className?: string;
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Bordered search card: an input row (leading icon/spinner, input, optional
|
|
718
|
+
* trailing slot and keyboard-shortcut hint) plus an optional row of
|
|
719
|
+
* mode-switcher pills below it. Headless on results — the caller renders
|
|
720
|
+
* whatever dropdown or inline results belong under it.
|
|
721
|
+
*/
|
|
722
|
+
declare function SearchPanel({ value, onChange, isLoading, trailingSlot, shortcutHint, modes, activeMode, onModeChange, expanded, inputRef, className, ...props }: SearchPanelProps): ReactElement;
|
|
723
|
+
|
|
724
|
+
interface SearchTriggerProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
|
|
725
|
+
/** Accessible label, also used as the tooltip text by callers that wrap this in one. @default "Search" */
|
|
726
|
+
label?: string;
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Icon-only header button that opens a search overlay (a `SearchPanel`, a
|
|
730
|
+
* dropdown, a `Sheet` — this owns no state or panel of its own). For a
|
|
731
|
+
* full-width always-visible input instead, use `SearchBar`.
|
|
732
|
+
*/
|
|
733
|
+
declare function SearchTrigger({ label, ...props }: SearchTriggerProps): ReactElement;
|
|
734
|
+
|
|
529
735
|
/** Shape a `lucide-react` icon component satisfies — `NavItem` sizes and colors it itself. */
|
|
530
736
|
interface NavIconProps {
|
|
531
737
|
className?: string;
|
|
@@ -633,4 +839,10 @@ declare function useSidebarCollapsed(): boolean;
|
|
|
633
839
|
/** Merges conditional class names, then dedupes conflicting Tailwind utility classes. */
|
|
634
840
|
declare function cn(...inputs: ClassValue[]): string;
|
|
635
841
|
|
|
636
|
-
|
|
842
|
+
/**
|
|
843
|
+
* Tracks whether a `matchMedia` query currently matches, updating on change.
|
|
844
|
+
* Used to switch between desktop/mobile layouts (see `ResponsivePanel`).
|
|
845
|
+
*/
|
|
846
|
+
declare function useMediaQuery(query: string): boolean;
|
|
847
|
+
|
|
848
|
+
export { AlertBox, type AlertBoxProps, type AlertBoxVariant, Badge, type BadgeProps, Button, ButtonGroup, type ButtonGroupOption, type ButtonGroupProps, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Combobox, type GridColumn as ComboboxColumn, type ComboboxMultiProps, type ComboboxOption, type ComboboxProps, type ComboboxSingleProps, ConfirmDialog, type ConfirmDialogProps, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DonutChart, type DonutSegment, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FormField, type FormFieldProps, FormModal, type FormModalProps, Input, type InputProps, KpiCard, type KpiCardProps, Label, LoadingOverlay, type LoadingOverlayProps, LoadingSpinner, type LoadingSpinnerProps, Modal, type ModalProps, NavGroup, type NavGroupProps, type NavIconProps, NavItem, type NavItemProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ResponsivePanel, type ResponsivePanelProps, type ResponsivePanelSize, ScrollArea, ScrollBar, SearchBar, type SearchBarProps, SearchPanel, type SearchPanelMode, type SearchPanelProps, SearchTrigger, type SearchTriggerProps, Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, type SelectTriggerProps, SelectValue, Separator, Sheet, SheetClose, SheetContent, type SheetContentProps, SheetDescription, SheetFooter, SheetHeader, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarNav, type SidebarNavProps, type SidebarProps, Skeleton, Sparkline, StatusBadge, type StatusBadgeProps, type StatusTone, Switch, type SwitchProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagCombobox, type TagComboboxOption, type TagComboboxProps, Textarea, type TextareaProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, cn, loadingSpinnerIconVariants, sheetVariants, useMediaQuery, useSidebarCollapsed };
|