@backstage/ui 0.7.2-next.0 → 0.7.2-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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @backstage/ui
2
2
 
3
+ ## 0.7.2-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 3c921c5: Making href mandatory in tabs that are part of a Header component
8
+ - 5c21e45: Add react router for internal routing for ButtonLinks
9
+ - 9781815: Remove auto selection of tabs for tabs that all have href defined
10
+ - f6dff5b: Using react router for internal links in the Menu component
11
+
12
+ ## 0.7.2-next.1
13
+
14
+ ### Patch Changes
15
+
16
+ - a9b88be: Enable tooltips on disabled buttons with automatic wrapper
17
+ - 4adbb03: Avoid overriding onChange when spreading props
18
+
3
19
  ## 0.7.2-next.0
4
20
 
5
21
  ### Patch Changes
@@ -1,7 +1,7 @@
1
- import { jsxs } from 'react/jsx-runtime';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import clsx from 'clsx';
3
3
  import { forwardRef } from 'react';
4
- import { Button as Button$1 } from 'react-aria-components';
4
+ import { Button as Button$1, Focusable } from 'react-aria-components';
5
5
  import { useStyles } from '../../hooks/useStyles.esm.js';
6
6
 
7
7
  const Button = forwardRef(
@@ -13,19 +13,21 @@ const Button = forwardRef(
13
13
  iconEnd,
14
14
  children,
15
15
  className,
16
+ isDisabled,
16
17
  ...rest
17
18
  } = props;
18
19
  const { classNames, dataAttributes } = useStyles("Button", {
19
20
  size,
20
21
  variant
21
22
  });
22
- return /* @__PURE__ */ jsxs(
23
+ const btn = /* @__PURE__ */ jsxs(
23
24
  Button$1,
24
25
  {
25
26
  className: clsx(classNames.root, className),
26
27
  ref,
27
28
  ...dataAttributes,
28
29
  ...rest,
30
+ isDisabled: !!isDisabled,
29
31
  children: [
30
32
  iconStart,
31
33
  children,
@@ -33,6 +35,7 @@ const Button = forwardRef(
33
35
  ]
34
36
  }
35
37
  );
38
+ return isDisabled ? /* @__PURE__ */ jsx(Focusable, { children: /* @__PURE__ */ jsx("span", { role: "button", tabIndex: 0, style: { display: "inline-flex" }, children: btn }) }) : btn;
36
39
  }
37
40
  );
38
41
  Button.displayName = "Button";
@@ -1 +1 @@
1
- {"version":3,"file":"Button.esm.js","sources":["../../../src/components/Button/Button.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 { Button as RAButton } from 'react-aria-components';\nimport type { ButtonProps } from './types';\nimport { useStyles } from '../../hooks/useStyles';\n\n/** @public */\nexport const Button = forwardRef(\n (props: ButtonProps, ref: Ref<HTMLButtonElement>) => {\n const {\n size = 'small',\n variant = 'primary',\n iconStart,\n iconEnd,\n children,\n className,\n ...rest\n } = props;\n\n const { classNames, dataAttributes } = useStyles('Button', {\n size,\n variant,\n });\n\n return (\n <RAButton\n className={clsx(classNames.root, className)}\n ref={ref}\n {...dataAttributes}\n {...rest}\n >\n {iconStart}\n {children}\n {iconEnd}\n </RAButton>\n );\n },\n);\n\nButton.displayName = 'Button';\n"],"names":["RAButton"],"mappings":";;;;;;AAuBO,MAAM,MAAA,GAAS,UAAA;AAAA,EACpB,CAAC,OAAoB,GAAA,KAAgC;AACnD,IAAA,MAAM;AAAA,MACJ,IAAA,GAAO,OAAA;AAAA,MACP,OAAA,GAAU,SAAA;AAAA,MACV,SAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,GAAG;AAAA,KACL,GAAI,KAAA;AAEJ,IAAA,MAAM,EAAE,UAAA,EAAY,cAAA,EAAe,GAAI,UAAU,QAAA,EAAU;AAAA,MACzD,IAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,uBACE,IAAA;AAAA,MAACA,QAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,IAAA,CAAK,UAAA,CAAW,IAAA,EAAM,SAAS,CAAA;AAAA,QAC1C,GAAA;AAAA,QACC,GAAG,cAAA;AAAA,QACH,GAAG,IAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,SAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA;AAAA,KACH;AAAA,EAEJ;AACF;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA;;;;"}
1
+ {"version":3,"file":"Button.esm.js","sources":["../../../src/components/Button/Button.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 { Button as RAButton, Focusable } from 'react-aria-components';\nimport type { ButtonProps } from './types';\nimport { useStyles } from '../../hooks/useStyles';\n\n/** @public */\nexport const Button = forwardRef(\n (props: ButtonProps, ref: Ref<HTMLButtonElement>) => {\n const {\n size = 'small',\n variant = 'primary',\n iconStart,\n iconEnd,\n children,\n className,\n isDisabled,\n ...rest\n } = props;\n\n const { classNames, dataAttributes } = useStyles('Button', {\n size,\n variant,\n });\n\n const btn = (\n <RAButton\n className={clsx(classNames.root, className)}\n ref={ref}\n {...dataAttributes}\n {...rest}\n isDisabled={!!isDisabled}\n >\n {iconStart}\n {children}\n {iconEnd}\n </RAButton>\n );\n\n return isDisabled ? (\n <Focusable>\n <span role=\"button\" tabIndex={0} style={{ display: 'inline-flex' }}>\n {btn}\n </span>\n </Focusable>\n ) : (\n btn\n );\n },\n);\n\nButton.displayName = 'Button';\n"],"names":["RAButton"],"mappings":";;;;;;AAuBO,MAAM,MAAA,GAAS,UAAA;AAAA,EACpB,CAAC,OAAoB,GAAA,KAAgC;AACnD,IAAA,MAAM;AAAA,MACJ,IAAA,GAAO,OAAA;AAAA,MACP,OAAA,GAAU,SAAA;AAAA,MACV,SAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,UAAA;AAAA,MACA,GAAG;AAAA,KACL,GAAI,KAAA;AAEJ,IAAA,MAAM,EAAE,UAAA,EAAY,cAAA,EAAe,GAAI,UAAU,QAAA,EAAU;AAAA,MACzD,IAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,MAAM,GAAA,mBACJ,IAAA;AAAA,MAACA,QAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,IAAA,CAAK,UAAA,CAAW,IAAA,EAAM,SAAS,CAAA;AAAA,QAC1C,GAAA;AAAA,QACC,GAAG,cAAA;AAAA,QACH,GAAG,IAAA;AAAA,QACJ,UAAA,EAAY,CAAC,CAAC,UAAA;AAAA,QAEb,QAAA,EAAA;AAAA,UAAA,SAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA;AAAA,KACH;AAGF,IAAA,OAAO,6BACL,GAAA,CAAC,SAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,MAAK,QAAA,EAAS,QAAA,EAAU,CAAA,EAAG,KAAA,EAAO,EAAE,OAAA,EAAS,aAAA,EAAc,EAC9D,QAAA,EAAA,GAAA,EACH,GACF,CAAA,GAEA,GAAA;AAAA,EAEJ;AACF;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA;;;;"}
@@ -1,11 +1,14 @@
1
- import { jsxs } from 'react/jsx-runtime';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import clsx from 'clsx';
3
3
  import { forwardRef } from 'react';
4
- import { Link } from 'react-aria-components';
4
+ import { Link, RouterProvider } from 'react-aria-components';
5
+ import { useNavigate, useHref } from 'react-router-dom';
5
6
  import { useStyles } from '../../hooks/useStyles.esm.js';
7
+ import { isExternalLink } from '../../utils/isExternalLink.esm.js';
6
8
 
7
9
  const ButtonLink = forwardRef(
8
10
  (props, ref) => {
11
+ const navigate = useNavigate();
9
12
  const {
10
13
  size = "small",
11
14
  variant = "primary",
@@ -13,6 +16,7 @@ const ButtonLink = forwardRef(
13
16
  iconEnd,
14
17
  children,
15
18
  className,
19
+ href,
16
20
  ...rest
17
21
  } = props;
18
22
  const { classNames, dataAttributes } = useStyles("Button", {
@@ -20,12 +24,39 @@ const ButtonLink = forwardRef(
20
24
  variant
21
25
  });
22
26
  const { classNames: classNamesButtonLink } = useStyles("ButtonLink");
23
- return /* @__PURE__ */ jsxs(
27
+ const isExternal = isExternalLink(href);
28
+ if (isExternal) {
29
+ return /* @__PURE__ */ jsxs(
30
+ Link,
31
+ {
32
+ className: clsx(
33
+ classNames.root,
34
+ classNamesButtonLink.root,
35
+ className
36
+ ),
37
+ ref,
38
+ ...dataAttributes,
39
+ href,
40
+ ...rest,
41
+ children: [
42
+ iconStart,
43
+ children,
44
+ iconEnd
45
+ ]
46
+ }
47
+ );
48
+ }
49
+ return /* @__PURE__ */ jsx(RouterProvider, { navigate, useHref, children: /* @__PURE__ */ jsxs(
24
50
  Link,
25
51
  {
26
- className: clsx(classNames.root, classNamesButtonLink.root, className),
52
+ className: clsx(
53
+ classNames.root,
54
+ classNamesButtonLink.root,
55
+ className
56
+ ),
27
57
  ref,
28
58
  ...dataAttributes,
59
+ href,
29
60
  ...rest,
30
61
  children: [
31
62
  iconStart,
@@ -33,7 +64,7 @@ const ButtonLink = forwardRef(
33
64
  iconEnd
34
65
  ]
35
66
  }
36
- );
67
+ ) });
37
68
  }
38
69
  );
39
70
  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 } from 'react-aria-components';\nimport type { ButtonLinkProps } from './types';\nimport { useStyles } from '../../hooks/useStyles';\n\n/** @public */\nexport const ButtonLink = forwardRef(\n (props: ButtonLinkProps, ref: Ref<HTMLAnchorElement>) => {\n const {\n size = 'small',\n variant = 'primary',\n iconStart,\n iconEnd,\n children,\n className,\n ...rest\n } = props;\n\n const { classNames, dataAttributes } = useStyles('Button', {\n size,\n variant,\n });\n\n const { classNames: classNamesButtonLink } = useStyles('ButtonLink');\n\n return (\n <RALink\n className={clsx(classNames.root, classNamesButtonLink.root, className)}\n ref={ref}\n {...dataAttributes}\n {...rest}\n >\n {iconStart}\n {children}\n {iconEnd}\n </RALink>\n );\n },\n);\n\nButtonLink.displayName = 'ButtonLink';\n"],"names":["RALink"],"mappings":";;;;;;AAuBO,MAAM,UAAA,GAAa,UAAA;AAAA,EACxB,CAAC,OAAwB,GAAA,KAAgC;AACvD,IAAA,MAAM;AAAA,MACJ,IAAA,GAAO,OAAA;AAAA,MACP,OAAA,GAAU,SAAA;AAAA,MACV,SAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,GAAG;AAAA,KACL,GAAI,KAAA;AAEJ,IAAA,MAAM,EAAE,UAAA,EAAY,cAAA,EAAe,GAAI,UAAU,QAAA,EAAU;AAAA,MACzD,IAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,MAAM,EAAE,UAAA,EAAY,oBAAA,EAAqB,GAAI,UAAU,YAAY,CAAA;AAEnE,IAAA,uBACE,IAAA;AAAA,MAACA,IAAA;AAAA,MAAA;AAAA,QACC,WAAW,IAAA,CAAK,UAAA,CAAW,IAAA,EAAM,oBAAA,CAAqB,MAAM,SAAS,CAAA;AAAA,QACrE,GAAA;AAAA,QACC,GAAG,cAAA;AAAA,QACH,GAAG,IAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,SAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA;AAAA,KACH;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 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 { isExternalLink } from '../../utils/isExternalLink';\n\n/** @public */\nexport const ButtonLink = forwardRef(\n (props: ButtonLinkProps, ref: Ref<HTMLAnchorElement>) => {\n const navigate = useNavigate();\n const {\n size = 'small',\n variant = 'primary',\n iconStart,\n iconEnd,\n children,\n className,\n href,\n ...rest\n } = props;\n\n const { classNames, dataAttributes } = useStyles('Button', {\n size,\n variant,\n });\n\n const { classNames: classNamesButtonLink } = useStyles('ButtonLink');\n\n const isExternal = isExternalLink(href);\n\n // If it's an external link, render RALink without RouterProvider\n if (isExternal) {\n return (\n <RALink\n className={clsx(\n classNames.root,\n classNamesButtonLink.root,\n className,\n )}\n ref={ref}\n {...dataAttributes}\n href={href}\n {...rest}\n >\n {iconStart}\n {children}\n {iconEnd}\n </RALink>\n );\n }\n\n // For internal links, use RouterProvider\n return (\n <RouterProvider navigate={navigate} useHref={useHref}>\n <RALink\n className={clsx(\n classNames.root,\n classNamesButtonLink.root,\n className,\n )}\n ref={ref}\n {...dataAttributes}\n href={href}\n {...rest}\n >\n {iconStart}\n {children}\n {iconEnd}\n </RALink>\n </RouterProvider>\n );\n },\n);\n\nButtonLink.displayName = 'ButtonLink';\n"],"names":["RALink"],"mappings":";;;;;;;;AAyBO,MAAM,UAAA,GAAa,UAAA;AAAA,EACxB,CAAC,OAAwB,GAAA,KAAgC;AACvD,IAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,IAAA,MAAM;AAAA,MACJ,IAAA,GAAO,OAAA;AAAA,MACP,OAAA,GAAU,SAAA;AAAA,MACV,SAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,IAAA;AAAA,MACA,GAAG;AAAA,KACL,GAAI,KAAA;AAEJ,IAAA,MAAM,EAAE,UAAA,EAAY,cAAA,EAAe,GAAI,UAAU,QAAA,EAAU;AAAA,MACzD,IAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,MAAM,EAAE,UAAA,EAAY,oBAAA,EAAqB,GAAI,UAAU,YAAY,CAAA;AAEnE,IAAA,MAAM,UAAA,GAAa,eAAe,IAAI,CAAA;AAGtC,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,uBACE,IAAA;AAAA,QAACA,IAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,IAAA;AAAA,YACT,UAAA,CAAW,IAAA;AAAA,YACX,oBAAA,CAAqB,IAAA;AAAA,YACrB;AAAA,WACF;AAAA,UACA,GAAA;AAAA,UACC,GAAG,cAAA;AAAA,UACJ,IAAA;AAAA,UACC,GAAG,IAAA;AAAA,UAEH,QAAA,EAAA;AAAA,YAAA,SAAA;AAAA,YACA,QAAA;AAAA,YACA;AAAA;AAAA;AAAA,OACH;AAAA,IAEJ;AAGA,IAAA,uBACE,GAAA,CAAC,cAAA,EAAA,EAAe,QAAA,EAAoB,OAAA,EAClC,QAAA,kBAAA,IAAA;AAAA,MAACA,IAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,IAAA;AAAA,UACT,UAAA,CAAW,IAAA;AAAA,UACX,oBAAA,CAAqB,IAAA;AAAA,UACrB;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG,cAAA;AAAA,QACJ,IAAA;AAAA,QACC,GAAG,IAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,SAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA;AAAA,KACH,EACF,CAAA;AAAA,EAEJ;AACF;AAEA,UAAA,CAAW,WAAA,GAAc,YAAA;;;;"}
@@ -1,10 +1,10 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { MenuTrigger as MenuTrigger$1, SubmenuTrigger as SubmenuTrigger$1, Popover, Menu as Menu$1, ListBox, useFilter, Autocomplete, SearchField, Input, Button, MenuItem as MenuItem$1, RouterProvider, ListBoxItem, MenuSection as MenuSection$1, Header, Separator } from 'react-aria-components';
2
+ import { MenuTrigger as MenuTrigger$1, SubmenuTrigger as SubmenuTrigger$1, Popover, RouterProvider, Menu as Menu$1, ListBox, useFilter, Autocomplete, SearchField, Input, Button, MenuItem as MenuItem$1, ListBoxItem, MenuSection as MenuSection$1, Header, Separator } from 'react-aria-components';
3
3
  import { ScrollArea } from '../ScrollArea/ScrollArea.esm.js';
4
4
  import { useStyles } from '../../hooks/useStyles.esm.js';
5
5
  import { RiCloseCircleLine, RiArrowRightSLine, RiCheckLine } from '@remixicon/react';
6
- import { isExternalLink } from '../../utils/isExternalLink.esm.js';
7
6
  import { useNavigate, useHref } from 'react-router-dom';
7
+ import { isExternalLink } from '../../utils/isExternalLink.esm.js';
8
8
 
9
9
  const MenuEmptyState = () => {
10
10
  const { classNames } = useStyles("Menu");
@@ -19,10 +19,11 @@ const SubmenuTrigger = (props) => {
19
19
  const Menu = (props) => {
20
20
  const { placement = "bottom start", ...rest } = props;
21
21
  const { classNames } = useStyles("Menu");
22
- return /* @__PURE__ */ jsx(Popover, { className: classNames.popover, placement, children: /* @__PURE__ */ jsxs(ScrollArea.Root, { children: [
22
+ const navigate = useNavigate();
23
+ return /* @__PURE__ */ jsx(Popover, { className: classNames.popover, placement, children: /* @__PURE__ */ jsx(RouterProvider, { navigate, useHref, children: /* @__PURE__ */ jsxs(ScrollArea.Root, { children: [
23
24
  /* @__PURE__ */ jsx(ScrollArea.Viewport, { children: /* @__PURE__ */ jsx(Menu$1, { className: classNames.content, ...rest, children: props.children }) }),
24
25
  /* @__PURE__ */ jsx(ScrollArea.Scrollbar, { orientation: "vertical", style: {}, children: /* @__PURE__ */ jsx(ScrollArea.Thumb, {}) })
25
- ] }) });
26
+ ] }) }) });
26
27
  };
27
28
  const MenuListBox = (props) => {
28
29
  const {
@@ -109,7 +110,6 @@ const MenuAutocompleteListbox = (props) => {
109
110
  const MenuItem = (props) => {
110
111
  const { iconStart, color = "primary", children, href, ...rest } = props;
111
112
  const { classNames } = useStyles("Menu");
112
- const navigate = useNavigate();
113
113
  const isLink = href !== void 0;
114
114
  const isExternal = isExternalLink(href);
115
115
  const content = /* @__PURE__ */ jsxs(
@@ -129,8 +129,24 @@ const MenuItem = (props) => {
129
129
  ]
130
130
  }
131
131
  );
132
- if (isLink && !isExternal) {
133
- return /* @__PURE__ */ jsx(RouterProvider, { navigate, useHref, children: content });
132
+ if (isLink && isExternal) {
133
+ return /* @__PURE__ */ jsxs(
134
+ MenuItem$1,
135
+ {
136
+ className: classNames.item,
137
+ "data-color": color,
138
+ textValue: typeof children === "string" ? children : void 0,
139
+ onAction: () => window.open(href, "_blank", "noopener,noreferrer"),
140
+ ...rest,
141
+ children: [
142
+ /* @__PURE__ */ jsxs("div", { className: classNames.itemContent, children: [
143
+ iconStart,
144
+ children
145
+ ] }),
146
+ /* @__PURE__ */ jsx("div", { className: classNames.itemArrow, children: /* @__PURE__ */ jsx(RiArrowRightSLine, {}) })
147
+ ]
148
+ }
149
+ );
134
150
  }
135
151
  return content;
136
152
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.esm.js","sources":["../../../src/components/Menu/Menu.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 MenuTrigger as RAMenuTrigger,\n Popover as RAPopover,\n MenuItem as RAMenuItem,\n Menu as RAMenu,\n MenuSection as RAMenuSection,\n Header as RAMenuHeader,\n Separator as RAMenuSeparator,\n SubmenuTrigger as RAMenuSubmenuTrigger,\n Autocomplete as RAAutocomplete,\n SearchField as RASearchField,\n Input as RAInput,\n Button as RAButton,\n ListBox as RAListBox,\n ListBoxItem as RAListBoxItem,\n useFilter,\n RouterProvider,\n} from 'react-aria-components';\nimport { ScrollArea } from '../ScrollArea';\nimport { useStyles } from '../../hooks/useStyles';\nimport type {\n MenuTriggerProps,\n SubmenuTriggerProps,\n MenuProps,\n MenuAutocompleteProps,\n MenuItemProps,\n MenuSectionProps,\n MenuSeparatorProps,\n MenuListBoxProps,\n MenuListBoxItemProps,\n MenuAutocompleteListBoxProps,\n} from './types';\nimport {\n RiArrowRightSLine,\n RiCheckLine,\n RiCloseCircleLine,\n} from '@remixicon/react';\nimport { isExternalLink } from '../../utils/isExternalLink';\nimport { useNavigate, useHref } from 'react-router-dom';\n\nconst MenuEmptyState = () => {\n const { classNames } = useStyles('Menu');\n\n return <div className={classNames.emptyState}>No results found.</div>;\n};\n\n/** @public */\nexport const MenuTrigger = (props: MenuTriggerProps) => {\n return <RAMenuTrigger {...props} />;\n};\n\n/** @public */\nexport const SubmenuTrigger = (props: SubmenuTriggerProps) => {\n return <RAMenuSubmenuTrigger {...props} />;\n};\n\n/** @public */\nexport const Menu = (props: MenuProps<object>) => {\n const { placement = 'bottom start', ...rest } = props;\n const { classNames } = useStyles('Menu');\n\n return (\n <RAPopover className={classNames.popover} placement={placement}>\n <ScrollArea.Root>\n <ScrollArea.Viewport>\n <RAMenu className={classNames.content} {...rest}>\n {props.children}\n </RAMenu>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar orientation=\"vertical\" style={{}}>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuListBox = (props: MenuListBoxProps<object>) => {\n const {\n selectionMode = 'single',\n placement = 'bottom start',\n ...rest\n } = props;\n const { classNames } = useStyles('Menu');\n\n return (\n <RAPopover className={classNames.popover} placement={placement}>\n <ScrollArea.Root>\n <ScrollArea.Viewport>\n <RAListBox\n className={classNames.content}\n selectionMode={selectionMode}\n {...rest}\n />\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar orientation=\"vertical\" style={{}}>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuAutocomplete = (props: MenuAutocompleteProps<object>) => {\n const { placement = 'bottom start', ...rest } = props;\n const { classNames } = useStyles('Menu');\n const { contains } = useFilter({ sensitivity: 'base' });\n\n return (\n <RAPopover className={classNames.popover} placement={placement}>\n <RAAutocomplete filter={contains}>\n <RASearchField className={classNames.searchField}>\n <RAInput\n className={classNames.searchFieldInput}\n aria-label=\"Search\"\n placeholder={props.placeholder || 'Search...'}\n />\n <RAButton className={classNames.searchFieldClear}>\n <RiCloseCircleLine />\n </RAButton>\n </RASearchField>\n <ScrollArea.Root>\n <ScrollArea.Viewport>\n <RAMenu\n className={classNames.content}\n renderEmptyState={() => <MenuEmptyState />}\n {...rest}\n />\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar orientation=\"vertical\" style={{}}>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </RAAutocomplete>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuAutocompleteListbox = (\n props: MenuAutocompleteListBoxProps<object>,\n) => {\n const {\n selectionMode = 'single',\n placement = 'bottom start',\n ...rest\n } = props;\n const { classNames } = useStyles('Menu');\n const { contains } = useFilter({ sensitivity: 'base' });\n\n return (\n <RAPopover className={classNames.popover} placement={placement}>\n <RAAutocomplete filter={contains}>\n <RASearchField className={classNames.searchField}>\n <RAInput\n className={classNames.searchFieldInput}\n aria-label=\"Search\"\n placeholder={props.placeholder || 'Search...'}\n />\n <RAButton className={classNames.searchFieldClear}>\n <RiCloseCircleLine />\n </RAButton>\n </RASearchField>\n <ScrollArea.Root>\n <ScrollArea.Viewport>\n <RAListBox\n className={classNames.content}\n renderEmptyState={() => <MenuEmptyState />}\n selectionMode={selectionMode}\n {...rest}\n />\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar orientation=\"vertical\" style={{}}>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </RAAutocomplete>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuItem = (props: MenuItemProps) => {\n const { iconStart, color = 'primary', children, href, ...rest } = props;\n const { classNames } = useStyles('Menu');\n const navigate = useNavigate();\n\n const isLink = href !== undefined;\n const isExternal = isExternalLink(href);\n\n const content = (\n <RAMenuItem\n className={classNames.item}\n data-color={color}\n href={href}\n textValue={typeof children === 'string' ? children : undefined}\n {...rest}\n >\n <div className={classNames.itemContent}>\n {iconStart}\n {children}\n </div>\n <div className={classNames.itemArrow}>\n <RiArrowRightSLine />\n </div>\n </RAMenuItem>\n );\n\n if (isLink && !isExternal) {\n return (\n <RouterProvider navigate={navigate} useHref={useHref}>\n {content}\n </RouterProvider>\n );\n }\n\n return content;\n};\n\n/** @public */\nexport const MenuListBoxItem = (props: MenuListBoxItemProps) => {\n const { children, ...rest } = props;\n const { classNames } = useStyles('Menu');\n\n return (\n <RAListBoxItem\n textValue={\n typeof props.children === 'string' ? props.children : undefined\n }\n className={classNames.itemListBox}\n {...rest}\n >\n <div className={classNames.itemContent}>\n <div className={classNames.itemListBoxCheck}>\n <RiCheckLine />\n </div>\n {children}\n </div>\n </RAListBoxItem>\n );\n};\n\n/** @public */\nexport const MenuSection = (props: MenuSectionProps<object>) => {\n const { classNames } = useStyles('Menu');\n\n return (\n <RAMenuSection className={classNames.section} {...props}>\n <RAMenuHeader className={classNames.sectionHeader}>\n {props.title}\n </RAMenuHeader>\n {props.children}\n </RAMenuSection>\n );\n};\n\n/** @public */\nexport const MenuSeparator = (props: MenuSeparatorProps) => {\n const { classNames } = useStyles('Menu');\n\n return <RAMenuSeparator className={classNames.separator} {...props} />;\n};\n"],"names":["RAMenuTrigger","RAMenuSubmenuTrigger","RAPopover","RAMenu","RAListBox","RAAutocomplete","RASearchField","RAInput","RAButton","RAMenuItem","RAListBoxItem","RAMenuSection","RAMenuHeader","RAMenuSeparator"],"mappings":"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"}
1
+ {"version":3,"file":"Menu.esm.js","sources":["../../../src/components/Menu/Menu.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 MenuTrigger as RAMenuTrigger,\n Popover as RAPopover,\n MenuItem as RAMenuItem,\n Menu as RAMenu,\n MenuSection as RAMenuSection,\n Header as RAMenuHeader,\n Separator as RAMenuSeparator,\n SubmenuTrigger as RAMenuSubmenuTrigger,\n Autocomplete as RAAutocomplete,\n SearchField as RASearchField,\n Input as RAInput,\n Button as RAButton,\n ListBox as RAListBox,\n ListBoxItem as RAListBoxItem,\n useFilter,\n RouterProvider,\n} from 'react-aria-components';\nimport { ScrollArea } from '../ScrollArea';\nimport { useStyles } from '../../hooks/useStyles';\nimport type {\n MenuTriggerProps,\n SubmenuTriggerProps,\n MenuProps,\n MenuAutocompleteProps,\n MenuItemProps,\n MenuSectionProps,\n MenuSeparatorProps,\n MenuListBoxProps,\n MenuListBoxItemProps,\n MenuAutocompleteListBoxProps,\n} from './types';\nimport {\n RiArrowRightSLine,\n RiCheckLine,\n RiCloseCircleLine,\n} from '@remixicon/react';\nimport { useNavigate, useHref } from 'react-router-dom';\nimport { isExternalLink } from '../../utils/isExternalLink';\n\nconst MenuEmptyState = () => {\n const { classNames } = useStyles('Menu');\n\n return <div className={classNames.emptyState}>No results found.</div>;\n};\n\n/** @public */\nexport const MenuTrigger = (props: MenuTriggerProps) => {\n return <RAMenuTrigger {...props} />;\n};\n\n/** @public */\nexport const SubmenuTrigger = (props: SubmenuTriggerProps) => {\n return <RAMenuSubmenuTrigger {...props} />;\n};\n\n/** @public */\nexport const Menu = (props: MenuProps<object>) => {\n const { placement = 'bottom start', ...rest } = props;\n const { classNames } = useStyles('Menu');\n const navigate = useNavigate();\n\n return (\n <RAPopover className={classNames.popover} placement={placement}>\n <RouterProvider navigate={navigate} useHref={useHref}>\n <ScrollArea.Root>\n <ScrollArea.Viewport>\n <RAMenu className={classNames.content} {...rest}>\n {props.children}\n </RAMenu>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar orientation=\"vertical\" style={{}}>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </RouterProvider>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuListBox = (props: MenuListBoxProps<object>) => {\n const {\n selectionMode = 'single',\n placement = 'bottom start',\n ...rest\n } = props;\n const { classNames } = useStyles('Menu');\n\n return (\n <RAPopover className={classNames.popover} placement={placement}>\n <ScrollArea.Root>\n <ScrollArea.Viewport>\n <RAListBox\n className={classNames.content}\n selectionMode={selectionMode}\n {...rest}\n />\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar orientation=\"vertical\" style={{}}>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuAutocomplete = (props: MenuAutocompleteProps<object>) => {\n const { placement = 'bottom start', ...rest } = props;\n const { classNames } = useStyles('Menu');\n const { contains } = useFilter({ sensitivity: 'base' });\n\n return (\n <RAPopover className={classNames.popover} placement={placement}>\n <RAAutocomplete filter={contains}>\n <RASearchField className={classNames.searchField}>\n <RAInput\n className={classNames.searchFieldInput}\n aria-label=\"Search\"\n placeholder={props.placeholder || 'Search...'}\n />\n <RAButton className={classNames.searchFieldClear}>\n <RiCloseCircleLine />\n </RAButton>\n </RASearchField>\n <ScrollArea.Root>\n <ScrollArea.Viewport>\n <RAMenu\n className={classNames.content}\n renderEmptyState={() => <MenuEmptyState />}\n {...rest}\n />\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar orientation=\"vertical\" style={{}}>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </RAAutocomplete>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuAutocompleteListbox = (\n props: MenuAutocompleteListBoxProps<object>,\n) => {\n const {\n selectionMode = 'single',\n placement = 'bottom start',\n ...rest\n } = props;\n const { classNames } = useStyles('Menu');\n const { contains } = useFilter({ sensitivity: 'base' });\n\n return (\n <RAPopover className={classNames.popover} placement={placement}>\n <RAAutocomplete filter={contains}>\n <RASearchField className={classNames.searchField}>\n <RAInput\n className={classNames.searchFieldInput}\n aria-label=\"Search\"\n placeholder={props.placeholder || 'Search...'}\n />\n <RAButton className={classNames.searchFieldClear}>\n <RiCloseCircleLine />\n </RAButton>\n </RASearchField>\n <ScrollArea.Root>\n <ScrollArea.Viewport>\n <RAListBox\n className={classNames.content}\n renderEmptyState={() => <MenuEmptyState />}\n selectionMode={selectionMode}\n {...rest}\n />\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar orientation=\"vertical\" style={{}}>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </RAAutocomplete>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuItem = (props: MenuItemProps) => {\n const { iconStart, color = 'primary', children, href, ...rest } = props;\n const { classNames } = useStyles('Menu');\n\n const isLink = href !== undefined;\n const isExternal = isExternalLink(href);\n\n const content = (\n <RAMenuItem\n className={classNames.item}\n data-color={color}\n href={href}\n textValue={typeof children === 'string' ? children : undefined}\n {...rest}\n >\n <div className={classNames.itemContent}>\n {iconStart}\n {children}\n </div>\n <div className={classNames.itemArrow}>\n <RiArrowRightSLine />\n </div>\n </RAMenuItem>\n );\n\n if (isLink && isExternal) {\n return (\n <RAMenuItem\n className={classNames.item}\n data-color={color}\n textValue={typeof children === 'string' ? children : undefined}\n onAction={() => window.open(href, '_blank', 'noopener,noreferrer')}\n {...rest}\n >\n <div className={classNames.itemContent}>\n {iconStart}\n {children}\n </div>\n <div className={classNames.itemArrow}>\n <RiArrowRightSLine />\n </div>\n </RAMenuItem>\n );\n }\n\n return content;\n};\n\n/** @public */\nexport const MenuListBoxItem = (props: MenuListBoxItemProps) => {\n const { children, ...rest } = props;\n const { classNames } = useStyles('Menu');\n\n return (\n <RAListBoxItem\n textValue={\n typeof props.children === 'string' ? props.children : undefined\n }\n className={classNames.itemListBox}\n {...rest}\n >\n <div className={classNames.itemContent}>\n <div className={classNames.itemListBoxCheck}>\n <RiCheckLine />\n </div>\n {children}\n </div>\n </RAListBoxItem>\n );\n};\n\n/** @public */\nexport const MenuSection = (props: MenuSectionProps<object>) => {\n const { classNames } = useStyles('Menu');\n\n return (\n <RAMenuSection className={classNames.section} {...props}>\n <RAMenuHeader className={classNames.sectionHeader}>\n {props.title}\n </RAMenuHeader>\n {props.children}\n </RAMenuSection>\n );\n};\n\n/** @public */\nexport const MenuSeparator = (props: MenuSeparatorProps) => {\n const { classNames } = useStyles('Menu');\n\n return <RAMenuSeparator className={classNames.separator} {...props} />;\n};\n"],"names":["RAMenuTrigger","RAMenuSubmenuTrigger","RAPopover","RAMenu","RAListBox","RAAutocomplete","RASearchField","RAInput","RAButton","RAMenuItem","RAListBoxItem","RAMenuSection","RAMenuHeader","RAMenuSeparator"],"mappings":"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"}
@@ -17,6 +17,7 @@ const SearchField = forwardRef(
17
17
  secondaryLabel,
18
18
  description,
19
19
  isRequired,
20
+ onChange,
20
21
  placeholder = "Search",
21
22
  startCollapsed = false,
22
23
  "aria-label": ariaLabel,
@@ -1 +1 @@
1
- {"version":3,"file":"SearchField.esm.js","sources":["../../../src/components/SearchField/SearchField.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, useEffect, useState } from 'react';\nimport {\n Input,\n SearchField as AriaSearchField,\n Button,\n} from 'react-aria-components';\nimport clsx from 'clsx';\nimport { FieldLabel } from '../FieldLabel';\nimport { FieldError } from '../FieldError';\nimport { RiSearch2Line, RiCloseCircleLine } from '@remixicon/react';\nimport { useStyles } from '../../hooks/useStyles';\n\nimport type { SearchFieldProps } from './types';\n\n/** @public */\nexport const SearchField = forwardRef<HTMLDivElement, SearchFieldProps>(\n (props, ref) => {\n const {\n className,\n icon,\n size = 'small',\n label,\n secondaryLabel,\n description,\n isRequired,\n placeholder = 'Search',\n startCollapsed = false,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...rest\n } = props;\n\n const [isCollapsed, setIsCollapsed] = useState(false);\n const [shouldCollapse, setShouldCollapse] = useState(true);\n\n useEffect(() => {\n if (!label && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n 'SearchField requires either a visible label, aria-label, or aria-labelledby for accessibility',\n );\n }\n }, [label, ariaLabel, ariaLabelledBy]);\n\n const { classNames: textFieldClassNames, dataAttributes } = useStyles(\n 'TextField',\n {\n size,\n },\n );\n\n const { classNames: searchFieldClassNames } = useStyles('SearchField', {});\n\n // If a secondary label is provided, use it. Otherwise, use 'Required' if the field is required.\n const secondaryLabelText =\n secondaryLabel || (isRequired ? 'Required' : null);\n\n const handleClick = (isFocused: boolean) => {\n props.onFocusChange?.(isFocused);\n if (shouldCollapse) {\n if (isFocused) {\n setIsCollapsed(true);\n } else {\n setIsCollapsed(false);\n }\n }\n };\n\n const handleChange = (value: string) => {\n props.onChange?.(value);\n if (value.length > 0) {\n setShouldCollapse(false);\n } else {\n setShouldCollapse(true);\n }\n };\n\n return (\n <AriaSearchField\n className={clsx(\n textFieldClassNames.root,\n searchFieldClassNames.root,\n className,\n )}\n {...dataAttributes}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n data-start-collapsed={startCollapsed}\n data-collapsed={isCollapsed}\n onFocusChange={handleClick}\n onChange={handleChange}\n {...rest}\n ref={ref}\n >\n <FieldLabel\n label={label}\n secondaryLabel={secondaryLabelText}\n description={description}\n />\n <div\n className={textFieldClassNames.inputWrapper}\n data-size={dataAttributes['data-size']}\n >\n {icon !== false && (\n <div\n className={textFieldClassNames.inputIcon}\n data-size={dataAttributes['data-size']}\n aria-hidden=\"true\"\n >\n {icon || <RiSearch2Line />}\n </div>\n )}\n <Input\n className={textFieldClassNames.input}\n {...(icon !== false && { 'data-icon': true })}\n placeholder={placeholder}\n />\n <Button\n className={searchFieldClassNames.clear}\n data-size={dataAttributes['data-size']}\n >\n <RiCloseCircleLine />\n </Button>\n </div>\n <FieldError />\n </AriaSearchField>\n );\n },\n);\n\nSearchField.displayName = 'searchField';\n"],"names":["AriaSearchField"],"mappings":"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"}
1
+ {"version":3,"file":"SearchField.esm.js","sources":["../../../src/components/SearchField/SearchField.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, useEffect, useState } from 'react';\nimport {\n Input,\n SearchField as AriaSearchField,\n Button,\n} from 'react-aria-components';\nimport clsx from 'clsx';\nimport { FieldLabel } from '../FieldLabel';\nimport { FieldError } from '../FieldError';\nimport { RiSearch2Line, RiCloseCircleLine } from '@remixicon/react';\nimport { useStyles } from '../../hooks/useStyles';\n\nimport type { SearchFieldProps } from './types';\n\n/** @public */\nexport const SearchField = forwardRef<HTMLDivElement, SearchFieldProps>(\n (props, ref) => {\n const {\n className,\n icon,\n size = 'small',\n label,\n secondaryLabel,\n description,\n isRequired,\n onChange,\n placeholder = 'Search',\n startCollapsed = false,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...rest\n } = props;\n\n const [isCollapsed, setIsCollapsed] = useState(false);\n const [shouldCollapse, setShouldCollapse] = useState(true);\n\n useEffect(() => {\n if (!label && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n 'SearchField requires either a visible label, aria-label, or aria-labelledby for accessibility',\n );\n }\n }, [label, ariaLabel, ariaLabelledBy]);\n\n const { classNames: textFieldClassNames, dataAttributes } = useStyles(\n 'TextField',\n {\n size,\n },\n );\n\n const { classNames: searchFieldClassNames } = useStyles('SearchField', {});\n\n // If a secondary label is provided, use it. Otherwise, use 'Required' if the field is required.\n const secondaryLabelText =\n secondaryLabel || (isRequired ? 'Required' : null);\n\n const handleClick = (isFocused: boolean) => {\n props.onFocusChange?.(isFocused);\n if (shouldCollapse) {\n if (isFocused) {\n setIsCollapsed(true);\n } else {\n setIsCollapsed(false);\n }\n }\n };\n\n const handleChange = (value: string) => {\n props.onChange?.(value);\n if (value.length > 0) {\n setShouldCollapse(false);\n } else {\n setShouldCollapse(true);\n }\n };\n\n return (\n <AriaSearchField\n className={clsx(\n textFieldClassNames.root,\n searchFieldClassNames.root,\n className,\n )}\n {...dataAttributes}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n data-start-collapsed={startCollapsed}\n data-collapsed={isCollapsed}\n onFocusChange={handleClick}\n onChange={handleChange}\n {...rest}\n ref={ref}\n >\n <FieldLabel\n label={label}\n secondaryLabel={secondaryLabelText}\n description={description}\n />\n <div\n className={textFieldClassNames.inputWrapper}\n data-size={dataAttributes['data-size']}\n >\n {icon !== false && (\n <div\n className={textFieldClassNames.inputIcon}\n data-size={dataAttributes['data-size']}\n aria-hidden=\"true\"\n >\n {icon || <RiSearch2Line />}\n </div>\n )}\n <Input\n className={textFieldClassNames.input}\n {...(icon !== false && { 'data-icon': true })}\n placeholder={placeholder}\n />\n <Button\n className={searchFieldClassNames.clear}\n data-size={dataAttributes['data-size']}\n >\n <RiCloseCircleLine />\n </Button>\n </div>\n <FieldError />\n </AriaSearchField>\n );\n },\n);\n\nSearchField.displayName = 'searchField';\n"],"names":["AriaSearchField"],"mappings":"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"}
@@ -51,9 +51,17 @@ const Tabs = (props) => {
51
51
  }
52
52
  }
53
53
  }
54
+ const allTabsHaveHref = tabListChildren.every(
55
+ (child2) => isValidElement(child2) && child2.props.href
56
+ );
57
+ if (allTabsHaveHref) {
58
+ return null;
59
+ } else {
60
+ return void 0;
61
+ }
54
62
  }
55
63
  }
56
- return null;
64
+ return void 0;
57
65
  })();
58
66
  if (!children) return null;
59
67
  const contextValue = {
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.esm.js","sources":["../../../src/components/Tabs/Tabs.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 {\n useRef,\n useState,\n Children,\n cloneElement,\n isValidElement,\n ReactNode,\n createContext,\n useContext,\n} from 'react';\nimport type {\n TabsProps,\n TabListProps,\n TabPanelProps,\n TabsContextValue,\n TabProps,\n} from './types';\nimport { useLocation, useNavigate, useHref } from 'react-router-dom';\nimport { TabsIndicators } from './TabsIndicators';\nimport {\n Tabs as AriaTabs,\n TabList as AriaTabList,\n Tab as AriaTab,\n TabPanel as AriaTabPanel,\n RouterProvider,\n TabProps as AriaTabProps,\n} from 'react-aria-components';\n\nimport { useStyles } from '../../hooks/useStyles';\n\nconst TabsContext = createContext<TabsContextValue | undefined>(undefined);\n\nconst useTabsContext = () => {\n const context = useContext(TabsContext);\n if (!context) {\n throw new Error('Tab components must be used within a Tabs component');\n }\n return context;\n};\n\n/**\n * Utility function to determine if a tab should be active based on the matching strategy.\n * This follows the pattern used in WorkaroundNavLink from the sidebar.\n */\nconst isTabActive = (\n tabHref: string,\n currentPathname: string,\n matchStrategy: 'exact' | 'prefix',\n): boolean => {\n if (matchStrategy === 'exact') {\n return tabHref === currentPathname;\n }\n\n // Prefix matching - similar to WorkaroundNavLink behavior\n if (tabHref === currentPathname) {\n return true;\n }\n\n // Check if current path starts with tab href followed by a slash\n // This prevents /foo matching /foobar\n return currentPathname.startsWith(`${tabHref}/`);\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const Tabs = (props: TabsProps) => {\n const { children, ...rest } = props;\n const { classNames } = useStyles('Tabs');\n const tabsRef = useRef<HTMLDivElement>(null);\n const tabRefs = useRef<Map<string, HTMLDivElement>>(new Map());\n const [hoveredKey, setHoveredKey] = useState<string | null>(null);\n const prevHoveredKey = useRef<string | null>(null);\n let navigate = useNavigate();\n const location = useLocation();\n\n const setTabRef = (key: string, element: HTMLDivElement | null) => {\n if (element) {\n tabRefs.current.set(key, element);\n } else {\n tabRefs.current.delete(key);\n }\n };\n\n // If selectedKey is not provided, try to determine it from the current route\n const computedSelectedKey = (() => {\n const childrenArray = Children.toArray(children as ReactNode);\n for (const child of childrenArray) {\n if (isValidElement(child) && child.type === TabList) {\n const tabListChildren = Children.toArray(child.props.children);\n for (const tabChild of tabListChildren) {\n if (isValidElement(tabChild) && tabChild.props.href) {\n // Use tab-specific strategy, defaulting to 'exact'\n const strategy = tabChild.props.matchStrategy || 'exact';\n if (isTabActive(tabChild.props.href, location.pathname, strategy)) {\n return tabChild.props.id;\n }\n }\n }\n }\n }\n return null;\n })();\n\n if (!children) return null;\n\n const contextValue: TabsContextValue = {\n tabsRef,\n tabRefs,\n hoveredKey,\n prevHoveredKey,\n setHoveredKey,\n setTabRef,\n };\n\n return (\n <TabsContext.Provider value={contextValue}>\n <RouterProvider navigate={navigate} useHref={useHref}>\n <AriaTabs\n className={classNames.tabs}\n keyboardActivation=\"manual\"\n selectedKey={computedSelectedKey}\n ref={tabsRef}\n {...rest}\n >\n {children as ReactNode}\n </AriaTabs>\n </RouterProvider>\n </TabsContext.Provider>\n );\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const TabList = (props: TabListProps) => {\n const { children, ...rest } = props;\n const { classNames } = useStyles('Tabs');\n const { setHoveredKey, tabRefs, tabsRef, hoveredKey, prevHoveredKey } =\n useTabsContext();\n\n const handleHover = (key: string | null) => {\n setHoveredKey(key);\n };\n\n // Clone children with additional props for hover and ref management\n const enhancedChildren = Children.map(children as ReactNode, child => {\n if (isValidElement(child)) {\n return cloneElement(child, {\n onHoverStart: () => handleHover(child.props.id as string),\n onHoverEnd: () => handleHover(null),\n } as Partial<AriaTabProps>);\n }\n return child;\n });\n\n return (\n <div className={classNames.tabListWrapper}>\n <AriaTabList\n className={classNames.tabList}\n aria-label=\"Toolbar tabs\"\n {...rest}\n >\n {enhancedChildren}\n </AriaTabList>\n <TabsIndicators\n tabRefs={tabRefs}\n tabsRef={tabsRef}\n hoveredKey={hoveredKey}\n prevHoveredKey={prevHoveredKey}\n />\n </div>\n );\n};\n\n/**\n * A component that renders a tab.\n *\n * @public\n */\nexport const Tab = (props: TabProps) => {\n const { href, children, id, matchStrategy: _matchStrategy, ...rest } = props;\n const { classNames } = useStyles('Tabs');\n const { setTabRef } = useTabsContext();\n\n return (\n <AriaTab\n id={id}\n className={classNames.tab}\n ref={el => setTabRef(id as string, el as HTMLDivElement)}\n href={href}\n {...rest}\n >\n {children}\n </AriaTab>\n );\n};\n\n/**\n * A component that renders the content of a tab.\n *\n * @public\n */\nexport const TabPanel = (props: TabPanelProps) => {\n const { children, ...rest } = props;\n const { classNames } = useStyles('Tabs');\n\n return (\n <AriaTabPanel className={classNames.panel} {...rest}>\n {children}\n </AriaTabPanel>\n );\n};\n"],"names":["AriaTabs","AriaTabList","AriaTab","AriaTabPanel"],"mappings":"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"}
1
+ {"version":3,"file":"Tabs.esm.js","sources":["../../../src/components/Tabs/Tabs.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 {\n useRef,\n useState,\n Children,\n cloneElement,\n isValidElement,\n ReactNode,\n createContext,\n useContext,\n} from 'react';\nimport type {\n TabsProps,\n TabListProps,\n TabPanelProps,\n TabsContextValue,\n TabProps,\n} from './types';\nimport { useLocation, useNavigate, useHref } from 'react-router-dom';\nimport { TabsIndicators } from './TabsIndicators';\nimport {\n Tabs as AriaTabs,\n TabList as AriaTabList,\n Tab as AriaTab,\n TabPanel as AriaTabPanel,\n RouterProvider,\n TabProps as AriaTabProps,\n} from 'react-aria-components';\n\nimport { useStyles } from '../../hooks/useStyles';\n\nconst TabsContext = createContext<TabsContextValue | undefined>(undefined);\n\nconst useTabsContext = () => {\n const context = useContext(TabsContext);\n if (!context) {\n throw new Error('Tab components must be used within a Tabs component');\n }\n return context;\n};\n\n/**\n * Utility function to determine if a tab should be active based on the matching strategy.\n * This follows the pattern used in WorkaroundNavLink from the sidebar.\n */\nconst isTabActive = (\n tabHref: string,\n currentPathname: string,\n matchStrategy: 'exact' | 'prefix',\n): boolean => {\n if (matchStrategy === 'exact') {\n return tabHref === currentPathname;\n }\n\n // Prefix matching - similar to WorkaroundNavLink behavior\n if (tabHref === currentPathname) {\n return true;\n }\n\n // Check if current path starts with tab href followed by a slash\n // This prevents /foo matching /foobar\n return currentPathname.startsWith(`${tabHref}/`);\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const Tabs = (props: TabsProps) => {\n const { children, ...rest } = props;\n const { classNames } = useStyles('Tabs');\n const tabsRef = useRef<HTMLDivElement>(null);\n const tabRefs = useRef<Map<string, HTMLDivElement>>(new Map());\n const [hoveredKey, setHoveredKey] = useState<string | null>(null);\n const prevHoveredKey = useRef<string | null>(null);\n let navigate = useNavigate();\n const location = useLocation();\n\n const setTabRef = (key: string, element: HTMLDivElement | null) => {\n if (element) {\n tabRefs.current.set(key, element);\n } else {\n tabRefs.current.delete(key);\n }\n };\n\n // If selectedKey is not provided, try to determine it from the current route\n const computedSelectedKey = (() => {\n const childrenArray = Children.toArray(children as ReactNode);\n for (const child of childrenArray) {\n if (isValidElement(child) && child.type === TabList) {\n const tabListChildren = Children.toArray(child.props.children);\n for (const tabChild of tabListChildren) {\n if (isValidElement(tabChild) && tabChild.props.href) {\n // Use tab-specific strategy, defaulting to 'exact'\n const strategy = tabChild.props.matchStrategy || 'exact';\n if (isTabActive(tabChild.props.href, location.pathname, strategy)) {\n return tabChild.props.id;\n }\n }\n }\n\n //No route matches - check if all tabs have hrefs (pure navigation)\n const allTabsHaveHref = tabListChildren.every(\n child => isValidElement(child) && child.props.href,\n );\n\n if (allTabsHaveHref) {\n // Pure navigation tabs, no route match\n return null;\n } else {\n // Mixed tabs or pure local state\n return undefined;\n }\n }\n }\n return undefined;\n })();\n\n if (!children) return null;\n\n const contextValue: TabsContextValue = {\n tabsRef,\n tabRefs,\n hoveredKey,\n prevHoveredKey,\n setHoveredKey,\n setTabRef,\n };\n\n return (\n <TabsContext.Provider value={contextValue}>\n <RouterProvider navigate={navigate} useHref={useHref}>\n <AriaTabs\n className={classNames.tabs}\n keyboardActivation=\"manual\"\n selectedKey={computedSelectedKey}\n ref={tabsRef}\n {...rest}\n >\n {children as ReactNode}\n </AriaTabs>\n </RouterProvider>\n </TabsContext.Provider>\n );\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const TabList = (props: TabListProps) => {\n const { children, ...rest } = props;\n const { classNames } = useStyles('Tabs');\n const { setHoveredKey, tabRefs, tabsRef, hoveredKey, prevHoveredKey } =\n useTabsContext();\n\n const handleHover = (key: string | null) => {\n setHoveredKey(key);\n };\n\n // Clone children with additional props for hover and ref management\n const enhancedChildren = Children.map(children as ReactNode, child => {\n if (isValidElement(child)) {\n return cloneElement(child, {\n onHoverStart: () => handleHover(child.props.id as string),\n onHoverEnd: () => handleHover(null),\n } as Partial<AriaTabProps>);\n }\n return child;\n });\n\n return (\n <div className={classNames.tabListWrapper}>\n <AriaTabList\n className={classNames.tabList}\n aria-label=\"Toolbar tabs\"\n {...rest}\n >\n {enhancedChildren}\n </AriaTabList>\n <TabsIndicators\n tabRefs={tabRefs}\n tabsRef={tabsRef}\n hoveredKey={hoveredKey}\n prevHoveredKey={prevHoveredKey}\n />\n </div>\n );\n};\n\n/**\n * A component that renders a tab.\n *\n * @public\n */\nexport const Tab = (props: TabProps) => {\n const { href, children, id, matchStrategy: _matchStrategy, ...rest } = props;\n const { classNames } = useStyles('Tabs');\n const { setTabRef } = useTabsContext();\n\n return (\n <AriaTab\n id={id}\n className={classNames.tab}\n ref={el => setTabRef(id as string, el as HTMLDivElement)}\n href={href}\n {...rest}\n >\n {children}\n </AriaTab>\n );\n};\n\n/**\n * A component that renders the content of a tab.\n *\n * @public\n */\nexport const TabPanel = (props: TabPanelProps) => {\n const { children, ...rest } = props;\n const { classNames } = useStyles('Tabs');\n\n return (\n <AriaTabPanel className={classNames.panel} {...rest}>\n {children}\n </AriaTabPanel>\n );\n};\n"],"names":["child","AriaTabs","AriaTabList","AriaTab","AriaTabPanel"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -934,7 +934,7 @@ interface HeaderProps {
934
934
  interface HeaderTab {
935
935
  id: string;
936
936
  label: string;
937
- href?: string;
937
+ href: string;
938
938
  /**
939
939
  * Strategy for matching the current route to determine if this tab should be active.
940
940
  * - 'exact': Tab href must exactly match the current pathname (default)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/ui",
3
- "version": "0.7.2-next.0",
3
+ "version": "0.7.2-next.2",
4
4
  "backstage": {
5
5
  "role": "web-library"
6
6
  },
@@ -45,7 +45,7 @@
45
45
  "react-aria-components": "^1.10.1"
46
46
  },
47
47
  "devDependencies": {
48
- "@backstage/cli": "0.34.4-next.0",
48
+ "@backstage/cli": "0.34.4-next.3",
49
49
  "@types/react": "^18.0.0",
50
50
  "@types/react-dom": "^18.0.0",
51
51
  "chalk": "^5.4.1",