@surflane/ui 0.12.0 → 0.13.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.
Files changed (126) hide show
  1. package/dist/alert-dialog.d.ts +25 -7
  2. package/dist/alert-dialog.js +9 -4
  3. package/dist/autocomplete.d.ts +2 -6
  4. package/dist/avatar.d.ts +7 -7
  5. package/dist/avatar.js +2 -2
  6. package/dist/bar-list.js +7 -1
  7. package/dist/button.d.ts +6 -11
  8. package/dist/button.js +8 -8
  9. package/dist/card.d.ts +15 -10
  10. package/dist/card.js +7 -2
  11. package/dist/chart.d.ts +6 -4
  12. package/dist/chart.js +83 -19
  13. package/dist/choice.d.ts +2 -2
  14. package/dist/class-names.d.ts +0 -4
  15. package/dist/class-names.js +0 -14
  16. package/dist/code.d.ts +19 -7
  17. package/dist/code.js +32 -38
  18. package/dist/combobox.d.ts +2 -8
  19. package/dist/combobox.js +2 -2
  20. package/dist/context-menu.d.ts +2 -8
  21. package/dist/context-menu.js +2 -2
  22. package/dist/css/rules/alert-dialog.css +4 -2
  23. package/dist/css/rules/app-shell.css +47 -10
  24. package/dist/css/rules/bar-list.css +2 -2
  25. package/dist/css/rules/bar.css +5 -12
  26. package/dist/css/rules/bottom-navigation.css +5 -2
  27. package/dist/css/rules/breadcrumbs.css +0 -6
  28. package/dist/css/rules/button.css +4 -12
  29. package/dist/css/rules/card.css +14 -0
  30. package/dist/css/rules/chart.css +13 -5
  31. package/dist/css/rules/choice.css +26 -2
  32. package/dist/css/rules/combobox.css +17 -16
  33. package/dist/css/rules/dashboard.css +53 -1
  34. package/dist/css/rules/date-picker.css +50 -27
  35. package/dist/css/rules/dialog.css +38 -9
  36. package/dist/css/rules/disclosure.css +17 -3
  37. package/dist/css/rules/field-control.css +9 -6
  38. package/dist/css/rules/file-upload.css +9 -5
  39. package/dist/css/rules/filter-bar.css +24 -1
  40. package/dist/css/rules/gauge.css +2 -2
  41. package/dist/css/rules/icon.css +0 -5
  42. package/dist/css/rules/input-group.css +23 -8
  43. package/dist/css/rules/link.css +0 -6
  44. package/dist/css/rules/menu.css +5 -2
  45. package/dist/css/rules/menubar.css +1 -1
  46. package/dist/css/rules/navigation-menu.css +31 -26
  47. package/dist/css/rules/number-field.css +8 -1
  48. package/dist/css/rules/otp-field.css +13 -3
  49. package/dist/css/rules/page-header.css +10 -0
  50. package/dist/css/rules/panel.css +51 -10
  51. package/dist/css/rules/popup.css +50 -0
  52. package/dist/css/rules/preview-card.css +0 -21
  53. package/dist/css/rules/scroll-area.css +20 -1
  54. package/dist/css/rules/select.css +4 -1
  55. package/dist/css/rules/sizing.css +15 -3
  56. package/dist/css/rules/skeleton.css +1 -1
  57. package/dist/css/rules/slider.css +16 -8
  58. package/dist/css/rules/spinner.css +1 -1
  59. package/dist/css/rules/stat.css +9 -0
  60. package/dist/css/rules/tabs.css +14 -6
  61. package/dist/css/rules/textarea.css +28 -0
  62. package/dist/css/rules/toast.css +3 -1
  63. package/dist/css/rules/toggle.css +10 -3
  64. package/dist/css/rules/toolbar.css +10 -3
  65. package/dist/css/rules/tree.css +29 -4
  66. package/dist/dashboard.d.ts +19 -7
  67. package/dist/dashboard.js +30 -5
  68. package/dist/date-picker.d.ts +32 -3
  69. package/dist/date-picker.js +43 -4
  70. package/dist/dialog.d.ts +25 -7
  71. package/dist/dialog.js +9 -4
  72. package/dist/drawer.d.ts +10 -2
  73. package/dist/drawer.js +6 -3
  74. package/dist/icon.d.ts +5 -5
  75. package/dist/icon.js +5 -3
  76. package/dist/index.d.ts +3 -3
  77. package/dist/index.js +2 -2
  78. package/dist/inline-message.d.ts +2 -2
  79. package/dist/inline-message.js +7 -2
  80. package/dist/input.d.ts +2 -2
  81. package/dist/layout.d.ts +1 -3
  82. package/dist/layout.js +2 -2
  83. package/dist/native-select.d.ts +2 -2
  84. package/dist/navigation-menu.d.ts +16 -0
  85. package/dist/navigation-menu.js +6 -1
  86. package/dist/page-header.d.ts +10 -2
  87. package/dist/page-header.js +3 -3
  88. package/dist/panel.d.ts +6 -3
  89. package/dist/panel.js +2 -2
  90. package/dist/parts.d.ts +7 -3
  91. package/dist/parts.js +12 -4
  92. package/dist/popover.d.ts +6 -6
  93. package/dist/popover.js +3 -2
  94. package/dist/preview-card.d.ts +2 -8
  95. package/dist/preview-card.js +2 -2
  96. package/dist/select.d.ts +7 -4
  97. package/dist/select.js +23 -8
  98. package/dist/sheet.d.ts +10 -2
  99. package/dist/sheet.js +6 -3
  100. package/dist/size.d.ts +8 -6
  101. package/dist/size.js +2 -7
  102. package/dist/sizing.d.ts +13 -6
  103. package/dist/sizing.js +13 -4
  104. package/dist/sparkline.d.ts +2 -2
  105. package/dist/sparkline.js +2 -2
  106. package/dist/spinner.d.ts +2 -2
  107. package/dist/spinner.js +2 -2
  108. package/dist/stat.d.ts +6 -2
  109. package/dist/stat.js +2 -2
  110. package/dist/table.d.ts +12 -4
  111. package/dist/table.js +8 -3
  112. package/dist/textarea.d.ts +6 -3
  113. package/dist/textarea.js +2 -2
  114. package/dist/time-range-picker.d.ts +2 -2
  115. package/dist/time-range-picker.js +2 -2
  116. package/dist/toggle.d.ts +2 -2
  117. package/dist/toggle.js +2 -2
  118. package/dist/toolbar.d.ts +11 -10
  119. package/dist/toolbar.js +23 -1
  120. package/dist/tooltip.d.ts +1 -3
  121. package/dist/tooltip.js +4 -2
  122. package/dist/tree.d.ts +1 -3
  123. package/dist/tree.js +2 -2
  124. package/dist/typography.d.ts +10 -3
  125. package/dist/typography.js +4 -3
  126. package/package.json +3 -3
@@ -1,35 +1,53 @@
1
1
  import * as React from 'react';
2
- import { type ComponentSizeAlias } from './sizing.js';
2
+ import { type ComponentSize } from './sizing.js';
3
3
  import { AlertDialog as BaseAlertDialog } from '@base-ui/react/alert-dialog';
4
4
  import { DialogFooter, DialogHeader } from './dialog.js';
5
5
  declare const AlertDialogContent: ({ size, className, focusBoundaryLabel, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Popup> & {
6
6
  /** Width and density; an alert dialog is small unless set. */
7
- size?: ComponentSizeAlias;
7
+ size?: ComponentSize;
8
8
  focusBoundaryLabel?: string;
9
9
  } & {
10
10
  ref?: React.Ref<HTMLDivElement>;
11
11
  }) => React.JSX.Element;
12
+ declare const AlertDialogTitle: ({ ref, ...props }: Omit<Omit<Omit<import("@base-ui/react/alert-dialog").AlertDialogTitleProps, "ref"> & React.RefAttributes<HTMLHeadingElement>, "ref">, "size"> & {
13
+ size?: ComponentSize;
14
+ } & {
15
+ ref?: React.Ref<HTMLHeadingElement> | undefined;
16
+ }) => React.JSX.Element;
17
+ declare const AlertDialogDescription: ({ ref, ...props }: Omit<Omit<Omit<import("@base-ui/react/alert-dialog").AlertDialogDescriptionProps, "ref"> & React.RefAttributes<HTMLParagraphElement>, "ref">, "size"> & {
18
+ size?: ComponentSize;
19
+ } & {
20
+ ref?: React.Ref<HTMLParagraphElement> | undefined;
21
+ }) => React.JSX.Element;
12
22
  export declare const AlertDialog: {
13
23
  Content: ({ size, className, focusBoundaryLabel, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Popup> & {
14
24
  /** Width and density; an alert dialog is small unless set. */
15
- size?: ComponentSizeAlias;
25
+ size?: ComponentSize;
16
26
  focusBoundaryLabel?: string;
17
27
  } & {
18
28
  ref?: React.Ref<HTMLDivElement>;
19
29
  }) => React.JSX.Element;
20
30
  Header: typeof DialogHeader;
21
31
  Footer: typeof DialogFooter;
32
+ Title: ({ ref, ...props }: Omit<Omit<Omit<import("@base-ui/react/alert-dialog").AlertDialogTitleProps, "ref"> & React.RefAttributes<HTMLHeadingElement>, "ref">, "size"> & {
33
+ size?: ComponentSize;
34
+ } & {
35
+ ref?: React.Ref<HTMLHeadingElement> | undefined;
36
+ }) => React.JSX.Element;
37
+ Description: ({ ref, ...props }: Omit<Omit<Omit<import("@base-ui/react/alert-dialog").AlertDialogDescriptionProps, "ref"> & React.RefAttributes<HTMLParagraphElement>, "ref">, "size"> & {
38
+ size?: ComponentSize;
39
+ } & {
40
+ ref?: React.Ref<HTMLParagraphElement> | undefined;
41
+ }) => React.JSX.Element;
22
42
  Root: typeof BaseAlertDialog.Root;
23
43
  Backdrop: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogBackdropProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
24
44
  Close: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogCloseProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
25
- Description: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogDescriptionProps, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
26
45
  Popup: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
27
46
  Portal: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogPortalProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
28
- Title: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogTitleProps, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
29
47
  Trigger: BaseAlertDialog.Trigger;
30
48
  Viewport: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogViewportProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
31
49
  Handle: typeof BaseAlertDialog.Handle;
32
50
  createHandle: typeof BaseAlertDialog.createHandle;
33
51
  };
34
- export { AlertDialogContent };
35
- export declare const AlertDialogBackdrop: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogBackdropProps, "ref"> & React.RefAttributes<HTMLDivElement>>, AlertDialogClose: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogCloseProps, "ref"> & React.RefAttributes<HTMLButtonElement>>, AlertDialogDescription: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogDescriptionProps, "ref"> & React.RefAttributes<HTMLParagraphElement>>, AlertDialogHandle: typeof BaseAlertDialog.Handle, AlertDialogPopup: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>>, AlertDialogPortal: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogPortalProps, "ref"> & React.RefAttributes<HTMLDivElement>>, AlertDialogRoot: typeof BaseAlertDialog.Root, AlertDialogTitle: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogTitleProps, "ref"> & React.RefAttributes<HTMLHeadingElement>>, AlertDialogTrigger: BaseAlertDialog.Trigger, AlertDialogViewport: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogViewportProps, "ref"> & React.RefAttributes<HTMLDivElement>>, AlertDialogHeader: typeof DialogHeader, AlertDialogFooter: typeof DialogFooter;
52
+ export { AlertDialogContent, AlertDialogTitle, AlertDialogDescription };
53
+ export declare const AlertDialogBackdrop: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogBackdropProps, "ref"> & React.RefAttributes<HTMLDivElement>>, AlertDialogClose: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogCloseProps, "ref"> & React.RefAttributes<HTMLButtonElement>>, AlertDialogHandle: typeof BaseAlertDialog.Handle, AlertDialogPopup: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>>, AlertDialogPortal: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogPortalProps, "ref"> & React.RefAttributes<HTMLDivElement>>, AlertDialogRoot: typeof BaseAlertDialog.Root, AlertDialogTrigger: BaseAlertDialog.Trigger, AlertDialogViewport: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/alert-dialog").AlertDialogViewportProps, "ref"> & React.RefAttributes<HTMLDivElement>>, AlertDialogHeader: typeof DialogHeader, AlertDialogFooter: typeof DialogFooter;
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { sizeName, skin } from './parts.js';
3
+ import { part, skin, usePortalDirection } from './parts.js';
4
4
  import { useDialogFocusBoundary } from './dialog-focus.js';
5
5
  import { useComponentSize } from './sizing.js';
6
6
  import { AlertDialog as BaseAlertDialog } from '@base-ui/react/alert-dialog';
@@ -8,14 +8,19 @@ import { DialogFooter, DialogHeader } from './dialog.js';
8
8
  const AlertDialogContent = function AlertDialogContent({ size, className, focusBoundaryLabel = 'Continue dialog navigation', ref, ...props }) {
9
9
  const scheme = useComponentSize(size);
10
10
  const portalRef = useDialogFocusBoundary(focusBoundaryLabel);
11
- return (_jsxs(BaseAlertDialog.Portal, { ref: portalRef, children: [_jsx(BaseAlertDialog.Backdrop, { className: 'surf-dialog-backdrop' }), _jsx(BaseAlertDialog.Popup, { "data-ui-size": scheme, "data-size": sizeName(size), ...props, ref: ref, className: skin('surf-dialog-popup surf-dialog-content surf-confirm-content', className) })] }));
11
+ const dir = usePortalDirection();
12
+ return (_jsxs(BaseAlertDialog.Portal, { ref: portalRef, children: [_jsx(BaseAlertDialog.Backdrop, { className: 'surf-dialog-backdrop' }), _jsx(BaseAlertDialog.Popup, { dir: dir, "data-ui-size": scheme, "data-size": size, ...props, ref: ref, className: skin('surf-dialog-popup surf-dialog-content surf-confirm-content', className) })] }));
12
13
  };
14
+ const AlertDialogTitle = /* @__PURE__ */ part(BaseAlertDialog.Title, 'surf-dialog-title');
15
+ const AlertDialogDescription = /* @__PURE__ */ part(BaseAlertDialog.Description, 'surf-dialog-description');
13
16
  export const AlertDialog = {
14
17
  ...BaseAlertDialog,
15
18
  Content: AlertDialogContent,
16
19
  Header: DialogHeader,
17
20
  Footer: DialogFooter,
21
+ Title: AlertDialogTitle,
22
+ Description: AlertDialogDescription,
18
23
  };
19
24
  // Flat names for React Server Components, which cannot dot into client exports.
20
- export { AlertDialogContent };
21
- export const { Backdrop: AlertDialogBackdrop, Close: AlertDialogClose, Description: AlertDialogDescription, Handle: AlertDialogHandle, Popup: AlertDialogPopup, Portal: AlertDialogPortal, Root: AlertDialogRoot, Title: AlertDialogTitle, Trigger: AlertDialogTrigger, Viewport: AlertDialogViewport, Header: AlertDialogHeader, Footer: AlertDialogFooter, } = AlertDialog;
25
+ export { AlertDialogContent, AlertDialogTitle, AlertDialogDescription };
26
+ export const { Backdrop: AlertDialogBackdrop, Close: AlertDialogClose, Handle: AlertDialogHandle, Popup: AlertDialogPopup, Portal: AlertDialogPortal, Root: AlertDialogRoot, Trigger: AlertDialogTrigger, Viewport: AlertDialogViewport, Header: AlertDialogHeader, Footer: AlertDialogFooter, } = AlertDialog;
@@ -4,9 +4,7 @@ declare const AutocompleteRoot: typeof BaseAutocomplete.Root;
4
4
  export declare const Autocomplete: {
5
5
  Root: typeof BaseAutocomplete.Root;
6
6
  Portal: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/autocomplete").AutocompletePortalProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
7
- Content: ({ side, align, sideOffset, collisionPadding, positionerProps, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Popup> & Pick<React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Positioner>, "side" | "align" | "sideOffset" | "collisionPadding"> & {
8
- positionerProps?: React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Positioner>;
9
- } & {
7
+ Content: ({ side, align, sideOffset, collisionPadding, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Popup> & Pick<React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Positioner>, "side" | "align" | "sideOffset" | "collisionPadding"> & {
10
8
  ref?: React.Ref<HTMLDivElement>;
11
9
  }) => React.JSX.Element;
12
10
  Popup: ({ ref, ...props }: Omit<Omit<Omit<import("@base-ui/react/autocomplete").AutocompletePopupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
@@ -128,8 +126,6 @@ export declare const AutocompleteArrow: React.ForwardRefExoticComponent<Omit<imp
128
126
  ref?: React.Ref<HTMLDivElement> | undefined;
129
127
  }) => React.JSX.Element, AutocompleteTrigger: ({ className, children, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Trigger> & {
130
128
  ref?: React.Ref<HTMLButtonElement>;
131
- }) => React.JSX.Element, AutocompleteValue: typeof BaseAutocomplete.Value, AutocompleteContent: ({ side, align, sideOffset, collisionPadding, positionerProps, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Popup> & Pick<React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Positioner>, "side" | "align" | "sideOffset" | "collisionPadding"> & {
132
- positionerProps?: React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Positioner>;
133
- } & {
129
+ }) => React.JSX.Element, AutocompleteValue: typeof BaseAutocomplete.Value, AutocompleteContent: ({ side, align, sideOffset, collisionPadding, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Popup> & Pick<React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Positioner>, "side" | "align" | "sideOffset" | "collisionPadding"> & {
134
130
  ref?: React.Ref<HTMLDivElement>;
135
131
  }) => React.JSX.Element;
package/dist/avatar.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import { Avatar as BaseAvatar } from '@base-ui/react/avatar';
3
- import { type ComponentSizeAlias } from './sizing.js';
3
+ import { type ComponentSize } from './sizing.js';
4
4
  declare const AvatarRoot: ({ size, className, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseAvatar.Root> & {
5
- size?: ComponentSizeAlias;
5
+ size?: ComponentSize;
6
6
  } & {
7
7
  ref?: React.Ref<React.ComponentRef<typeof BaseAvatar.Root>>;
8
8
  }) => React.JSX.Element;
@@ -11,12 +11,12 @@ declare const AvatarFallback: ({ children, className, ref, ...props }: React.Com
11
11
  }) => React.JSX.Element;
12
12
  export declare const Avatar: {
13
13
  Root: ({ size, className, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseAvatar.Root> & {
14
- size?: ComponentSizeAlias;
14
+ size?: ComponentSize;
15
15
  } & {
16
16
  ref?: React.Ref<React.ComponentRef<typeof BaseAvatar.Root>>;
17
17
  }) => React.JSX.Element;
18
18
  Status: ({ ref, ...props }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref">, "size"> & {
19
- size?: import("./size.js").ComponentSize;
19
+ size?: ComponentSize;
20
20
  } & {
21
21
  ref?: React.Ref<HTMLSpanElement> | undefined;
22
22
  }) => React.JSX.Element;
@@ -24,18 +24,18 @@ export declare const Avatar: {
24
24
  ref?: React.Ref<React.ComponentRef<typeof BaseAvatar.Fallback>>;
25
25
  }) => React.JSX.Element;
26
26
  Image: ({ ref, ...props }: Omit<Omit<Omit<import("@base-ui/react/avatar").AvatarImageProps, "ref"> & React.RefAttributes<HTMLImageElement>, "ref">, "size"> & {
27
- size?: import("./size.js").ComponentSize;
27
+ size?: ComponentSize;
28
28
  } & {
29
29
  ref?: React.Ref<HTMLImageElement> | undefined;
30
30
  }) => React.JSX.Element;
31
31
  };
32
32
  export { AvatarFallback, AvatarRoot };
33
33
  export declare const AvatarImage: ({ ref, ...props }: Omit<Omit<Omit<import("@base-ui/react/avatar").AvatarImageProps, "ref"> & React.RefAttributes<HTMLImageElement>, "ref">, "size"> & {
34
- size?: import("./size.js").ComponentSize;
34
+ size?: ComponentSize;
35
35
  } & {
36
36
  ref?: React.Ref<HTMLImageElement> | undefined;
37
37
  }) => React.JSX.Element, AvatarStatus: ({ ref, ...props }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref">, "size"> & {
38
- size?: import("./size.js").ComponentSize;
38
+ size?: ComponentSize;
39
39
  } & {
40
40
  ref?: React.Ref<HTMLSpanElement> | undefined;
41
41
  }) => React.JSX.Element;
package/dist/avatar.js CHANGED
@@ -3,10 +3,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { Icon } from './icon.js';
4
4
  import { Avatar as BaseAvatar } from '@base-ui/react/avatar';
5
5
  import { useComponentSize } from './sizing.js';
6
- import { sizeName, skin, part } from './parts.js';
6
+ import { skin, part } from './parts.js';
7
7
  const AvatarRoot = function AvatarRoot({ size, className, ref, ...props }) {
8
8
  const scheme = useComponentSize(size);
9
- return (_jsx(BaseAvatar.Root, { ...props, ref: ref, "data-size": sizeName(size), "data-ui-size": scheme, className: skin('surf-avatar', className) }));
9
+ return (_jsx(BaseAvatar.Root, { ...props, ref: ref, "data-size": size, "data-ui-size": scheme, className: skin('surf-avatar', className) }));
10
10
  };
11
11
  const AvatarFallback = function AvatarFallback({ children, className, ref, ...props }) {
12
12
  return (_jsx(BaseAvatar.Fallback, { ...props, ref: ref, className: skin('surf-avatar-fallback', className), children: children ?? _jsx(Icon, { name: 'user' }) }));
package/dist/bar-list.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cx } from './class-names.js';
3
+ import { missingValue } from './format.js';
3
4
  import { ScrollArea } from './scroll-area.js';
4
5
  /** A ranked list of named values, each with a bar in proportion to the largest, such
5
6
  * as disk by directory or tokens by project. Names and values are text; the bars are
@@ -8,7 +9,12 @@ export const BarList = function BarList({ label, items, max, sorted = true, maxR
8
9
  const rows = sorted ? [...items].sort((a, b) => b.value - a.value) : items;
9
10
  const top = max ?? rows.reduce((largest, item) => Math.max(largest, item.value), 0);
10
11
  const number = new Intl.NumberFormat(locale);
11
- const write = (value) => formatValue ? formatValue(value) : number.format(value);
12
+ // A value that is missing reads as the dash every other number helper writes.
13
+ const write = (value) => !Number.isFinite(value)
14
+ ? missingValue
15
+ : formatValue
16
+ ? formatValue(value)
17
+ : number.format(value);
12
18
  const scrolls = maxRows !== undefined && rows.length > maxRows;
13
19
  const list = (_jsx("ol", { className: 'surf-bar-list-items', "aria-label": label, children: rows.map((item) => {
14
20
  const share = top > 0 && Number.isFinite(item.value)
package/dist/button.d.ts CHANGED
@@ -1,17 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import { Button as BaseButton } from '@base-ui/react/button';
3
3
  import { useRender } from '@base-ui/react/use-render';
4
- import { type ComponentSizeAlias } from './sizing.js';
5
- /** Visual priority. `default` is deprecated: it is `primary` under its former name, and
6
- * is removed in a later minor. Without a variant a button is `primary`. */
7
- export type ButtonVariant = 'primary' | 'default' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'link';
8
- /**
9
- * small, default and large set the size scheme; icon, icon-small and icon-large are
10
- * square icon buttons. Deprecated, removed in a later minor: sm, md and lg (write the
11
- * full names), icon-sm, icon-xs and icon-lg (icon-small, icon-large) and xs, which is
12
- * off the scale and keeps 24px on touch screens.
13
- */
14
- export type ButtonSize = ComponentSizeAlias | 'icon' | 'icon-small' | 'icon-large' | 'xs' | 'icon-xs' | 'icon-sm' | 'icon-lg';
4
+ import { type ComponentSize } from './sizing.js';
5
+ /** Visual priority. Without a variant a button is `primary`. */
6
+ export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'link';
7
+ /** small, default and large set the size scheme; icon, icon-small and icon-large are
8
+ * square icon buttons on the same scale. */
9
+ export type ButtonSize = ComponentSize | 'icon' | 'icon-small' | 'icon-large';
15
10
  export type ButtonProps = Omit<React.ComponentProps<typeof BaseButton>, 'ref'> & {
16
11
  variant?: ButtonVariant;
17
12
  size?: ButtonSize;
package/dist/button.js CHANGED
@@ -3,21 +3,21 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { Button as BaseButton } from '@base-ui/react/button';
4
4
  import { useRender } from '@base-ui/react/use-render';
5
5
  import { useComponentSize } from './sizing.js';
6
- import { sizeName, skin, cx } from './parts.js';
7
- /** The size scheme a button size implies: icon sizes follow the scale, xs and icon
8
- * keep the surrounding scheme. */
6
+ import { skin, cx } from './parts.js';
7
+ /** The size scheme a button size implies: icon sizes follow the scale, and icon keeps
8
+ * the surrounding scheme. */
9
9
  function schemeOf(size) {
10
- return size === 'icon-small' || size === 'icon-sm' || size === 'icon-xs'
10
+ return size === 'icon-small'
11
11
  ? 'small'
12
- : size === 'icon-large' || size === 'icon-lg'
12
+ : size === 'icon-large'
13
13
  ? 'large'
14
- : size === 'xs' || size === 'icon'
14
+ : size === 'icon'
15
15
  ? undefined
16
16
  : size;
17
17
  }
18
18
  export const Button = function Button({ className, variant = 'primary', size, ref, ...props }) {
19
19
  const scheme = useComponentSize(schemeOf(size));
20
- return (_jsx(BaseButton, { ref: ref, ...props, className: skin('surf-button', className), "data-variant": variant, "data-size": sizeName(size), "data-ui-size": scheme }));
20
+ return (_jsx(BaseButton, { ref: ref, ...props, className: skin('surf-button', className), "data-variant": variant, "data-size": size, "data-ui-size": scheme }));
21
21
  };
22
22
  /** A link that looks like a Button. It navigates, so it stays a link for assistive
23
23
  * technology; pass a router's link element as `render` to keep client navigation. */
@@ -31,7 +31,7 @@ export const LinkButton = function LinkButton({ render, className, variant = 'pr
31
31
  ...props,
32
32
  className: cx('surf-button', className),
33
33
  'data-variant': variant,
34
- 'data-size': sizeName(size),
34
+ 'data-size': size,
35
35
  'data-ui-size': scheme,
36
36
  },
37
37
  });
package/dist/card.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { Surface } from './layout.js';
3
- declare const CardRoot: ({ className, padding, ref, ...props }: React.ComponentPropsWithoutRef<typeof Surface> & {
3
+ import { type ComponentSize } from './size.js';
4
+ declare const CardRoot: ({ className, padding, size, ref, ...props }: React.ComponentPropsWithoutRef<typeof Surface> & {
5
+ /** The card's padding, title and the controls inside, as a SizeProvider would set. */
6
+ size?: ComponentSize;
4
7
  ref?: React.Ref<HTMLDivElement>;
5
8
  }) => React.JSX.Element;
6
9
  declare const CardTitle: ({ level, className, ref, ...props }: React.ComponentPropsWithoutRef<"h3"> & {
@@ -292,11 +295,13 @@ declare const CardTitle: ({ level, className, ref, ...props }: React.ComponentPr
292
295
  exportparts?: string | undefined | undefined;
293
296
  }, HTMLHeadingElement>;
294
297
  export declare const Card: {
295
- Root: ({ className, padding, ref, ...props }: React.ComponentPropsWithoutRef<typeof Surface> & {
298
+ Root: ({ className, padding, size, ref, ...props }: React.ComponentPropsWithoutRef<typeof Surface> & {
299
+ /** The card's padding, title and the controls inside, as a SizeProvider would set. */
300
+ size?: ComponentSize;
296
301
  ref?: React.Ref<HTMLDivElement>;
297
302
  }) => React.JSX.Element;
298
303
  Header: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
299
- size?: import("./size.js").ComponentSize;
304
+ size?: ComponentSize;
300
305
  ref?: React.Ref<HTMLDivElement> | undefined;
301
306
  }) => React.JSX.Element;
302
307
  Title: ({ level, className, ref, ...props }: React.ComponentPropsWithoutRef<"h3"> & {
@@ -588,29 +593,29 @@ export declare const Card: {
588
593
  exportparts?: string | undefined | undefined;
589
594
  }, HTMLHeadingElement>;
590
595
  Description: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref">, "size"> & {
591
- size?: import("./size.js").ComponentSize;
596
+ size?: ComponentSize;
592
597
  ref?: React.Ref<HTMLParagraphElement> | undefined;
593
598
  }) => React.JSX.Element;
594
599
  Body: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
595
- size?: import("./size.js").ComponentSize;
600
+ size?: ComponentSize;
596
601
  ref?: React.Ref<HTMLDivElement> | undefined;
597
602
  }) => React.JSX.Element;
598
603
  Footer: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
599
- size?: import("./size.js").ComponentSize;
604
+ size?: ComponentSize;
600
605
  ref?: React.Ref<HTMLDivElement> | undefined;
601
606
  }) => React.JSX.Element;
602
607
  };
603
608
  export { CardRoot, CardTitle };
604
609
  export declare const CardHeader: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
605
- size?: import("./size.js").ComponentSize;
610
+ size?: ComponentSize;
606
611
  ref?: React.Ref<HTMLDivElement> | undefined;
607
612
  }) => React.JSX.Element, CardDescription: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref">, "size"> & {
608
- size?: import("./size.js").ComponentSize;
613
+ size?: ComponentSize;
609
614
  ref?: React.Ref<HTMLParagraphElement> | undefined;
610
615
  }) => React.JSX.Element, CardBody: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
611
- size?: import("./size.js").ComponentSize;
616
+ size?: ComponentSize;
612
617
  ref?: React.Ref<HTMLDivElement> | undefined;
613
618
  }) => React.JSX.Element, CardFooter: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
614
- size?: import("./size.js").ComponentSize;
619
+ size?: ComponentSize;
615
620
  ref?: React.Ref<HTMLDivElement> | undefined;
616
621
  }) => React.JSX.Element;
package/dist/card.js CHANGED
@@ -3,8 +3,13 @@ import * as React from 'react';
3
3
  import { Surface } from './layout.js';
4
4
  import { cx } from './class-names.js';
5
5
  import { elementPart } from './element-part.js';
6
- const CardRoot = function CardRoot({ className, padding, ref, ...props }) {
7
- return (_jsx(Surface, { ...props, padding: padding, ref: ref, className: cx('surf-card', className) }));
6
+ import { normalizeSize } from './size.js';
7
+ import { SizeScope } from './sizing.js';
8
+ const CardRoot = function CardRoot({ className, padding, size, ref, ...props }) {
9
+ const scheme = normalizeSize(size);
10
+ const card = (_jsx(Surface, { ...props, padding: padding, ref: ref, "data-ui-size": scheme, className: cx('surf-card', className) }));
11
+ // Only an explicit size opens a client boundary, so popups inside keep it.
12
+ return scheme ? _jsx(SizeScope, { size: scheme, children: card }) : card;
8
13
  };
9
14
  const CardTitle = function CardTitle({ level = 3, className, ref, ...props }) {
10
15
  return React.createElement(`h${level}`, {
package/dist/chart.d.ts CHANGED
@@ -58,12 +58,14 @@ export type ChartProps = Omit<React.ComponentPropsWithoutRef<'figure'>, 'childre
58
58
  /** Thresholds and target bands over the plot. The value axis reaches them. */
59
59
  references?: readonly ChartReference[];
60
60
  /** compact keeps the plot, legend and floating values for a dashboard card; the
61
- * caption, keyboard help and readout stay for assistive technology. */
61
+ * caption, keyboard help and readout stay for assistive technology. Without it the
62
+ * chart follows a SizeProvider density. Its data table takes the same density. */
62
63
  density?: 'default' | 'compact';
63
64
  /** Above the plot, beside the value axis name, or below it. */
64
65
  legendPosition?: 'top' | 'bottom';
65
- /** Shows this many series in the legend; the rest fold behind a "+N" button. */
66
- legendLimit?: number;
66
+ /** Shows this many series in the legend; the rest fold behind a "+N" button. auto
67
+ * keeps the legend on one line: as many as fit the chart's width, the rest folded. */
68
+ legendLimit?: number | 'auto';
67
69
  locale?: string;
68
70
  /** Formats a value for the readout, the table and the value axis ticks. The unit
69
71
  * follows it in the readout and the table, and names the axis. */
@@ -108,6 +110,6 @@ export type ChartSeriesMarkProps = {
108
110
  export declare function ChartSeriesMark({ type, index, palette, color, }: ChartSeriesMarkProps): React.JSX.Element;
109
111
  /** Cartesian trends with a persistent, keyboard-readable tooltip region and a
110
112
  * full data-table alternative. Missing values are gaps, never fabricated zeros. */
111
- export declare const Chart: ({ title, description, data, series, unit, xLabel, yLabel, type, height, includeZero, palette, xScale, yScale, curve, stacked, references, density, legendPosition, legendLimit, locale, formatValue, labels, hiddenSeries, defaultHiddenSeries, onHiddenSeriesChange, className, ref, ...props }: ChartProps & {
113
+ export declare const Chart: ({ title, description, data, series, unit, xLabel, yLabel, type, height, includeZero, palette, xScale, yScale, curve, stacked, references, density: ownDensity, legendPosition, legendLimit, locale, formatValue, labels, hiddenSeries, defaultHiddenSeries, onHiddenSeriesChange, className, ref, ...props }: ChartProps & {
112
114
  ref?: React.Ref<HTMLElement>;
113
115
  }) => React.JSX.Element;
package/dist/chart.js CHANGED
@@ -7,6 +7,7 @@ import { Table } from './table.js';
7
7
  import { Button } from './button.js';
8
8
  import { Popover } from './popover.js';
9
9
  import { cx } from './parts.js';
10
+ import { useComponentDensity } from './sizing.js';
10
11
  const chartLabels = {
11
12
  missing: 'Not available',
12
13
  empty: 'No numeric measurements to display.',
@@ -70,11 +71,10 @@ const timeSteps = [
70
71
  ['month', 6, 182 * DAY],
71
72
  ['year', 1, 365 * DAY],
72
73
  ];
73
- /** Ticks on round local times, such as every 6 hours or the first of each month, at
74
- * most six across the span. */
75
- function timeTicks(min, max) {
76
- const [unit, count] = timeSteps.find(([, , ms]) => (max - min) / ms <= 6) ??
77
- timeSteps[timeSteps.length - 1];
74
+ /** Ticks on round local times, such as every 6 hours or the first of each month: at
75
+ * most six across the span, and no more than fit, so their steps stay even. */
76
+ function timeTicks(min, max, fits = () => true) {
77
+ const [unit, count] = timeSteps.find(([stepUnit, , ms]) => (max - min) / ms <= 6 && fits(stepUnit, ms)) ?? timeSteps[timeSteps.length - 1];
78
78
  const date = new Date(min);
79
79
  date.setSeconds(0, 0);
80
80
  if (unit === 'minute')
@@ -117,6 +117,36 @@ function logTicks(low, high) {
117
117
  return ticks;
118
118
  }
119
119
  const isNumber = (value) => typeof value === 'number' && Number.isFinite(value);
120
+ /** An element's content width, kept current as it resizes; 0 before it is measured. */
121
+ function useWidth() {
122
+ const [element, setElement] = React.useState(null);
123
+ const [width, setWidth] = React.useState(0);
124
+ React.useLayoutEffect(() => {
125
+ if (!element)
126
+ return;
127
+ setWidth(element.clientWidth);
128
+ if (typeof ResizeObserver === 'undefined')
129
+ return;
130
+ const observer = new ResizeObserver(([entry]) => setWidth(entry.contentRect.width));
131
+ observer.observe(element);
132
+ return () => observer.disconnect();
133
+ }, [element]);
134
+ return [setElement, width, element];
135
+ }
136
+ let measureCanvas;
137
+ /** How wide a tick label draws, in the font it draws in. */
138
+ function textWidth(text, font) {
139
+ measureCanvas ??= document.createElement('canvas');
140
+ const context = measureCanvas.getContext('2d');
141
+ if (!context)
142
+ return text.length * 7.5;
143
+ context.font = font;
144
+ return context.measureText(text).width;
145
+ }
146
+ /** The gap Recharts keeps between tick labels. */
147
+ const TICK_GAP = 24;
148
+ /** The value axis and the plot's right margin: what the plot gives up of the frame. */
149
+ const PLOT_INSET = 56 + 20;
120
150
  /** True once the font of the tick labels has loaded. Recharts measures a label to keep
121
151
  * it inside the chart and caches that width; measured in the fallback font, the last
122
152
  * label overflows by a few pixels once the real font arrives. */
@@ -196,13 +226,14 @@ function FloatingValues({ host, hidden, render, }) {
196
226
  }
197
227
  /** Cartesian trends with a persistent, keyboard-readable tooltip region and a
198
228
  * full data-table alternative. Missing values are gaps, never fabricated zeros. */
199
- export const Chart = function Chart({ title, description, data, series, unit, xLabel, yLabel, type = 'line', height, includeZero = true, palette = 'neutral', xScale = 'category', yScale = 'linear', curve = 'linear', stacked = false, references = [], density = 'default', legendPosition = 'top', legendLimit, locale = 'en-US', formatValue, labels, hiddenSeries, defaultHiddenSeries = [], onHiddenSeriesChange, className, ref, ...props }) {
229
+ export const Chart = function Chart({ title, description, data, series, unit, xLabel, yLabel, type = 'line', height, includeZero = true, palette = 'neutral', xScale = 'category', yScale = 'linear', curve = 'linear', stacked = false, references = [], density: ownDensity, legendPosition = 'top', legendLimit, locale, formatValue, labels, hiddenSeries, defaultHiddenSeries = [], onHiddenSeriesChange, className, ref, ...props }) {
200
230
  const text = { ...chartLabels, ...labels };
201
231
  const id = React.useId().replace(/[^a-zA-Z0-9_-]/g, '_');
202
232
  const colorFor = (index) => seriesColor(index, palette, series[index]?.color);
203
233
  const timeScale = xScale === 'time';
204
234
  const logScale = yScale === 'log';
205
235
  const stacks = stacked && type !== 'line';
236
+ const density = useComponentDensity(ownDensity);
206
237
  const compact = density === 'compact';
207
238
  const [internalHidden, setInternalHidden] = React.useState(defaultHiddenSeries);
208
239
  const hidden = new Set(hiddenSeries ?? internalHidden);
@@ -210,6 +241,24 @@ export const Chart = function Chart({ title, description, data, series, unit, xL
210
241
  const [host, setHost] = React.useState(null);
211
242
  const fontsReady = useFontReady(host, data.map((d) => d.label).join(''));
212
243
  const [floatHost, setFloatHost] = React.useState(null);
244
+ const [setFrame, frameWidth, frame] = useWidth();
245
+ // legendLimit='auto': lay every series out, count those on the first line, then
246
+ // fold the rest, keeping room for the "+N" button. A new width lays them out again.
247
+ const legendList = React.useRef(null);
248
+ const [legendFit, setLegendFit] = React.useState();
249
+ React.useLayoutEffect(() => {
250
+ if (legendLimit === 'auto')
251
+ setLegendFit(undefined);
252
+ }, [legendLimit, frameWidth, series.length]);
253
+ React.useLayoutEffect(() => {
254
+ if (legendLimit !== 'auto' || legendFit !== undefined)
255
+ return;
256
+ const items = Array.from(legendList.current?.querySelectorAll(':scope > [data-series]') ?? []);
257
+ if (!items.length)
258
+ return;
259
+ const line = items.filter((item) => item.offsetTop === items[0].offsetTop).length;
260
+ setLegendFit(line >= items.length ? items.length : Math.max(1, line - 1));
261
+ });
213
262
  const [dismissed, setDismissed] = React.useState(false);
214
263
  // The table renders once it is first opened, so a page of charts stays light.
215
264
  const [tableOpened, setTableOpened] = React.useState(false);
@@ -341,17 +390,31 @@ export const Chart = function Chart({ title, description, data, series, unit, xL
341
390
  if (!timeScale || !rows.length)
342
391
  return undefined;
343
392
  const first = rows[0].time, last = rows[rows.length - 1].time;
344
- const { ticks: timeAxisTicks, unit: timeUnit } = timeTicks(first, last);
345
- // Bars sit on their time, so half an interval on each side keeps the end ones whole.
346
- const pad = type === 'bar' ? (interval || DAY) / 2 : 0;
347
- const subDay = timeUnit === 'minute' || timeUnit === 'hour';
348
- const tickFormat = new Intl.DateTimeFormat(locale, subDay
393
+ const formatFor = (unit) => new Intl.DateTimeFormat(locale, unit === 'minute' || unit === 'hour'
349
394
  ? { hour: 'numeric', minute: '2-digit' }
350
- : timeUnit === 'day'
395
+ : unit === 'day'
351
396
  ? { month: 'short', day: 'numeric' }
352
- : timeUnit === 'month'
397
+ : unit === 'month'
353
398
  ? { month: 'short', year: 'numeric' }
354
399
  : { year: 'numeric' });
400
+ // Pick the step from the plot's width and the width its labels draw at, so a
401
+ // narrow chart steps every 2 or 3 hours instead of dropping uneven ticks.
402
+ const plotWidth = frameWidth - PLOT_INSET;
403
+ const font = frame && fontsReady
404
+ ? `12px ${getComputedStyle(frame).fontFamily}`
405
+ : undefined;
406
+ const fits = (unit, ms) => {
407
+ if (plotWidth <= 0 || !font)
408
+ return true;
409
+ const label = Math.max(textWidth(formatFor(unit).format(new Date(first)), font), textWidth(formatFor(unit).format(new Date(2026, 9, 24, 22, 30)), font));
410
+ const count = Math.floor((last - first) / ms) + 1;
411
+ return count * (label + TICK_GAP) - TICK_GAP <= plotWidth;
412
+ };
413
+ const { ticks: timeAxisTicks, unit: timeUnit } = timeTicks(first, last, fits);
414
+ // Bars sit on their time, so half an interval on each side keeps the end ones whole.
415
+ const pad = type === 'bar' ? (interval || DAY) / 2 : 0;
416
+ const subDay = timeUnit === 'minute' || timeUnit === 'hour';
417
+ const tickFormat = formatFor(timeUnit);
355
418
  const dayFormat = new Intl.DateTimeFormat(locale, {
356
419
  month: 'short',
357
420
  day: 'numeric',
@@ -367,7 +430,7 @@ export const Chart = function Chart({ title, description, data, series, unit, xL
367
430
  : tickFormat.format(date);
368
431
  },
369
432
  };
370
- }, [rows, timeScale, type, interval, locale]);
433
+ }, [rows, timeScale, type, interval, locale, frameWidth, frame, fontsReady]);
371
434
  const hasValues = values.length > 0;
372
435
  const changeHidden = (next) => {
373
436
  if (hiddenSeries === undefined)
@@ -390,12 +453,13 @@ export const Chart = function Chart({ title, description, data, series, unit, xL
390
453
  ? `${r.label} ${format(r.y)}`
391
454
  : `${r.label} ${formatNumber(r.from) ?? text.missing}–${format(r.to)}`;
392
455
  const legendButton = (s, index) => (_jsxs("button", { ref: index === 0 ? firstLegend : undefined, type: 'button', className: 'surf-chart-legend-button', "aria-label": text.series(s.label), "aria-pressed": !hidden.has(s.key), onClick: () => toggle(s.key), children: [_jsx(SeriesMark, { type: type, index: index, color: colorFor(index), pattern: `${id}-legend-${index}` }), _jsx("span", { children: s.label })] }));
393
- const shown = legendLimit !== undefined && legendLimit < series.length
394
- ? series.slice(0, Math.max(0, legendLimit))
456
+ const limit = legendLimit === 'auto' ? legendFit : legendLimit;
457
+ const shown = limit !== undefined && limit < series.length
458
+ ? series.slice(0, Math.max(0, limit))
395
459
  : series;
396
460
  const folded = series.slice(shown.length);
397
- const legend = (_jsxs("ul", { className: 'surf-chart-legend', "aria-label": text.legend(title), children: [shown.map((s, index) => (_jsx("li", { children: legendButton(s, index) }, s.key))), folded.length > 0 && (_jsx("li", { children: _jsxs(Popover.Root, { children: [_jsxs(Popover.Trigger, { className: 'surf-chart-legend-button surf-chart-legend-more', "aria-label": text.moreSeries(folded.length), children: ["+", folded.length] }), _jsx(Popover.Content, { size: 'small', children: _jsx("ul", { className: 'surf-chart-legend-list', children: folded.map((s, index) => (_jsx("li", { children: legendButton(s, shown.length + index) }, s.key))) }) })] }) })), references.map((reference, index) => (_jsxs("li", { className: 'surf-chart-legend-reference', children: [_jsx(ReferenceMark, { reference: reference }), _jsx("span", { children: referenceText(reference) })] }, index)))] }));
398
- return (_jsxs("figure", { ...props, ref: ref, "data-density": density, className: cx('surf-chart', className), "aria-labelledby": `${id}-title`, children: [_jsxs("figcaption", { className: 'surf-chart-caption', children: [_jsx("strong", { id: `${id}-title`, children: title }), _jsx("p", { id: `${id}-summary`, children: description })] }), _jsxs("div", { className: 'surf-chart-frame', children: [_jsxs("div", { className: 'surf-chart-key', children: [_jsxs("p", { className: 'surf-chart-axis-label', children: [yLabel, " (", unit, ")"] }), legendPosition === 'top' && legend] }), hasValues ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: 'surf-chart-plot', onKeyDownCapture: (event) => {
461
+ const legend = (_jsxs("ul", { ref: legendList, className: 'surf-chart-legend', "aria-label": text.legend(title), children: [shown.map((s, index) => (_jsx("li", { "data-series": '', children: legendButton(s, index) }, s.key))), folded.length > 0 && (_jsx("li", { children: _jsxs(Popover.Root, { children: [_jsxs(Popover.Trigger, { className: 'surf-chart-legend-button surf-chart-legend-more', "aria-label": text.moreSeries(folded.length), children: ["+", folded.length] }), _jsx(Popover.Content, { size: 'small', children: _jsx("ul", { className: 'surf-chart-legend-list', children: folded.map((s, index) => (_jsx("li", { children: legendButton(s, shown.length + index) }, s.key))) }) })] }) })), references.map((reference, index) => (_jsxs("li", { className: 'surf-chart-legend-reference', children: [_jsx(ReferenceMark, { reference: reference }), _jsx("span", { children: referenceText(reference) })] }, index)))] }));
462
+ return (_jsxs("figure", { ...props, ref: ref, "data-density": density, className: cx('surf-chart', className), "aria-labelledby": `${id}-title`, children: [_jsxs("figcaption", { className: 'surf-chart-caption', children: [_jsx("strong", { id: `${id}-title`, children: title }), _jsx("p", { id: `${id}-summary`, children: description })] }), _jsxs("div", { className: 'surf-chart-frame', ref: setFrame, children: [_jsxs("div", { className: 'surf-chart-key', children: [_jsxs("p", { className: 'surf-chart-axis-label', children: [yLabel, " (", unit, ")"] }), legendPosition === 'top' && legend] }), hasValues ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: 'surf-chart-plot', onKeyDownCapture: (event) => {
399
463
  if (event.key === 'Escape')
400
464
  setDismissed(true);
401
465
  else if (event.key === 'ArrowLeft' ||
@@ -455,5 +519,5 @@ export const Chart = function Chart({ title, description, data, series, unit, xL
455
519
  }, children: text.showAll })] })) : (_jsx("p", { children: text.empty })) })), legendPosition === 'bottom' && (_jsx("div", { className: 'surf-chart-key', "data-position": 'bottom', children: legend }))] }), hasValues && (_jsx("p", { className: 'surf-chart-help', id: `${id}-keys`, children: text.keyboardHelp })), _jsx("div", { className: 'surf-chart-inspector', ref: setHost, role: 'status', "aria-live": 'polite', "aria-atomic": 'true', "aria-label": text.values(title), hidden: !hasValues }), _jsxs("details", { className: 'surf-chart-table', onToggle: (event) => {
456
520
  if (event.currentTarget.open)
457
521
  setTableOpened(true);
458
- }, children: [_jsx("summary", { children: text.viewTable }), tableOpened && (_jsx(Table.Container, { label: text.table(title), orientation: 'both', scrollChain: 'contain', children: _jsxs(Table.Root, { children: [_jsx(Table.Caption, { children: text.tableCaption(unit) }), _jsx(Table.Head, { children: _jsxs(Table.Row, { children: [_jsx(Table.HeaderCell, { scope: 'col', children: xLabel }), series.map((s) => (_jsxs(Table.HeaderCell, { scope: 'col', numeric: true, children: [s.label, " (", unit, ")"] }, s.key)))] }) }), _jsx(Table.Body, { children: rows.length ? (rows.map((row) => (_jsxs(Table.Row, { children: [_jsx(Table.HeaderCell, { scope: 'row', children: row.label }), series.map((s) => (_jsx(Table.Cell, { numeric: true, children: formatNumber(row.values[s.key]) ?? text.missing }, s.key)))] }, row.id)))) : (_jsx(Table.Row, { children: _jsx(Table.Cell, { colSpan: series.length + 1, children: text.noRows }) })) })] }) }))] })] }));
522
+ }, children: [_jsx("summary", { children: text.viewTable }), tableOpened && (_jsx(Table.Container, { label: text.table(title), orientation: 'both', scrollChain: 'contain', children: _jsxs(Table.Root, { density: density, children: [_jsx(Table.Caption, { children: text.tableCaption(unit) }), _jsx(Table.Head, { children: _jsxs(Table.Row, { children: [_jsx(Table.HeaderCell, { scope: 'col', children: xLabel }), series.map((s) => (_jsxs(Table.HeaderCell, { scope: 'col', numeric: true, children: [s.label, " (", unit, ")"] }, s.key)))] }) }), _jsx(Table.Body, { children: rows.length ? (rows.map((row) => (_jsxs(Table.Row, { children: [_jsx(Table.HeaderCell, { scope: 'row', children: row.label }), series.map((s) => (_jsx(Table.Cell, { numeric: true, children: formatNumber(row.values[s.key]) ?? text.missing }, s.key)))] }, row.id)))) : (_jsx(Table.Row, { children: _jsx(Table.Cell, { colSpan: series.length + 1, children: text.noRows }) })) })] }) }))] })] }));
459
523
  };
package/dist/choice.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
- import { type ComponentSizeAlias } from './sizing.js';
2
+ import { type ComponentSize } from './sizing.js';
3
3
  export declare const ChoiceResetPaint: React.Context<number>;
4
4
  /** Choice controls follow the surrounding size; `size` sets one control's scale. */
5
5
  export type ChoiceSize = {
6
- size?: ComponentSizeAlias;
6
+ size?: ComponentSize;
7
7
  };
@@ -1,6 +1,2 @@
1
1
  /** Joins class names, skipping empty ones. */
2
2
  export declare function cx(...classes: (string | false | null | undefined)[]): string;
3
- /** The data-size value: a deprecated short spelling (sm, md, lg, icon-sm, icon-xs,
4
- * icon-lg) renders as its full name, so both spellings meet the same CSS; other values
5
- * such as xs or icon pass through. */
6
- export declare function sizeName<Size extends string>(size?: Size): import("./size.js").ComponentSize | Size | "icon-small" | "icon-large" | undefined;
@@ -1,18 +1,4 @@
1
- // Class and data attribute helpers, with no React: server components use them too.
2
- import { normalizeSize } from './size.js';
3
1
  /** Joins class names, skipping empty ones. */
4
2
  export function cx(...classes) {
5
3
  return classes.filter(Boolean).join(' ');
6
4
  }
7
- /** The data-size value: a deprecated short spelling (sm, md, lg, icon-sm, icon-xs,
8
- * icon-lg) renders as its full name, so both spellings meet the same CSS; other values
9
- * such as xs or icon pass through. */
10
- export function sizeName(size) {
11
- return size === 'sm' || size === 'md' || size === 'lg'
12
- ? normalizeSize(size)
13
- : size === 'icon-sm' || size === 'icon-xs'
14
- ? 'icon-small'
15
- : size === 'icon-lg'
16
- ? 'icon-large'
17
- : size;
18
- }