@bmsuisse/ui 0.7.0 → 0.11.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 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-4xl";
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;
@@ -356,6 +428,67 @@ type ComboboxProps = ComboboxSingleProps | ComboboxMultiProps;
356
428
  */
357
429
  declare function Combobox(props: ComboboxProps): ReactElement;
358
430
 
431
+ interface TagComboboxOption {
432
+ value: string;
433
+ label: string;
434
+ disabled?: boolean;
435
+ /** Groups this option under a header with the given key, rendered as a bold label
436
+ * plus a tri-state "select all" checkbox (unchecked/checked/indeterminate, reflecting
437
+ * how many of the group's members are selected — toggling it selects or clears the
438
+ * whole group). Options sharing a `group` must be contiguous in `options` — see
439
+ * `Combobox`'s own `group` doc for the same constraint and the reasoning behind it. */
440
+ group?: string;
441
+ }
442
+ interface TagComboboxProps {
443
+ /** The full option list. Filtering happens client-side against `label`,
444
+ * unless `onSearchChange` is given (see below). */
445
+ options: TagComboboxOption[];
446
+ /** Selected options' `value`s. */
447
+ value: string[];
448
+ /** Called with the full updated selection after a toggle or a chip removal. */
449
+ onChange: (value: string[]) => void;
450
+ /** Shown in the field when nothing is selected and nothing is typed. Defaults to `"Select…"`. */
451
+ placeholder?: string;
452
+ /** Shown when the search term matches nothing. Defaults to `"No matches."`. */
453
+ emptyMessage?: string;
454
+ disabled?: boolean;
455
+ /** Shows `loadingMessage` in the option list instead of `emptyMessage`, for a
456
+ * combobox whose `options` are still being fetched (e.g. a server search whose
457
+ * request hasn't resolved yet). Defaults to `false`. */
458
+ loading?: boolean;
459
+ /** Message shown in the option list while `loading` is true. Defaults to `"Loading…"`. */
460
+ loadingMessage?: string;
461
+ className?: string;
462
+ id?: string;
463
+ /** Forwarded to the field, for test targeting (e.g. Playwright/Testing Library). */
464
+ "data-testid"?: string;
465
+ /** Switches the search input to server-driven mode: called with the raw search
466
+ * text on every keystroke, and `options` is rendered as-is instead of being
467
+ * filtered locally against `label`. Omit for the default client-side filtering
468
+ * behavior — see `Combobox`'s own `onSearchChange` for the same contract. */
469
+ onSearchChange?: (search: string) => void;
470
+ /** Portal target for the popover, forwarded to the underlying `PopoverContent`.
471
+ * Needed when the combobox is opened from inside a modal Dialog/Sheet — pass the
472
+ * Dialog/Sheet content element so the popover portals inside it instead of
473
+ * `document.body`, which would otherwise fight with the Dialog's focus trap. */
474
+ container?: ComponentProps<typeof PopoverContent>["container"];
475
+ /** Display label for a group key (`TagComboboxOption.group`). Falls back to the raw
476
+ * key when an entry is missing. Only relevant when at least one option sets `group`. */
477
+ groupLabels?: Record<string, string>;
478
+ }
479
+ /**
480
+ * A tags-and-search multi-select: selected options render as removable chips
481
+ * inline inside one bordered field, with a search input immediately after
482
+ * the last chip. Typing opens a popover listing matches below the field;
483
+ * picking one adds a chip right where the caret was and clears the search
484
+ * term so the user can keep typing. Complements `Combobox`'s `multiple`
485
+ * mode (a trigger button + a summary count) for the case where every
486
+ * individual selection needs to stay visible and removable at a glance —
487
+ * built on the same `Popover`/keyboard-nav shape rather than forking it,
488
+ * so both patterns share one mental model.
489
+ */
490
+ declare function TagCombobox({ options, value, onChange, placeholder, emptyMessage, disabled, loading, loadingMessage, className, id, onSearchChange, container, groupLabels, ...rest }: TagComboboxProps): ReactElement;
491
+
359
492
  type AlertBoxVariant = "error" | "warning" | "info" | "success";
360
493
  interface AlertBoxProps {
361
494
  /** Determines the color scheme and the default icon. */
@@ -572,4 +705,10 @@ declare function useSidebarCollapsed(): boolean;
572
705
  /** Merges conditional class names, then dedupes conflicting Tailwind utility classes. */
573
706
  declare function cn(...inputs: ClassValue[]): string;
574
707
 
575
- 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 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, NavGroup, type NavGroupProps, type NavIconProps, NavItem, type NavItemProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ScrollArea, ScrollBar, SearchBar, type SearchBarProps, 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, 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, useSidebarCollapsed };
708
+ /**
709
+ * Tracks whether a `matchMedia` query currently matches, updating on change.
710
+ * Used to switch between desktop/mobile layouts (see `ResponsivePanel`).
711
+ */
712
+ declare function useMediaQuery(query: string): boolean;
713
+
714
+ 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 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, NavGroup, type NavGroupProps, type NavIconProps, NavItem, type NavItemProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ResponsivePanel, type ResponsivePanelProps, type ResponsivePanelSize, ScrollArea, ScrollBar, SearchBar, type SearchBarProps, 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, 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 };