@boostdev/design-system-components 1.2.1 → 1.2.2

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.
Files changed (51) hide show
  1. package/AGENTS.md +21 -0
  2. package/README.md +15 -15
  3. package/dist/client.cjs +141 -120
  4. package/dist/client.css +468 -468
  5. package/dist/client.d.cts +71 -96
  6. package/dist/client.d.ts +71 -96
  7. package/dist/client.js +141 -120
  8. package/dist/index.cjs +141 -120
  9. package/dist/index.css +468 -468
  10. package/dist/index.d.cts +71 -96
  11. package/dist/index.d.ts +71 -96
  12. package/dist/index.js +141 -120
  13. package/package.json +1 -1
  14. package/src/components/interaction/Command/Command.tsx +4 -3
  15. package/src/components/interaction/Dialog/Dialog.tsx +4 -5
  16. package/src/components/interaction/Drawer/Drawer.spec.tsx +3 -3
  17. package/src/components/interaction/Drawer/Drawer.tsx +4 -7
  18. package/src/components/interaction/DropdownMenu/DropdownMenu.tsx +4 -2
  19. package/src/components/interaction/Popover/Popover.tsx +4 -3
  20. package/src/components/interaction/Rating/Rating.tsx +4 -2
  21. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.tsx +4 -6
  22. package/src/components/interaction/form/Combobox/Combobox.tsx +4 -2
  23. package/src/components/interaction/form/FileInput/FileInput.tsx +4 -3
  24. package/src/components/interaction/form/NumberInput/NumberInput.tsx +4 -3
  25. package/src/components/interaction/form/RadioGroup/RadioGroup.tsx +4 -6
  26. package/src/components/interaction/form/SegmentedControl/SegmentedControl.tsx +4 -6
  27. package/src/components/interaction/form/atoms/InputContainer.tsx +2 -2
  28. package/src/components/layout/ButtonGroup/ButtonGroup.tsx +4 -6
  29. package/src/components/layout/Card/Card.tsx +4 -10
  30. package/src/components/layout/IconWrapper/IconWrapper.tsx +4 -5
  31. package/src/components/layout/SectionHeader/SectionHeader.tsx +5 -4
  32. package/src/components/ui/Accordion/Accordion.tsx +4 -3
  33. package/src/components/ui/Alert/Alert.tsx +4 -3
  34. package/src/components/ui/Avatar/Avatar.tsx +5 -3
  35. package/src/components/ui/Badge/Badge.tsx +4 -5
  36. package/src/components/ui/Breadcrumb/Breadcrumb.tsx +4 -3
  37. package/src/components/ui/Calendar/Calendar.tsx +4 -4
  38. package/src/components/ui/Carousel/Carousel.tsx +4 -4
  39. package/src/components/ui/DescriptionList/DescriptionList.tsx +4 -4
  40. package/src/components/ui/Loading/Loading.tsx +4 -3
  41. package/src/components/ui/NotificationBanner/NotificationBanner.tsx +4 -2
  42. package/src/components/ui/Pagination/Pagination.tsx +4 -2
  43. package/src/components/ui/Progress/Progress.tsx +4 -2
  44. package/src/components/ui/ProgressCircle/ProgressCircle.tsx +4 -1
  45. package/src/components/ui/Separator/Separator.tsx +5 -3
  46. package/src/components/ui/Skeleton/Skeleton.tsx +4 -3
  47. package/src/components/ui/SkipLink/SkipLink.tsx +4 -5
  48. package/src/components/ui/Tabs/Tabs.tsx +4 -4
  49. package/src/components/ui/Tooltip/Tooltip.tsx +4 -2
  50. package/src/components/ui/Typography/Typography.tsx +4 -5
  51. package/src/stories/DesignSystem/Grid.mdx +2 -0
@@ -1,13 +1,12 @@
1
- import { ReactNode } from 'react';
1
+ import { HTMLAttributes } from 'react';
2
2
  import css from './Badge.module.css';
3
3
  import { cn } from '@boostdev/design-system-foundation';
4
4
  import type { WithClassName } from '../../../types';
5
5
 
6
- interface BadgeProps extends WithClassName {
7
- children: ReactNode;
6
+ interface BadgeProps extends WithClassName, HTMLAttributes<HTMLSpanElement> {
8
7
  variant?: 'primary' | 'secondary' | 'success' | 'error' | 'warning';
9
8
  }
10
9
 
11
- export function Badge({ children, variant = 'primary', className }: BadgeProps) {
12
- return <span className={cn(css.badge, css[`--variant_${variant}`], className)}>{children}</span>;
10
+ export function Badge({ children, variant = 'primary', className, ...rest }: BadgeProps) {
11
+ return <span {...rest} className={cn(css.badge, css[`--variant_${variant}`], className)}>{children}</span>;
13
12
  }
@@ -1,3 +1,4 @@
1
+ import { HTMLAttributes } from 'react';
1
2
  import css from './Breadcrumb.module.css';
2
3
  import { cn } from '@boostdev/design-system-foundation';
3
4
  import type { WithClassName } from '../../../types';
@@ -7,13 +8,13 @@ export interface BreadcrumbItem {
7
8
  href?: string;
8
9
  }
9
10
 
10
- interface BreadcrumbProps extends WithClassName {
11
+ interface BreadcrumbProps extends WithClassName, HTMLAttributes<HTMLElement> {
11
12
  items: BreadcrumbItem[];
12
13
  }
13
14
 
14
- export function Breadcrumb({ items, className }: Readonly<BreadcrumbProps>) {
15
+ export function Breadcrumb({ items, className, ...rest }: Readonly<BreadcrumbProps>) {
15
16
  return (
16
- <nav aria-label="Breadcrumb" className={cn(css.breadcrumb, className)}>
17
+ <nav {...rest} aria-label="Breadcrumb" className={cn(css.breadcrumb, className)}>
17
18
  <ol className={css.list}>
18
19
  {items.map((item, index) => {
19
20
  const isLast = index === items.length - 1;
@@ -1,4 +1,4 @@
1
- import { useState, useId, KeyboardEvent } from 'react';
1
+ import { HTMLAttributes, useState, useId, KeyboardEvent } from 'react';
2
2
  import css from './Calendar.module.css';
3
3
  import { cn } from '@boostdev/design-system-foundation';
4
4
  import type { WithClassName } from '../../../types';
@@ -13,7 +13,7 @@ const MONTHS = [
13
13
  'July', 'August', 'September', 'October', 'November', 'December',
14
14
  ];
15
15
 
16
- interface CalendarProps extends WithClassName {
16
+ interface CalendarProps extends WithClassName, Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange'> {
17
17
  value?: Date;
18
18
  defaultValue?: Date;
19
19
  min?: Date;
@@ -46,7 +46,7 @@ function getFirstDayOfMonth(year: number, month: number): number {
46
46
  return new Date(year, month, 1).getDay();
47
47
  }
48
48
 
49
- export function Calendar({ value, defaultValue, min, max, onChange, className }: Readonly<CalendarProps>) {
49
+ export function Calendar({ value, defaultValue, min, max, onChange, className, ...rest }: Readonly<CalendarProps>) {
50
50
  const today = new Date();
51
51
  const controlled = value !== undefined;
52
52
  const [internal, setInternal] = useState<Date | undefined>(defaultValue);
@@ -107,7 +107,7 @@ export function Calendar({ value, defaultValue, min, max, onChange, className }:
107
107
  while (cells.length % 7 !== 0) cells.push(null);
108
108
 
109
109
  return (
110
- <div className={cn(css.calendar, className)} role="group" aria-labelledby={titleId}>
110
+ <div {...rest} className={cn(css.calendar, className)} role="group" aria-labelledby={titleId}>
111
111
  <div className={css.header}>
112
112
  <button
113
113
  type="button"
@@ -1,14 +1,14 @@
1
- import { ReactNode, useRef, useId } from 'react';
1
+ import { HTMLAttributes, ReactNode, useRef, useId } from 'react';
2
2
  import css from './Carousel.module.css';
3
3
  import { cn } from '@boostdev/design-system-foundation';
4
4
  import type { WithClassName } from '../../../types';
5
5
 
6
- interface CarouselProps extends WithClassName {
6
+ interface CarouselProps extends WithClassName, HTMLAttributes<HTMLElement> {
7
7
  items: ReactNode[];
8
8
  label: string;
9
9
  }
10
10
 
11
- export function Carousel({ items, label, className }: Readonly<CarouselProps>) {
11
+ export function Carousel({ items, label, className, ...rest }: Readonly<CarouselProps>) {
12
12
  const trackRef = useRef<HTMLDivElement>(null);
13
13
  const listId = useId();
14
14
 
@@ -22,7 +22,7 @@ export function Carousel({ items, label, className }: Readonly<CarouselProps>) {
22
22
  };
23
23
 
24
24
  return (
25
- <section aria-label={label} className={cn(css.carousel, className)}>
25
+ <section {...rest} aria-label={label} className={cn(css.carousel, className)}>
26
26
  <button
27
27
  type="button"
28
28
  className={cn(css.navBtn, css['--prev'])}
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
2
  import css from './DescriptionList.module.css';
3
3
  import { cn } from '@boostdev/design-system-foundation';
4
4
  import type { WithClassName } from '../../../types';
@@ -8,14 +8,14 @@ export interface DescriptionItem {
8
8
  details: ReactNode | ReactNode[];
9
9
  }
10
10
 
11
- interface DescriptionListProps extends WithClassName {
11
+ interface DescriptionListProps extends WithClassName, HTMLAttributes<HTMLDListElement> {
12
12
  items: DescriptionItem[];
13
13
  layout?: 'stacked' | 'inline';
14
14
  }
15
15
 
16
- export function DescriptionList({ items, layout = 'stacked', className }: Readonly<DescriptionListProps>) {
16
+ export function DescriptionList({ items, layout = 'stacked', className, ...rest }: Readonly<DescriptionListProps>) {
17
17
  return (
18
- <dl className={cn(css.list, css[`--layout_${layout}`], className)}>
18
+ <dl {...rest} className={cn(css.list, css[`--layout_${layout}`], className)}>
19
19
  {items.map((item, i) => (
20
20
  <div key={i} className={css.group}>
21
21
  <dt className={css.term}>{item.term}</dt>
@@ -1,14 +1,15 @@
1
+ import { HTMLAttributes } from 'react';
1
2
  import css from './Loading.module.css';
2
3
  import { cn } from '@boostdev/design-system-foundation';
3
4
  import type { WithClassName } from '../../../types';
4
5
 
5
- interface LoadingProps extends WithClassName {
6
+ interface LoadingProps extends WithClassName, HTMLAttributes<HTMLDivElement> {
6
7
  size?: 'small' | 'medium' | 'large';
7
8
  }
8
9
 
9
- export function Loading({ size = 'medium', className }: LoadingProps) {
10
+ export function Loading({ size = 'medium', className, ...rest }: LoadingProps) {
10
11
  return (
11
- <div className={cn(css.loading, css[`--size_${size}`], className)}>
12
+ <div {...rest} className={cn(css.loading, css[`--size_${size}`], className)}>
12
13
  <div className={css.spinner} role="status" aria-label="Loading" />
13
14
  </div>
14
15
  );
@@ -1,9 +1,9 @@
1
- import { ReactNode } from 'react';
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
2
  import css from './NotificationBanner.module.css';
3
3
  import { cn } from '@boostdev/design-system-foundation';
4
4
  import type { WithClassName } from '../../../types';
5
5
 
6
- interface NotificationBannerProps extends WithClassName {
6
+ interface NotificationBannerProps extends WithClassName, HTMLAttributes<HTMLDivElement> {
7
7
  variant?: 'info' | 'success' | 'warning' | 'error';
8
8
  children: ReactNode;
9
9
  action?: ReactNode;
@@ -16,11 +16,13 @@ export function NotificationBanner({
16
16
  action,
17
17
  onDismiss,
18
18
  className,
19
+ ...rest
19
20
  }: Readonly<NotificationBannerProps>) {
20
21
  const isUrgent = variant === 'error' || variant === 'warning';
21
22
 
22
23
  return (
23
24
  <div
25
+ {...rest}
24
26
  role={isUrgent ? 'alert' : 'status'}
25
27
  aria-live={isUrgent ? 'assertive' : 'polite'}
26
28
  aria-atomic="true"
@@ -1,8 +1,9 @@
1
+ import { HTMLAttributes } from 'react';
1
2
  import css from './Pagination.module.css';
2
3
  import { cn } from '@boostdev/design-system-foundation';
3
4
  import type { WithClassName } from '../../../types';
4
5
 
5
- interface PaginationProps extends WithClassName {
6
+ interface PaginationProps extends WithClassName, HTMLAttributes<HTMLElement> {
6
7
  currentPage: number;
7
8
  totalPages: number;
8
9
  onPageChange: (page: number) => void;
@@ -28,11 +29,12 @@ export function Pagination({
28
29
  totalPages,
29
30
  onPageChange,
30
31
  className,
32
+ ...rest
31
33
  }: Readonly<PaginationProps>) {
32
34
  const pages = getPageRange(currentPage, totalPages);
33
35
 
34
36
  return (
35
- <nav aria-label="Pagination" className={cn(css.pagination, className)}>
37
+ <nav {...rest} aria-label="Pagination" className={cn(css.pagination, className)}>
36
38
  <ul className={css.list}>
37
39
  <li>
38
40
  <button
@@ -1,8 +1,9 @@
1
+ import { HTMLAttributes } from 'react';
1
2
  import css from './Progress.module.css';
2
3
  import { cn } from '@boostdev/design-system-foundation';
3
4
  import type { WithClassName } from '../../../types';
4
5
 
5
- interface ProgressProps extends WithClassName {
6
+ interface ProgressProps extends WithClassName, HTMLAttributes<HTMLDivElement> {
6
7
  value: number;
7
8
  max?: number;
8
9
  label: string;
@@ -17,11 +18,12 @@ export function Progress({
17
18
  showLabel = false,
18
19
  size = 'medium',
19
20
  className,
21
+ ...rest
20
22
  }: Readonly<ProgressProps>) {
21
23
  const percentage = Math.min(100, Math.max(0, (value / max) * 100));
22
24
 
23
25
  return (
24
- <div className={cn(css.container, className)}>
26
+ <div {...rest} className={cn(css.container, className)}>
25
27
  {showLabel && (
26
28
  <div className={css.labelRow}>
27
29
  <span className={css.label}>{label}</span>
@@ -1,8 +1,9 @@
1
+ import { HTMLAttributes } from 'react';
1
2
  import css from './ProgressCircle.module.css';
2
3
  import { cn } from '@boostdev/design-system-foundation';
3
4
  import type { WithClassName } from '../../../types';
4
5
 
5
- interface ProgressCircleProps extends WithClassName {
6
+ interface ProgressCircleProps extends WithClassName, HTMLAttributes<HTMLDivElement> {
6
7
  value: number;
7
8
  max?: number;
8
9
  label: string;
@@ -20,6 +21,7 @@ export function ProgressCircle({
20
21
  showValue = false,
21
22
  size = 'medium',
22
23
  className,
24
+ ...rest
23
25
  }: Readonly<ProgressCircleProps>) {
24
26
  const percentage = Math.min(100, Math.max(0, (value / max) * 100));
25
27
  const px = SIZE_PX[size];
@@ -30,6 +32,7 @@ export function ProgressCircle({
30
32
 
31
33
  return (
32
34
  <div
35
+ {...rest}
33
36
  role="progressbar"
34
37
  aria-label={label}
35
38
  aria-valuenow={value}
@@ -1,15 +1,17 @@
1
+ import { HTMLAttributes } from 'react';
1
2
  import css from './Separator.module.css';
2
3
  import { cn } from '@boostdev/design-system-foundation';
3
4
  import type { WithClassName } from '../../../types';
4
5
 
5
- interface SeparatorProps extends WithClassName {
6
+ interface SeparatorProps extends WithClassName, HTMLAttributes<HTMLElement> {
6
7
  orientation?: 'horizontal' | 'vertical';
7
8
  }
8
9
 
9
- export function Separator({ orientation = 'horizontal', className }: Readonly<SeparatorProps>) {
10
+ export function Separator({ orientation = 'horizontal', className, ...rest }: Readonly<SeparatorProps>) {
10
11
  if (orientation === 'vertical') {
11
12
  return (
12
13
  <div
14
+ {...rest}
13
15
  role="separator"
14
16
  aria-orientation="vertical"
15
17
  className={cn(css.separator, css['--vertical'], className)}
@@ -17,5 +19,5 @@ export function Separator({ orientation = 'horizontal', className }: Readonly<Se
17
19
  );
18
20
  }
19
21
 
20
- return <hr aria-orientation="horizontal" className={cn(css.separator, css['--horizontal'], className)} />;
22
+ return <hr {...rest} aria-orientation="horizontal" className={cn(css.separator, css['--horizontal'], className)} />;
21
23
  }
@@ -1,11 +1,12 @@
1
+ import { HTMLAttributes } from 'react';
1
2
  import { cn } from '@boostdev/design-system-foundation';
2
3
  import css from './Skeleton.module.css';
3
4
  import type { WithClassName } from '../../../types';
4
5
 
5
- type SkeletonProps = WithClassName;
6
+ type SkeletonProps = WithClassName & HTMLAttributes<HTMLDivElement>;
6
7
 
7
- export function Skeleton({ className }: SkeletonProps) {
8
+ export function Skeleton({ className, ...rest }: SkeletonProps) {
8
9
  return (
9
- <div aria-hidden="true" className={cn(css.skeleton, className)} />
10
+ <div {...rest} aria-hidden="true" className={cn(css.skeleton, className)} />
10
11
  );
11
12
  }
@@ -1,15 +1,14 @@
1
+ import { AnchorHTMLAttributes } from 'react';
1
2
  import css from './SkipLink.module.css';
2
3
  import { cn } from '@boostdev/design-system-foundation';
3
4
  import type { WithClassName } from '../../../types';
4
5
 
5
- interface SkipLinkProps extends WithClassName {
6
- href?: string;
7
- children?: string;
6
+ interface SkipLinkProps extends WithClassName, AnchorHTMLAttributes<HTMLAnchorElement> {
8
7
  }
9
8
 
10
- export function SkipLink({ href = '#main', children = 'Skip to main content', className }: SkipLinkProps) {
9
+ export function SkipLink({ href = '#main', children = 'Skip to main content', className, ...rest }: SkipLinkProps) {
11
10
  return (
12
- <a href={href} className={cn(css.skipLink, className)}>
11
+ <a {...rest} href={href} className={cn(css.skipLink, className)}>
13
12
  {children}
14
13
  </a>
15
14
  );
@@ -1,4 +1,4 @@
1
- import { KeyboardEvent, ReactNode, useId, useRef, useState } from 'react';
1
+ import { HTMLAttributes, KeyboardEvent, ReactNode, useId, useRef, useState } from 'react';
2
2
  import css from './Tabs.module.css';
3
3
  import { cn } from '@boostdev/design-system-foundation';
4
4
  import type { WithClassName } from '../../../types';
@@ -10,12 +10,12 @@ export interface TabItem {
10
10
  disabled?: boolean;
11
11
  }
12
12
 
13
- interface TabsProps extends WithClassName {
13
+ interface TabsProps extends WithClassName, HTMLAttributes<HTMLDivElement> {
14
14
  tabs: TabItem[];
15
15
  defaultTab?: string;
16
16
  }
17
17
 
18
- export function Tabs({ tabs, defaultTab, className }: Readonly<TabsProps>) {
18
+ export function Tabs({ tabs, defaultTab, className, ...rest }: Readonly<TabsProps>) {
19
19
  const baseId = useId();
20
20
  const [activeTab, setActiveTab] = useState(defaultTab ?? tabs[0]?.id);
21
21
  const tabRefs = useRef<(HTMLButtonElement | null)[]>([]);
@@ -49,7 +49,7 @@ export function Tabs({ tabs, defaultTab, className }: Readonly<TabsProps>) {
49
49
  };
50
50
 
51
51
  return (
52
- <div className={cn(css.tabs, className)}>
52
+ <div {...rest} className={cn(css.tabs, className)}>
53
53
  <div role="tablist" className={css.tabList}>
54
54
  {tabs.map((tab, i) => {
55
55
  const tabId = `${baseId}-tab-${tab.id}`;
@@ -1,9 +1,9 @@
1
- import { ReactElement, ReactNode, cloneElement, isValidElement, useId, useState } from 'react';
1
+ import { HTMLAttributes, ReactElement, ReactNode, cloneElement, isValidElement, useId, useState } from 'react';
2
2
  import css from './Tooltip.module.css';
3
3
  import { cn } from '@boostdev/design-system-foundation';
4
4
  import type { WithClassName } from '../../../types';
5
5
 
6
- interface TooltipProps extends WithClassName {
6
+ interface TooltipProps extends WithClassName, Omit<HTMLAttributes<HTMLSpanElement>, 'content'> {
7
7
  content: ReactNode;
8
8
  placement?: 'top' | 'bottom' | 'left' | 'right';
9
9
  children: ReactElement;
@@ -14,6 +14,7 @@ export function Tooltip({
14
14
  placement = 'top',
15
15
  children,
16
16
  className,
17
+ ...rest
17
18
  }: Readonly<TooltipProps>) {
18
19
  const tooltipId = useId();
19
20
  const [isVisible, setIsVisible] = useState(false);
@@ -26,6 +27,7 @@ export function Tooltip({
26
27
 
27
28
  return (
28
29
  <span
30
+ {...rest}
29
31
  className={cn(css.wrapper, className)}
30
32
  onMouseEnter={() => setIsVisible(true)}
31
33
  onMouseLeave={() => setIsVisible(false)}
@@ -1,14 +1,13 @@
1
- import { ReactNode, ElementType } from 'react';
1
+ import { ElementType, HTMLAttributes } from 'react';
2
2
  import css from './Typography.module.css';
3
3
  import { cn } from '@boostdev/design-system-foundation';
4
4
  import type { WithClassName } from '../../../types';
5
5
 
6
6
  type TypographyVariant = 'h1' | 'h2' | 'h3' | 'body' | 'body_s';
7
7
 
8
- interface TypographyProps extends WithClassName {
8
+ interface TypographyProps extends WithClassName, HTMLAttributes<HTMLElement> {
9
9
  variant?: TypographyVariant;
10
10
  component?: ElementType;
11
- children: ReactNode;
12
11
  }
13
12
 
14
13
  const variantToElement: Record<TypographyVariant, ElementType> = {
@@ -19,10 +18,10 @@ const variantToElement: Record<TypographyVariant, ElementType> = {
19
18
  body_s: 'p',
20
19
  };
21
20
 
22
- export function Typography({ variant = 'body', component, children, className }: TypographyProps) {
21
+ export function Typography({ variant = 'body', component, children, className, ...rest }: TypographyProps) {
23
22
  const Component = component || variantToElement[variant];
24
23
 
25
24
  return (
26
- <Component className={cn(css.typography, css[`--${variant}`], className)}>{children}</Component>
25
+ <Component {...rest} className={cn(css.typography, css[`--${variant}`], className)}>{children}</Component>
27
26
  );
28
27
  }
@@ -122,6 +122,8 @@ Apply the built-in layout utilities to use the grid system without writing CSS:
122
122
  </div>
123
123
  ```
124
124
 
125
+ > **Important:** Every direct child of `utl-main-grid` **must** set `grid-column: var(--bds-grid_span-<variant>);` (e.g. `--bds-grid_span-100`, `--bds-grid_span-50`). Without it the child collapses to a single column and the responsive grid behaviour is lost.
126
+
125
127
  ## Custom grid usage
126
128
 
127
129
  ```css