@backstage/ui 0.15.0-next.1 → 0.15.0-next.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 (32) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/components/Accordion/Accordion.module.css.esm.js +2 -2
  3. package/dist/components/Box/Box.module.css.esm.js +2 -2
  4. package/dist/components/Card/Card.module.css.esm.js +2 -2
  5. package/dist/components/Combobox/Combobox.esm.js +72 -0
  6. package/dist/components/Combobox/Combobox.esm.js.map +1 -0
  7. package/dist/components/Combobox/Combobox.module.css.esm.js +8 -0
  8. package/dist/components/Combobox/Combobox.module.css.esm.js.map +1 -0
  9. package/dist/components/Combobox/ComboboxInput.esm.js +21 -0
  10. package/dist/components/Combobox/ComboboxInput.esm.js.map +1 -0
  11. package/dist/components/Combobox/ComboboxListBox.esm.js +46 -0
  12. package/dist/components/Combobox/ComboboxListBox.esm.js.map +1 -0
  13. package/dist/components/Combobox/definition.esm.js +74 -0
  14. package/dist/components/Combobox/definition.esm.js.map +1 -0
  15. package/dist/components/Flex/Flex.module.css.esm.js +2 -2
  16. package/dist/components/Grid/Grid.module.css.esm.js +2 -2
  17. package/dist/components/Header/Header.module.css.esm.js +2 -2
  18. package/dist/components/Link/Link.esm.js +4 -2
  19. package/dist/components/Link/Link.esm.js.map +1 -1
  20. package/dist/components/Link/Link.module.css.esm.js +2 -2
  21. package/dist/components/PluginHeader/PluginHeader.esm.js +8 -17
  22. package/dist/components/PluginHeader/PluginHeader.esm.js.map +1 -1
  23. package/dist/components/PluginHeader/PluginHeader.module.css.esm.js +2 -2
  24. package/dist/components/Table/hooks/useCompletePagination.esm.js +28 -11
  25. package/dist/components/Table/hooks/useCompletePagination.esm.js.map +1 -1
  26. package/dist/components/Table/hooks/useDebouncedValue.esm.js +16 -0
  27. package/dist/components/Table/hooks/useDebouncedValue.esm.js.map +1 -0
  28. package/dist/css/styles.css +34 -0
  29. package/dist/index.d.ts +200 -56
  30. package/dist/index.esm.js +2 -0
  31. package/dist/index.esm.js.map +1 -1
  32. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # @backstage/ui
2
2
 
3
+ ## 0.15.0-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 37535b2: Added a public `--bui-bg-inherit` CSS variable that resolves to the background
8
+ color of the nearest enclosing bg provider (`Box`, `Flex`, `Grid`, `Card`,
9
+ `Accordion`, or any element with a `data-bg` attribute), falling back to
10
+ `--bui-bg-app`. Use it from CSS for sticky or fixed elements that need to match
11
+ their surrounding surface without hardcoding a specific level.
12
+
13
+ ```css
14
+ .searchBarContainer {
15
+ position: sticky;
16
+ top: 0;
17
+ background-color: var(--bui-bg-inherit);
18
+ }
19
+ ```
20
+
21
+ As part of this change, the `data-bg` painting rules previously duplicated in
22
+ `Box`, `Flex`, `Grid`, `Accordion`, and `Card` have been centralized into a
23
+ single source in `core.css`. Painting and component behavior are unchanged for
24
+ all existing usages, with one minor expansion: any element with a `data-bg`
25
+ attribute (including provider elements and any element that sets it directly)
26
+ is now painted, not only `Box`/`Flex`/`Grid`/`Card`/`Accordion` elements.
27
+
28
+ - 5b85902: Fix `Card href=...` not showing a focus indicator on keyboard navigation. `Link` now composes `useFocusRing`, emits `data-focus-visible`, and renders a `--bui-ring` outline when keyboard-focused. The Card's existing focus-ring CSS matches when the trigger is focused.
29
+
30
+ _Affected components_: Card, Link
31
+
32
+ - 38bb056: Adjusted PluginHeader spacing and borders so headers with and without tabs align more consistently with surrounding page content, including when paired with page headers.
33
+
34
+ **Affected components:** PluginHeader, Header
35
+
36
+ - 25909ba: Added `searchDebounceMs` and `filterDebounceMs` options to `useTable` in `complete` mode. Both default to `0` (no debounce, no observable change for existing consumers); set them to defer the client-side filter/search/sort pipeline on large datasets without reimplementing input-layer debouncing. The controlled `search` / `onSearchChange` and `filter` / `onFilterChange` callbacks continue to fire on every change.
37
+
38
+ **Affected components:** Table
39
+
40
+ - ddca41f: Added a new `Combobox` component. It pairs a text input with a filterable dropdown of options and supports single selection, sectioned options, icons, sizes, and custom typed values via `allowsCustomValue`.
41
+
42
+ **Affected components:** Combobox
43
+
3
44
  ## 0.15.0-next.1
4
45
 
5
46
  ### Minor Changes
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
2
 
3
- var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Accordion_bui-Accordion__b3bc0ab8d6 {\n width: 100%;\n border-radius: var(--bui-radius-3);\n padding: var(--bui-space-3);\n\n &[data-bg='neutral-1'] {\n background-color: var(--bui-bg-neutral-1);\n }\n\n &[data-bg='neutral-2'] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n &[data-bg='neutral-3'] {\n background-color: var(--bui-bg-neutral-3);\n }\n }\n\n .Accordion_bui-AccordionTrigger__b3bc0ab8d6 {\n all: unset;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .Accordion_bui-AccordionTriggerButton__b3bc0ab8d6 {\n all: unset;\n width: 100%;\n color: var(--bui-fg-primary);\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n text-align: left;\n\n &[data-focus-visible] {\n outline: none;\n transition: none;\n box-shadow: inset 0 0 0 2px var(--bui-ring);\n }\n\n &[data-disabled='true'] {\n background-color: transparent;\n color: var(--bui-fg-disabled);\n cursor: not-allowed;\n }\n }\n\n .Accordion_bui-AccordionTriggerTitle__b3bc0ab8d6 {\n font-size: var(--bui-font-size-4);\n font-weight: var(--bui-font-weight-bold);\n line-height: 140%;\n }\n\n .Accordion_bui-AccordionTriggerSubtitle__b3bc0ab8d6 {\n font-size: var(--bui-font-size-2);\n line-height: 140%;\n color: var(--bui-fg-secondary);\n }\n\n .Accordion_bui-AccordionTriggerIcon__b3bc0ab8d6 {\n transition: transform 150ms ease-out;\n flex-shrink: 0;\n width: 1rem;\n height: 1rem;\n\n .Accordion_bui-Accordion__b3bc0ab8d6[data-expanded='true'] > .Accordion_bui-AccordionTrigger__b3bc0ab8d6 & {\n transform: rotate(180deg);\n }\n }\n\n .Accordion_bui-AccordionPanel__b3bc0ab8d6 {\n .Accordion_bui-Accordion__b3bc0ab8d6[data-expanded='true'] > & {\n padding-top: var(--bui-space-1);\n }\n }\n\n .Accordion_bui-AccordionGroup__b3bc0ab8d6 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-3);\n width: 100%;\n }\n}\n";
4
- var styles = {"bui-Accordion":"Accordion_bui-Accordion__b3bc0ab8d6","bui-AccordionTrigger":"Accordion_bui-AccordionTrigger__b3bc0ab8d6","bui-AccordionTriggerButton":"Accordion_bui-AccordionTriggerButton__b3bc0ab8d6","bui-AccordionTriggerTitle":"Accordion_bui-AccordionTriggerTitle__b3bc0ab8d6","bui-AccordionTriggerSubtitle":"Accordion_bui-AccordionTriggerSubtitle__b3bc0ab8d6","bui-AccordionTriggerIcon":"Accordion_bui-AccordionTriggerIcon__b3bc0ab8d6","bui-AccordionPanel":"Accordion_bui-AccordionPanel__b3bc0ab8d6","bui-AccordionGroup":"Accordion_bui-AccordionGroup__b3bc0ab8d6"};
3
+ var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Accordion_bui-Accordion__c1521aeef0 {\n width: 100%;\n border-radius: var(--bui-radius-3);\n padding: var(--bui-space-3);\n }\n\n .Accordion_bui-Accordion__c1521aeef0[data-bg='danger'],\n .Accordion_bui-Accordion__c1521aeef0[data-bg='warning'],\n .Accordion_bui-Accordion__c1521aeef0[data-bg='success'] {\n background-color: transparent;\n }\n\n .Accordion_bui-AccordionTrigger__c1521aeef0 {\n all: unset;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .Accordion_bui-AccordionTriggerButton__c1521aeef0 {\n all: unset;\n width: 100%;\n color: var(--bui-fg-primary);\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n text-align: left;\n\n &[data-focus-visible] {\n outline: none;\n transition: none;\n box-shadow: inset 0 0 0 2px var(--bui-ring);\n }\n\n &[data-disabled='true'] {\n background-color: transparent;\n color: var(--bui-fg-disabled);\n cursor: not-allowed;\n }\n }\n\n .Accordion_bui-AccordionTriggerTitle__c1521aeef0 {\n font-size: var(--bui-font-size-4);\n font-weight: var(--bui-font-weight-bold);\n line-height: 140%;\n }\n\n .Accordion_bui-AccordionTriggerSubtitle__c1521aeef0 {\n font-size: var(--bui-font-size-2);\n line-height: 140%;\n color: var(--bui-fg-secondary);\n }\n\n .Accordion_bui-AccordionTriggerIcon__c1521aeef0 {\n transition: transform 150ms ease-out;\n flex-shrink: 0;\n width: 1rem;\n height: 1rem;\n\n .Accordion_bui-Accordion__c1521aeef0[data-expanded='true'] > .Accordion_bui-AccordionTrigger__c1521aeef0 & {\n transform: rotate(180deg);\n }\n }\n\n .Accordion_bui-AccordionPanel__c1521aeef0 {\n .Accordion_bui-Accordion__c1521aeef0[data-expanded='true'] > & {\n padding-top: var(--bui-space-1);\n }\n }\n\n .Accordion_bui-AccordionGroup__c1521aeef0 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-3);\n width: 100%;\n }\n}\n";
4
+ var styles = {"bui-Accordion":"Accordion_bui-Accordion__c1521aeef0","bui-AccordionTrigger":"Accordion_bui-AccordionTrigger__c1521aeef0","bui-AccordionTriggerButton":"Accordion_bui-AccordionTriggerButton__c1521aeef0","bui-AccordionTriggerTitle":"Accordion_bui-AccordionTriggerTitle__c1521aeef0","bui-AccordionTriggerSubtitle":"Accordion_bui-AccordionTriggerSubtitle__c1521aeef0","bui-AccordionTriggerIcon":"Accordion_bui-AccordionTriggerIcon__c1521aeef0","bui-AccordionPanel":"Accordion_bui-AccordionPanel__c1521aeef0","bui-AccordionGroup":"Accordion_bui-AccordionGroup__c1521aeef0"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { styles as default };
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
2
 
3
- var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Box_bui-Box__11dddfa448 {\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-regular);\n color: var(--bui-fg-primary);\n }\n\n .Box_bui-Box__11dddfa448[data-bg='neutral-1'] {\n background-color: var(--bui-bg-neutral-1);\n }\n\n .Box_bui-Box__11dddfa448[data-bg='neutral-2'] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n .Box_bui-Box__11dddfa448[data-bg='neutral-3'] {\n background-color: var(--bui-bg-neutral-3);\n }\n\n .Box_bui-Box__11dddfa448[data-bg='danger'] {\n background-color: var(--bui-bg-danger);\n }\n\n .Box_bui-Box__11dddfa448[data-bg='warning'] {\n background-color: var(--bui-bg-warning);\n }\n\n .Box_bui-Box__11dddfa448[data-bg='success'] {\n background-color: var(--bui-bg-success);\n }\n}\n";
4
- var styles = {"bui-Box":"Box_bui-Box__11dddfa448"};
3
+ var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Box_bui-Box__ab80215ae2 {\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-regular);\n color: var(--bui-fg-primary);\n }\n}\n";
4
+ var styles = {"bui-Box":"Box_bui-Box__ab80215ae2"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { styles as default };
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
2
 
3
- var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Card_bui-Card__c3fb74b317 {\n display: flex;\n flex-direction: column;\n border-radius: var(--bui-radius-3);\n color: var(--bui-fg-primary);\n overflow: auto;\n min-height: 0;\n width: 100%;\n position: relative;\n padding: var(--bui-space-3);\n }\n\n .Card_bui-Card__c3fb74b317[data-bg='neutral-1'] {\n --bui-card-bg: var(--bui-bg-neutral-1);\n }\n\n .Card_bui-Card__c3fb74b317[data-bg='neutral-2'] {\n --bui-card-bg: var(--bui-bg-neutral-2);\n }\n\n .Card_bui-Card__c3fb74b317[data-bg='neutral-3'] {\n --bui-card-bg: var(--bui-bg-neutral-3);\n }\n\n .Card_bui-Card__c3fb74b317:has(.Card_bui-CardHeader__c3fb74b317, .Card_bui-CardBody__c3fb74b317, .Card_bui-CardFooter__c3fb74b317) {\n padding: 0;\n }\n\n /*\n * Cursor and hover tint are applied at the card level so they cover the\n * entire surface.\n */\n .Card_bui-Card__c3fb74b317[data-interactive] {\n cursor: pointer;\n\n &::after {\n content: '';\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, currentColor 5%, transparent);\n border-radius: inherit;\n pointer-events: none;\n z-index: 3;\n opacity: 0;\n transition: opacity 200ms ease-in-out;\n }\n\n &:hover::after {\n opacity: 1;\n }\n }\n\n .Card_bui-Card__c3fb74b317[data-interactive]:has(.Card_bui-CardTrigger__c3fb74b317[data-focus-visible]) {\n outline: 2px solid var(--bui-ring);\n outline-offset: -2px;\n }\n\n .Card_bui-CardTrigger__c3fb74b317 {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(100%);\n white-space: nowrap;\n border: 0;\n }\n\n .Card_bui-CardHeader__c3fb74b317 {\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-3);\n }\n\n .Card_bui-CardBody__c3fb74b317 {\n flex: 1;\n min-height: var(--bui-space-6);\n overflow: auto;\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-3);\n }\n\n @keyframes Card_bui-card-body-shadow__c3fb74b317 {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n .Card_bui-Card__c3fb74b317:has(.Card_bui-CardHeader__c3fb74b317) .Card_bui-CardBody__c3fb74b317 {\n padding-block-start: 0;\n }\n\n .Card_bui-Card__c3fb74b317:has(.Card_bui-CardFooter__c3fb74b317) .Card_bui-CardBody__c3fb74b317 {\n padding-block-end: 0;\n }\n\n @supports (animation-timeline: scroll()) {\n .Card_bui-Card__c3fb74b317:has(.Card_bui-CardHeader__c3fb74b317) .Card_bui-CardBody__c3fb74b317::before {\n content: '';\n position: sticky;\n top: 0;\n display: block;\n height: 1.5rem;\n margin-bottom: -1.5rem;\n background: linear-gradient(\n to bottom,\n var(--bui-card-bg),\n rgb(from var(--bui-card-bg) r g b / 0)\n );\n pointer-events: none;\n opacity: 0;\n animation: Card_bui-card-body-shadow__c3fb74b317 linear both;\n animation-timeline: scroll();\n animation-range: 0px 2.5rem;\n }\n\n .Card_bui-Card__c3fb74b317:has(.Card_bui-CardFooter__c3fb74b317) .Card_bui-CardBody__c3fb74b317::after {\n content: '';\n position: sticky;\n bottom: 0;\n display: block;\n height: 1.5rem;\n margin-top: -1.5rem;\n background: linear-gradient(\n to top,\n var(--bui-card-bg),\n rgb(from var(--bui-card-bg) r g b / 0)\n );\n pointer-events: none;\n opacity: 0;\n animation: Card_bui-card-body-shadow__c3fb74b317 linear forwards,\n Card_bui-card-body-shadow__c3fb74b317 linear forwards reverse;\n animation-timeline: scroll(), scroll();\n animation-range: 0px 1px, calc(100% - 2.5rem) 100%;\n }\n }\n\n .Card_bui-CardFooter__c3fb74b317 {\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-3);\n }\n}\n";
4
- var styles = {"bui-Card":"Card_bui-Card__c3fb74b317","bui-CardHeader":"Card_bui-CardHeader__c3fb74b317","bui-CardBody":"Card_bui-CardBody__c3fb74b317","bui-CardFooter":"Card_bui-CardFooter__c3fb74b317","bui-CardTrigger":"Card_bui-CardTrigger__c3fb74b317","bui-card-body-shadow":"Card_bui-card-body-shadow__c3fb74b317"};
3
+ var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Card_bui-Card__d452bb14b2 {\n display: flex;\n flex-direction: column;\n border-radius: var(--bui-radius-3);\n color: var(--bui-fg-primary);\n overflow: auto;\n min-height: 0;\n width: 100%;\n position: relative;\n padding: var(--bui-space-3);\n }\n\n .Card_bui-Card__d452bb14b2:has(.Card_bui-CardHeader__d452bb14b2, .Card_bui-CardBody__d452bb14b2, .Card_bui-CardFooter__d452bb14b2) {\n padding: 0;\n }\n\n /*\n * Cursor and hover tint are applied at the card level so they cover the\n * entire surface.\n */\n .Card_bui-Card__d452bb14b2[data-interactive] {\n cursor: pointer;\n\n &::after {\n content: '';\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, currentColor 5%, transparent);\n border-radius: inherit;\n pointer-events: none;\n z-index: 3;\n opacity: 0;\n transition: opacity 200ms ease-in-out;\n }\n\n &:hover::after {\n opacity: 1;\n }\n }\n\n .Card_bui-Card__d452bb14b2[data-interactive]:has(.Card_bui-CardTrigger__d452bb14b2[data-focus-visible]) {\n outline: 2px solid var(--bui-ring);\n outline-offset: -2px;\n }\n\n .Card_bui-CardTrigger__d452bb14b2 {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(100%);\n white-space: nowrap;\n border: 0;\n }\n\n .Card_bui-CardHeader__d452bb14b2 {\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-3);\n }\n\n .Card_bui-CardBody__d452bb14b2 {\n flex: 1;\n min-height: var(--bui-space-6);\n overflow: auto;\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-3);\n }\n\n @keyframes Card_bui-card-body-shadow__d452bb14b2 {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n .Card_bui-Card__d452bb14b2:has(.Card_bui-CardHeader__d452bb14b2) .Card_bui-CardBody__d452bb14b2 {\n padding-block-start: 0;\n }\n\n .Card_bui-Card__d452bb14b2:has(.Card_bui-CardFooter__d452bb14b2) .Card_bui-CardBody__d452bb14b2 {\n padding-block-end: 0;\n }\n\n @supports (animation-timeline: scroll()) {\n .Card_bui-Card__d452bb14b2:has(.Card_bui-CardHeader__d452bb14b2) .Card_bui-CardBody__d452bb14b2::before {\n content: '';\n position: sticky;\n top: 0;\n display: block;\n height: 1.5rem;\n margin-bottom: -1.5rem;\n background: linear-gradient(\n to bottom,\n var(--bui-bg-inherit),\n rgb(from var(--bui-bg-inherit) r g b / 0)\n );\n pointer-events: none;\n opacity: 0;\n animation: Card_bui-card-body-shadow__d452bb14b2 linear both;\n animation-timeline: scroll();\n animation-range: 0px 2.5rem;\n }\n\n .Card_bui-Card__d452bb14b2:has(.Card_bui-CardFooter__d452bb14b2) .Card_bui-CardBody__d452bb14b2::after {\n content: '';\n position: sticky;\n bottom: 0;\n display: block;\n height: 1.5rem;\n margin-top: -1.5rem;\n background: linear-gradient(\n to top,\n var(--bui-bg-inherit),\n rgb(from var(--bui-bg-inherit) r g b / 0)\n );\n pointer-events: none;\n opacity: 0;\n animation: Card_bui-card-body-shadow__d452bb14b2 linear forwards,\n Card_bui-card-body-shadow__d452bb14b2 linear forwards reverse;\n animation-timeline: scroll(), scroll();\n animation-range: 0px 1px, calc(100% - 2.5rem) 100%;\n }\n }\n\n .Card_bui-CardFooter__d452bb14b2 {\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-3);\n }\n}\n";
4
+ var styles = {"bui-Card":"Card_bui-Card__d452bb14b2","bui-CardHeader":"Card_bui-CardHeader__d452bb14b2","bui-CardBody":"Card_bui-CardBody__d452bb14b2","bui-CardFooter":"Card_bui-CardFooter__d452bb14b2","bui-CardTrigger":"Card_bui-CardTrigger__d452bb14b2","bui-card-body-shadow":"Card_bui-card-body-shadow__d452bb14b2"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { styles as default };
@@ -0,0 +1,72 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { forwardRef, useEffect } from 'react';
3
+ import { ComboBox } from 'react-aria-components';
4
+ import { useFilter } from 'react-aria';
5
+ import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
6
+ import { ComboboxDefinition } from './definition.esm.js';
7
+ import { Popover } from '../Popover/Popover.esm.js';
8
+ import '../Popover/Popover.module.css.esm.js';
9
+ import { FieldLabel } from '../FieldLabel/FieldLabel.esm.js';
10
+ import '../FieldLabel/FieldLabel.module.css.esm.js';
11
+ import { FieldError } from '../FieldError/FieldError.esm.js';
12
+ import '../FieldError/FieldError.module.css.esm.js';
13
+ import { ComboboxInput } from './ComboboxInput.esm.js';
14
+ import { ComboboxListBox } from './ComboboxListBox.esm.js';
15
+
16
+ const Combobox = forwardRef(
17
+ (props, ref) => {
18
+ const { contains } = useFilter({ sensitivity: "base" });
19
+ const { ownProps, restProps, dataAttributes } = useDefinition(
20
+ ComboboxDefinition,
21
+ props
22
+ );
23
+ const {
24
+ classes,
25
+ label,
26
+ description,
27
+ options,
28
+ icon,
29
+ placeholder,
30
+ isRequired,
31
+ secondaryLabel
32
+ } = ownProps;
33
+ const ariaLabel = restProps["aria-label"];
34
+ const ariaLabelledBy = restProps["aria-labelledby"];
35
+ useEffect(() => {
36
+ if (!label && !ariaLabel && !ariaLabelledBy) {
37
+ console.warn(
38
+ "Combobox requires either a visible label, aria-label, or aria-labelledby for accessibility"
39
+ );
40
+ }
41
+ }, [label, ariaLabel, ariaLabelledBy]);
42
+ const secondaryLabelText = secondaryLabel || (isRequired ? "Required" : null);
43
+ return /* @__PURE__ */ jsxs(
44
+ ComboBox,
45
+ {
46
+ className: classes.root,
47
+ defaultFilter: contains,
48
+ ...dataAttributes,
49
+ ref,
50
+ ...restProps,
51
+ children: [
52
+ /* @__PURE__ */ jsx(
53
+ FieldLabel,
54
+ {
55
+ label,
56
+ secondaryLabel: secondaryLabelText,
57
+ description,
58
+ descriptionSlot: "description"
59
+ }
60
+ ),
61
+ /* @__PURE__ */ jsx(ComboboxInput, { icon, placeholder }),
62
+ /* @__PURE__ */ jsx(FieldError, {}),
63
+ /* @__PURE__ */ jsx(Popover, { className: classes.popover, hideArrow: true, ...dataAttributes, children: /* @__PURE__ */ jsx(ComboboxListBox, { options }) })
64
+ ]
65
+ }
66
+ );
67
+ }
68
+ );
69
+ Combobox.displayName = "Combobox";
70
+
71
+ export { Combobox };
72
+ //# sourceMappingURL=Combobox.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Combobox.esm.js","sources":["../../../src/components/Combobox/Combobox.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { forwardRef, useEffect } from 'react';\nimport { ComboBox as AriaComboBox } from 'react-aria-components';\nimport { useFilter } from 'react-aria';\nimport { ComboboxProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { ComboboxDefinition } from './definition';\nimport { Popover } from '../Popover';\nimport { FieldLabel } from '../FieldLabel';\nimport { FieldError } from '../FieldError';\nimport { ComboboxInput } from './ComboboxInput';\nimport { ComboboxListBox } from './ComboboxListBox';\n\n/**\n * A text input combined with a dropdown list of options. The user can type to filter\n * suggestions, navigate with the keyboard, and pick a value. With `allowsCustomValue`\n * the typed text can be committed even if no option matches.\n *\n * @public\n */\nexport const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(\n (props, ref) => {\n const { contains } = useFilter({ sensitivity: 'base' });\n const { ownProps, restProps, dataAttributes } = useDefinition(\n ComboboxDefinition,\n props,\n );\n const {\n classes,\n label,\n description,\n options,\n icon,\n placeholder,\n isRequired,\n secondaryLabel,\n } = ownProps;\n\n const ariaLabel = restProps['aria-label'];\n const ariaLabelledBy = restProps['aria-labelledby'];\n\n useEffect(() => {\n if (!label && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n 'Combobox requires either a visible label, aria-label, or aria-labelledby for accessibility',\n );\n }\n }, [label, ariaLabel, ariaLabelledBy]);\n\n const secondaryLabelText =\n secondaryLabel || (isRequired ? 'Required' : null);\n\n return (\n <AriaComboBox\n className={classes.root}\n defaultFilter={contains}\n {...dataAttributes}\n ref={ref}\n {...restProps}\n >\n <FieldLabel\n label={label}\n secondaryLabel={secondaryLabelText}\n description={description}\n descriptionSlot=\"description\"\n />\n <ComboboxInput icon={icon} placeholder={placeholder} />\n <FieldError />\n <Popover className={classes.popover} hideArrow {...dataAttributes}>\n <ComboboxListBox options={options} />\n </Popover>\n </AriaComboBox>\n );\n },\n);\n\nCombobox.displayName = 'Combobox';\n"],"names":["AriaComboBox"],"mappings":";;;;;;;;;;;;;;;AAmCO,MAAM,QAAA,GAAW,UAAA;AAAA,EACtB,CAAC,OAAO,GAAA,KAAQ;AACd,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,UAAU,EAAE,WAAA,EAAa,QAAQ,CAAA;AACtD,IAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAe,GAAI,aAAA;AAAA,MAC9C,kBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM;AAAA,MACJ,OAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA;AAAA,MACA,WAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACF,GAAI,QAAA;AAEJ,IAAA,MAAM,SAAA,GAAY,UAAU,YAAY,CAAA;AACxC,IAAA,MAAM,cAAA,GAAiB,UAAU,iBAAiB,CAAA;AAElD,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,CAAC,KAAA,IAAS,CAAC,SAAA,IAAa,CAAC,cAAA,EAAgB;AAC3C,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN;AAAA,SACF;AAAA,MACF;AAAA,IACF,CAAA,EAAG,CAAC,KAAA,EAAO,SAAA,EAAW,cAAc,CAAC,CAAA;AAErC,IAAA,MAAM,kBAAA,GACJ,cAAA,KAAmB,UAAA,GAAa,UAAA,GAAa,IAAA,CAAA;AAE/C,IAAA,uBACE,IAAA;AAAA,MAACA,QAAA;AAAA,MAAA;AAAA,QACC,WAAW,OAAA,CAAQ,IAAA;AAAA,QACnB,aAAA,EAAe,QAAA;AAAA,QACd,GAAG,cAAA;AAAA,QACJ,GAAA;AAAA,QACC,GAAG,SAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,KAAA;AAAA,cACA,cAAA,EAAgB,kBAAA;AAAA,cAChB,WAAA;AAAA,cACA,eAAA,EAAgB;AAAA;AAAA,WAClB;AAAA,0BACA,GAAA,CAAC,aAAA,EAAA,EAAc,IAAA,EAAY,WAAA,EAA0B,CAAA;AAAA,8BACpD,UAAA,EAAA,EAAW,CAAA;AAAA,0BACZ,GAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAW,OAAA,CAAQ,OAAA,EAAS,SAAA,EAAS,IAAA,EAAE,GAAG,cAAA,EACjD,QAAA,kBAAA,GAAA,CAAC,eAAA,EAAA,EAAgB,OAAA,EAAkB,CAAA,EACrC;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AAEA,QAAA,CAAS,WAAA,GAAc,UAAA;;;;"}
@@ -0,0 +1,8 @@
1
+ import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
+
3
+ var css_248z = "/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Combobox_bui-Combobox__90f6359000,\n .Combobox_bui-ComboboxPopover__90f6359000 {\n &[data-size='small'] {\n --combobox-item-height: 2rem;\n }\n\n &[data-size='medium'] {\n --combobox-item-height: 2.5rem;\n }\n }\n\n .Combobox_bui-ComboboxPopover__90f6359000 {\n min-width: var(--trigger-width);\n\n .bui-PopoverContent {\n padding: 0;\n }\n }\n\n .Combobox_bui-ComboboxInput__90f6359000 {\n box-sizing: border-box;\n border-radius: var(--bui-radius-3);\n border: none;\n outline: none;\n background-color: var(--bui-bg-neutral-1);\n transition: box-shadow 0.2s ease-in-out;\n\n &[data-on-bg='neutral-1'] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n &[data-on-bg='neutral-2'] {\n background-color: var(--bui-bg-neutral-3);\n }\n\n &[data-on-bg='neutral-3'] {\n background-color: var(--bui-bg-neutral-4);\n }\n\n .Combobox_bui-Combobox__90f6359000[data-focus-within] & {\n box-shadow: inset 0 0 0 1px var(--bui-ring);\n }\n\n .Combobox_bui-Combobox__90f6359000[data-invalid] & {\n box-shadow: inset 0 0 0 1px var(--bui-border-danger);\n }\n\n display: flex;\n align-items: center;\n gap: var(--bui-space-2);\n width: 100%;\n height: var(--combobox-item-height);\n\n .Combobox_bui-Combobox__90f6359000[data-size='small'] & {\n padding-inline: var(--bui-space-3) 0;\n }\n\n .Combobox_bui-Combobox__90f6359000[data-size='medium'] & {\n padding-inline: var(--bui-space-4) 0;\n }\n\n &[data-disabled] {\n cursor: not-allowed;\n }\n }\n\n .Combobox_bui-ComboboxInputIcon__90f6359000 {\n display: grid;\n place-content: center;\n flex-shrink: 0;\n color: var(--bui-fg-secondary);\n pointer-events: none;\n\n .Combobox_bui-Combobox__90f6359000[data-size='small'] & svg {\n width: 1rem;\n height: 1rem;\n }\n\n .Combobox_bui-Combobox__90f6359000[data-size='medium'] & svg {\n width: 1.25rem;\n height: 1.25rem;\n }\n }\n\n .Combobox_bui-ComboboxInputField__90f6359000 {\n flex: 1;\n min-width: 0;\n width: 100%;\n border: none;\n outline: none;\n background-color: transparent;\n padding: 0;\n color: var(--bui-fg-primary);\n font-size: var(--bui-font-size-3);\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-regular);\n line-height: var(--combobox-item-height);\n height: 100%;\n text-overflow: ellipsis;\n\n &::placeholder {\n color: var(--bui-fg-secondary);\n }\n\n &[disabled] {\n cursor: not-allowed;\n color: var(--bui-fg-disabled);\n }\n }\n\n .Combobox_bui-ComboboxInputChevron__90f6359000 {\n flex-shrink: 0;\n flex-grow: 0;\n display: grid;\n place-content: center;\n width: var(--combobox-item-height);\n height: var(--combobox-item-height);\n background-color: transparent;\n border: none;\n padding: 0;\n margin: 0;\n cursor: pointer;\n color: var(--bui-fg-secondary);\n outline: none;\n transition: color 0.2s ease-in-out;\n\n &:hover {\n color: var(--bui-fg-primary);\n }\n\n & svg {\n .Combobox_bui-Combobox__90f6359000[data-size='small'] & {\n width: 1rem;\n height: 1rem;\n }\n\n .Combobox_bui-Combobox__90f6359000[data-size='medium'] & {\n width: 1.25rem;\n height: 1.25rem;\n }\n }\n\n &[data-disabled] {\n cursor: not-allowed;\n color: var(--bui-fg-disabled);\n }\n }\n\n .Combobox_bui-ComboboxList__90f6359000 {\n overflow: auto;\n min-height: 0;\n padding-block: var(--bui-space-1);\n padding-inline: var(--bui-space-1);\n\n &[data-focus-visible] {\n outline: none;\n }\n }\n\n .Combobox_bui-ComboboxItem__90f6359000 {\n box-sizing: border-box;\n position: relative;\n display: grid;\n grid-template-areas: 'icon text';\n grid-template-columns: 1rem 1fr;\n align-items: center;\n min-height: var(--combobox-item-height);\n padding-block: var(--bui-space-1);\n padding-left: var(--bui-space-3);\n padding-right: var(--bui-space-4);\n color: var(--bui-fg-primary);\n cursor: pointer;\n user-select: none;\n font-size: var(--bui-font-size-3);\n gap: var(--bui-space-2);\n outline: none;\n border-radius: var(--bui-radius-2);\n\n &[data-focused] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n &[data-disabled] {\n cursor: not-allowed;\n color: var(--bui-fg-disabled);\n }\n\n &[data-selected] .Combobox_bui-ComboboxItemIndicator__90f6359000 {\n opacity: 1;\n }\n }\n\n .Combobox_bui-ComboboxItemIndicator__90f6359000 {\n grid-area: icon;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.2s ease-in-out;\n }\n\n .Combobox_bui-ComboboxItemLabel__90f6359000 {\n flex: 1;\n grid-area: text;\n }\n\n .Combobox_bui-ComboboxSection__90f6359000 {\n &:first-child .Combobox_bui-ComboboxSectionHeader__90f6359000 {\n padding-top: 0;\n }\n }\n\n .Combobox_bui-ComboboxSectionHeader__90f6359000 {\n height: 2rem;\n display: flex;\n align-items: center;\n padding-top: var(--bui-space-3);\n padding-left: var(--bui-space-3);\n color: var(--bui-fg-primary);\n font-size: var(--bui-font-size-1);\n font-weight: bold;\n letter-spacing: 0.05rem;\n text-transform: uppercase;\n }\n\n .Combobox_bui-ComboboxNoResults__90f6359000 {\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-2);\n color: var(--bui-fg-secondary);\n font-size: var(--bui-font-size-3);\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-regular);\n }\n}\n";
4
+ var styles = {"bui-Combobox":"Combobox_bui-Combobox__90f6359000","bui-ComboboxPopover":"Combobox_bui-ComboboxPopover__90f6359000","bui-ComboboxInput":"Combobox_bui-ComboboxInput__90f6359000","bui-ComboboxInputIcon":"Combobox_bui-ComboboxInputIcon__90f6359000","bui-ComboboxInputField":"Combobox_bui-ComboboxInputField__90f6359000","bui-ComboboxInputChevron":"Combobox_bui-ComboboxInputChevron__90f6359000","bui-ComboboxList":"Combobox_bui-ComboboxList__90f6359000","bui-ComboboxItem":"Combobox_bui-ComboboxItem__90f6359000","bui-ComboboxItemIndicator":"Combobox_bui-ComboboxItemIndicator__90f6359000","bui-ComboboxItemLabel":"Combobox_bui-ComboboxItemLabel__90f6359000","bui-ComboboxSection":"Combobox_bui-ComboboxSection__90f6359000","bui-ComboboxSectionHeader":"Combobox_bui-ComboboxSectionHeader__90f6359000","bui-ComboboxNoResults":"Combobox_bui-ComboboxNoResults__90f6359000"};
5
+ styleInject(css_248z);
6
+
7
+ export { styles as default };
8
+ //# sourceMappingURL=Combobox.module.css.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Combobox.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,21 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Group, Input, Button } from 'react-aria-components';
3
+ import { RiArrowDownSLine } from '@remixicon/react';
4
+ import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
5
+ import { ComboboxInputDefinition } from './definition.esm.js';
6
+
7
+ function ComboboxInput(props) {
8
+ const { ownProps, dataAttributes } = useDefinition(
9
+ ComboboxInputDefinition,
10
+ props
11
+ );
12
+ const { classes, icon, placeholder } = ownProps;
13
+ return /* @__PURE__ */ jsxs(Group, { className: classes.root, ...dataAttributes, children: [
14
+ icon ? /* @__PURE__ */ jsx("div", { className: classes.icon, "aria-hidden": "true", children: icon }) : null,
15
+ /* @__PURE__ */ jsx(Input, { className: classes.input, placeholder }),
16
+ /* @__PURE__ */ jsx(Button, { className: classes.chevron, children: /* @__PURE__ */ jsx(RiArrowDownSLine, { "aria-hidden": "true" }) })
17
+ ] });
18
+ }
19
+
20
+ export { ComboboxInput };
21
+ //# sourceMappingURL=ComboboxInput.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComboboxInput.esm.js","sources":["../../../src/components/Combobox/ComboboxInput.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Button, Group, Input } from 'react-aria-components';\nimport { RiArrowDownSLine } from '@remixicon/react';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { ComboboxInputDefinition } from './definition';\nimport type { ComboboxInputOwnProps } from './types';\n\nexport function ComboboxInput(props: ComboboxInputOwnProps) {\n const { ownProps, dataAttributes } = useDefinition(\n ComboboxInputDefinition,\n props,\n );\n const { classes, icon, placeholder } = ownProps;\n\n return (\n <Group className={classes.root} {...dataAttributes}>\n {icon ? (\n <div className={classes.icon} aria-hidden=\"true\">\n {icon}\n </div>\n ) : null}\n <Input className={classes.input} placeholder={placeholder} />\n <Button className={classes.chevron}>\n <RiArrowDownSLine aria-hidden=\"true\" />\n </Button>\n </Group>\n );\n}\n"],"names":[],"mappings":";;;;;;AAsBO,SAAS,cAAc,KAAA,EAA8B;AAC1D,EAAA,MAAM,EAAE,QAAA,EAAU,cAAA,EAAe,GAAI,aAAA;AAAA,IACnC,uBAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,IAAA,EAAM,WAAA,EAAY,GAAI,QAAA;AAEvC,EAAA,4BACG,KAAA,EAAA,EAAM,SAAA,EAAW,OAAA,CAAQ,IAAA,EAAO,GAAG,cAAA,EACjC,QAAA,EAAA;AAAA,IAAA,IAAA,mBACC,GAAA,CAAC,SAAI,SAAA,EAAW,OAAA,CAAQ,MAAM,aAAA,EAAY,MAAA,EACvC,gBACH,CAAA,GACE,IAAA;AAAA,oBACJ,GAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAW,OAAA,CAAQ,OAAO,WAAA,EAA0B,CAAA;AAAA,oBAC3D,GAAA,CAAC,UAAO,SAAA,EAAW,OAAA,CAAQ,SACzB,QAAA,kBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,aAAA,EAAY,MAAA,EAAO,CAAA,EACvC;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
@@ -0,0 +1,46 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { ListBox, ListBoxSection, Header, ListBoxItem, Text } from 'react-aria-components';
3
+ import { RiCheckLine } from '@remixicon/react';
4
+ import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
5
+ import { ComboboxListBoxDefinition, ComboboxSectionDefinition, ComboboxListBoxItemDefinition } from './definition.esm.js';
6
+
7
+ const NoResults = () => {
8
+ const { ownProps } = useDefinition(ComboboxListBoxDefinition, {});
9
+ const { classes } = ownProps;
10
+ return /* @__PURE__ */ jsx("div", { className: classes.noResults, children: "No results found." });
11
+ };
12
+ function ComboboxItem({ option }) {
13
+ const { ownProps } = useDefinition(ComboboxListBoxItemDefinition, {});
14
+ const { classes } = ownProps;
15
+ return /* @__PURE__ */ jsxs(
16
+ ListBoxItem,
17
+ {
18
+ id: option.value,
19
+ textValue: option.label,
20
+ className: classes.root,
21
+ isDisabled: option.disabled,
22
+ children: [
23
+ /* @__PURE__ */ jsx("div", { className: classes.indicator, children: /* @__PURE__ */ jsx(RiCheckLine, { "aria-hidden": "true" }) }),
24
+ /* @__PURE__ */ jsx(Text, { slot: "label", className: classes.label, children: option.label })
25
+ ]
26
+ }
27
+ );
28
+ }
29
+ function ComboboxSectionItems({ section }) {
30
+ const { ownProps } = useDefinition(ComboboxSectionDefinition, {});
31
+ const { classes } = ownProps;
32
+ return /* @__PURE__ */ jsxs(ListBoxSection, { className: classes.root, children: [
33
+ /* @__PURE__ */ jsx(Header, { className: classes.header, children: section.title }),
34
+ section.options.map((option) => /* @__PURE__ */ jsx(ComboboxItem, { option }, option.value))
35
+ ] });
36
+ }
37
+ function ComboboxListBox(props) {
38
+ const { ownProps } = useDefinition(ComboboxListBoxDefinition, props);
39
+ const { classes, options } = ownProps;
40
+ return /* @__PURE__ */ jsx(ListBox, { className: classes.root, renderEmptyState: () => /* @__PURE__ */ jsx(NoResults, {}), children: options?.map(
41
+ (item) => "options" in item ? /* @__PURE__ */ jsx(ComboboxSectionItems, { section: item }, item.title) : /* @__PURE__ */ jsx(ComboboxItem, { option: item }, item.value)
42
+ ) });
43
+ }
44
+
45
+ export { ComboboxListBox };
46
+ //# sourceMappingURL=ComboboxListBox.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComboboxListBox.esm.js","sources":["../../../src/components/Combobox/ComboboxListBox.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ListBox,\n ListBoxItem,\n ListBoxSection,\n Header,\n Text,\n} from 'react-aria-components';\nimport { RiCheckLine } from '@remixicon/react';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport {\n ComboboxListBoxDefinition,\n ComboboxListBoxItemDefinition,\n ComboboxSectionDefinition,\n} from './definition';\nimport type { Option, OptionSection, ComboboxListBoxOwnProps } from './types';\n\nconst NoResults = () => {\n const { ownProps } = useDefinition(ComboboxListBoxDefinition, {});\n const { classes } = ownProps;\n\n return <div className={classes.noResults}>No results found.</div>;\n};\n\nfunction ComboboxItem({ option }: { option: Option }) {\n const { ownProps } = useDefinition(ComboboxListBoxItemDefinition, {});\n const { classes } = ownProps;\n\n return (\n <ListBoxItem\n id={option.value}\n textValue={option.label}\n className={classes.root}\n isDisabled={option.disabled}\n >\n <div className={classes.indicator}>\n <RiCheckLine aria-hidden=\"true\" />\n </div>\n <Text slot=\"label\" className={classes.label}>\n {option.label}\n </Text>\n </ListBoxItem>\n );\n}\n\nfunction ComboboxSectionItems({ section }: { section: OptionSection }) {\n const { ownProps } = useDefinition(ComboboxSectionDefinition, {});\n const { classes } = ownProps;\n\n return (\n <ListBoxSection className={classes.root}>\n <Header className={classes.header}>{section.title}</Header>\n {section.options.map(option => (\n <ComboboxItem key={option.value} option={option} />\n ))}\n </ListBoxSection>\n );\n}\n\nexport function ComboboxListBox(props: ComboboxListBoxOwnProps) {\n const { ownProps } = useDefinition(ComboboxListBoxDefinition, props);\n const { classes, options } = ownProps;\n\n return (\n <ListBox className={classes.root} renderEmptyState={() => <NoResults />}>\n {options?.map(item =>\n 'options' in item ? (\n <ComboboxSectionItems key={item.title} section={item} />\n ) : (\n <ComboboxItem key={item.value} option={item} />\n ),\n )}\n </ListBox>\n );\n}\n"],"names":[],"mappings":";;;;;;AAgCA,MAAM,YAAY,MAAM;AACtB,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,aAAA,CAAc,yBAAA,EAA2B,EAAE,CAAA;AAChE,EAAA,MAAM,EAAE,SAAQ,GAAI,QAAA;AAEpB,EAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,WAAW,QAAA,EAAA,mBAAA,EAAiB,CAAA;AAC7D,CAAA;AAEA,SAAS,YAAA,CAAa,EAAE,MAAA,EAAO,EAAuB;AACpD,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,aAAA,CAAc,6BAAA,EAA+B,EAAE,CAAA;AACpE,EAAA,MAAM,EAAE,SAAQ,GAAI,QAAA;AAEpB,EAAA,uBACE,IAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,IAAI,MAAA,CAAO,KAAA;AAAA,MACX,WAAW,MAAA,CAAO,KAAA;AAAA,MAClB,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,YAAY,MAAA,CAAO,QAAA;AAAA,MAEnB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAW,OAAA,CAAQ,SAAA,EACtB,8BAAC,WAAA,EAAA,EAAY,aAAA,EAAY,QAAO,CAAA,EAClC,CAAA;AAAA,wBACA,GAAA,CAAC,QAAK,IAAA,EAAK,OAAA,EAAQ,WAAW,OAAA,CAAQ,KAAA,EACnC,iBAAO,KAAA,EACV;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,SAAS,oBAAA,CAAqB,EAAE,OAAA,EAAQ,EAA+B;AACrE,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,aAAA,CAAc,yBAAA,EAA2B,EAAE,CAAA;AAChE,EAAA,MAAM,EAAE,SAAQ,GAAI,QAAA;AAEpB,EAAA,uBACE,IAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EAAW,OAAA,CAAQ,IAAA,EACjC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAW,OAAA,CAAQ,MAAA,EAAS,kBAAQ,KAAA,EAAM,CAAA;AAAA,IACjD,OAAA,CAAQ,QAAQ,GAAA,CAAI,CAAA,MAAA,yBAClB,YAAA,EAAA,EAAgC,MAAA,EAAA,EAAd,MAAA,CAAO,KAAuB,CAClD;AAAA,GAAA,EACH,CAAA;AAEJ;AAEO,SAAS,gBAAgB,KAAA,EAAgC;AAC9D,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,aAAA,CAAc,2BAA2B,KAAK,CAAA;AACnE,EAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAQ,GAAI,QAAA;AAE7B,EAAA,uBACE,GAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAW,OAAA,CAAQ,IAAA,EAAM,kBAAkB,sBAAM,GAAA,CAAC,SAAA,EAAA,EAAU,CAAA,EAClE,QAAA,EAAA,OAAA,EAAS,GAAA;AAAA,IAAI,CAAA,IAAA,KACZ,SAAA,IAAa,IAAA,mBACX,GAAA,CAAC,wBAAsC,OAAA,EAAS,IAAA,EAAA,EAArB,IAAA,CAAK,KAAsB,oBAEtD,GAAA,CAAC,YAAA,EAAA,EAA8B,MAAA,EAAQ,IAAA,EAAA,EAApB,KAAK,KAAqB;AAAA,GAEjD,EACF,CAAA;AAEJ;;;;"}
@@ -0,0 +1,74 @@
1
+ import 'react/jsx-runtime';
2
+ import 'clsx';
3
+ import '../../hooks/useBreakpoint.esm.js';
4
+ import '../../hooks/useBg.esm.js';
5
+ import '../../hooks/useDefinition/helpers.esm.js';
6
+ import '../../analytics/useAnalytics.esm.js';
7
+ import 'react-router-dom';
8
+ import { defineComponent } from '../../hooks/useDefinition/defineComponent.esm.js';
9
+ import styles from './Combobox.module.css.esm.js';
10
+
11
+ const ComboboxDefinition = defineComponent()({
12
+ styles,
13
+ classNames: {
14
+ root: "bui-Combobox",
15
+ popover: "bui-ComboboxPopover"
16
+ },
17
+ propDefs: {
18
+ icon: {},
19
+ size: { dataAttribute: true, default: "small" },
20
+ options: {},
21
+ placeholder: {},
22
+ label: {},
23
+ secondaryLabel: {},
24
+ description: {},
25
+ isRequired: {},
26
+ className: {}
27
+ }
28
+ });
29
+ const ComboboxInputDefinition = defineComponent()(
30
+ {
31
+ styles,
32
+ classNames: {
33
+ root: "bui-ComboboxInput",
34
+ icon: "bui-ComboboxInputIcon",
35
+ input: "bui-ComboboxInputField",
36
+ chevron: "bui-ComboboxInputChevron"
37
+ },
38
+ bg: "consumer",
39
+ propDefs: {
40
+ icon: {},
41
+ placeholder: {}
42
+ }
43
+ }
44
+ );
45
+ const ComboboxListBoxDefinition = defineComponent()({
46
+ styles,
47
+ classNames: {
48
+ root: "bui-ComboboxList",
49
+ noResults: "bui-ComboboxNoResults"
50
+ },
51
+ propDefs: {
52
+ options: {}
53
+ }
54
+ });
55
+ const ComboboxListBoxItemDefinition = defineComponent()({
56
+ styles,
57
+ classNames: {
58
+ root: "bui-ComboboxItem",
59
+ indicator: "bui-ComboboxItemIndicator",
60
+ label: "bui-ComboboxItemLabel"
61
+ },
62
+ propDefs: {}
63
+ });
64
+ const ComboboxSectionDefinition = defineComponent()({
65
+ styles,
66
+ classNames: {
67
+ root: "bui-ComboboxSection",
68
+ header: "bui-ComboboxSectionHeader"
69
+ },
70
+ propDefs: {}
71
+ });
72
+
73
+ export { ComboboxDefinition, ComboboxInputDefinition, ComboboxListBoxDefinition, ComboboxListBoxItemDefinition, ComboboxSectionDefinition };
74
+ //# sourceMappingURL=definition.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.esm.js","sources":["../../../src/components/Combobox/definition.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { defineComponent } from '../../hooks/useDefinition';\nimport type {\n ComboboxOwnProps,\n ComboboxInputOwnProps,\n ComboboxListBoxOwnProps,\n ComboboxListBoxItemOwnProps,\n ComboboxSectionOwnProps,\n} from './types';\nimport styles from './Combobox.module.css';\n\n/**\n * Component definition for Combobox\n * @public\n */\nexport const ComboboxDefinition = defineComponent<ComboboxOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Combobox',\n popover: 'bui-ComboboxPopover',\n },\n propDefs: {\n icon: {},\n size: { dataAttribute: true, default: 'small' },\n options: {},\n placeholder: {},\n label: {},\n secondaryLabel: {},\n description: {},\n isRequired: {},\n className: {},\n },\n});\n\n/**\n * Component definition for ComboboxInput\n * @public\n */\nexport const ComboboxInputDefinition = defineComponent<ComboboxInputOwnProps>()(\n {\n styles,\n classNames: {\n root: 'bui-ComboboxInput',\n icon: 'bui-ComboboxInputIcon',\n input: 'bui-ComboboxInputField',\n chevron: 'bui-ComboboxInputChevron',\n },\n bg: 'consumer',\n propDefs: {\n icon: {},\n placeholder: {},\n },\n },\n);\n\n/**\n * Component definition for ComboboxListBox\n * @public\n */\nexport const ComboboxListBoxDefinition =\n defineComponent<ComboboxListBoxOwnProps>()({\n styles,\n classNames: {\n root: 'bui-ComboboxList',\n noResults: 'bui-ComboboxNoResults',\n },\n propDefs: {\n options: {},\n },\n });\n\n/**\n * Component definition for ComboboxListBoxItem\n * @public\n */\nexport const ComboboxListBoxItemDefinition =\n defineComponent<ComboboxListBoxItemOwnProps>()({\n styles,\n classNames: {\n root: 'bui-ComboboxItem',\n indicator: 'bui-ComboboxItemIndicator',\n label: 'bui-ComboboxItemLabel',\n },\n propDefs: {},\n });\n\n/**\n * Component definition for ComboboxSection\n * @public\n */\nexport const ComboboxSectionDefinition =\n defineComponent<ComboboxSectionOwnProps>()({\n styles,\n classNames: {\n root: 'bui-ComboboxSection',\n header: 'bui-ComboboxSectionHeader',\n },\n propDefs: {},\n });\n"],"names":[],"mappings":";;;;;;;;;;AA8BO,MAAM,kBAAA,GAAqB,iBAAkC,CAAE;AAAA,EACpE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,cAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACR,MAAM,EAAC;AAAA,IACP,IAAA,EAAM,EAAE,aAAA,EAAe,IAAA,EAAM,SAAS,OAAA,EAAQ;AAAA,IAC9C,SAAS,EAAC;AAAA,IACV,aAAa,EAAC;AAAA,IACd,OAAO,EAAC;AAAA,IACR,gBAAgB,EAAC;AAAA,IACjB,aAAa,EAAC;AAAA,IACd,YAAY,EAAC;AAAA,IACb,WAAW;AAAC;AAEhB,CAAC;AAMM,MAAM,0BAA0B,eAAA,EAAuC;AAAA,EAC5E;AAAA,IACE,MAAA;AAAA,IACA,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,mBAAA;AAAA,MACN,IAAA,EAAM,uBAAA;AAAA,MACN,KAAA,EAAO,wBAAA;AAAA,MACP,OAAA,EAAS;AAAA,KACX;AAAA,IACA,EAAA,EAAI,UAAA;AAAA,IACJ,QAAA,EAAU;AAAA,MACR,MAAM,EAAC;AAAA,MACP,aAAa;AAAC;AAChB;AAEJ;AAMO,MAAM,yBAAA,GACX,iBAAyC,CAAE;AAAA,EACzC,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,kBAAA;AAAA,IACN,SAAA,EAAW;AAAA,GACb;AAAA,EACA,QAAA,EAAU;AAAA,IACR,SAAS;AAAC;AAEd,CAAC;AAMI,MAAM,6BAAA,GACX,iBAA6C,CAAE;AAAA,EAC7C,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,kBAAA;AAAA,IACN,SAAA,EAAW,2BAAA;AAAA,IACX,KAAA,EAAO;AAAA,GACT;AAAA,EACA,UAAU;AACZ,CAAC;AAMI,MAAM,yBAAA,GACX,iBAAyC,CAAE;AAAA,EACzC,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,qBAAA;AAAA,IACN,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,UAAU;AACZ,CAAC;;;;"}
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
2
 
3
- var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Flex_bui-Flex__13abc0796b {\n display: flex;\n\n /* This helps when using `truncate` on text inside a flex container */\n min-width: 0;\n }\n\n .Flex_bui-Flex__13abc0796b[data-bg='neutral-1'] {\n background-color: var(--bui-bg-neutral-1);\n }\n\n .Flex_bui-Flex__13abc0796b[data-bg='neutral-2'] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n .Flex_bui-Flex__13abc0796b[data-bg='neutral-3'] {\n background-color: var(--bui-bg-neutral-3);\n }\n\n .Flex_bui-Flex__13abc0796b[data-bg='danger'] {\n background-color: var(--bui-bg-danger);\n }\n\n .Flex_bui-Flex__13abc0796b[data-bg='warning'] {\n background-color: var(--bui-bg-warning);\n }\n\n .Flex_bui-Flex__13abc0796b[data-bg='success'] {\n background-color: var(--bui-bg-success);\n }\n}\n";
4
- var styles = {"bui-Flex":"Flex_bui-Flex__13abc0796b"};
3
+ var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Flex_bui-Flex__2bb9a18026 {\n display: flex;\n\n /* This helps when using `truncate` on text inside a flex container */\n min-width: 0;\n }\n}\n";
4
+ var styles = {"bui-Flex":"Flex_bui-Flex__2bb9a18026"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { styles as default };
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
2
 
3
- var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Grid_bui-Grid__90096dfd16 {\n display: grid;\n }\n\n .Grid_bui-Grid__90096dfd16[data-bg='neutral-1'],\n .Grid_bui-GridItem__90096dfd16[data-bg='neutral-1'] {\n background-color: var(--bui-bg-neutral-1);\n }\n\n .Grid_bui-Grid__90096dfd16[data-bg='neutral-2'],\n .Grid_bui-GridItem__90096dfd16[data-bg='neutral-2'] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n .Grid_bui-Grid__90096dfd16[data-bg='neutral-3'],\n .Grid_bui-GridItem__90096dfd16[data-bg='neutral-3'] {\n background-color: var(--bui-bg-neutral-3);\n }\n\n .Grid_bui-Grid__90096dfd16[data-bg='danger'],\n .Grid_bui-GridItem__90096dfd16[data-bg='danger'] {\n background-color: var(--bui-bg-danger);\n }\n\n .Grid_bui-Grid__90096dfd16[data-bg='warning'],\n .Grid_bui-GridItem__90096dfd16[data-bg='warning'] {\n background-color: var(--bui-bg-warning);\n }\n\n .Grid_bui-Grid__90096dfd16[data-bg='success'],\n .Grid_bui-GridItem__90096dfd16[data-bg='success'] {\n background-color: var(--bui-bg-success);\n }\n}\n";
4
- var styles = {"bui-Grid":"Grid_bui-Grid__90096dfd16","bui-GridItem":"Grid_bui-GridItem__90096dfd16"};
3
+ var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Grid_bui-Grid__b251778c91 {\n display: grid;\n }\n}\n";
4
+ var styles = {"bui-Grid":"Grid_bui-Grid__b251778c91"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { styles as default };
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
2
 
3
- var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Header_bui-HeaderBottom__3fe4f51ce9 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-3);\n margin-bottom: var(--bui-space-5);\n }\n\n .Header_bui-HeaderTop__3fe4f51ce9,\n .Header_bui-HeaderContent__3fe4f51ce9,\n .Header_bui-HeaderBottom__3fe4f51ce9 {\n width: 100%;\n padding-inline: var(--bui-space-5);\n box-sizing: border-box;\n }\n\n .Header_bui-HeaderTop__3fe4f51ce9 {\n padding-top: var(--bui-space-6);\n }\n\n .Header_bui-HeaderStickySentinel__3fe4f51ce9 {\n height: 1px;\n margin-bottom: -1px;\n pointer-events: none;\n }\n\n .Header_bui-HeaderContent__3fe4f51ce9 {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n gap: var(--bui-space-3);\n padding-top: var(--bui-space-3);\n padding-bottom: var(--bui-space-3);\n }\n\n .Header_bui-HeaderContent__3fe4f51ce9[data-has-tags] {\n padding-top: var(--bui-space-2);\n }\n\n .Header_bui-HeaderContent__3fe4f51ce9[data-sticky] {\n position: sticky;\n top: 0;\n z-index: 10;\n background-color: var(--bui-bg-app);\n\n &[data-on-bg='neutral-1'] {\n background-color: var(--bui-bg-neutral-1);\n }\n\n &[data-on-bg='neutral-2'] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n &[data-on-bg='neutral-3'] {\n background-color: var(--bui-bg-neutral-3);\n }\n }\n\n .Header_bui-HeaderContent__3fe4f51ce9[data-sticky]::after {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n content: '';\n background-color: var(--bui-border-1);\n opacity: 0;\n transition: opacity 200ms ease;\n }\n\n .Header_bui-HeaderContent__3fe4f51ce9[data-stuck]::after {\n opacity: 1;\n }\n\n .Header_bui-HeaderTabsWrapper__3fe4f51ce9 {\n margin-left: -8px;\n }\n\n .Header_bui-HeaderControls__3fe4f51ce9 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n flex-shrink: 0;\n }\n\n .Header_bui-HeaderTitleStack__3fe4f51ce9 {\n position: relative;\n flex: 1 1 auto;\n height: 1lh;\n min-width: 0;\n font-size: var(--bui-font-size-6);\n line-height: 140%;\n overflow: hidden;\n }\n\n .Header_bui-HeaderBreadcrumbs__3fe4f51ce9,\n .Header_bui-HeaderBreadcrumbsSmall__3fe4f51ce9 {\n position: absolute;\n inset-inline: 0;\n top: 50%;\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n min-width: 0;\n transform: translateY(-50%);\n }\n\n .Header_bui-HeaderBreadcrumbsSmall__3fe4f51ce9 {\n gap: var(--bui-space-1);\n }\n\n .Header_bui-HeaderBreadcrumbs__3fe4f51ce9 .Header_bui-HeaderBreadcrumbLink__3fe4f51ce9,\n .Header_bui-HeaderBreadcrumbsSmall__3fe4f51ce9 .Header_bui-HeaderBreadcrumbLinkSmall__3fe4f51ce9 {\n max-width: 240px;\n overflow: hidden;\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-bold);\n line-height: inherit;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .Header_bui-HeaderBreadcrumbs__3fe4f51ce9 .Header_bui-HeaderBreadcrumbLink__3fe4f51ce9 {\n font-size: inherit;\n }\n\n .Header_bui-HeaderBreadcrumbsSmall__3fe4f51ce9 .Header_bui-HeaderBreadcrumbLinkSmall__3fe4f51ce9 {\n font-size: var(--bui-font-size-4);\n }\n\n .Header_bui-HeaderBreadcrumbSeparator__3fe4f51ce9 {\n flex-shrink: 0;\n }\n\n .Header_bui-HeaderTitle__3fe4f51ce9,\n .Header_bui-HeaderTitleSmall__3fe4f51ce9 {\n margin: 0;\n padding: 0;\n flex: 1 1 auto;\n min-width: 0;\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-bold);\n line-height: inherit;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .Header_bui-HeaderTitle__3fe4f51ce9 {\n font-size: inherit;\n }\n\n .Header_bui-HeaderTitleSmall__3fe4f51ce9 {\n font-size: var(--bui-font-size-4);\n }\n\n .Header_bui-HeaderTags__3fe4f51ce9 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n flex-wrap: wrap;\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .Header_bui-HeaderTag__3fe4f51ce9 {\n display: flex;\n align-items: center;\n gap: var(--bui-space-2);\n }\n\n .Header_bui-HeaderTag__3fe4f51ce9 + .Header_bui-HeaderTag__3fe4f51ce9::before {\n content: '';\n width: 3px;\n height: 3px;\n border-radius: 50%;\n background-color: var(--bui-fg-secondary);\n flex-shrink: 0;\n }\n\n .Header_bui-HeaderMetaRow__3fe4f51ce9 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-5);\n flex-wrap: wrap;\n margin: 0;\n }\n\n .Header_bui-HeaderMetaItem__3fe4f51ce9 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n\n dd {\n margin: 0;\n }\n }\n}\n";
4
- var styles = {"bui-HeaderBottom":"Header_bui-HeaderBottom__3fe4f51ce9","bui-HeaderTop":"Header_bui-HeaderTop__3fe4f51ce9","bui-HeaderContent":"Header_bui-HeaderContent__3fe4f51ce9","bui-HeaderStickySentinel":"Header_bui-HeaderStickySentinel__3fe4f51ce9","bui-HeaderTabsWrapper":"Header_bui-HeaderTabsWrapper__3fe4f51ce9","bui-HeaderControls":"Header_bui-HeaderControls__3fe4f51ce9","bui-HeaderTitleStack":"Header_bui-HeaderTitleStack__3fe4f51ce9","bui-HeaderBreadcrumbs":"Header_bui-HeaderBreadcrumbs__3fe4f51ce9","bui-HeaderBreadcrumbsSmall":"Header_bui-HeaderBreadcrumbsSmall__3fe4f51ce9","bui-HeaderBreadcrumbLink":"Header_bui-HeaderBreadcrumbLink__3fe4f51ce9","bui-HeaderBreadcrumbLinkSmall":"Header_bui-HeaderBreadcrumbLinkSmall__3fe4f51ce9","bui-HeaderBreadcrumbSeparator":"Header_bui-HeaderBreadcrumbSeparator__3fe4f51ce9","bui-HeaderTitle":"Header_bui-HeaderTitle__3fe4f51ce9","bui-HeaderTitleSmall":"Header_bui-HeaderTitleSmall__3fe4f51ce9","bui-HeaderTags":"Header_bui-HeaderTags__3fe4f51ce9","bui-HeaderTag":"Header_bui-HeaderTag__3fe4f51ce9","bui-HeaderMetaRow":"Header_bui-HeaderMetaRow__3fe4f51ce9","bui-HeaderMetaItem":"Header_bui-HeaderMetaItem__3fe4f51ce9"};
3
+ var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Header_bui-HeaderBottom__88cf7f55e4 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-3);\n margin-bottom: var(--bui-space-5);\n }\n\n .Header_bui-HeaderTop__88cf7f55e4,\n .Header_bui-HeaderContent__88cf7f55e4,\n .Header_bui-HeaderBottom__88cf7f55e4 {\n width: 100%;\n padding-inline: var(--bui-space-5);\n box-sizing: border-box;\n }\n\n .Header_bui-HeaderStickySentinel__88cf7f55e4 {\n height: 1px;\n margin-bottom: -1px;\n pointer-events: none;\n }\n\n .Header_bui-HeaderContent__88cf7f55e4 {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n gap: var(--bui-space-3);\n padding-top: var(--bui-space-3);\n padding-bottom: var(--bui-space-3);\n }\n\n .Header_bui-HeaderContent__88cf7f55e4[data-has-tags] {\n padding-top: var(--bui-space-2);\n }\n\n .Header_bui-HeaderContent__88cf7f55e4[data-sticky] {\n position: sticky;\n top: 0;\n z-index: 10;\n background-color: var(--bui-bg-app);\n\n &[data-on-bg='neutral-1'] {\n background-color: var(--bui-bg-neutral-1);\n }\n\n &[data-on-bg='neutral-2'] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n &[data-on-bg='neutral-3'] {\n background-color: var(--bui-bg-neutral-3);\n }\n }\n\n .Header_bui-HeaderContent__88cf7f55e4[data-sticky]::after {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n content: '';\n background-color: var(--bui-border-1);\n opacity: 0;\n transition: opacity 200ms ease;\n }\n\n .Header_bui-HeaderContent__88cf7f55e4[data-stuck]::after {\n opacity: 1;\n }\n\n .Header_bui-HeaderTabsWrapper__88cf7f55e4 {\n margin-left: -8px;\n }\n\n .Header_bui-HeaderControls__88cf7f55e4 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n flex-shrink: 0;\n }\n\n .Header_bui-HeaderTitleStack__88cf7f55e4 {\n position: relative;\n flex: 1 1 auto;\n height: 1lh;\n min-width: 0;\n font-size: var(--bui-font-size-6);\n line-height: 140%;\n overflow: hidden;\n }\n\n .Header_bui-HeaderBreadcrumbs__88cf7f55e4,\n .Header_bui-HeaderBreadcrumbsSmall__88cf7f55e4 {\n position: absolute;\n inset-inline: 0;\n top: 50%;\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n min-width: 0;\n transform: translateY(-50%);\n }\n\n .Header_bui-HeaderBreadcrumbsSmall__88cf7f55e4 {\n gap: var(--bui-space-1);\n }\n\n .Header_bui-HeaderBreadcrumbs__88cf7f55e4 .Header_bui-HeaderBreadcrumbLink__88cf7f55e4,\n .Header_bui-HeaderBreadcrumbsSmall__88cf7f55e4 .Header_bui-HeaderBreadcrumbLinkSmall__88cf7f55e4 {\n max-width: 240px;\n overflow: hidden;\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-bold);\n line-height: inherit;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .Header_bui-HeaderBreadcrumbs__88cf7f55e4 .Header_bui-HeaderBreadcrumbLink__88cf7f55e4 {\n font-size: inherit;\n }\n\n .Header_bui-HeaderBreadcrumbsSmall__88cf7f55e4 .Header_bui-HeaderBreadcrumbLinkSmall__88cf7f55e4 {\n font-size: var(--bui-font-size-4);\n }\n\n .Header_bui-HeaderBreadcrumbSeparator__88cf7f55e4 {\n flex-shrink: 0;\n }\n\n .Header_bui-HeaderTitle__88cf7f55e4,\n .Header_bui-HeaderTitleSmall__88cf7f55e4 {\n margin: 0;\n padding: 0;\n flex: 1 1 auto;\n min-width: 0;\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-bold);\n line-height: inherit;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .Header_bui-HeaderTitle__88cf7f55e4 {\n font-size: inherit;\n }\n\n .Header_bui-HeaderTitleSmall__88cf7f55e4 {\n font-size: var(--bui-font-size-4);\n }\n\n .Header_bui-HeaderTags__88cf7f55e4 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n flex-wrap: wrap;\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .Header_bui-HeaderTag__88cf7f55e4 {\n display: flex;\n align-items: center;\n gap: var(--bui-space-2);\n }\n\n .Header_bui-HeaderTag__88cf7f55e4 + .Header_bui-HeaderTag__88cf7f55e4::before {\n content: '';\n width: 3px;\n height: 3px;\n border-radius: 50%;\n background-color: var(--bui-fg-secondary);\n flex-shrink: 0;\n }\n\n .Header_bui-HeaderMetaRow__88cf7f55e4 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-5);\n flex-wrap: wrap;\n margin: 0;\n }\n\n .Header_bui-HeaderMetaItem__88cf7f55e4 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n\n dd {\n margin: 0;\n }\n }\n}\n";
4
+ var styles = {"bui-HeaderBottom":"Header_bui-HeaderBottom__88cf7f55e4","bui-HeaderTop":"Header_bui-HeaderTop__88cf7f55e4","bui-HeaderContent":"Header_bui-HeaderContent__88cf7f55e4","bui-HeaderStickySentinel":"Header_bui-HeaderStickySentinel__88cf7f55e4","bui-HeaderTabsWrapper":"Header_bui-HeaderTabsWrapper__88cf7f55e4","bui-HeaderControls":"Header_bui-HeaderControls__88cf7f55e4","bui-HeaderTitleStack":"Header_bui-HeaderTitleStack__88cf7f55e4","bui-HeaderBreadcrumbs":"Header_bui-HeaderBreadcrumbs__88cf7f55e4","bui-HeaderBreadcrumbsSmall":"Header_bui-HeaderBreadcrumbsSmall__88cf7f55e4","bui-HeaderBreadcrumbLink":"Header_bui-HeaderBreadcrumbLink__88cf7f55e4","bui-HeaderBreadcrumbLinkSmall":"Header_bui-HeaderBreadcrumbLinkSmall__88cf7f55e4","bui-HeaderBreadcrumbSeparator":"Header_bui-HeaderBreadcrumbSeparator__88cf7f55e4","bui-HeaderTitle":"Header_bui-HeaderTitle__88cf7f55e4","bui-HeaderTitleSmall":"Header_bui-HeaderTitleSmall__88cf7f55e4","bui-HeaderTags":"Header_bui-HeaderTags__88cf7f55e4","bui-HeaderTag":"Header_bui-HeaderTag__88cf7f55e4","bui-HeaderMetaRow":"Header_bui-HeaderMetaRow__88cf7f55e4","bui-HeaderMetaItem":"Header_bui-HeaderMetaItem__88cf7f55e4"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { styles as default };
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { forwardRef, useRef } from 'react';
3
- import { useLink } from 'react-aria';
3
+ import { useLink, useFocusRing, mergeProps } from 'react-aria';
4
4
  import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
5
5
  import { useResolvedHref } from '../../hooks/useResolvedHref.esm.js';
6
6
  import { LinkDefinition } from './definition.esm.js';
@@ -15,6 +15,7 @@ const LinkInternal = forwardRef((props, ref) => {
15
15
  const internalRef = useRef(null);
16
16
  const linkRef = ref || internalRef;
17
17
  const { linkProps } = useLink(restProps, linkRef);
18
+ const { isFocusVisible, focusProps } = useFocusRing();
18
19
  const resolvedHref = useResolvedHref(restProps.href);
19
20
  const handleClick = (e) => {
20
21
  linkProps.onClick?.(e);
@@ -26,13 +27,14 @@ const LinkInternal = forwardRef((props, ref) => {
26
27
  return /* @__PURE__ */ jsx(
27
28
  "a",
28
29
  {
29
- ...linkProps,
30
+ ...mergeProps(linkProps, focusProps),
30
31
  ...dataAttributes,
31
32
  ...restProps,
32
33
  href: resolvedHref,
33
34
  ref: linkRef,
34
35
  title,
35
36
  className: classes.root,
37
+ "data-focus-visible": isFocusVisible || void 0,
36
38
  onClick: handleClick,
37
39
  children
38
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Link.esm.js","sources":["../../../src/components/Link/Link.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { forwardRef, useRef } from 'react';\nimport { useLink } from 'react-aria';\nimport type { LinkProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { useResolvedHref } from '../../hooks/useResolvedHref';\nimport { LinkDefinition } from './definition';\nimport { getNodeText } from '../../analytics/getNodeText';\n\nconst LinkInternal = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n const { ownProps, restProps, dataAttributes, analytics } = useDefinition(\n LinkDefinition,\n props,\n );\n const { classes, title, children } = ownProps;\n\n const internalRef = useRef<HTMLAnchorElement>(null);\n const linkRef = (ref || internalRef) as React.RefObject<HTMLAnchorElement>;\n\n const { linkProps } = useLink(restProps, linkRef);\n const resolvedHref = useResolvedHref(restProps.href);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n linkProps.onClick?.(e);\n const text =\n restProps['aria-label'] ??\n getNodeText(children) ??\n String(restProps.href ?? '');\n analytics.captureEvent('click', text, {\n attributes: { to: String(restProps.href ?? '') },\n });\n };\n\n return (\n <a\n {...linkProps}\n {...dataAttributes}\n {...(restProps as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n href={resolvedHref}\n ref={linkRef}\n title={title}\n className={classes.root}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n});\n\nLinkInternal.displayName = 'LinkInternal';\n\n/**\n * A styled anchor element that supports analytics event tracking on click.\n *\n * @public\n */\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n return <LinkInternal {...props} ref={ref} />;\n});\n\nLink.displayName = 'Link';\n"],"names":[],"mappings":";;;;;;;;AAwBA,MAAM,YAAA,GAAe,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC5E,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAgB,WAAU,GAAI,aAAA;AAAA,IACzD,cAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAO,QAAA,EAAS,GAAI,QAAA;AAErC,EAAA,MAAM,WAAA,GAAc,OAA0B,IAAI,CAAA;AAClD,EAAA,MAAM,UAAW,GAAA,IAAO,WAAA;AAExB,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,OAAA,CAAQ,WAAW,OAAO,CAAA;AAChD,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,SAAA,CAAU,IAAI,CAAA;AAEnD,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAA2C;AAC9D,IAAA,SAAA,CAAU,UAAU,CAAC,CAAA;AACrB,IAAA,MAAM,IAAA,GACJ,SAAA,CAAU,YAAY,CAAA,IACtB,WAAA,CAAY,QAAQ,CAAA,IACpB,MAAA,CAAO,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAC7B,IAAA,SAAA,CAAU,YAAA,CAAa,SAAS,IAAA,EAAM;AAAA,MACpC,YAAY,EAAE,EAAA,EAAI,OAAO,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAAE,KAChD,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACE,GAAG,SAAA;AAAA,MACH,GAAG,cAAA;AAAA,MACH,GAAI,SAAA;AAAA,MACL,IAAA,EAAM,YAAA;AAAA,MACN,GAAA,EAAK,OAAA;AAAA,MACL,KAAA;AAAA,MACA,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,OAAA,EAAS,WAAA;AAAA,MAER;AAAA;AAAA,GACH;AAEJ,CAAC,CAAA;AAED,YAAA,CAAa,WAAA,GAAc,cAAA;AAOpB,MAAM,IAAA,GAAO,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC3E,EAAA,uBAAO,GAAA,CAAC,YAAA,EAAA,EAAc,GAAG,KAAA,EAAO,GAAA,EAAU,CAAA;AAC5C,CAAC;AAED,IAAA,CAAK,WAAA,GAAc,MAAA;;;;"}
1
+ {"version":3,"file":"Link.esm.js","sources":["../../../src/components/Link/Link.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { forwardRef, useRef } from 'react';\nimport { mergeProps, useFocusRing, useLink } from 'react-aria';\nimport type { LinkProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { useResolvedHref } from '../../hooks/useResolvedHref';\nimport { LinkDefinition } from './definition';\nimport { getNodeText } from '../../analytics/getNodeText';\n\nconst LinkInternal = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n const { ownProps, restProps, dataAttributes, analytics } = useDefinition(\n LinkDefinition,\n props,\n );\n const { classes, title, children } = ownProps;\n\n const internalRef = useRef<HTMLAnchorElement>(null);\n const linkRef = (ref || internalRef) as React.RefObject<HTMLAnchorElement>;\n\n const { linkProps } = useLink(restProps, linkRef);\n const { isFocusVisible, focusProps } = useFocusRing();\n const resolvedHref = useResolvedHref(restProps.href);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n linkProps.onClick?.(e);\n const text =\n restProps['aria-label'] ??\n getNodeText(children) ??\n String(restProps.href ?? '');\n analytics.captureEvent('click', text, {\n attributes: { to: String(restProps.href ?? '') },\n });\n };\n\n return (\n <a\n {...mergeProps(linkProps, focusProps)}\n {...dataAttributes}\n {...(restProps as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n href={resolvedHref}\n ref={linkRef}\n title={title}\n className={classes.root}\n data-focus-visible={isFocusVisible || undefined}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n});\n\nLinkInternal.displayName = 'LinkInternal';\n\n/**\n * A styled anchor element that supports analytics event tracking on click.\n *\n * @public\n */\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n return <LinkInternal {...props} ref={ref} />;\n});\n\nLink.displayName = 'Link';\n"],"names":[],"mappings":";;;;;;;;AAwBA,MAAM,YAAA,GAAe,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC5E,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAgB,WAAU,GAAI,aAAA;AAAA,IACzD,cAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAO,QAAA,EAAS,GAAI,QAAA;AAErC,EAAA,MAAM,WAAA,GAAc,OAA0B,IAAI,CAAA;AAClD,EAAA,MAAM,UAAW,GAAA,IAAO,WAAA;AAExB,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,OAAA,CAAQ,WAAW,OAAO,CAAA;AAChD,EAAA,MAAM,EAAE,cAAA,EAAgB,UAAA,EAAW,GAAI,YAAA,EAAa;AACpD,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,SAAA,CAAU,IAAI,CAAA;AAEnD,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAA2C;AAC9D,IAAA,SAAA,CAAU,UAAU,CAAC,CAAA;AACrB,IAAA,MAAM,IAAA,GACJ,SAAA,CAAU,YAAY,CAAA,IACtB,WAAA,CAAY,QAAQ,CAAA,IACpB,MAAA,CAAO,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAC7B,IAAA,SAAA,CAAU,YAAA,CAAa,SAAS,IAAA,EAAM;AAAA,MACpC,YAAY,EAAE,EAAA,EAAI,OAAO,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAAE,KAChD,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACE,GAAG,UAAA,CAAW,SAAA,EAAW,UAAU,CAAA;AAAA,MACnC,GAAG,cAAA;AAAA,MACH,GAAI,SAAA;AAAA,MACL,IAAA,EAAM,YAAA;AAAA,MACN,GAAA,EAAK,OAAA;AAAA,MACL,KAAA;AAAA,MACA,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,sBAAoB,cAAA,IAAkB,MAAA;AAAA,MACtC,OAAA,EAAS,WAAA;AAAA,MAER;AAAA;AAAA,GACH;AAEJ,CAAC,CAAA;AAED,YAAA,CAAa,WAAA,GAAc,cAAA;AAOpB,MAAM,IAAA,GAAO,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC3E,EAAA,uBAAO,GAAA,CAAC,YAAA,EAAA,EAAc,GAAG,KAAA,EAAO,GAAA,EAAU,CAAA;AAC5C,CAAC;AAED,IAAA,CAAK,WAAA,GAAc,MAAA;;;;"}
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
2
 
3
- var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Link_bui-Link__bb74dc66c4 {\n font-family: var(--bui-font-regular);\n padding: 0;\n margin: 0;\n cursor: pointer;\n display: inline-block;\n\n text-decoration-line: underline;\n text-decoration-style: solid;\n text-decoration-thickness: min(2px, max(1px, 0.05em));\n text-underline-offset: calc(0.025em + 2px);\n text-decoration-color: color-mix(in srgb, currentColor 30%, transparent);\n\n &:hover {\n text-decoration-line: underline;\n text-decoration-style: solid;\n text-decoration-thickness: min(2px, max(1px, 0.05em));\n text-underline-offset: calc(0.025em + 2px);\n text-decoration-color: color-mix(in srgb, currentColor 30%, transparent);\n }\n }\n\n .Link_bui-Link__bb74dc66c4[data-variant='title-large'] {\n font-size: var(--bui-font-size-8);\n line-height: 140%;\n }\n\n .Link_bui-Link__bb74dc66c4[data-variant='title-medium'] {\n font-size: var(--bui-font-size-7);\n line-height: 140%;\n }\n\n .Link_bui-Link__bb74dc66c4[data-variant='title-small'] {\n font-size: var(--bui-font-size-6);\n line-height: 140%;\n }\n\n .Link_bui-Link__bb74dc66c4[data-variant='title-x-small'] {\n font-size: var(--bui-font-size-5);\n line-height: 140%;\n }\n\n .Link_bui-Link__bb74dc66c4[data-variant='body-large'] {\n font-size: var(--bui-font-size-4);\n line-height: 140%;\n }\n\n .Link_bui-Link__bb74dc66c4[data-variant='body-medium'] {\n font-size: var(--bui-font-size-3);\n line-height: 140%;\n }\n\n .Link_bui-Link__bb74dc66c4[data-variant='body-small'] {\n font-size: var(--bui-font-size-2);\n line-height: 140%;\n }\n\n .Link_bui-Link__bb74dc66c4[data-variant='body-x-small'] {\n font-size: var(--bui-font-size-1);\n line-height: 140%;\n }\n\n .Link_bui-Link__bb74dc66c4[data-weight='regular'] {\n font-weight: var(--bui-font-weight-regular);\n }\n\n .Link_bui-Link__bb74dc66c4[data-weight='bold'] {\n font-weight: var(--bui-font-weight-bold);\n }\n\n .Link_bui-Link__bb74dc66c4[data-color='primary'] {\n color: var(--bui-fg-primary);\n }\n\n .Link_bui-Link__bb74dc66c4[data-color='secondary'] {\n color: var(--bui-fg-secondary);\n }\n\n .Link_bui-Link__bb74dc66c4[data-color='danger'] {\n color: var(--bui-fg-danger);\n }\n\n .Link_bui-Link__bb74dc66c4[data-color='warning'] {\n color: var(--bui-fg-warning);\n }\n\n .Link_bui-Link__bb74dc66c4[data-color='success'] {\n color: var(--bui-fg-success);\n }\n\n .Link_bui-Link__bb74dc66c4[data-color='info'] {\n color: var(--bui-fg-info);\n }\n\n .Link_bui-Link__bb74dc66c4[data-truncate] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .Link_bui-Link__bb74dc66c4[data-standalone] {\n text-decoration-line: none;\n\n &:hover {\n text-decoration-line: underline;\n text-decoration-style: solid;\n text-decoration-thickness: min(2px, max(1px, 0.05em));\n text-underline-offset: calc(0.025em + 2px);\n text-decoration-color: color-mix(in srgb, currentColor 30%, transparent);\n }\n }\n}\n";
4
- var styles = {"bui-Link":"Link_bui-Link__bb74dc66c4"};
3
+ var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Link_bui-Link__b9cba1725b {\n font-family: var(--bui-font-regular);\n padding: 0;\n margin: 0;\n cursor: pointer;\n display: inline-block;\n\n text-decoration-line: underline;\n text-decoration-style: solid;\n text-decoration-thickness: min(2px, max(1px, 0.05em));\n text-underline-offset: calc(0.025em + 2px);\n text-decoration-color: color-mix(in srgb, currentColor 30%, transparent);\n\n &:hover {\n text-decoration-line: underline;\n text-decoration-style: solid;\n text-decoration-thickness: min(2px, max(1px, 0.05em));\n text-underline-offset: calc(0.025em + 2px);\n text-decoration-color: color-mix(in srgb, currentColor 30%, transparent);\n }\n\n &[data-focus-visible] {\n outline: 2px solid var(--bui-ring);\n outline-offset: 2px;\n }\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='title-large'] {\n font-size: var(--bui-font-size-8);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='title-medium'] {\n font-size: var(--bui-font-size-7);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='title-small'] {\n font-size: var(--bui-font-size-6);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='title-x-small'] {\n font-size: var(--bui-font-size-5);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='body-large'] {\n font-size: var(--bui-font-size-4);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='body-medium'] {\n font-size: var(--bui-font-size-3);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='body-small'] {\n font-size: var(--bui-font-size-2);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='body-x-small'] {\n font-size: var(--bui-font-size-1);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-weight='regular'] {\n font-weight: var(--bui-font-weight-regular);\n }\n\n .Link_bui-Link__b9cba1725b[data-weight='bold'] {\n font-weight: var(--bui-font-weight-bold);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='primary'] {\n color: var(--bui-fg-primary);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='secondary'] {\n color: var(--bui-fg-secondary);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='danger'] {\n color: var(--bui-fg-danger);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='warning'] {\n color: var(--bui-fg-warning);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='success'] {\n color: var(--bui-fg-success);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='info'] {\n color: var(--bui-fg-info);\n }\n\n .Link_bui-Link__b9cba1725b[data-truncate] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .Link_bui-Link__b9cba1725b[data-standalone] {\n text-decoration-line: none;\n\n &:hover {\n text-decoration-line: underline;\n text-decoration-style: solid;\n text-decoration-thickness: min(2px, max(1px, 0.05em));\n text-underline-offset: calc(0.025em + 2px);\n text-decoration-color: color-mix(in srgb, currentColor 30%, transparent);\n }\n }\n}\n";
4
+ var styles = {"bui-Link":"Link_bui-Link__b9cba1725b"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { styles as default };