cetec-design-system 3.2.1-0 → 3.4.0-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/README.md CHANGED
@@ -79,8 +79,8 @@ Repository plan documents now live in `plans/`.
79
79
 
80
80
  This design system is built on **Panda CSS** with a strict tokens-first approach:
81
81
 
82
- - **Tokens** (`src/styles/tokens.ts`) - Design tokens for colors, spacing, typography, shadows, etc.
83
- - **Semantic Tokens** (`src/styles/semanticTokens.ts`) - Theme-specific token aliases for light/dark modes
82
+ - **Tokens** (`src/styles/primitives/`) - Design tokens for colors, spacing, typography, shadows, etc.
83
+ - **Semantic Tokens** (`src/styles/semantics/`) - Theme-specific token aliases for light/dark modes
84
84
  - **Recipes** (`src/recipes/`) - Component style variants (button, input, text, etc.)
85
85
  - **Components** (`src/components/`) - React components using recipes and tokens
86
86
  - **Icons** (`src/utils/svgsSource/`) - SVG icons compiled into a sprite system
@@ -99,8 +99,8 @@ This design system is built on **Panda CSS** with a strict tokens-first approach
99
99
 
100
100
  1. Create component directory: `src/components/[ComponentName]/`
101
101
  2. Create a recipe in `src/recipes/[componentname].ts` defining style variants
102
- 3. Export recipe from `src/recipes/index.ts`
103
- 4. Standard `recipes` are registered automatically, but new `slotRecipes` need to be manually registered in `panda.config.ts` under `theme.extend.recipes`
102
+ 3. Export the recipe from `src/recipes/recipes-regular.ts` or, for a slot recipe, `src/recipes/recipes-slot.ts`
103
+ 4. Both files are registered automatically through the preset (`src/cetec-preset.ts`); no manual registration is needed
104
104
  5. Run `npm run prepare` to regenerate Panda CSS types
105
105
  6. Implement component using the recipe
106
106
  7. Create Storybook story in component directory: `ComponentName.stories.tsx`
@@ -156,7 +156,7 @@ building `styled-system` and `styles.css`.
156
156
  1. **Import the stylesheet** at the root of your project:
157
157
 
158
158
  ```typescript
159
- import '@styled-system/styles.css';
159
+ import 'cetec-design-system/styles.css';
160
160
  ```
161
161
 
162
162
  2. **Wrap your app with ThemeProvider**:
@@ -189,6 +189,20 @@ function MyComponent() {
189
189
  }
190
190
  ```
191
191
 
192
+ ### Fonts
193
+
194
+ The package ships the Ruda and Recursive variable fonts. Import the font
195
+ stylesheet once, next to the main stylesheet:
196
+
197
+ ```typescript
198
+ import 'cetec-design-system/fonts.css';
199
+ ```
200
+
201
+ `fonts.css` points at `./fonts/*.woff2` relative to itself, so any bundler
202
+ (Vite, webpack, esbuild) resolves the files from `node_modules`. Consumers do not
203
+ need to install `@fontsource-variable/*`. The source is
204
+ `src/styles/font-imports.css`; `tools/build-fonts.mjs` builds the published copy.
205
+
192
206
  ## Release Process
193
207
 
194
208
  This project uses [Auto](https://intuit.github.io/auto/) for automated releases and changelog generation.
@@ -0,0 +1,93 @@
1
+ Copyright 2019 The Recursive Project Authors (github.com/arrowtype/recursive)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,93 @@
1
+ Copyright 2019 The Ruda Project Authors (https://github.com/marmonsalve/Ruda-new)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
package/dist/fonts.css ADDED
@@ -0,0 +1,35 @@
1
+ /*
2
+ --------------------
3
+ Font imports
4
+ --------------------
5
+ */
6
+
7
+ @layer base {
8
+ /* ruda-latin-wght-normal */
9
+ @font-face {
10
+ font-family: 'Ruda Variable';
11
+ font-style: normal;
12
+ font-display: swap;
13
+ font-weight: 400 900;
14
+ src: url('./fonts/ruda-latin-wght-normal.woff2')
15
+ format('woff2-variations');
16
+ unicode-range:
17
+ U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
18
+ U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
19
+ U+2212, U+2215, U+FEFF, U+FFFD;
20
+ }
21
+ /* recursive-latin-wght-normal */
22
+ /* https://www.recursive.design/ */
23
+ @font-face {
24
+ font-family: 'Recursive Variable';
25
+ font-style: oblique 0deg 15deg;
26
+ font-display: swap;
27
+ font-weight: 300 1000;
28
+ src: url('./fonts/recursive-latin-full-normal.woff2')
29
+ format('woff2-variations');
30
+ unicode-range:
31
+ U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
32
+ U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
33
+ U+2212, U+2215, U+FEFF, U+FFFD;
34
+ }
35
+ }
package/dist/index.js CHANGED
@@ -757,6 +757,7 @@ const labelVariantMap = {
757
757
  "32",
758
758
  "40",
759
759
  "48",
760
+ "56",
760
761
  "64",
761
762
  "72",
762
763
  "80",
@@ -826,6 +827,7 @@ const linkVariantMap = {
826
827
  "32",
827
828
  "40",
828
829
  "48",
830
+ "56",
829
831
  "64",
830
832
  "72",
831
833
  "80",
@@ -1576,6 +1578,7 @@ const textVariantMap = {
1576
1578
  "32",
1577
1579
  "40",
1578
1580
  "48",
1581
+ "56",
1579
1582
  "64",
1580
1583
  "72",
1581
1584
  "80",
@@ -11078,6 +11081,10 @@ const tokens = {
11078
11081
  "value": "var(--cetec-sizes-48)",
11079
11082
  "variable": "var(--cetec-font-sizes-48)"
11080
11083
  },
11084
+ "fontSizes.56": {
11085
+ "value": "var(--cetec-sizes-56)",
11086
+ "variable": "var(--cetec-font-sizes-56)"
11087
+ },
11081
11088
  "fontSizes.64": {
11082
11089
  "value": "var(--cetec-sizes-64)",
11083
11090
  "variable": "var(--cetec-font-sizes-64)"
@@ -11390,10 +11397,18 @@ const tokens = {
11390
11397
  "value": "var(--cetec-sizes-4)",
11391
11398
  "variable": "var(--cetec-radii-4)"
11392
11399
  },
11400
+ "radii.6": {
11401
+ "value": "var(--cetec-sizes-6)",
11402
+ "variable": "var(--cetec-radii-6)"
11403
+ },
11393
11404
  "radii.8": {
11394
11405
  "value": "var(--cetec-sizes-8)",
11395
11406
  "variable": "var(--cetec-radii-8)"
11396
11407
  },
11408
+ "radii.12": {
11409
+ "value": "var(--cetec-sizes-12)",
11410
+ "variable": "var(--cetec-radii-12)"
11411
+ },
11397
11412
  "radii.16": {
11398
11413
  "value": "var(--cetec-sizes-16)",
11399
11414
  "variable": "var(--cetec-radii-16)"
@@ -14933,6 +14948,21 @@ const createOverlayMiddleware = (options = {}) => {
14933
14948
  ...extras
14934
14949
  ];
14935
14950
  };
14951
+ const availableHeightMiddleware = (options = {}) => {
14952
+ const { matchReferenceWidth = false, padding = 8 } = options;
14953
+ return size({
14954
+ padding,
14955
+ apply({ rects, elements, availableHeight }) {
14956
+ if (matchReferenceWidth) {
14957
+ elements.floating.style.minWidth = `${rects.reference.width}px`;
14958
+ }
14959
+ elements.floating.style.setProperty(
14960
+ "--available-height",
14961
+ `${Math.max(availableHeight, 0)}px`
14962
+ );
14963
+ }
14964
+ });
14965
+ };
14936
14966
  const useOverlayFloating = (options) => {
14937
14967
  const {
14938
14968
  open,
@@ -14988,13 +15018,15 @@ const Tooltip = (props) => {
14988
15018
  placement = "bottom",
14989
15019
  offset: offset2 = 8,
14990
15020
  delay,
15021
+ disabled = false,
14991
15022
  ...rest
14992
15023
  } = props;
14993
15024
  const [className, otherProps] = splitProps(rest);
14994
15025
  const [isOpen, setIsOpen] = useState(false);
15026
+ if (disabled && isOpen) setIsOpen(false);
14995
15027
  const arrowRef = useRef(null);
14996
15028
  const { refs, elements, floatingStyles, context: context2 } = useOverlayFloating({
14997
- open: isOpen,
15029
+ open: isOpen && !disabled,
14998
15030
  onOpenChange: setIsOpen,
14999
15031
  placement,
15000
15032
  middleware: createOverlayMiddleware({
@@ -15002,10 +15034,10 @@ const Tooltip = (props) => {
15002
15034
  extras: [arrow({ element: arrowRef })]
15003
15035
  })
15004
15036
  });
15005
- const hover = useHover(context2, { move: false, delay });
15006
- const focus = useFocus(context2);
15007
- const dismiss = useDismiss(context2);
15008
- const role = useRole(context2, { role: "tooltip" });
15037
+ const hover = useHover(context2, { move: false, delay, enabled: !disabled });
15038
+ const focus = useFocus(context2, { enabled: !disabled });
15039
+ const dismiss = useDismiss(context2, { enabled: !disabled });
15040
+ const role = useRole(context2, { role: "tooltip", enabled: !disabled });
15009
15041
  const { getReferenceProps, getFloatingProps } = useInteractions([
15010
15042
  hover,
15011
15043
  focus,
@@ -15027,7 +15059,7 @@ const Tooltip = (props) => {
15027
15059
  children
15028
15060
  }
15029
15061
  ),
15030
- isOpen && /* @__PURE__ */ jsx(FloatingPortal, { children: /* @__PURE__ */ jsx(DsChainPortalRoot, { reference: elements.domReference, children: /* @__PURE__ */ jsxs(
15062
+ isOpen && !disabled && /* @__PURE__ */ jsx(FloatingPortal, { children: /* @__PURE__ */ jsx(DsChainPortalRoot, { reference: elements.domReference, children: /* @__PURE__ */ jsxs(
15031
15063
  Box,
15032
15064
  {
15033
15065
  ...dsComponent("Tooltip"),
@@ -16540,6 +16572,7 @@ const ChipGroupContext = createContext(
16540
16572
  const useChipGroup = () => {
16541
16573
  return useContext(ChipGroupContext);
16542
16574
  };
16575
+ const MAX_VISIBLE_ITEMS = 2;
16543
16576
  const Chip = (props) => {
16544
16577
  const groupContext = useChipGroup();
16545
16578
  const fieldContext = useFieldContext();
@@ -16547,6 +16580,7 @@ const Chip = (props) => {
16547
16580
  const {
16548
16581
  size: sizeProp,
16549
16582
  children,
16583
+ items,
16550
16584
  before,
16551
16585
  after,
16552
16586
  loading,
@@ -16576,19 +16610,20 @@ const Chip = (props) => {
16576
16610
  const isDisabled = disabled || loading;
16577
16611
  const isSelectable = value !== void 0 && groupContext !== null;
16578
16612
  const hasPrimaryAction = Boolean(onClick) || isSelectable;
16613
+ const isEmpty = (items == null ? void 0 : items.length) === 0;
16579
16614
  const isMultiSelected = isSelectable && value !== void 0 && groupContext !== null && groupContext.type === "multi" && Array.isArray(groupContext.value) && groupContext.value.includes(value);
16580
16615
  const isSelected = isSelectable && groupContext !== null ? groupContext.type === "single" ? groupContext.value === value : isMultiSelected : false;
16581
16616
  const hasBefore = Boolean(before) || isMultiSelected;
16582
16617
  const hasAfter = Boolean(after) || dismissable;
16583
16618
  useEffect(() => {
16584
- if (!isSelectable || isDisabled || !registerChip || !unregisterChip || value === void 0) {
16619
+ if (!isSelectable || isDisabled || isEmpty || !registerChip || !unregisterChip || value === void 0) {
16585
16620
  return;
16586
16621
  }
16587
16622
  registerChip(value, buttonRef);
16588
16623
  return () => {
16589
16624
  unregisterChip(value);
16590
16625
  };
16591
- }, [isDisabled, isSelectable, registerChip, unregisterChip, value]);
16626
+ }, [isDisabled, isEmpty, isSelectable, registerChip, unregisterChip, value]);
16592
16627
  const classes = chip({
16593
16628
  size: size2,
16594
16629
  before: hasBefore,
@@ -16659,7 +16694,9 @@ const Chip = (props) => {
16659
16694
  }
16660
16695
  return 0;
16661
16696
  };
16662
- const resolvedDismissLabel = dismissLabel || `Remove ${children}`;
16697
+ const isOverflowing = items !== void 0 && items.length > MAX_VISIBLE_ITEMS;
16698
+ const label2 = items ? isOverflowing ? `${items.slice(0, MAX_VISIBLE_ITEMS).join(", ")} +${items.length - MAX_VISIBLE_ITEMS}` : items.join(", ") : children;
16699
+ const resolvedDismissLabel = dismissLabel || `Remove ${items ? items.join(", ") : children}`;
16663
16700
  const handleDismissClick = (e) => {
16664
16701
  e.stopPropagation();
16665
16702
  onDismiss == null ? void 0 : onDismiss();
@@ -16689,7 +16726,10 @@ const Chip = (props) => {
16689
16726
  const bodyContent = /* @__PURE__ */ jsxs(Fragment, { children: [
16690
16727
  isMultiSelected && /* @__PURE__ */ jsx(Box, { as: "span", className: classes.slot, children: /* @__PURE__ */ jsx(Icon, { name: "check", fill: "icon.inverse", "aria-hidden": true }) }),
16691
16728
  renderSlot(before, "before"),
16692
- /* @__PURE__ */ jsx(Box, { as: "span", className: classes.mainContent, children }),
16729
+ /* @__PURE__ */ jsx(Box, { as: "span", className: classes.mainContent, children: items ? /* @__PURE__ */ jsxs(Fragment, { children: [
16730
+ /* @__PURE__ */ jsx("span", { "aria-hidden": isOverflowing || void 0, children: label2 }),
16731
+ isOverflowing && /* @__PURE__ */ jsx(Box, { as: "span", srOnly: true, children: items.join(", ") })
16732
+ ] }) : label2 }),
16693
16733
  renderSlot(after, "after")
16694
16734
  ] });
16695
16735
  const body = hasPrimaryAction ? /* @__PURE__ */ jsx(
@@ -16719,6 +16759,7 @@ const Chip = (props) => {
16719
16759
  {
16720
16760
  as: "span",
16721
16761
  className: classes.body,
16762
+ tabIndex: isOverflowing && !isDisabled ? 0 : void 0,
16722
16763
  "data-deleted": deleted ? true : void 0,
16723
16764
  "data-disabled": isDisabled || void 0,
16724
16765
  "data-error": error2 || void 0,
@@ -16727,6 +16768,9 @@ const Chip = (props) => {
16727
16768
  children: bodyContent
16728
16769
  }
16729
16770
  );
16771
+ if (isEmpty) {
16772
+ return null;
16773
+ }
16730
16774
  return /* @__PURE__ */ jsxs(
16731
16775
  Box,
16732
16776
  {
@@ -16742,7 +16786,7 @@ const Chip = (props) => {
16742
16786
  "aria-invalid": invalid || void 0,
16743
16787
  ...otherProps,
16744
16788
  children: [
16745
- body,
16789
+ items ? /* @__PURE__ */ jsx(Tooltip, { text: items.join(", "), disabled: !isOverflowing || loading, children: body }) : body,
16746
16790
  dismissable && dismissButton,
16747
16791
  loading && /* @__PURE__ */ jsx(Spinner, { size: "sm", centered: true })
16748
16792
  ]
@@ -18440,9 +18484,14 @@ const Menu = (props) => {
18440
18484
  } = props;
18441
18485
  const [className, otherProps] = splitProps(rest);
18442
18486
  const userStyle = otherProps.style;
18443
- const classes = menu({ density, panel, layer: floatingLayer });
18444
- const listClassName = list({ density });
18445
18487
  const hasReference = Boolean(trigger) && !inline;
18488
+ const classes = menu({
18489
+ density,
18490
+ panel,
18491
+ layer: floatingLayer,
18492
+ scrollable: hasReference && !panel
18493
+ });
18494
+ const listClassName = list({ density });
18446
18495
  const [uncontrolledOpen, setUncontrolledOpen] = useState(
18447
18496
  defaultOpen ?? false
18448
18497
  );
@@ -18478,7 +18527,7 @@ const Menu = (props) => {
18478
18527
  placement,
18479
18528
  strategy,
18480
18529
  middleware: createOverlayMiddleware({
18481
- extras: [size()]
18530
+ extras: [availableHeightMiddleware()]
18482
18531
  })
18483
18532
  });
18484
18533
  const listRef = useRef([]);
@@ -18585,6 +18634,25 @@ const Menu = (props) => {
18585
18634
  const shouldUsePanelDiginProbeFill = Boolean(panel) && subMenuInteraction === "digin";
18586
18635
  const shouldUseDiginSizing = subMenuInteraction === "digin" && hasVisibleResults;
18587
18636
  const sizeProbeRef = useRef(null);
18637
+ const activeLevelRef = useRef(null);
18638
+ const activeBackHeaderRef = useRef(null);
18639
+ useLayoutEffect(() => {
18640
+ const levelEl = activeLevelRef.current;
18641
+ const headerEl = activeBackHeaderRef.current;
18642
+ if (!levelEl) return;
18643
+ if (!headerEl) {
18644
+ levelEl.style.removeProperty("--menu-back-header-height");
18645
+ return;
18646
+ }
18647
+ const update = () => levelEl.style.setProperty(
18648
+ "--menu-back-header-height",
18649
+ `${headerEl.offsetHeight}px`
18650
+ );
18651
+ update();
18652
+ const observer = new ResizeObserver(update);
18653
+ observer.observe(headerEl);
18654
+ return () => observer.disconnect();
18655
+ }, [diginDepth, density, hasVisibleResults]);
18588
18656
  useLayoutEffect(() => {
18589
18657
  if (!isMenuVisible || !shouldUseDiginSizing) {
18590
18658
  setWrapperSize({ width: null, height: null });
@@ -18722,6 +18790,7 @@ const Menu = (props) => {
18722
18790
  children: /* @__PURE__ */ jsx(FloatingList, { elementsRef: listRef, labelsRef, children: /* @__PURE__ */ jsxs(
18723
18791
  Box,
18724
18792
  {
18793
+ ref: activeLevelRef,
18725
18794
  className: classes.level,
18726
18795
  style: {
18727
18796
  flex: `0 0 ${levelWidthPercent}%`
@@ -18732,6 +18801,7 @@ const Menu = (props) => {
18732
18801
  {
18733
18802
  as: "button",
18734
18803
  type: "button",
18804
+ ref: activeBackHeaderRef,
18735
18805
  className: classes.backHeader,
18736
18806
  onClick: rootContextValue.onPopDiginLevel,
18737
18807
  children: [
@@ -19240,7 +19310,8 @@ const SubMenu = (props) => {
19240
19310
  const resolvedDensity = typeof density === "string" ? density : rootContext.density;
19241
19311
  const classes = menu({
19242
19312
  density: resolvedDensity,
19243
- layer: floatingLayer
19313
+ layer: floatingLayer,
19314
+ scrollable: true
19244
19315
  });
19245
19316
  const listClassName = list({ density: resolvedDensity });
19246
19317
  const itemClassName = listItem({
@@ -19288,7 +19359,8 @@ const SubMenu = (props) => {
19288
19359
  middleware: [
19289
19360
  offset({ mainAxis: 0, alignmentAxis: -4 }),
19290
19361
  flip(),
19291
- shift({ padding: 8 })
19362
+ shift({ padding: 8 }),
19363
+ availableHeightMiddleware()
19292
19364
  ]
19293
19365
  });
19294
19366
  const hover = useHover(floating.context, {
@@ -23165,7 +23237,7 @@ const Select = (props) => {
23165
23237
  name,
23166
23238
  disabled = false,
23167
23239
  error: error2 = false,
23168
- size: size$12 = "md",
23240
+ size: size2 = "md",
23169
23241
  density = defaultDensity,
23170
23242
  autoSize = false,
23171
23243
  "data-ds-component": dsComponentName,
@@ -23244,19 +23316,8 @@ const Select = (props) => {
23244
23316
  extras: [
23245
23317
  // Floating UI only positions the listbox; without a height cap a long
23246
23318
  // option list overflows the viewport on whichever side flip() picks.
23247
- // Only measured values are written here; the `menu` recipe's
23248
- // `scrollable` variant applies the cap and scrolling. `padding`
23249
- // mirrors the overlay middleware's default `shiftPadding`.
23250
- size({
23251
- padding: 8,
23252
- apply({ rects, elements, availableHeight }) {
23253
- elements.floating.style.minWidth = `${rects.reference.width}px`;
23254
- elements.floating.style.setProperty(
23255
- "--available-height",
23256
- `${Math.max(availableHeight, 0)}px`
23257
- );
23258
- }
23259
- })
23319
+ // The `menu` recipe's `scrollable` variant applies the cap.
23320
+ availableHeightMiddleware({ matchReferenceWidth: true })
23260
23321
  ]
23261
23322
  })
23262
23323
  });
@@ -23300,14 +23361,14 @@ const Select = (props) => {
23300
23361
  placeholder
23301
23362
  );
23302
23363
  const selectedOptions = getSelectedOptions(options, value, multiple);
23303
- const classes = select({ size: size$12, multiple, autoSize });
23364
+ const classes = select({ size: size2, multiple, autoSize });
23304
23365
  const menuClasses = menu({
23305
23366
  density,
23306
23367
  layer: floatingLayer,
23307
23368
  scrollable: true
23308
23369
  });
23309
23370
  const hasValue = value !== null && value !== void 0 && value !== "";
23310
- const chipSize = resolveChipSize(size$12);
23371
+ const chipSize = resolveChipSize(size2);
23311
23372
  const accessibleName = typeof displayValue === "string" && displayValue.length > 0 ? displayValue : placeholder;
23312
23373
  const handleTriggerKeyDown = (event) => {
23313
23374
  if (disabled) {