@backstage/ui 0.11.1 → 0.12.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +222 -106
  2. package/css/styles.css +17 -11
  3. package/dist/components/Alert/Alert.esm.js +81 -0
  4. package/dist/components/Alert/Alert.esm.js.map +1 -0
  5. package/dist/components/Alert/Alert.module.css.esm.js +8 -0
  6. package/dist/components/Alert/Alert.module.css.esm.js.map +1 -0
  7. package/dist/components/Alert/definition.esm.js +37 -0
  8. package/dist/components/Alert/definition.esm.js.map +1 -0
  9. package/dist/components/Box/Box.esm.js +10 -23
  10. package/dist/components/Box/Box.esm.js.map +1 -1
  11. package/dist/components/Box/definition.esm.js +20 -6
  12. package/dist/components/Box/definition.esm.js.map +1 -1
  13. package/dist/components/Button/Button.esm.js +12 -35
  14. package/dist/components/Button/Button.esm.js.map +1 -1
  15. package/dist/components/Button/Button.module.css.esm.js +2 -2
  16. package/dist/components/Button/definition.esm.js +22 -6
  17. package/dist/components/Button/definition.esm.js.map +1 -1
  18. package/dist/components/ButtonIcon/ButtonIcon.esm.js +9 -40
  19. package/dist/components/ButtonIcon/ButtonIcon.esm.js.map +1 -1
  20. package/dist/components/ButtonIcon/ButtonIcon.module.css.esm.js +3 -3
  21. package/dist/components/ButtonIcon/definition.esm.js +21 -2
  22. package/dist/components/ButtonIcon/definition.esm.js.map +1 -1
  23. package/dist/components/ButtonLink/ButtonLink.esm.js +16 -43
  24. package/dist/components/ButtonLink/ButtonLink.esm.js.map +1 -1
  25. package/dist/components/ButtonLink/ButtonLink.module.css.esm.js +8 -0
  26. package/dist/components/ButtonLink/ButtonLink.module.css.esm.js.map +1 -0
  27. package/dist/components/ButtonLink/definition.esm.js +24 -3
  28. package/dist/components/ButtonLink/definition.esm.js.map +1 -1
  29. package/dist/components/Dialog/Dialog.esm.js +3 -0
  30. package/dist/components/Dialog/Dialog.esm.js.map +1 -1
  31. package/dist/components/InternalLinkProvider/InternalLinkProvider.esm.js +55 -0
  32. package/dist/components/InternalLinkProvider/InternalLinkProvider.esm.js.map +1 -0
  33. package/dist/components/Link/Link.esm.js +2 -9
  34. package/dist/components/Link/Link.esm.js.map +1 -1
  35. package/dist/components/Menu/Menu.esm.js +13 -16
  36. package/dist/components/Menu/Menu.esm.js.map +1 -1
  37. package/dist/components/Table/components/Row.esm.js +5 -18
  38. package/dist/components/Table/components/Row.esm.js.map +1 -1
  39. package/dist/components/Table/components/Table.esm.js +4 -4
  40. package/dist/components/Table/components/Table.esm.js.map +1 -1
  41. package/dist/components/TablePagination/TablePagination.esm.js +4 -1
  42. package/dist/components/TablePagination/TablePagination.esm.js.map +1 -1
  43. package/dist/components/Tabs/Tabs.esm.js +120 -54
  44. package/dist/components/Tabs/Tabs.esm.js.map +1 -1
  45. package/dist/components/TagGroup/TagGroup.esm.js +7 -13
  46. package/dist/components/TagGroup/TagGroup.esm.js.map +1 -1
  47. package/dist/hooks/useDefinition/defineComponent.esm.js +6 -0
  48. package/dist/hooks/useDefinition/defineComponent.esm.js.map +1 -0
  49. package/dist/hooks/useDefinition/helpers.esm.js +69 -0
  50. package/dist/hooks/useDefinition/helpers.esm.js.map +1 -0
  51. package/dist/hooks/useDefinition/useDefinition.esm.js +78 -0
  52. package/dist/hooks/useDefinition/useDefinition.esm.js.map +1 -0
  53. package/dist/hooks/useStyles.esm.js +7 -54
  54. package/dist/hooks/useStyles.esm.js.map +1 -1
  55. package/dist/index.d.ts +313 -104
  56. package/dist/index.esm.js +4 -2
  57. package/dist/index.esm.js.map +1 -1
  58. package/dist/utils/utilityClassMap.esm.js.map +1 -1
  59. package/package.json +4 -4
@@ -1,8 +1,8 @@
1
1
  import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
2
 
3
- var css_248z = "/*\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\n@layer tokens, base, components, utilities;\n\n@layer components {\n .ButtonIcon_bui-ButtonIcon__8091494e93 {\n align-items: center;\n justify-content: center;\n }\n\n .ButtonIcon_bui-ButtonIcon__8091494e93[data-size='small'] {\n padding: 0;\n width: 2rem;\n }\n\n .ButtonIcon_bui-ButtonIcon__8091494e93[data-size='medium'] {\n padding: 0;\n width: 2.5rem;\n }\n}\n";
4
- var stylesButtonIcon = {"bui-ButtonIcon":"ButtonIcon_bui-ButtonIcon__8091494e93"};
3
+ var css_248z = "/*\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\n@layer tokens, base, components, utilities;\n\n@layer components {\n .ButtonIcon_bui-ButtonIcon__b71a70bcf2 {\n --loading-duration: 200ms;\n --bg: transparent;\n --bg-hover: transparent;\n --bg-active: transparent;\n --fg: inherit;\n\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n user-select: none;\n padding: 0;\n cursor: pointer;\n border-radius: var(--bui-radius-2);\n flex-shrink: 0;\n transition: background-color var(--loading-duration) ease-out,\n box-shadow var(--loading-duration) ease-out;\n\n /* Apply variables */\n color: var(--fg);\n background-color: var(--bg);\n\n &:hover {\n background-color: var(--bg-hover);\n transition: background-color 150ms ease;\n }\n\n &:active {\n background-color: var(--bg-active);\n }\n\n &[data-disabled='true'] {\n cursor: not-allowed;\n }\n\n &[data-loading='true'] {\n cursor: wait;\n }\n }\n\n .ButtonIcon_bui-ButtonIcon__b71a70bcf2[data-variant='primary'] {\n --bg: var(--bui-bg-solid);\n --bg-hover: var(--bui-bg-solid-hover);\n --bg-active: var(--bui-bg-solid-pressed);\n --fg: var(--bui-fg-solid);\n\n &[data-disabled='true'],\n &[data-loading='true'] {\n --bg: var(--bui-bg-solid-disabled);\n --bg-hover: var(--bui-bg-solid-disabled);\n --bg-active: var(--bui-bg-solid-disabled);\n --fg: var(--bui-fg-solid-disabled);\n }\n\n &:focus-visible {\n outline: 2px solid var(--bui-ring);\n outline-offset: 2px;\n }\n }\n\n .ButtonIcon_bui-ButtonIcon__b71a70bcf2[data-variant='secondary'] {\n --bg: var(--bui-bg-neutral-on-surface-0);\n --bg-hover: var(--bui-bg-neutral-on-surface-0-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-0-pressed);\n --fg: var(--bui-fg-primary);\n\n &[data-on-surface='1'] {\n --bg: var(--bui-bg-neutral-on-surface-1);\n --bg-hover: var(--bui-bg-neutral-on-surface-1-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-1-pressed);\n }\n\n &[data-on-surface='2'] {\n --bg: var(--bui-bg-neutral-on-surface-2);\n --bg-hover: var(--bui-bg-neutral-on-surface-2-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-2-pressed);\n }\n\n &[data-on-surface='3'] {\n --bg: var(--bui-bg-neutral-on-surface-3);\n --bg-hover: var(--bui-bg-neutral-on-surface-3-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-3-pressed);\n }\n\n &[data-disabled='true'],\n &[data-loading='true'] {\n --bg-hover: var(--bg);\n --bg-active: var(--bg);\n --fg: var(--bui-fg-disabled);\n }\n\n &:focus-visible {\n outline: none;\n transition: none;\n box-shadow: inset 0 0 0 2px var(--bui-ring);\n }\n }\n\n .ButtonIcon_bui-ButtonIcon__b71a70bcf2[data-variant='tertiary'] {\n --bg-hover: var(--bui-bg-neutral-on-surface-0-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-0-pressed);\n --fg: var(--bui-fg-primary);\n\n &[data-on-surface='1'] {\n --bg-hover: var(--bui-bg-neutral-on-surface-1-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-1-pressed);\n }\n\n &[data-on-surface='2'] {\n --bg-hover: var(--bui-bg-neutral-on-surface-2-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-2-pressed);\n }\n\n &[data-on-surface='3'] {\n --bg-hover: var(--bui-bg-neutral-on-surface-3-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-3-pressed);\n }\n\n &[data-disabled='true'],\n &[data-loading='true'] {\n --bg-hover: var(--bg);\n --bg-active: var(--bg);\n --fg: var(--bui-fg-disabled);\n }\n\n &:focus-visible {\n outline: none;\n transition: none;\n box-shadow: inset 0 0 0 2px var(--bui-ring);\n }\n }\n\n .ButtonIcon_bui-ButtonIcon__b71a70bcf2[data-size='small'] {\n width: 2rem;\n height: 2rem;\n\n svg {\n width: 1rem;\n height: 1rem;\n }\n }\n\n .ButtonIcon_bui-ButtonIcon__b71a70bcf2[data-size='medium'] {\n width: 2.5rem;\n height: 2.5rem;\n\n svg {\n width: 1.25rem;\n height: 1.25rem;\n }\n }\n\n .ButtonIcon_bui-ButtonIconContent__b71a70bcf2 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n transition: opacity var(--loading-duration) ease-out;\n\n .ButtonIcon_bui-ButtonIcon__b71a70bcf2[data-loading='true'] & {\n opacity: 0;\n }\n }\n\n .ButtonIcon_bui-ButtonIconSpinner__b71a70bcf2 {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n opacity: 0;\n transition: opacity var(--loading-duration) ease-in;\n\n .ButtonIcon_bui-ButtonIcon__b71a70bcf2[data-loading='true'] & {\n opacity: 1;\n }\n\n & svg {\n animation: ButtonIcon_bui-spin__b71a70bcf2 1s linear infinite;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .ButtonIcon_bui-ButtonIcon__b71a70bcf2 {\n transition-duration: 50ms;\n }\n\n .ButtonIcon_bui-ButtonIconContent__b71a70bcf2 {\n transition-duration: 50ms;\n }\n\n .ButtonIcon_bui-ButtonIconSpinner__b71a70bcf2 {\n transition-duration: 50ms;\n }\n\n .ButtonIcon_bui-ButtonIconSpinner__b71a70bcf2 svg {\n animation: none;\n }\n }\n}\n";
4
+ var styles = {"bui-ButtonIcon":"ButtonIcon_bui-ButtonIcon__b71a70bcf2","bui-ButtonIconContent":"ButtonIcon_bui-ButtonIconContent__b71a70bcf2","bui-ButtonIconSpinner":"ButtonIcon_bui-ButtonIconSpinner__b71a70bcf2","bui-spin":"ButtonIcon_bui-spin__b71a70bcf2"};
5
5
  styleInject(css_248z);
6
6
 
7
- export { stylesButtonIcon as default };
7
+ export { styles as default };
8
8
  //# sourceMappingURL=ButtonIcon.module.css.esm.js.map
@@ -1,10 +1,29 @@
1
- const ButtonIconDefinition = {
1
+ import 'react/jsx-runtime';
2
+ import 'clsx';
3
+ import 'react';
4
+ import '../../hooks/useSurface.esm.js';
5
+ import '../../hooks/useDefinition/helpers.esm.js';
6
+ import { defineComponent } from '../../hooks/useDefinition/defineComponent.esm.js';
7
+ import styles from './ButtonIcon.module.css.esm.js';
8
+
9
+ const ButtonIconDefinition = defineComponent()({
10
+ styles,
2
11
  classNames: {
3
12
  root: "bui-ButtonIcon",
4
13
  content: "bui-ButtonIconContent",
5
14
  spinner: "bui-ButtonIconSpinner"
15
+ },
16
+ surface: "leaf",
17
+ propDefs: {
18
+ size: { dataAttribute: true, default: "small" },
19
+ variant: { dataAttribute: true, default: "primary" },
20
+ loading: { dataAttribute: true },
21
+ icon: {},
22
+ onSurface: {},
23
+ className: {},
24
+ style: {}
6
25
  }
7
- };
26
+ });
8
27
 
9
28
  export { ButtonIconDefinition };
10
29
  //# sourceMappingURL=definition.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"definition.esm.js","sources":["../../../src/components/ButtonIcon/definition.ts"],"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 type { ComponentDefinition } from '../../types';\n\n/**\n * Component definition for ButtonIcon\n * @public\n */\nexport const ButtonIconDefinition = {\n classNames: {\n root: 'bui-ButtonIcon',\n content: 'bui-ButtonIconContent',\n spinner: 'bui-ButtonIconSpinner',\n },\n} as const satisfies ComponentDefinition;\n"],"names":[],"mappings":"AAsBO,MAAM,oBAAA,GAAuB;AAAA,EAClC,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,gBAAA;AAAA,IACN,OAAA,EAAS,uBAAA;AAAA,IACT,OAAA,EAAS;AAAA;AAEb;;;;"}
1
+ {"version":3,"file":"definition.esm.js","sources":["../../../src/components/ButtonIcon/definition.ts"],"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 { defineComponent } from '../../hooks/useDefinition';\nimport type { ButtonIconOwnProps } from './types';\nimport styles from './ButtonIcon.module.css';\n\n/**\n * Component definition for ButtonIcon\n * @public\n */\nexport const ButtonIconDefinition = defineComponent<ButtonIconOwnProps>()({\n styles,\n classNames: {\n root: 'bui-ButtonIcon',\n content: 'bui-ButtonIconContent',\n spinner: 'bui-ButtonIconSpinner',\n },\n surface: 'leaf',\n propDefs: {\n size: { dataAttribute: true, default: 'small' },\n variant: { dataAttribute: true, default: 'primary' },\n loading: { dataAttribute: true },\n icon: {},\n onSurface: {},\n className: {},\n style: {},\n },\n});\n"],"names":[],"mappings":";;;;;;;;AAwBO,MAAM,oBAAA,GAAuB,iBAAoC,CAAE;AAAA,EACxE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,gBAAA;AAAA,IACN,OAAA,EAAS,uBAAA;AAAA,IACT,OAAA,EAAS;AAAA,GACX;AAAA,EACA,OAAA,EAAS,MAAA;AAAA,EACT,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,EAAE,aAAA,EAAe,IAAA,EAAM,SAAS,OAAA,EAAQ;AAAA,IAC9C,OAAA,EAAS,EAAE,aAAA,EAAe,IAAA,EAAM,SAAS,SAAA,EAAU;AAAA,IACnD,OAAA,EAAS,EAAE,aAAA,EAAe,IAAA,EAAK;AAAA,IAC/B,MAAM,EAAC;AAAA,IACP,WAAW,EAAC;AAAA,IACZ,WAAW,EAAC;AAAA,IACZ,OAAO;AAAC;AAEZ,CAAC;;;;"}
@@ -1,58 +1,31 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import clsx from 'clsx';
3
2
  import { forwardRef } from 'react';
4
- import { Link, RouterProvider } from 'react-aria-components';
5
- import { useNavigate, useHref } from 'react-router-dom';
6
- import { useStyles } from '../../hooks/useStyles.esm.js';
7
- import { ButtonDefinition } from '../Button/definition.esm.js';
3
+ import { Link } from 'react-aria-components';
4
+ import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
8
5
  import { ButtonLinkDefinition } from './definition.esm.js';
9
- import { isExternalLink } from '../../utils/isExternalLink.esm.js';
10
- import stylesButton from '../Button/Button.module.css.esm.js';
6
+ import { InternalLinkProvider } from '../InternalLinkProvider/InternalLinkProvider.esm.js';
11
7
 
12
8
  const ButtonLink = forwardRef(
13
9
  (props, ref) => {
14
- const navigate = useNavigate();
15
- const { classNames, dataAttributes, cleanedProps } = useStyles(
16
- ButtonDefinition,
17
- {
18
- size: "small",
19
- variant: "primary",
20
- ...props
21
- }
10
+ const { ownProps, restProps, dataAttributes } = useDefinition(
11
+ ButtonLinkDefinition,
12
+ props
22
13
  );
23
- const { classNames: classNamesButtonLink } = useStyles(ButtonLinkDefinition);
24
- const { children, className, iconStart, iconEnd, href, ...rest } = cleanedProps;
25
- const isExternal = isExternalLink(href);
26
- const linkButton = /* @__PURE__ */ jsx(
14
+ const { classes, iconStart, iconEnd, children } = ownProps;
15
+ return /* @__PURE__ */ jsx(InternalLinkProvider, { href: restProps.href, children: /* @__PURE__ */ jsx(
27
16
  Link,
28
17
  {
29
- className: clsx(
30
- classNames.root,
31
- classNamesButtonLink.root,
32
- stylesButton[classNames.root],
33
- className
34
- ),
18
+ className: classes.root,
35
19
  ref,
36
20
  ...dataAttributes,
37
- href,
38
- ...rest,
39
- children: /* @__PURE__ */ jsxs(
40
- "span",
41
- {
42
- className: clsx(classNames.content, stylesButton[classNames.content]),
43
- children: [
44
- iconStart,
45
- children,
46
- iconEnd
47
- ]
48
- }
49
- )
21
+ ...restProps,
22
+ children: /* @__PURE__ */ jsxs("span", { className: classes.content, children: [
23
+ iconStart,
24
+ children,
25
+ iconEnd
26
+ ] })
50
27
  }
51
- );
52
- if (isExternal) {
53
- return linkButton;
54
- }
55
- return /* @__PURE__ */ jsx(RouterProvider, { navigate, useHref, children: linkButton });
28
+ ) });
56
29
  }
57
30
  );
58
31
  ButtonLink.displayName = "ButtonLink";
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonLink.esm.js","sources":["../../../src/components/ButtonLink/ButtonLink.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 clsx from 'clsx';\nimport { forwardRef, Ref } from 'react';\nimport { Link as RALink, RouterProvider } from 'react-aria-components';\nimport { useNavigate, useHref } from 'react-router-dom';\nimport type { ButtonLinkProps } from './types';\nimport { useStyles } from '../../hooks/useStyles';\nimport { ButtonDefinition } from '../Button/definition';\nimport { ButtonLinkDefinition } from './definition';\nimport { isExternalLink } from '../../utils/isExternalLink';\nimport stylesButton from '../Button/Button.module.css';\n\n/** @public */\nexport const ButtonLink = forwardRef(\n (props: ButtonLinkProps, ref: Ref<HTMLAnchorElement>) => {\n const navigate = useNavigate();\n\n const { classNames, dataAttributes, cleanedProps } = useStyles(\n ButtonDefinition,\n {\n size: 'small',\n variant: 'primary',\n ...props,\n },\n );\n\n const { classNames: classNamesButtonLink } =\n useStyles(ButtonLinkDefinition);\n\n const { children, className, iconStart, iconEnd, href, ...rest } =\n cleanedProps;\n\n const isExternal = isExternalLink(href);\n\n const linkButton = (\n <RALink\n className={clsx(\n classNames.root,\n classNamesButtonLink.root,\n stylesButton[classNames.root],\n className,\n )}\n ref={ref}\n {...dataAttributes}\n href={href}\n {...rest}\n >\n <span\n className={clsx(classNames.content, stylesButton[classNames.content])}\n >\n {iconStart}\n {children}\n {iconEnd}\n </span>\n </RALink>\n );\n\n // If it's an external link, render RALink without RouterProvider\n if (isExternal) {\n return linkButton;\n }\n\n // For internal links, use RouterProvider\n return (\n <RouterProvider navigate={navigate} useHref={useHref}>\n {linkButton}\n </RouterProvider>\n );\n },\n);\n\nButtonLink.displayName = 'ButtonLink';\n"],"names":["RALink"],"mappings":";;;;;;;;;;;AA4BO,MAAM,UAAA,GAAa,UAAA;AAAA,EACxB,CAAC,OAAwB,GAAA,KAAgC;AACvD,IAAA,MAAM,WAAW,WAAA,EAAY;AAE7B,IAAA,MAAM,EAAE,UAAA,EAAY,cAAA,EAAgB,YAAA,EAAa,GAAI,SAAA;AAAA,MACnD,gBAAA;AAAA,MACA;AAAA,QACE,IAAA,EAAM,OAAA;AAAA,QACN,OAAA,EAAS,SAAA;AAAA,QACT,GAAG;AAAA;AACL,KACF;AAEA,IAAA,MAAM,EAAE,UAAA,EAAY,oBAAA,EAAqB,GACvC,UAAU,oBAAoB,CAAA;AAEhC,IAAA,MAAM,EAAE,UAAU,SAAA,EAAW,SAAA,EAAW,SAAS,IAAA,EAAM,GAAG,MAAK,GAC7D,YAAA;AAEF,IAAA,MAAM,UAAA,GAAa,eAAe,IAAI,CAAA;AAEtC,IAAA,MAAM,UAAA,mBACJ,GAAA;AAAA,MAACA,IAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,IAAA;AAAA,UACT,UAAA,CAAW,IAAA;AAAA,UACX,oBAAA,CAAqB,IAAA;AAAA,UACrB,YAAA,CAAa,WAAW,IAAI,CAAA;AAAA,UAC5B;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG,cAAA;AAAA,QACJ,IAAA;AAAA,QACC,GAAG,IAAA;AAAA,QAEJ,QAAA,kBAAA,IAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,WAAW,IAAA,CAAK,UAAA,CAAW,SAAS,YAAA,CAAa,UAAA,CAAW,OAAO,CAAC,CAAA;AAAA,YAEnE,QAAA,EAAA;AAAA,cAAA,SAAA;AAAA,cACA,QAAA;AAAA,cACA;AAAA;AAAA;AAAA;AACH;AAAA,KACF;AAIF,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,OAAO,UAAA;AAAA,IACT;AAGA,IAAA,uBACE,GAAA,CAAC,cAAA,EAAA,EAAe,QAAA,EAAoB,OAAA,EACjC,QAAA,EAAA,UAAA,EACH,CAAA;AAAA,EAEJ;AACF;AAEA,UAAA,CAAW,WAAA,GAAc,YAAA;;;;"}
1
+ {"version":3,"file":"ButtonLink.esm.js","sources":["../../../src/components/ButtonLink/ButtonLink.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, Ref } from 'react';\nimport { Link as RALink } from 'react-aria-components';\nimport type { ButtonLinkProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { ButtonLinkDefinition } from './definition';\nimport { InternalLinkProvider } from '../InternalLinkProvider';\n\n/** @public */\nexport const ButtonLink = forwardRef(\n (props: ButtonLinkProps, ref: Ref<HTMLAnchorElement>) => {\n const { ownProps, restProps, dataAttributes } = useDefinition(\n ButtonLinkDefinition,\n props,\n );\n const { classes, iconStart, iconEnd, children } = ownProps;\n\n return (\n <InternalLinkProvider href={restProps.href}>\n <RALink\n className={classes.root}\n ref={ref}\n {...dataAttributes}\n {...restProps}\n >\n <span className={classes.content}>\n {iconStart}\n {children}\n {iconEnd}\n </span>\n </RALink>\n </InternalLinkProvider>\n );\n },\n);\n\nButtonLink.displayName = 'ButtonLink';\n"],"names":["RALink"],"mappings":";;;;;;;AAwBO,MAAM,UAAA,GAAa,UAAA;AAAA,EACxB,CAAC,OAAwB,GAAA,KAAgC;AACvD,IAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAe,GAAI,aAAA;AAAA,MAC9C,oBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAW,OAAA,EAAS,UAAS,GAAI,QAAA;AAElD,IAAA,uBACE,GAAA,CAAC,oBAAA,EAAA,EAAqB,IAAA,EAAM,SAAA,CAAU,IAAA,EACpC,QAAA,kBAAA,GAAA;AAAA,MAACA,IAAA;AAAA,MAAA;AAAA,QACC,WAAW,OAAA,CAAQ,IAAA;AAAA,QACnB,GAAA;AAAA,QACC,GAAG,cAAA;AAAA,QACH,GAAG,SAAA;AAAA,QAEJ,QAAA,kBAAA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,OAAA,CAAQ,OAAA,EACtB,QAAA,EAAA;AAAA,UAAA,SAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA,SAAA,EACH;AAAA;AAAA,KACF,EACF,CAAA;AAAA,EAEJ;AACF;AAEA,UAAA,CAAW,WAAA,GAAc,YAAA;;;;"}
@@ -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 .ButtonLink_bui-ButtonLink__dd6cf6db14 {\n --bg: transparent;\n --bg-hover: transparent;\n --bg-active: transparent;\n --fg: inherit;\n\n position: relative;\n display: inline-flex;\n border: none;\n user-select: none;\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-bold);\n padding: 0;\n cursor: pointer;\n border-radius: var(--bui-radius-2);\n flex-shrink: 0;\n text-decoration: none;\n transition: background-color 200ms ease-out, box-shadow 200ms ease-out;\n\n /* Apply variables */\n color: var(--fg);\n background-color: var(--bg);\n\n &:hover {\n background-color: var(--bg-hover);\n transition: background-color 150ms ease;\n }\n\n &:active {\n background-color: var(--bg-active);\n }\n\n &[data-disabled='true'] {\n cursor: not-allowed;\n }\n }\n\n .ButtonLink_bui-ButtonLink__dd6cf6db14[data-variant='primary'] {\n --bg: var(--bui-bg-solid);\n --bg-hover: var(--bui-bg-solid-hover);\n --bg-active: var(--bui-bg-solid-pressed);\n --fg: var(--bui-fg-solid);\n\n &[data-disabled='true'] {\n --bg: var(--bui-bg-solid-disabled);\n --bg-hover: var(--bui-bg-solid-disabled);\n --bg-active: var(--bui-bg-solid-disabled);\n --fg: var(--bui-fg-solid-disabled);\n }\n\n &:focus-visible {\n outline: 2px solid var(--bui-ring);\n outline-offset: 2px;\n }\n }\n\n .ButtonLink_bui-ButtonLink__dd6cf6db14[data-variant='secondary'] {\n --bg: var(--bui-bg-neutral-on-surface-0);\n --bg-hover: var(--bui-bg-neutral-on-surface-0-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-0-pressed);\n --fg: var(--bui-fg-primary);\n\n &[data-on-surface='1'] {\n --bg: var(--bui-bg-neutral-on-surface-1);\n --bg-hover: var(--bui-bg-neutral-on-surface-1-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-1-pressed);\n }\n\n &[data-on-surface='2'] {\n --bg: var(--bui-bg-neutral-on-surface-2);\n --bg-hover: var(--bui-bg-neutral-on-surface-2-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-2-pressed);\n }\n\n &[data-on-surface='3'] {\n --bg: var(--bui-bg-neutral-on-surface-3);\n --bg-hover: var(--bui-bg-neutral-on-surface-3-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-3-pressed);\n }\n\n &[data-disabled='true'] {\n --bg-hover: var(--bg);\n --bg-active: var(--bg);\n --fg: var(--bui-fg-disabled);\n }\n\n &:focus-visible {\n outline: none;\n transition: none;\n box-shadow: inset 0 0 0 2px var(--bui-ring);\n }\n }\n\n .ButtonLink_bui-ButtonLink__dd6cf6db14[data-variant='tertiary'] {\n --bg-hover: var(--bui-bg-neutral-on-surface-0-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-0-pressed);\n --fg: var(--bui-fg-primary);\n\n &[data-on-surface='1'] {\n --bg-hover: var(--bui-bg-neutral-on-surface-1-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-1-pressed);\n }\n\n &[data-on-surface='2'] {\n --bg-hover: var(--bui-bg-neutral-on-surface-2-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-2-pressed);\n }\n\n &[data-on-surface='3'] {\n --bg-hover: var(--bui-bg-neutral-on-surface-3-hover);\n --bg-active: var(--bui-bg-neutral-on-surface-3-pressed);\n }\n\n &[data-disabled='true'] {\n --bg-hover: var(--bg);\n --bg-active: var(--bg);\n --fg: var(--bui-fg-disabled);\n }\n\n &:focus-visible {\n outline: none;\n transition: none;\n box-shadow: inset 0 0 0 2px var(--bui-ring);\n }\n }\n\n .ButtonLink_bui-ButtonLink__dd6cf6db14[data-size='small'] {\n font-size: var(--bui-font-size-3);\n padding: 0 var(--bui-space-2);\n height: 2rem;\n\n svg {\n width: 1rem;\n height: 1rem;\n }\n }\n\n .ButtonLink_bui-ButtonLink__dd6cf6db14[data-size='medium'] {\n font-size: var(--bui-font-size-4);\n padding: 0 var(--bui-space-3);\n height: 2.5rem;\n\n svg {\n width: 1.25rem;\n height: 1.25rem;\n }\n }\n\n .ButtonLink_bui-ButtonLinkContent__dd6cf6db14 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--bui-space-1_5);\n height: 100%;\n width: 100%;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .ButtonLink_bui-ButtonLink__dd6cf6db14 {\n transition-duration: 50ms;\n }\n }\n}\n";
4
+ var styles = {"bui-ButtonLink":"ButtonLink_bui-ButtonLink__dd6cf6db14","bui-ButtonLinkContent":"ButtonLink_bui-ButtonLinkContent__dd6cf6db14"};
5
+ styleInject(css_248z);
6
+
7
+ export { styles as default };
8
+ //# sourceMappingURL=ButtonLink.module.css.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonLink.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -1,8 +1,29 @@
1
- const ButtonLinkDefinition = {
1
+ import 'react/jsx-runtime';
2
+ import 'clsx';
3
+ import 'react';
4
+ import '../../hooks/useSurface.esm.js';
5
+ import '../../hooks/useDefinition/helpers.esm.js';
6
+ import { defineComponent } from '../../hooks/useDefinition/defineComponent.esm.js';
7
+ import styles from './ButtonLink.module.css.esm.js';
8
+
9
+ const ButtonLinkDefinition = defineComponent()({
10
+ styles,
2
11
  classNames: {
3
- root: "bui-ButtonLink"
12
+ root: "bui-ButtonLink",
13
+ content: "bui-ButtonLinkContent"
14
+ },
15
+ surface: "leaf",
16
+ propDefs: {
17
+ size: { dataAttribute: true, default: "small" },
18
+ variant: { dataAttribute: true, default: "primary" },
19
+ iconStart: {},
20
+ iconEnd: {},
21
+ onSurface: {},
22
+ children: {},
23
+ className: {},
24
+ style: {}
4
25
  }
5
- };
26
+ });
6
27
 
7
28
  export { ButtonLinkDefinition };
8
29
  //# sourceMappingURL=definition.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"definition.esm.js","sources":["../../../src/components/ButtonLink/definition.ts"],"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 type { ComponentDefinition } from '../../types';\n\n/**\n * Component definition for ButtonLink\n * @public\n */\nexport const ButtonLinkDefinition = {\n classNames: {\n root: 'bui-ButtonLink',\n },\n} as const satisfies ComponentDefinition;\n"],"names":[],"mappings":"AAsBO,MAAM,oBAAA,GAAuB;AAAA,EAClC,UAAA,EAAY;AAAA,IACV,IAAA,EAAM;AAAA;AAEV;;;;"}
1
+ {"version":3,"file":"definition.esm.js","sources":["../../../src/components/ButtonLink/definition.ts"],"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 { defineComponent } from '../../hooks/useDefinition';\nimport type { ButtonLinkOwnProps } from './types';\nimport styles from './ButtonLink.module.css';\n\n/**\n * Component definition for ButtonLink\n * @public\n */\nexport const ButtonLinkDefinition = defineComponent<ButtonLinkOwnProps>()({\n styles,\n classNames: {\n root: 'bui-ButtonLink',\n content: 'bui-ButtonLinkContent',\n },\n surface: 'leaf',\n propDefs: {\n size: { dataAttribute: true, default: 'small' },\n variant: { dataAttribute: true, default: 'primary' },\n iconStart: {},\n iconEnd: {},\n onSurface: {},\n children: {},\n className: {},\n style: {},\n },\n});\n"],"names":[],"mappings":";;;;;;;;AAwBO,MAAM,oBAAA,GAAuB,iBAAoC,CAAE;AAAA,EACxE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,gBAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,OAAA,EAAS,MAAA;AAAA,EACT,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,EAAE,aAAA,EAAe,IAAA,EAAM,SAAS,OAAA,EAAQ;AAAA,IAC9C,OAAA,EAAS,EAAE,aAAA,EAAe,IAAA,EAAM,SAAS,SAAA,EAAU;AAAA,IACnD,WAAW,EAAC;AAAA,IACZ,SAAS,EAAC;AAAA,IACV,WAAW,EAAC;AAAA,IACZ,UAAU,EAAC;AAAA,IACX,WAAW,EAAC;AAAA,IACZ,OAAO;AAAC;AAEZ,CAAC;;;;"}
@@ -4,6 +4,9 @@ import { Modal, Dialog as Dialog$1, Heading, DialogTrigger as DialogTrigger$1 }
4
4
  import clsx from 'clsx';
5
5
  import { RiCloseLine } from '@remixicon/react';
6
6
  import { Button } from '../Button/Button.esm.js';
7
+ import '../../hooks/useSurface.esm.js';
8
+ import '../../hooks/useDefinition/helpers.esm.js';
9
+ import '../Button/Button.module.css.esm.js';
7
10
  import { useStyles } from '../../hooks/useStyles.esm.js';
8
11
  import { DialogDefinition } from './definition.esm.js';
9
12
  import { Flex } from '../Flex/Flex.esm.js';
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.esm.js","sources":["../../../src/components/Dialog/Dialog.tsx"],"sourcesContent":["/*\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\nimport { forwardRef } from 'react';\nimport {\n Dialog as RADialog,\n DialogTrigger as RADialogTrigger,\n Modal,\n Heading,\n} from 'react-aria-components';\nimport clsx from 'clsx';\nimport type {\n DialogTriggerProps,\n DialogHeaderProps,\n DialogProps,\n DialogBodyProps,\n} from './types';\nimport { RiCloseLine } from '@remixicon/react';\nimport { Button } from '../Button';\nimport { useStyles } from '../../hooks/useStyles';\nimport { DialogDefinition } from './definition';\nimport { Flex } from '../Flex';\nimport styles from './Dialog.module.css';\n\n/** @public */\nexport const DialogTrigger = (props: DialogTriggerProps) => {\n return <RADialogTrigger {...props} />;\n};\n\n/** @public */\nexport const Dialog = forwardRef<React.ElementRef<typeof Modal>, DialogProps>(\n (props, ref) => {\n const { classNames, cleanedProps } = useStyles(DialogDefinition, props);\n const { className, children, width, height, style, ...rest } = cleanedProps;\n\n return (\n <Modal\n ref={ref}\n className={clsx(classNames.overlay, styles[classNames.overlay])}\n isDismissable\n isKeyboardDismissDisabled={false}\n {...rest}\n >\n <RADialog\n className={clsx(\n classNames.dialog,\n styles[classNames.dialog],\n className,\n )}\n style={{\n ['--bui-dialog-min-width' as keyof React.CSSProperties]:\n typeof width === 'number' ? `${width}px` : width || '400px',\n ['--bui-dialog-min-height' as keyof React.CSSProperties]: height\n ? typeof height === 'number'\n ? `${height}px`\n : height\n : 'auto',\n ...style,\n }}\n >\n {children}\n </RADialog>\n </Modal>\n );\n },\n);\n\nDialog.displayName = 'Dialog';\n\n/** @public */\nexport const DialogHeader = forwardRef<\n React.ElementRef<'div'>,\n DialogHeaderProps\n>((props, ref) => {\n const { classNames, cleanedProps } = useStyles(DialogDefinition, props);\n const { className, children, ...rest } = cleanedProps;\n\n return (\n <Flex\n ref={ref}\n className={clsx(classNames.header, styles[classNames.header], className)}\n {...rest}\n >\n <Heading\n slot=\"title\"\n className={clsx(classNames.headerTitle, styles[classNames.headerTitle])}\n >\n {children}\n </Heading>\n <Button name=\"close\" aria-label=\"Close\" variant=\"tertiary\" slot=\"close\">\n <RiCloseLine />\n </Button>\n </Flex>\n );\n});\nDialogHeader.displayName = 'DialogHeader';\n\n/** @public */\nexport const DialogBody = forwardRef<React.ElementRef<'div'>, DialogBodyProps>(\n (props, ref) => {\n const { classNames, cleanedProps } = useStyles(DialogDefinition, props);\n const { className, children, ...rest } = cleanedProps;\n\n return (\n <div\n className={clsx(classNames.body, styles[classNames.body], className)}\n ref={ref}\n {...rest}\n >\n {children}\n </div>\n );\n },\n);\n\nDialogBody.displayName = 'DialogBody';\n\n/** @public */\nexport const DialogFooter = forwardRef<\n React.ElementRef<'div'>,\n React.ComponentPropsWithoutRef<'div'>\n>((props, ref) => {\n const { classNames, cleanedProps } = useStyles(DialogDefinition, props);\n const { className, children, ...rest } = cleanedProps;\n\n return (\n <div\n ref={ref}\n className={clsx(classNames.footer, styles[classNames.footer], className)}\n {...rest}\n >\n {children}\n </div>\n );\n});\nDialogFooter.displayName = 'DialogFooter';\n"],"names":["RADialogTrigger","RADialog"],"mappings":"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"}
1
+ {"version":3,"file":"Dialog.esm.js","sources":["../../../src/components/Dialog/Dialog.tsx"],"sourcesContent":["/*\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\nimport { forwardRef } from 'react';\nimport {\n Dialog as RADialog,\n DialogTrigger as RADialogTrigger,\n Modal,\n Heading,\n} from 'react-aria-components';\nimport clsx from 'clsx';\nimport type {\n DialogTriggerProps,\n DialogHeaderProps,\n DialogProps,\n DialogBodyProps,\n} from './types';\nimport { RiCloseLine } from '@remixicon/react';\nimport { Button } from '../Button';\nimport { useStyles } from '../../hooks/useStyles';\nimport { DialogDefinition } from './definition';\nimport { Flex } from '../Flex';\nimport styles from './Dialog.module.css';\n\n/** @public */\nexport const DialogTrigger = (props: DialogTriggerProps) => {\n return <RADialogTrigger {...props} />;\n};\n\n/** @public */\nexport const Dialog = forwardRef<React.ElementRef<typeof Modal>, DialogProps>(\n (props, ref) => {\n const { classNames, cleanedProps } = useStyles(DialogDefinition, props);\n const { className, children, width, height, style, ...rest } = cleanedProps;\n\n return (\n <Modal\n ref={ref}\n className={clsx(classNames.overlay, styles[classNames.overlay])}\n isDismissable\n isKeyboardDismissDisabled={false}\n {...rest}\n >\n <RADialog\n className={clsx(\n classNames.dialog,\n styles[classNames.dialog],\n className,\n )}\n style={{\n ['--bui-dialog-min-width' as keyof React.CSSProperties]:\n typeof width === 'number' ? `${width}px` : width || '400px',\n ['--bui-dialog-min-height' as keyof React.CSSProperties]: height\n ? typeof height === 'number'\n ? `${height}px`\n : height\n : 'auto',\n ...style,\n }}\n >\n {children}\n </RADialog>\n </Modal>\n );\n },\n);\n\nDialog.displayName = 'Dialog';\n\n/** @public */\nexport const DialogHeader = forwardRef<\n React.ElementRef<'div'>,\n DialogHeaderProps\n>((props, ref) => {\n const { classNames, cleanedProps } = useStyles(DialogDefinition, props);\n const { className, children, ...rest } = cleanedProps;\n\n return (\n <Flex\n ref={ref}\n className={clsx(classNames.header, styles[classNames.header], className)}\n {...rest}\n >\n <Heading\n slot=\"title\"\n className={clsx(classNames.headerTitle, styles[classNames.headerTitle])}\n >\n {children}\n </Heading>\n <Button name=\"close\" aria-label=\"Close\" variant=\"tertiary\" slot=\"close\">\n <RiCloseLine />\n </Button>\n </Flex>\n );\n});\nDialogHeader.displayName = 'DialogHeader';\n\n/** @public */\nexport const DialogBody = forwardRef<React.ElementRef<'div'>, DialogBodyProps>(\n (props, ref) => {\n const { classNames, cleanedProps } = useStyles(DialogDefinition, props);\n const { className, children, ...rest } = cleanedProps;\n\n return (\n <div\n className={clsx(classNames.body, styles[classNames.body], className)}\n ref={ref}\n {...rest}\n >\n {children}\n </div>\n );\n },\n);\n\nDialogBody.displayName = 'DialogBody';\n\n/** @public */\nexport const DialogFooter = forwardRef<\n React.ElementRef<'div'>,\n React.ComponentPropsWithoutRef<'div'>\n>((props, ref) => {\n const { classNames, cleanedProps } = useStyles(DialogDefinition, props);\n const { className, children, ...rest } = cleanedProps;\n\n return (\n <div\n ref={ref}\n className={clsx(classNames.footer, styles[classNames.footer], className)}\n {...rest}\n >\n {children}\n </div>\n );\n});\nDialogFooter.displayName = 'DialogFooter';\n"],"names":["RADialogTrigger","RADialog"],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { jsx, Fragment } from 'react/jsx-runtime';
2
+ import { createContext, useContext, useEffect, useState, useCallback } from 'react';
3
+ import { RouterProvider } from 'react-aria-components';
4
+ import { useNavigate, useHref } from 'react-router-dom';
5
+ import { isExternalLink } from '../../utils/isExternalLink.esm.js';
6
+
7
+ function isInternalLink(href) {
8
+ return !!href && !isExternalLink(href);
9
+ }
10
+ function RoutedContainer({ children }) {
11
+ const navigate = useNavigate();
12
+ return /* @__PURE__ */ jsx(RouterProvider, { navigate, useHref, children });
13
+ }
14
+ function useRoutingRegistration() {
15
+ const [count, setCount] = useState(0);
16
+ const register = useCallback(() => {
17
+ setCount((c) => c + 1);
18
+ return () => setCount((c) => c - 1);
19
+ }, []);
20
+ return { hasRoutedChildren: count > 0, contextValue: { register } };
21
+ }
22
+ function createRoutingRegistration() {
23
+ const RoutingContext = createContext(null);
24
+ function RoutingProvider({ children }) {
25
+ const { hasRoutedChildren, contextValue } = useRoutingRegistration();
26
+ const content = /* @__PURE__ */ jsx(RoutingContext.Provider, { value: contextValue, children });
27
+ if (hasRoutedChildren) {
28
+ return /* @__PURE__ */ jsx(RoutedContainer, { children: content });
29
+ }
30
+ return content;
31
+ }
32
+ function useRoutingRegistrationEffect(href) {
33
+ const routingCtx = useContext(RoutingContext);
34
+ const hasInternalHref = isInternalLink(href);
35
+ useEffect(() => {
36
+ if (hasInternalHref && routingCtx) {
37
+ return routingCtx.register();
38
+ }
39
+ return void 0;
40
+ }, [hasInternalHref, routingCtx]);
41
+ }
42
+ return { RoutingContext, RoutingProvider, useRoutingRegistrationEffect };
43
+ }
44
+ function InternalLinkProvider({
45
+ href,
46
+ children
47
+ }) {
48
+ if (!isInternalLink(href)) {
49
+ return /* @__PURE__ */ jsx(Fragment, { children });
50
+ }
51
+ return /* @__PURE__ */ jsx(RoutedContainer, { children });
52
+ }
53
+
54
+ export { InternalLinkProvider, RoutedContainer, createRoutingRegistration, isInternalLink, useRoutingRegistration };
55
+ //# sourceMappingURL=InternalLinkProvider.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InternalLinkProvider.esm.js","sources":["../../../src/components/InternalLinkProvider/InternalLinkProvider.tsx"],"sourcesContent":["/*\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\nimport {\n ReactNode,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport { RouterProvider } from 'react-aria-components';\nimport { useNavigate, useHref } from 'react-router-dom';\nimport { isExternalLink } from '../../utils/isExternalLink';\n\n/**\n * Checks if an href is an internal link (not external and not empty).\n *\n * @internal\n */\nexport function isInternalLink(href: string | undefined): href is string {\n return !!href && !isExternalLink(href);\n}\n\n/**\n * Context value type for routing registration.\n * Used by container components to track children that need RouterProvider.\n *\n * @internal\n */\nexport type RoutingContextValue = {\n register: () => () => void;\n};\n\n/**\n * Wraps children in a RouterProvider for client-side navigation.\n * Must be rendered within a React Router context.\n *\n * @internal\n */\nexport function RoutedContainer({ children }: { children: ReactNode }) {\n const navigate = useNavigate();\n return (\n <RouterProvider navigate={navigate} useHref={useHref}>\n {children}\n </RouterProvider>\n );\n}\n\n/**\n * Hook for container components that need to conditionally provide routing.\n *\n * Usage:\n * 1. Call this hook in the container component\n * 2. Pass `contextValue` to a RoutingContextValue context provider\n * 3. Children call `register()` via context when they have internal hrefs\n * 4. If `hasRoutedChildren` is true, wrap content in RoutedContainer\n *\n * @internal\n */\nexport function useRoutingRegistration(): {\n hasRoutedChildren: boolean;\n contextValue: RoutingContextValue;\n} {\n const [count, setCount] = useState(0);\n\n const register = useCallback(() => {\n setCount(c => c + 1);\n return () => setCount(c => c - 1);\n }, []);\n\n return { hasRoutedChildren: count > 0, contextValue: { register } };\n}\n\n/**\n * Creates a routing registration context and provider for container components.\n *\n * Usage:\n * ```tsx\n * // At module level\n * const { RoutingProvider, useRoutingRegistrationEffect } = createRoutingRegistration();\n *\n * // Container component wraps content with provider\n * <RoutingProvider>{content}</RoutingProvider>\n *\n * // Child items register when they have internal hrefs\n * useRoutingRegistrationEffect(href);\n * ```\n *\n * @internal\n */\nexport function createRoutingRegistration() {\n const RoutingContext = createContext<RoutingContextValue | null>(null);\n\n function RoutingProvider({ children }: { children: ReactNode }) {\n const { hasRoutedChildren, contextValue } = useRoutingRegistration();\n\n const content = (\n <RoutingContext.Provider value={contextValue}>\n {children}\n </RoutingContext.Provider>\n );\n\n if (hasRoutedChildren) {\n return <RoutedContainer>{content}</RoutedContainer>;\n }\n\n return content;\n }\n\n function useRoutingRegistrationEffect(href: string | undefined) {\n const routingCtx = useContext(RoutingContext);\n const hasInternalHref = isInternalLink(href);\n\n useEffect(() => {\n if (hasInternalHref && routingCtx) {\n return routingCtx.register();\n }\n return undefined;\n }, [hasInternalHref, routingCtx]);\n }\n\n return { RoutingContext, RoutingProvider, useRoutingRegistrationEffect };\n}\n\n/**\n * Conditionally wraps children in a RouterProvider for internal link navigation.\n * Only mounts the router hooks when `href` is an internal link, avoiding the\n * requirement for a Router context when rendering components without internal hrefs.\n *\n * @internal\n */\nexport function InternalLinkProvider({\n href,\n children,\n}: {\n href: string | undefined;\n children: ReactNode;\n}) {\n if (!isInternalLink(href)) {\n return <>{children}</>;\n }\n return <RoutedContainer>{children}</RoutedContainer>;\n}\n"],"names":[],"mappings":";;;;;;AAiCO,SAAS,eAAe,IAAA,EAA0C;AACvE,EAAA,OAAO,CAAC,CAAC,IAAA,IAAQ,CAAC,eAAe,IAAI,CAAA;AACvC;AAkBO,SAAS,eAAA,CAAgB,EAAE,QAAA,EAAS,EAA4B;AACrE,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,uBACE,GAAA,CAAC,cAAA,EAAA,EAAe,QAAA,EAAoB,OAAA,EACjC,QAAA,EACH,CAAA;AAEJ;AAaO,SAAS,sBAAA,GAGd;AACA,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,CAAC,CAAA;AAEpC,EAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,IAAA,QAAA,CAAS,CAAA,CAAA,KAAK,IAAI,CAAC,CAAA;AACnB,IAAA,OAAO,MAAM,QAAA,CAAS,CAAA,CAAA,KAAK,CAAA,GAAI,CAAC,CAAA;AAAA,EAClC,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,EAAE,iBAAA,EAAmB,KAAA,GAAQ,GAAG,YAAA,EAAc,EAAE,UAAS,EAAE;AACpE;AAmBO,SAAS,yBAAA,GAA4B;AAC1C,EAAA,MAAM,cAAA,GAAiB,cAA0C,IAAI,CAAA;AAErE,EAAA,SAAS,eAAA,CAAgB,EAAE,QAAA,EAAS,EAA4B;AAC9D,IAAA,MAAM,EAAE,iBAAA,EAAmB,YAAA,EAAa,GAAI,sBAAA,EAAuB;AAEnE,IAAA,MAAM,0BACJ,GAAA,CAAC,cAAA,CAAe,UAAf,EAAwB,KAAA,EAAO,cAC7B,QAAA,EACH,CAAA;AAGF,IAAA,IAAI,iBAAA,EAAmB;AACrB,MAAA,uBAAO,GAAA,CAAC,mBAAiB,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,IACnC;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,SAAS,6BAA6B,IAAA,EAA0B;AAC9D,IAAA,MAAM,UAAA,GAAa,WAAW,cAAc,CAAA;AAC5C,IAAA,MAAM,eAAA,GAAkB,eAAe,IAAI,CAAA;AAE3C,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,mBAAmB,UAAA,EAAY;AACjC,QAAA,OAAO,WAAW,QAAA,EAAS;AAAA,MAC7B;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA,EAAG,CAAC,eAAA,EAAiB,UAAU,CAAC,CAAA;AAAA,EAClC;AAEA,EAAA,OAAO,EAAE,cAAA,EAAgB,eAAA,EAAiB,4BAAA,EAA6B;AACzE;AASO,SAAS,oBAAA,CAAqB;AAAA,EACnC,IAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,IAAI,CAAC,cAAA,CAAe,IAAI,CAAA,EAAG;AACzB,IAAA,uCAAU,QAAA,EAAS,CAAA;AAAA,EACrB;AACA,EAAA,uBAAO,GAAA,CAAC,mBAAiB,QAAA,EAAS,CAAA;AACpC;;;;"}
@@ -1,12 +1,10 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { forwardRef, useRef } from 'react';
3
3
  import { useLink } from 'react-aria';
4
- import { RouterProvider } from 'react-aria-components';
5
4
  import clsx from 'clsx';
6
5
  import { useStyles } from '../../hooks/useStyles.esm.js';
7
6
  import { LinkDefinition } from './definition.esm.js';
8
- import { useNavigate, useHref } from 'react-router-dom';
9
- import { isExternalLink } from '../../utils/isExternalLink.esm.js';
7
+ import { InternalLinkProvider } from '../InternalLinkProvider/InternalLinkProvider.esm.js';
10
8
  import styles from './Link.module.css.esm.js';
11
9
 
12
10
  const LinkInternal = forwardRef((props, ref) => {
@@ -58,12 +56,7 @@ const LinkInternal = forwardRef((props, ref) => {
58
56
  });
59
57
  LinkInternal.displayName = "LinkInternal";
60
58
  const Link = forwardRef((props, ref) => {
61
- const navigate = useNavigate();
62
- const isExternal = isExternalLink(props.href);
63
- if (isExternal) {
64
- return /* @__PURE__ */ jsx(LinkInternal, { ...props, ref });
65
- }
66
- return /* @__PURE__ */ jsx(RouterProvider, { navigate, useHref, children: /* @__PURE__ */ jsx(LinkInternal, { ...props, ref }) });
59
+ return /* @__PURE__ */ jsx(InternalLinkProvider, { href: props.href, children: /* @__PURE__ */ jsx(LinkInternal, { ...props, ref }) });
67
60
  });
68
61
  Link.displayName = "Link";
69
62
 
@@ -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 { RouterProvider } from 'react-aria-components';\nimport clsx from 'clsx';\nimport { useStyles } from '../../hooks/useStyles';\nimport { LinkDefinition } from './definition';\nimport type { LinkProps } from './types';\nimport { useNavigate, useHref } from 'react-router-dom';\nimport { isExternalLink } from '../../utils/isExternalLink';\nimport styles from './Link.module.css';\n\nconst LinkInternal = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n const { classNames, dataAttributes, cleanedProps } = useStyles(\n LinkDefinition,\n {\n variant: 'body',\n weight: 'regular',\n color: 'primary',\n ...props,\n },\n );\n\n const {\n className,\n href,\n title,\n children,\n onPress,\n variant,\n weight,\n color,\n truncate,\n slot,\n ...restProps\n } = cleanedProps;\n\n const internalRef = useRef<HTMLAnchorElement>(null);\n const linkRef = (ref || internalRef) as React.RefObject<HTMLAnchorElement>;\n\n // Use useLink hook to get link props\n // For internal links, this will use the RouterProvider's navigate function\n const { linkProps } = useLink(\n {\n href,\n onPress,\n ...restProps,\n },\n linkRef,\n );\n\n return (\n <a\n {...linkProps}\n {...dataAttributes}\n {...(restProps as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n ref={linkRef}\n href={href}\n title={title}\n className={clsx(classNames.root, styles[classNames.root], className)}\n >\n {children}\n </a>\n );\n});\n\nLinkInternal.displayName = 'LinkInternal';\n\n/** @public */\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n const navigate = useNavigate();\n const isExternal = isExternalLink(props.href);\n\n // If it's an external link, render without RouterProvider\n if (isExternal) {\n return <LinkInternal {...props} ref={ref} />;\n }\n\n // For internal links, wrap in RouterProvider so useLink can access the router\n return (\n <RouterProvider navigate={navigate} useHref={useHref}>\n <LinkInternal {...props} ref={ref} />\n </RouterProvider>\n );\n});\n\nLink.displayName = 'Link';\n"],"names":[],"mappings":";;;;;;;;;;;AA2BA,MAAM,YAAA,GAAe,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC5E,EAAA,MAAM,EAAE,UAAA,EAAY,cAAA,EAAgB,YAAA,EAAa,GAAI,SAAA;AAAA,IACnD,cAAA;AAAA,IACA;AAAA,MACE,OAAA,EAAS,MAAA;AAAA,MACT,MAAA,EAAQ,SAAA;AAAA,MACR,KAAA,EAAO,SAAA;AAAA,MACP,GAAG;AAAA;AACL,GACF;AAEA,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA;AAAA,IACA,GAAG;AAAA,GACL,GAAI,YAAA;AAEJ,EAAA,MAAM,WAAA,GAAc,OAA0B,IAAI,CAAA;AAClD,EAAA,MAAM,UAAW,GAAA,IAAO,WAAA;AAIxB,EAAA,MAAM,EAAE,WAAU,GAAI,OAAA;AAAA,IACpB;AAAA,MACE,IAAA;AAAA,MACA,OAAA;AAAA,MACA,GAAG;AAAA,KACL;AAAA,IACA;AAAA,GACF;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACE,GAAG,SAAA;AAAA,MACH,GAAG,cAAA;AAAA,MACH,GAAI,SAAA;AAAA,MACL,GAAA,EAAK,OAAA;AAAA,MACL,IAAA;AAAA,MACA,KAAA;AAAA,MACA,SAAA,EAAW,KAAK,UAAA,CAAW,IAAA,EAAM,OAAO,UAAA,CAAW,IAAI,GAAG,SAAS,CAAA;AAAA,MAElE;AAAA;AAAA,GACH;AAEJ,CAAC,CAAA;AAED,YAAA,CAAa,WAAA,GAAc,cAAA;AAGpB,MAAM,IAAA,GAAO,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC3E,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,UAAA,GAAa,cAAA,CAAe,KAAA,CAAM,IAAI,CAAA;AAG5C,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,uBAAO,GAAA,CAAC,YAAA,EAAA,EAAc,GAAG,KAAA,EAAO,GAAA,EAAU,CAAA;AAAA,EAC5C;AAGA,EAAA,uBACE,GAAA,CAAC,kBAAe,QAAA,EAAoB,OAAA,EAClC,8BAAC,YAAA,EAAA,EAAc,GAAG,KAAA,EAAO,GAAA,EAAU,CAAA,EACrC,CAAA;AAEJ,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 { useLink } from 'react-aria';\nimport clsx from 'clsx';\nimport { useStyles } from '../../hooks/useStyles';\nimport { LinkDefinition } from './definition';\nimport type { LinkProps } from './types';\nimport { InternalLinkProvider } from '../InternalLinkProvider';\nimport styles from './Link.module.css';\n\nconst LinkInternal = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n const { classNames, dataAttributes, cleanedProps } = useStyles(\n LinkDefinition,\n {\n variant: 'body',\n weight: 'regular',\n color: 'primary',\n ...props,\n },\n );\n\n const {\n className,\n href,\n title,\n children,\n onPress,\n variant,\n weight,\n color,\n truncate,\n slot,\n ...restProps\n } = cleanedProps;\n\n const internalRef = useRef<HTMLAnchorElement>(null);\n const linkRef = (ref || internalRef) as React.RefObject<HTMLAnchorElement>;\n\n // Use useLink hook to get link props\n // For internal links, this will use the RouterProvider's navigate function\n const { linkProps } = useLink(\n {\n href,\n onPress,\n ...restProps,\n },\n linkRef,\n );\n\n return (\n <a\n {...linkProps}\n {...dataAttributes}\n {...(restProps as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n ref={linkRef}\n href={href}\n title={title}\n className={clsx(classNames.root, styles[classNames.root], className)}\n >\n {children}\n </a>\n );\n});\n\nLinkInternal.displayName = 'LinkInternal';\n\n/** @public */\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n return (\n <InternalLinkProvider href={props.href}>\n <LinkInternal {...props} ref={ref} />\n </InternalLinkProvider>\n );\n});\n\nLink.displayName = 'Link';\n"],"names":[],"mappings":";;;;;;;;;AAyBA,MAAM,YAAA,GAAe,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC5E,EAAA,MAAM,EAAE,UAAA,EAAY,cAAA,EAAgB,YAAA,EAAa,GAAI,SAAA;AAAA,IACnD,cAAA;AAAA,IACA;AAAA,MACE,OAAA,EAAS,MAAA;AAAA,MACT,MAAA,EAAQ,SAAA;AAAA,MACR,KAAA,EAAO,SAAA;AAAA,MACP,GAAG;AAAA;AACL,GACF;AAEA,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA;AAAA,IACA,GAAG;AAAA,GACL,GAAI,YAAA;AAEJ,EAAA,MAAM,WAAA,GAAc,OAA0B,IAAI,CAAA;AAClD,EAAA,MAAM,UAAW,GAAA,IAAO,WAAA;AAIxB,EAAA,MAAM,EAAE,WAAU,GAAI,OAAA;AAAA,IACpB;AAAA,MACE,IAAA;AAAA,MACA,OAAA;AAAA,MACA,GAAG;AAAA,KACL;AAAA,IACA;AAAA,GACF;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACE,GAAG,SAAA;AAAA,MACH,GAAG,cAAA;AAAA,MACH,GAAI,SAAA;AAAA,MACL,GAAA,EAAK,OAAA;AAAA,MACL,IAAA;AAAA,MACA,KAAA;AAAA,MACA,SAAA,EAAW,KAAK,UAAA,CAAW,IAAA,EAAM,OAAO,UAAA,CAAW,IAAI,GAAG,SAAS,CAAA;AAAA,MAElE;AAAA;AAAA,GACH;AAEJ,CAAC,CAAA;AAED,YAAA,CAAa,WAAA,GAAc,cAAA;AAGpB,MAAM,IAAA,GAAO,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC3E,EAAA,uBACE,GAAA,CAAC,oBAAA,EAAA,EAAqB,IAAA,EAAM,KAAA,CAAM,IAAA,EAChC,8BAAC,YAAA,EAAA,EAAc,GAAG,KAAA,EAAO,GAAA,EAAU,CAAA,EACrC,CAAA;AAEJ,CAAC;AAED,IAAA,CAAK,WAAA,GAAc,MAAA;;;;"}
@@ -1,13 +1,13 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { MenuTrigger as MenuTrigger$1, SubmenuTrigger as SubmenuTrigger$1, Menu as Menu$1, Popover, RouterProvider, Virtualizer, ListLayout, ListBox, useFilter, Autocomplete, SearchField, Input, Button, MenuItem as MenuItem$1, ListBoxItem, MenuSection as MenuSection$1, Header, Separator } from 'react-aria-components';
2
+ import { MenuTrigger as MenuTrigger$1, SubmenuTrigger as SubmenuTrigger$1, Menu as Menu$1, Popover, Virtualizer, ListLayout, ListBox, useFilter, Autocomplete, SearchField, Input, Button, MenuItem as MenuItem$1, ListBoxItem, MenuSection as MenuSection$1, Header, Separator } from 'react-aria-components';
3
3
  import { useStyles } from '../../hooks/useStyles.esm.js';
4
4
  import { MenuDefinition } from './definition.esm.js';
5
5
  import { RiCloseCircleLine, RiArrowRightSLine, RiCheckLine } from '@remixicon/react';
6
- import { useNavigate, useHref } from 'react-router-dom';
7
- import { isExternalLink } from '../../utils/isExternalLink.esm.js';
6
+ import { createRoutingRegistration, isInternalLink } from '../InternalLinkProvider/InternalLinkProvider.esm.js';
8
7
  import styles from './Menu.module.css.esm.js';
9
8
  import clsx from 'clsx';
10
9
 
10
+ const { RoutingProvider, useRoutingRegistrationEffect } = createRoutingRegistration();
11
11
  const rowHeight = 32;
12
12
  const MenuEmptyState = () => {
13
13
  const { classNames } = useStyles(MenuDefinition);
@@ -30,7 +30,6 @@ const Menu = (props) => {
30
30
  style,
31
31
  ...rest
32
32
  } = cleanedProps;
33
- const navigate = useNavigate();
34
33
  let newMaxWidth = maxWidth || (virtualized ? "260px" : "undefined");
35
34
  const menuContent = /* @__PURE__ */ jsx(
36
35
  Menu$1,
@@ -41,7 +40,7 @@ const Menu = (props) => {
41
40
  ...rest
42
41
  }
43
42
  );
44
- return /* @__PURE__ */ jsx(
43
+ return /* @__PURE__ */ jsx(RoutingProvider, { children: /* @__PURE__ */ jsx(
45
44
  Popover,
46
45
  {
47
46
  className: clsx(
@@ -50,7 +49,7 @@ const Menu = (props) => {
50
49
  className
51
50
  ),
52
51
  placement,
53
- children: /* @__PURE__ */ jsx(RouterProvider, { navigate, useHref, children: virtualized ? /* @__PURE__ */ jsx(
52
+ children: virtualized ? /* @__PURE__ */ jsx(
54
53
  Virtualizer,
55
54
  {
56
55
  layout: ListLayout,
@@ -59,9 +58,9 @@ const Menu = (props) => {
59
58
  },
60
59
  children: menuContent
61
60
  }
62
- ) : menuContent })
61
+ ) : menuContent
63
62
  }
64
- );
63
+ ) });
65
64
  };
66
65
  const MenuListBox = (props) => {
67
66
  const { classNames, cleanedProps } = useStyles(MenuDefinition, props);
@@ -120,7 +119,6 @@ const MenuAutocomplete = (props) => {
120
119
  } = cleanedProps;
121
120
  const { contains } = useFilter({ sensitivity: "base" });
122
121
  let newMaxWidth = maxWidth || (virtualized ? "260px" : "undefined");
123
- const navigate = useNavigate();
124
122
  const menuContent = /* @__PURE__ */ jsx(
125
123
  Menu$1,
126
124
  {
@@ -130,7 +128,7 @@ const MenuAutocomplete = (props) => {
130
128
  ...rest
131
129
  }
132
130
  );
133
- return /* @__PURE__ */ jsx(
131
+ return /* @__PURE__ */ jsx(RoutingProvider, { children: /* @__PURE__ */ jsx(
134
132
  Popover,
135
133
  {
136
134
  className: clsx(
@@ -139,7 +137,7 @@ const MenuAutocomplete = (props) => {
139
137
  className
140
138
  ),
141
139
  placement,
142
- children: /* @__PURE__ */ jsx(RouterProvider, { navigate, useHref, children: /* @__PURE__ */ jsxs(Autocomplete, { filter: contains, children: [
140
+ children: /* @__PURE__ */ jsxs(Autocomplete, { filter: contains, children: [
143
141
  /* @__PURE__ */ jsxs(
144
142
  SearchField,
145
143
  {
@@ -182,9 +180,9 @@ const MenuAutocomplete = (props) => {
182
180
  children: menuContent
183
181
  }
184
182
  ) : menuContent
185
- ] }) })
183
+ ] })
186
184
  }
187
- );
185
+ ) });
188
186
  };
189
187
  const MenuAutocompleteListbox = (props) => {
190
188
  const { classNames, cleanedProps } = useStyles(MenuDefinition, props);
@@ -276,9 +274,8 @@ const MenuItem = (props) => {
276
274
  href,
277
275
  ...rest
278
276
  } = cleanedProps;
279
- const isLink = href !== void 0;
280
- const isExternal = isExternalLink(href);
281
- if (isLink && isExternal) {
277
+ useRoutingRegistrationEffect(href);
278
+ if (href && !isInternalLink(href)) {
282
279
  return /* @__PURE__ */ jsx(
283
280
  MenuItem$1,
284
281
  {