@backstage/ui 0.13.2 → 0.14.0-next.1
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 +67 -7
- package/dist/components/Accordion/Accordion.esm.js.map +1 -1
- package/dist/components/Avatar/Avatar.esm.js.map +1 -1
- package/dist/components/Avatar/Avatar.module.css.esm.js +2 -2
- package/dist/components/Box/Box.esm.js.map +1 -1
- package/dist/components/ButtonIcon/ButtonIcon.esm.js.map +1 -1
- package/dist/components/ButtonIcon/ButtonIcon.module.css.esm.js +2 -2
- package/dist/components/ButtonLink/ButtonLink.esm.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.esm.js.map +1 -1
- package/dist/components/Container/Container.esm.js.map +1 -1
- package/dist/components/Dialog/Dialog.esm.js.map +1 -1
- package/dist/components/FieldError/FieldError.esm.js.map +1 -1
- package/dist/components/FieldLabel/FieldLabel.esm.js +10 -2
- package/dist/components/FieldLabel/FieldLabel.esm.js.map +1 -1
- package/dist/components/FieldLabel/definition.esm.js +1 -0
- package/dist/components/FieldLabel/definition.esm.js.map +1 -1
- package/dist/components/Flex/Flex.esm.js.map +1 -1
- package/dist/components/Header/Header.esm.js +4 -14
- package/dist/components/Header/Header.esm.js.map +1 -1
- package/dist/components/Header/HeaderNav.esm.js +163 -0
- package/dist/components/Header/HeaderNav.esm.js.map +1 -0
- package/dist/components/Header/HeaderNav.module.css.esm.js +8 -0
- package/dist/components/Header/HeaderNav.module.css.esm.js.map +1 -0
- package/dist/components/Header/HeaderNavDefinition.esm.js +48 -0
- package/dist/components/Header/HeaderNavDefinition.esm.js.map +1 -0
- package/dist/components/Header/HeaderNavIndicators.esm.js +92 -0
- package/dist/components/Header/HeaderNavIndicators.esm.js.map +1 -0
- package/dist/components/Header/definition.esm.js +1 -0
- package/dist/components/Header/definition.esm.js.map +1 -1
- package/dist/components/Link/Link.esm.js.map +1 -1
- package/dist/components/Menu/Menu.esm.js +16 -39
- package/dist/components/Menu/Menu.esm.js.map +1 -1
- package/dist/components/Menu/Menu.module.css.esm.js +2 -2
- package/dist/components/Menu/definition.esm.js +0 -2
- package/dist/components/Menu/definition.esm.js.map +1 -1
- package/dist/components/PasswordField/PasswordField.esm.js.map +1 -1
- package/dist/components/PluginHeader/PluginHeader.esm.js +22 -15
- package/dist/components/PluginHeader/PluginHeader.esm.js.map +1 -1
- package/dist/components/PluginHeader/PluginHeader.module.css.esm.js +2 -2
- package/dist/components/PluginHeader/definition.esm.js +0 -1
- package/dist/components/PluginHeader/definition.esm.js.map +1 -1
- package/dist/components/RadioGroup/RadioGroup.esm.js.map +1 -1
- package/dist/components/SearchAutocomplete/SearchAutocomplete.esm.js.map +1 -1
- package/dist/components/SearchField/SearchField.esm.js.map +1 -1
- package/dist/components/Select/Select.esm.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.esm.js.map +1 -1
- package/dist/components/Slider/Slider.esm.js +76 -0
- package/dist/components/Slider/Slider.esm.js.map +1 -0
- package/dist/components/Slider/Slider.module.css.esm.js +8 -0
- package/dist/components/Slider/Slider.module.css.esm.js.map +1 -0
- package/dist/components/Slider/definition.esm.js +31 -0
- package/dist/components/Slider/definition.esm.js.map +1 -0
- package/dist/components/Switch/Switch.esm.js.map +1 -1
- package/dist/components/Table/components/Cell.esm.js.map +1 -1
- package/dist/components/Table/components/CellProfile.esm.js.map +1 -1
- package/dist/components/Table/components/CellText.esm.js.map +1 -1
- package/dist/components/Table/components/Column.esm.js.map +1 -1
- package/dist/components/Table/components/Row.esm.js.map +1 -1
- package/dist/components/Table/components/Table.esm.js.map +1 -1
- package/dist/components/Table/components/TableBody.esm.js.map +1 -1
- package/dist/components/Table/components/TableHeader.esm.js.map +1 -1
- package/dist/components/Table/components/TableRoot.esm.js.map +1 -1
- package/dist/components/Table/hooks/useTable.esm.js.map +1 -1
- package/dist/components/Tabs/Tabs.esm.js +4 -4
- package/dist/components/Tabs/Tabs.module.css.esm.js +2 -2
- package/dist/components/Text/Text.esm.js.map +1 -1
- package/dist/components/TextField/TextField.esm.js.map +1 -1
- package/dist/components/ToggleButton/ToggleButton.esm.js.map +1 -1
- package/dist/components/ToggleButtonGroup/ToggleButtonGroup.esm.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.esm.js.map +1 -1
- package/dist/index.d.ts +358 -51
- package/dist/index.esm.js +3 -0
- package/dist/index.esm.js.map +1 -1
- package/package.json +15 -10
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useRef, useState, useMemo, useCallback } from 'react';
|
|
3
|
+
import { useFocusVisible, useHover, useLink } from 'react-aria';
|
|
4
|
+
import { Button } from 'react-aria-components';
|
|
5
|
+
import { RiArrowDownSLine } from '@remixicon/react';
|
|
6
|
+
import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
|
|
7
|
+
import { HeaderNavDefinition, HeaderNavGroupDefinition, HeaderNavItemDefinition } from './HeaderNavDefinition.esm.js';
|
|
8
|
+
import { HeaderNavIndicators } from './HeaderNavIndicators.esm.js';
|
|
9
|
+
import { MenuTrigger, Menu, MenuItem } from '../Menu/Menu.esm.js';
|
|
10
|
+
import '../Menu/definition.esm.js';
|
|
11
|
+
|
|
12
|
+
function isTabGroup(tab) {
|
|
13
|
+
return "items" in tab;
|
|
14
|
+
}
|
|
15
|
+
function HeaderNavLink(props) {
|
|
16
|
+
const { tab, active, analytics, registerRef, onHighlight } = props;
|
|
17
|
+
const { ownProps } = useDefinition(HeaderNavItemDefinition, {});
|
|
18
|
+
const linkRef = useRef(null);
|
|
19
|
+
const { linkProps } = useLink({ href: tab.href }, linkRef);
|
|
20
|
+
const { hoverProps } = useHover({
|
|
21
|
+
onHoverStart: () => onHighlight(tab.id),
|
|
22
|
+
onHoverEnd: () => onHighlight(null)
|
|
23
|
+
});
|
|
24
|
+
const handleClick = (e) => {
|
|
25
|
+
linkProps.onClick?.(e);
|
|
26
|
+
analytics.captureEvent("click", tab.label, {
|
|
27
|
+
attributes: { to: tab.href }
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
31
|
+
"a",
|
|
32
|
+
{
|
|
33
|
+
...linkProps,
|
|
34
|
+
...hoverProps,
|
|
35
|
+
ref: (el) => {
|
|
36
|
+
linkRef.current = el;
|
|
37
|
+
registerRef(tab.id, el);
|
|
38
|
+
},
|
|
39
|
+
href: tab.href,
|
|
40
|
+
className: ownProps.classes.root,
|
|
41
|
+
"aria-current": active ? "page" : void 0,
|
|
42
|
+
onClick: handleClick,
|
|
43
|
+
onFocus: () => onHighlight(tab.id),
|
|
44
|
+
onBlur: () => onHighlight(null),
|
|
45
|
+
children: tab.label
|
|
46
|
+
}
|
|
47
|
+
) });
|
|
48
|
+
}
|
|
49
|
+
function HeaderNavGroupItem(props) {
|
|
50
|
+
const { group, active, activeChildId, registerRef, onHighlight } = props;
|
|
51
|
+
const { ownProps } = useDefinition(HeaderNavGroupDefinition, {});
|
|
52
|
+
const { hoverProps } = useHover({
|
|
53
|
+
onHoverStart: () => onHighlight(group.id),
|
|
54
|
+
onHoverEnd: () => onHighlight(null)
|
|
55
|
+
});
|
|
56
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(MenuTrigger, { children: [
|
|
57
|
+
/* @__PURE__ */ jsxs(
|
|
58
|
+
Button,
|
|
59
|
+
{
|
|
60
|
+
ref: (el) => {
|
|
61
|
+
registerRef(group.id, el);
|
|
62
|
+
},
|
|
63
|
+
className: ownProps.classes.root,
|
|
64
|
+
"aria-current": active ? "page" : void 0,
|
|
65
|
+
...hoverProps,
|
|
66
|
+
onFocus: () => onHighlight(group.id),
|
|
67
|
+
onBlur: () => onHighlight(null),
|
|
68
|
+
children: [
|
|
69
|
+
group.label,
|
|
70
|
+
/* @__PURE__ */ jsx(RiArrowDownSLine, { size: 16 })
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
),
|
|
74
|
+
/* @__PURE__ */ jsx(
|
|
75
|
+
Menu,
|
|
76
|
+
{
|
|
77
|
+
selectionMode: "single",
|
|
78
|
+
selectedKeys: new Set(activeChildId ? [activeChildId] : []),
|
|
79
|
+
children: group.items.map((item) => /* @__PURE__ */ jsx(MenuItem, { id: item.id, href: item.href, children: item.label }, item.id))
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
] }) });
|
|
83
|
+
}
|
|
84
|
+
function HeaderNav(props) {
|
|
85
|
+
const { tabs, activeTabId } = props;
|
|
86
|
+
const { ownProps, analytics } = useDefinition(HeaderNavDefinition, {
|
|
87
|
+
tabs,
|
|
88
|
+
activeTabId
|
|
89
|
+
});
|
|
90
|
+
const { classes } = ownProps;
|
|
91
|
+
const { isFocusVisible } = useFocusVisible();
|
|
92
|
+
const navRef = useRef(null);
|
|
93
|
+
const itemRefs = useRef(/* @__PURE__ */ new Map());
|
|
94
|
+
const [highlightedKey, setHighlightedKey] = useState(null);
|
|
95
|
+
const { activeKey, activeChildId } = useMemo(() => {
|
|
96
|
+
if (!activeTabId) return { activeKey: void 0, activeChildId: void 0 };
|
|
97
|
+
for (const item of tabs) {
|
|
98
|
+
if (isTabGroup(item)) {
|
|
99
|
+
const child = item.items.find((c) => c.id === activeTabId);
|
|
100
|
+
if (child) {
|
|
101
|
+
return { activeKey: item.id, activeChildId: child.id };
|
|
102
|
+
}
|
|
103
|
+
} else if (item.id === activeTabId) {
|
|
104
|
+
return { activeKey: item.id, activeChildId: void 0 };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { activeKey: void 0, activeChildId: void 0 };
|
|
108
|
+
}, [activeTabId, tabs]);
|
|
109
|
+
const registerRef = useCallback((key, el) => {
|
|
110
|
+
if (el) {
|
|
111
|
+
itemRefs.current.set(key, el);
|
|
112
|
+
} else {
|
|
113
|
+
itemRefs.current.delete(key);
|
|
114
|
+
}
|
|
115
|
+
}, []);
|
|
116
|
+
return /* @__PURE__ */ jsxs(
|
|
117
|
+
"nav",
|
|
118
|
+
{
|
|
119
|
+
ref: navRef,
|
|
120
|
+
"aria-label": "Content navigation",
|
|
121
|
+
className: classes.root,
|
|
122
|
+
"data-focus-visible": isFocusVisible || void 0,
|
|
123
|
+
children: [
|
|
124
|
+
/* @__PURE__ */ jsx("ul", { role: "list", className: classes.list, children: tabs.map(
|
|
125
|
+
(item) => isTabGroup(item) ? /* @__PURE__ */ jsx(
|
|
126
|
+
HeaderNavGroupItem,
|
|
127
|
+
{
|
|
128
|
+
group: item,
|
|
129
|
+
active: activeKey === item.id,
|
|
130
|
+
activeChildId,
|
|
131
|
+
registerRef,
|
|
132
|
+
onHighlight: setHighlightedKey
|
|
133
|
+
},
|
|
134
|
+
item.id
|
|
135
|
+
) : /* @__PURE__ */ jsx(
|
|
136
|
+
HeaderNavLink,
|
|
137
|
+
{
|
|
138
|
+
tab: item,
|
|
139
|
+
active: activeKey === item.id,
|
|
140
|
+
analytics,
|
|
141
|
+
registerRef,
|
|
142
|
+
onHighlight: setHighlightedKey
|
|
143
|
+
},
|
|
144
|
+
item.id
|
|
145
|
+
)
|
|
146
|
+
) }),
|
|
147
|
+
/* @__PURE__ */ jsx(
|
|
148
|
+
HeaderNavIndicators,
|
|
149
|
+
{
|
|
150
|
+
navRef,
|
|
151
|
+
itemRefs,
|
|
152
|
+
activeKey,
|
|
153
|
+
highlightedKey,
|
|
154
|
+
classes: { active: classes.active, hovered: classes.hovered }
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export { HeaderNav };
|
|
163
|
+
//# sourceMappingURL=HeaderNav.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeaderNav.esm.js","sources":["../../../src/components/Header/HeaderNav.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport { useFocusVisible, useHover, useLink } from 'react-aria';\nimport { Button as RAButton } from 'react-aria-components';\nimport { RiArrowDownSLine } from '@remixicon/react';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport {\n HeaderNavDefinition,\n HeaderNavItemDefinition,\n HeaderNavGroupDefinition,\n} from './HeaderNavDefinition';\nimport { HeaderNavIndicators } from './HeaderNavIndicators';\nimport { MenuTrigger, Menu, MenuItem } from '../Menu';\nimport type { AnalyticsTracker } from '../../analytics/types';\nimport type {\n HeaderNavTab,\n HeaderNavTabGroup,\n HeaderNavTabItem,\n} from './types';\n\nfunction isTabGroup(tab: HeaderNavTabItem): tab is HeaderNavTabGroup {\n return 'items' in tab;\n}\n\ninterface HeaderNavLinkProps {\n tab: HeaderNavTab;\n active: boolean;\n analytics: AnalyticsTracker;\n registerRef: (key: string, el: HTMLElement | null) => void;\n onHighlight: (key: string | null) => void;\n}\n\nfunction HeaderNavLink(props: HeaderNavLinkProps) {\n const { tab, active, analytics, registerRef, onHighlight } = props;\n const { ownProps } = useDefinition(HeaderNavItemDefinition, {});\n\n const linkRef = useRef<HTMLAnchorElement>(null);\n const { linkProps } = useLink({ href: tab.href }, linkRef);\n const { hoverProps } = useHover({\n onHoverStart: () => onHighlight(tab.id),\n onHoverEnd: () => onHighlight(null),\n });\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n linkProps.onClick?.(e);\n analytics.captureEvent('click', tab.label, {\n attributes: { to: tab.href },\n });\n };\n\n return (\n <li>\n <a\n {...linkProps}\n {...hoverProps}\n ref={el => {\n (\n linkRef as React.MutableRefObject<HTMLAnchorElement | null>\n ).current = el;\n registerRef(tab.id, el);\n }}\n href={tab.href}\n className={ownProps.classes.root}\n aria-current={active ? 'page' : undefined}\n onClick={handleClick}\n onFocus={() => onHighlight(tab.id)}\n onBlur={() => onHighlight(null)}\n >\n {tab.label}\n </a>\n </li>\n );\n}\n\ninterface HeaderNavGroupItemProps {\n group: HeaderNavTabGroup;\n active: boolean;\n activeChildId?: string;\n registerRef: (key: string, el: HTMLElement | null) => void;\n onHighlight: (key: string | null) => void;\n}\n\nfunction HeaderNavGroupItem(props: HeaderNavGroupItemProps) {\n const { group, active, activeChildId, registerRef, onHighlight } = props;\n const { ownProps } = useDefinition(HeaderNavGroupDefinition, {});\n const { hoverProps } = useHover({\n onHoverStart: () => onHighlight(group.id),\n onHoverEnd: () => onHighlight(null),\n });\n\n return (\n <li>\n <MenuTrigger>\n <RAButton\n ref={el => {\n registerRef(group.id, el);\n }}\n className={ownProps.classes.root}\n aria-current={active ? 'page' : undefined}\n {...hoverProps}\n onFocus={() => onHighlight(group.id)}\n onBlur={() => onHighlight(null)}\n >\n {group.label}\n <RiArrowDownSLine size={16} />\n </RAButton>\n <Menu\n selectionMode=\"single\"\n selectedKeys={new Set(activeChildId ? [activeChildId] : [])}\n >\n {group.items.map(item => (\n <MenuItem key={item.id} id={item.id} href={item.href}>\n {item.label}\n </MenuItem>\n ))}\n </Menu>\n </MenuTrigger>\n </li>\n );\n}\n\ninterface HeaderNavProps {\n tabs: HeaderNavTabItem[];\n activeTabId?: string;\n}\n\n/** @internal */\nexport function HeaderNav(props: HeaderNavProps) {\n const { tabs, activeTabId } = props;\n const { ownProps, analytics } = useDefinition(HeaderNavDefinition, {\n tabs,\n activeTabId,\n });\n const { classes } = ownProps;\n\n const { isFocusVisible } = useFocusVisible();\n const navRef = useRef<HTMLElement>(null);\n const itemRefs = useRef<Map<string, HTMLElement>>(new Map());\n\n const [highlightedKey, setHighlightedKey] = useState<string | null>(null);\n\n // Resolve activeTabId to a top-level key (groups own their children's active state)\n const { activeKey, activeChildId } = useMemo(() => {\n if (!activeTabId) return { activeKey: undefined, activeChildId: undefined };\n for (const item of tabs) {\n if (isTabGroup(item)) {\n const child = item.items.find(c => c.id === activeTabId);\n if (child) {\n return { activeKey: item.id, activeChildId: child.id };\n }\n } else if (item.id === activeTabId) {\n return { activeKey: item.id, activeChildId: undefined };\n }\n }\n return { activeKey: undefined, activeChildId: undefined };\n }, [activeTabId, tabs]);\n\n const registerRef = useCallback((key: string, el: HTMLElement | null) => {\n if (el) {\n itemRefs.current.set(key, el);\n } else {\n itemRefs.current.delete(key);\n }\n }, []);\n\n return (\n <nav\n ref={navRef}\n aria-label=\"Content navigation\"\n className={classes.root}\n data-focus-visible={isFocusVisible || undefined}\n >\n <ul role=\"list\" className={classes.list}>\n {tabs.map(item =>\n isTabGroup(item) ? (\n <HeaderNavGroupItem\n key={item.id}\n group={item}\n active={activeKey === item.id}\n activeChildId={activeChildId}\n registerRef={registerRef}\n onHighlight={setHighlightedKey}\n />\n ) : (\n <HeaderNavLink\n key={item.id}\n tab={item}\n active={activeKey === item.id}\n analytics={analytics}\n registerRef={registerRef}\n onHighlight={setHighlightedKey}\n />\n ),\n )}\n </ul>\n <HeaderNavIndicators\n navRef={navRef}\n itemRefs={itemRefs}\n activeKey={activeKey}\n highlightedKey={highlightedKey}\n classes={{ active: classes.active, hovered: classes.hovered }}\n />\n </nav>\n );\n}\n"],"names":["RAButton"],"mappings":"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"}
|
|
@@ -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 .HeaderNav_bui-HeaderNav__203c060f73 {\n position: relative;\n\n /* CSS custom properties for indicator positioning — set by HeaderNavIndicators */\n --active-tab-left: 0px;\n --active-tab-right: 0px;\n --active-tab-top: 0px;\n --active-tab-bottom: 0px;\n --active-tab-width: 0px;\n --active-tab-height: 0px;\n --active-tab-opacity: 0;\n --active-transition-duration: 0s;\n\n --hovered-tab-left: 0px;\n --hovered-tab-right: 0px;\n --hovered-tab-top: 0px;\n --hovered-tab-bottom: 0px;\n --hovered-tab-width: 0px;\n --hovered-tab-height: 0px;\n --hovered-tab-opacity: 0;\n --hovered-transition-duration: 0s;\n }\n\n .HeaderNav_bui-HeaderNavList__203c060f73 {\n display: flex;\n flex-direction: row;\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .HeaderNav_bui-HeaderNavItem__203c060f73,\n .HeaderNav_bui-HeaderNavGroup__203c060f73 {\n font-family: var(--bui-font-regular);\n font-size: var(--bui-font-size-3);\n font-weight: var(--bui-font-weight-regular);\n color: var(--bui-fg-secondary);\n height: 36px;\n display: flex;\n gap: var(--bui-space-1);\n align-items: center;\n padding-inline: var(--bui-space-2);\n text-decoration: none;\n cursor: pointer;\n position: relative;\n z-index: 2;\n border: none;\n background: none;\n outline: none;\n }\n\n .HeaderNav_bui-HeaderNavItem__203c060f73[aria-current='page'],\n .HeaderNav_bui-HeaderNavGroup__203c060f73[aria-current='page'] {\n color: var(--bui-fg-primary);\n }\n\n .HeaderNav_bui-HeaderNavActive__203c060f73 {\n pointer-events: none;\n position: absolute;\n bottom: -1px;\n left: calc(var(--active-tab-left) + var(--bui-space-2));\n width: calc(var(--active-tab-width) - var(--bui-space-4));\n height: 1px;\n background-color: var(--bui-fg-primary);\n border-radius: 4px;\n opacity: var(--active-tab-opacity);\n transition: left var(--active-transition-duration) ease-out,\n width var(--active-transition-duration) ease-out, opacity 0.15s;\n }\n\n .HeaderNav_bui-HeaderNavHovered__203c060f73 {\n pointer-events: none;\n position: absolute;\n left: var(--hovered-tab-left);\n top: calc(var(--hovered-tab-top) + 4px);\n width: var(--hovered-tab-width);\n height: calc(var(--hovered-tab-height) - 8px);\n background-color: var(--bui-bg-neutral-2);\n border-radius: 4px;\n opacity: var(--hovered-tab-opacity);\n transition: left var(--hovered-transition-duration) ease-out,\n top var(--hovered-transition-duration) ease-out,\n width var(--hovered-transition-duration) ease-out,\n height var(--hovered-transition-duration) ease-out, opacity 0.15s;\n\n [data-focus-visible] & {\n outline: 2px solid var(--bui-ring);\n outline-offset: -2px;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .HeaderNav_bui-HeaderNavActive__203c060f73,\n .HeaderNav_bui-HeaderNavHovered__203c060f73 {\n transition: none;\n }\n }\n}\n";
|
|
4
|
+
var styles = {"bui-HeaderNav":"HeaderNav_bui-HeaderNav__203c060f73","bui-HeaderNavList":"HeaderNav_bui-HeaderNavList__203c060f73","bui-HeaderNavItem":"HeaderNav_bui-HeaderNavItem__203c060f73","bui-HeaderNavGroup":"HeaderNav_bui-HeaderNavGroup__203c060f73","bui-HeaderNavActive":"HeaderNav_bui-HeaderNavActive__203c060f73","bui-HeaderNavHovered":"HeaderNav_bui-HeaderNavHovered__203c060f73"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { styles as default };
|
|
8
|
+
//# sourceMappingURL=HeaderNav.module.css.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeaderNav.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import 'react/jsx-runtime';
|
|
2
|
+
import 'clsx';
|
|
3
|
+
import '../../hooks/useBreakpoint.esm.js';
|
|
4
|
+
import '../../hooks/useBg.esm.js';
|
|
5
|
+
import '../../hooks/useDefinition/helpers.esm.js';
|
|
6
|
+
import '../../analytics/useAnalytics.esm.js';
|
|
7
|
+
import 'react-router-dom';
|
|
8
|
+
import { defineComponent } from '../../hooks/useDefinition/defineComponent.esm.js';
|
|
9
|
+
import styles from './HeaderNav.module.css.esm.js';
|
|
10
|
+
|
|
11
|
+
const HeaderNavDefinition = defineComponent()({
|
|
12
|
+
styles,
|
|
13
|
+
classNames: {
|
|
14
|
+
root: "bui-HeaderNav",
|
|
15
|
+
list: "bui-HeaderNavList",
|
|
16
|
+
active: "bui-HeaderNavActive",
|
|
17
|
+
hovered: "bui-HeaderNavHovered"
|
|
18
|
+
},
|
|
19
|
+
analytics: true,
|
|
20
|
+
propDefs: {
|
|
21
|
+
noTrack: {},
|
|
22
|
+
tabs: {},
|
|
23
|
+
activeTabId: {},
|
|
24
|
+
children: {},
|
|
25
|
+
className: {}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const HeaderNavItemDefinition = defineComponent()({
|
|
29
|
+
styles,
|
|
30
|
+
classNames: {
|
|
31
|
+
root: "bui-HeaderNavItem"
|
|
32
|
+
},
|
|
33
|
+
propDefs: {
|
|
34
|
+
className: {}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
const HeaderNavGroupDefinition = defineComponent()({
|
|
38
|
+
styles,
|
|
39
|
+
classNames: {
|
|
40
|
+
root: "bui-HeaderNavGroup"
|
|
41
|
+
},
|
|
42
|
+
propDefs: {
|
|
43
|
+
className: {}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export { HeaderNavDefinition, HeaderNavGroupDefinition, HeaderNavItemDefinition };
|
|
48
|
+
//# sourceMappingURL=HeaderNavDefinition.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeaderNavDefinition.esm.js","sources":["../../../src/components/Header/HeaderNavDefinition.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { defineComponent } from '../../hooks/useDefinition';\nimport type { HeaderNavTabItem } from './types';\nimport styles from './HeaderNav.module.css';\n\n/** @public */\nexport const HeaderNavDefinition = defineComponent<{\n noTrack?: boolean;\n tabs: HeaderNavTabItem[];\n activeTabId?: string;\n children?: React.ReactNode;\n className?: string;\n}>()({\n styles,\n classNames: {\n root: 'bui-HeaderNav',\n list: 'bui-HeaderNavList',\n active: 'bui-HeaderNavActive',\n hovered: 'bui-HeaderNavHovered',\n },\n analytics: true,\n propDefs: {\n noTrack: {},\n tabs: {},\n activeTabId: {},\n children: {},\n className: {},\n },\n});\n\n/** @public */\nexport const HeaderNavItemDefinition = defineComponent<{\n className?: string;\n}>()({\n styles,\n classNames: {\n root: 'bui-HeaderNavItem',\n },\n propDefs: {\n className: {},\n },\n});\n\n/** @public */\nexport const HeaderNavGroupDefinition = defineComponent<{\n className?: string;\n}>()({\n styles,\n classNames: {\n root: 'bui-HeaderNavGroup',\n },\n propDefs: {\n className: {},\n },\n});\n"],"names":[],"mappings":";;;;;;;;;;AAqBO,MAAM,mBAAA,GAAsB,iBAMhC,CAAE;AAAA,EACH,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,eAAA;AAAA,IACN,IAAA,EAAM,mBAAA;AAAA,IACN,MAAA,EAAQ,qBAAA;AAAA,IACR,OAAA,EAAS;AAAA,GACX;AAAA,EACA,SAAA,EAAW,IAAA;AAAA,EACX,QAAA,EAAU;AAAA,IACR,SAAS,EAAC;AAAA,IACV,MAAM,EAAC;AAAA,IACP,aAAa,EAAC;AAAA,IACd,UAAU,EAAC;AAAA,IACX,WAAW;AAAC;AAEhB,CAAC;AAGM,MAAM,uBAAA,GAA0B,iBAEpC,CAAE;AAAA,EACH,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM;AAAA,GACR;AAAA,EACA,QAAA,EAAU;AAAA,IACR,WAAW;AAAC;AAEhB,CAAC;AAGM,MAAM,wBAAA,GAA2B,iBAErC,CAAE;AAAA,EACH,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM;AAAA,GACR;AAAA,EACA,QAAA,EAAU;AAAA,IACR,WAAW;AAAC;AAEhB,CAAC;;;;"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useRef, useCallback, useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
function HeaderNavIndicators(props) {
|
|
5
|
+
const { navRef, itemRefs, activeKey, highlightedKey, classes } = props;
|
|
6
|
+
const prevActiveKey = useRef(null);
|
|
7
|
+
const prevHoveredKey = useRef(null);
|
|
8
|
+
const resetTimer = useRef(null);
|
|
9
|
+
const updateCSSVariables = useCallback(() => {
|
|
10
|
+
const container = navRef.current;
|
|
11
|
+
if (!container) return;
|
|
12
|
+
const containerRect = container.getBoundingClientRect();
|
|
13
|
+
if (activeKey) {
|
|
14
|
+
const el = itemRefs.current.get(activeKey);
|
|
15
|
+
if (el) {
|
|
16
|
+
const rect = el.getBoundingClientRect();
|
|
17
|
+
const relativeLeft = rect.left - containerRect.left;
|
|
18
|
+
const relativeTop = rect.top - containerRect.top;
|
|
19
|
+
if (prevActiveKey.current === null) {
|
|
20
|
+
container.style.setProperty("--active-transition-duration", "0s");
|
|
21
|
+
requestAnimationFrame(() => {
|
|
22
|
+
container.style.setProperty(
|
|
23
|
+
"--active-transition-duration",
|
|
24
|
+
"0.25s"
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
} else {
|
|
28
|
+
container.style.setProperty("--active-transition-duration", "0.25s");
|
|
29
|
+
}
|
|
30
|
+
container.style.setProperty("--active-tab-left", `${relativeLeft}px`);
|
|
31
|
+
container.style.setProperty("--active-tab-width", `${rect.width}px`);
|
|
32
|
+
container.style.setProperty("--active-tab-height", `${rect.height}px`);
|
|
33
|
+
container.style.setProperty("--active-tab-top", `${relativeTop}px`);
|
|
34
|
+
container.style.setProperty("--active-tab-opacity", "1");
|
|
35
|
+
prevActiveKey.current = activeKey;
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
container.style.setProperty("--active-tab-opacity", "0");
|
|
39
|
+
prevActiveKey.current = null;
|
|
40
|
+
}
|
|
41
|
+
if (highlightedKey) {
|
|
42
|
+
if (resetTimer.current !== null) {
|
|
43
|
+
cancelAnimationFrame(resetTimer.current);
|
|
44
|
+
resetTimer.current = null;
|
|
45
|
+
}
|
|
46
|
+
const el = itemRefs.current.get(highlightedKey);
|
|
47
|
+
if (el) {
|
|
48
|
+
const rect = el.getBoundingClientRect();
|
|
49
|
+
const relativeLeft = rect.left - containerRect.left;
|
|
50
|
+
const relativeTop = rect.top - containerRect.top;
|
|
51
|
+
if (prevHoveredKey.current === null) {
|
|
52
|
+
container.style.setProperty("--hovered-transition-duration", "0s");
|
|
53
|
+
requestAnimationFrame(() => {
|
|
54
|
+
container.style.setProperty(
|
|
55
|
+
"--hovered-transition-duration",
|
|
56
|
+
"0.2s"
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
container.style.setProperty("--hovered-transition-duration", "0.2s");
|
|
61
|
+
}
|
|
62
|
+
container.style.setProperty("--hovered-tab-left", `${relativeLeft}px`);
|
|
63
|
+
container.style.setProperty("--hovered-tab-top", `${relativeTop}px`);
|
|
64
|
+
container.style.setProperty("--hovered-tab-width", `${rect.width}px`);
|
|
65
|
+
container.style.setProperty("--hovered-tab-height", `${rect.height}px`);
|
|
66
|
+
container.style.setProperty("--hovered-tab-opacity", "1");
|
|
67
|
+
prevHoveredKey.current = highlightedKey;
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
container.style.setProperty("--hovered-tab-opacity", "0");
|
|
71
|
+
resetTimer.current = requestAnimationFrame(() => {
|
|
72
|
+
prevHoveredKey.current = null;
|
|
73
|
+
resetTimer.current = null;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}, [activeKey, highlightedKey, navRef, itemRefs]);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
updateCSSVariables();
|
|
79
|
+
}, [updateCSSVariables]);
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
const handleResize = () => updateCSSVariables();
|
|
82
|
+
window.addEventListener("resize", handleResize);
|
|
83
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
84
|
+
}, [updateCSSVariables]);
|
|
85
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
86
|
+
/* @__PURE__ */ jsx("div", { className: classes.active }),
|
|
87
|
+
/* @__PURE__ */ jsx("div", { className: classes.hovered })
|
|
88
|
+
] });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { HeaderNavIndicators };
|
|
92
|
+
//# sourceMappingURL=HeaderNavIndicators.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeaderNavIndicators.esm.js","sources":["../../../src/components/Header/HeaderNavIndicators.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useEffect, useRef } from 'react';\n\ninterface HeaderNavIndicatorsProps {\n navRef: React.RefObject<HTMLElement | null>;\n itemRefs: React.MutableRefObject<Map<string, HTMLElement>>;\n activeKey: string | undefined;\n highlightedKey: string | null;\n classes: {\n active: string;\n hovered: string;\n };\n}\n\nexport function HeaderNavIndicators(props: HeaderNavIndicatorsProps) {\n const { navRef, itemRefs, activeKey, highlightedKey, classes } = props;\n const prevActiveKey = useRef<string | null>(null);\n const prevHoveredKey = useRef<string | null>(null);\n const resetTimer = useRef<number | null>(null);\n\n const updateCSSVariables = useCallback(() => {\n const container = navRef.current;\n if (!container) return;\n\n const containerRect = container.getBoundingClientRect();\n\n // Active indicator\n if (activeKey) {\n const el = itemRefs.current.get(activeKey);\n if (el) {\n const rect = el.getBoundingClientRect();\n const relativeLeft = rect.left - containerRect.left;\n const relativeTop = rect.top - containerRect.top;\n\n if (prevActiveKey.current === null) {\n container.style.setProperty('--active-transition-duration', '0s');\n requestAnimationFrame(() => {\n container.style.setProperty(\n '--active-transition-duration',\n '0.25s',\n );\n });\n } else {\n container.style.setProperty('--active-transition-duration', '0.25s');\n }\n\n container.style.setProperty('--active-tab-left', `${relativeLeft}px`);\n container.style.setProperty('--active-tab-width', `${rect.width}px`);\n container.style.setProperty('--active-tab-height', `${rect.height}px`);\n container.style.setProperty('--active-tab-top', `${relativeTop}px`);\n container.style.setProperty('--active-tab-opacity', '1');\n prevActiveKey.current = activeKey;\n }\n } else {\n container.style.setProperty('--active-tab-opacity', '0');\n prevActiveKey.current = null;\n }\n\n // Highlight indicator (follows whichever interaction happened last — hover or focus)\n if (highlightedKey) {\n if (resetTimer.current !== null) {\n cancelAnimationFrame(resetTimer.current);\n resetTimer.current = null;\n }\n const el = itemRefs.current.get(highlightedKey);\n if (el) {\n const rect = el.getBoundingClientRect();\n const relativeLeft = rect.left - containerRect.left;\n const relativeTop = rect.top - containerRect.top;\n\n if (prevHoveredKey.current === null) {\n container.style.setProperty('--hovered-transition-duration', '0s');\n requestAnimationFrame(() => {\n container.style.setProperty(\n '--hovered-transition-duration',\n '0.2s',\n );\n });\n } else {\n container.style.setProperty('--hovered-transition-duration', '0.2s');\n }\n\n container.style.setProperty('--hovered-tab-left', `${relativeLeft}px`);\n container.style.setProperty('--hovered-tab-top', `${relativeTop}px`);\n container.style.setProperty('--hovered-tab-width', `${rect.width}px`);\n container.style.setProperty('--hovered-tab-height', `${rect.height}px`);\n container.style.setProperty('--hovered-tab-opacity', '1');\n prevHoveredKey.current = highlightedKey;\n }\n } else {\n container.style.setProperty('--hovered-tab-opacity', '0');\n resetTimer.current = requestAnimationFrame(() => {\n prevHoveredKey.current = null;\n resetTimer.current = null;\n });\n }\n }, [activeKey, highlightedKey, navRef, itemRefs]);\n\n useEffect(() => {\n updateCSSVariables();\n }, [updateCSSVariables]);\n\n useEffect(() => {\n const handleResize = () => updateCSSVariables();\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [updateCSSVariables]);\n\n return (\n <>\n <div className={classes.active} />\n <div className={classes.hovered} />\n </>\n );\n}\n"],"names":[],"mappings":";;;AA6BO,SAAS,oBAAoB,KAAA,EAAiC;AACnE,EAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAU,SAAA,EAAW,cAAA,EAAgB,SAAQ,GAAI,KAAA;AACjE,EAAA,MAAM,aAAA,GAAgB,OAAsB,IAAI,CAAA;AAChD,EAAA,MAAM,cAAA,GAAiB,OAAsB,IAAI,CAAA;AACjD,EAAA,MAAM,UAAA,GAAa,OAAsB,IAAI,CAAA;AAE7C,EAAA,MAAM,kBAAA,GAAqB,YAAY,MAAM;AAC3C,IAAA,MAAM,YAAY,MAAA,CAAO,OAAA;AACzB,IAAA,IAAI,CAAC,SAAA,EAAW;AAEhB,IAAA,MAAM,aAAA,GAAgB,UAAU,qBAAA,EAAsB;AAGtD,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAM,EAAA,GAAK,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA;AACzC,MAAA,IAAI,EAAA,EAAI;AACN,QAAA,MAAM,IAAA,GAAO,GAAG,qBAAA,EAAsB;AACtC,QAAA,MAAM,YAAA,GAAe,IAAA,CAAK,IAAA,GAAO,aAAA,CAAc,IAAA;AAC/C,QAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,GAAM,aAAA,CAAc,GAAA;AAE7C,QAAA,IAAI,aAAA,CAAc,YAAY,IAAA,EAAM;AAClC,UAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,8BAAA,EAAgC,IAAI,CAAA;AAChE,UAAA,qBAAA,CAAsB,MAAM;AAC1B,YAAA,SAAA,CAAU,KAAA,CAAM,WAAA;AAAA,cACd,8BAAA;AAAA,cACA;AAAA,aACF;AAAA,UACF,CAAC,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,8BAAA,EAAgC,OAAO,CAAA;AAAA,QACrE;AAEA,QAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,mBAAA,EAAqB,CAAA,EAAG,YAAY,CAAA,EAAA,CAAI,CAAA;AACpE,QAAA,SAAA,CAAU,MAAM,WAAA,CAAY,oBAAA,EAAsB,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,EAAA,CAAI,CAAA;AACnE,QAAA,SAAA,CAAU,MAAM,WAAA,CAAY,qBAAA,EAAuB,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA,EAAA,CAAI,CAAA;AACrE,QAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,kBAAA,EAAoB,CAAA,EAAG,WAAW,CAAA,EAAA,CAAI,CAAA;AAClE,QAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,sBAAA,EAAwB,GAAG,CAAA;AACvD,QAAA,aAAA,CAAc,OAAA,GAAU,SAAA;AAAA,MAC1B;AAAA,IACF,CAAA,MAAO;AACL,MAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,sBAAA,EAAwB,GAAG,CAAA;AACvD,MAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AAAA,IAC1B;AAGA,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,IAAI,UAAA,CAAW,YAAY,IAAA,EAAM;AAC/B,QAAA,oBAAA,CAAqB,WAAW,OAAO,CAAA;AACvC,QAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,MACvB;AACA,MAAA,MAAM,EAAA,GAAK,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA;AAC9C,MAAA,IAAI,EAAA,EAAI;AACN,QAAA,MAAM,IAAA,GAAO,GAAG,qBAAA,EAAsB;AACtC,QAAA,MAAM,YAAA,GAAe,IAAA,CAAK,IAAA,GAAO,aAAA,CAAc,IAAA;AAC/C,QAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,GAAM,aAAA,CAAc,GAAA;AAE7C,QAAA,IAAI,cAAA,CAAe,YAAY,IAAA,EAAM;AACnC,UAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,+BAAA,EAAiC,IAAI,CAAA;AACjE,UAAA,qBAAA,CAAsB,MAAM;AAC1B,YAAA,SAAA,CAAU,KAAA,CAAM,WAAA;AAAA,cACd,+BAAA;AAAA,cACA;AAAA,aACF;AAAA,UACF,CAAC,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,+BAAA,EAAiC,MAAM,CAAA;AAAA,QACrE;AAEA,QAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,oBAAA,EAAsB,CAAA,EAAG,YAAY,CAAA,EAAA,CAAI,CAAA;AACrE,QAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,mBAAA,EAAqB,CAAA,EAAG,WAAW,CAAA,EAAA,CAAI,CAAA;AACnE,QAAA,SAAA,CAAU,MAAM,WAAA,CAAY,qBAAA,EAAuB,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,EAAA,CAAI,CAAA;AACpE,QAAA,SAAA,CAAU,MAAM,WAAA,CAAY,sBAAA,EAAwB,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA,EAAA,CAAI,CAAA;AACtE,QAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,uBAAA,EAAyB,GAAG,CAAA;AACxD,QAAA,cAAA,CAAe,OAAA,GAAU,cAAA;AAAA,MAC3B;AAAA,IACF,CAAA,MAAO;AACL,MAAA,SAAA,CAAU,KAAA,CAAM,WAAA,CAAY,uBAAA,EAAyB,GAAG,CAAA;AACxD,MAAA,UAAA,CAAW,OAAA,GAAU,sBAAsB,MAAM;AAC/C,QAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AACzB,QAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,MACvB,CAAC,CAAA;AAAA,IACH;AAAA,EACF,GAAG,CAAC,SAAA,EAAW,cAAA,EAAgB,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAEhD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,kBAAA,EAAmB;AAAA,EACrB,CAAA,EAAG,CAAC,kBAAkB,CAAC,CAAA;AAEvB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,YAAA,GAAe,MAAM,kBAAA,EAAmB;AAC9C,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,YAAY,CAAA;AAC9C,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,QAAA,EAAU,YAAY,CAAA;AAAA,EAChE,CAAA,EAAG,CAAC,kBAAkB,CAAC,CAAA;AAEvB,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,MAAA,EAAQ,CAAA;AAAA,oBAChC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,OAAA,EAAS;AAAA,GAAA,EACnC,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.esm.js","sources":["../../../src/components/Header/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 { HeaderOwnProps } from './types';\nimport styles from './Header.module.css';\n\n/**\n * Component definition for Header\n * @public\n */\nexport const HeaderDefinition = defineComponent<HeaderOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Header',\n content: 'bui-HeaderContent',\n breadcrumbs: 'bui-HeaderBreadcrumbs',\n tabsWrapper: 'bui-HeaderTabsWrapper',\n controls: 'bui-HeaderControls',\n },\n propDefs: {\n title: {},\n customActions: {},\n tabs: {},\n breadcrumbs: {},\n className: {},\n },\n});\n\n/**\n * @public\n * @deprecated Use {@link HeaderDefinition} instead.\n */\nexport const HeaderPageDefinition = HeaderDefinition;\n"],"names":[],"mappings":";;;;;;;;;;AAwBO,MAAM,gBAAA,GAAmB,iBAAgC,CAAE;AAAA,EAChE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,YAAA;AAAA,IACN,OAAA,EAAS,mBAAA;AAAA,IACT,WAAA,EAAa,uBAAA;AAAA,IACb,WAAA,EAAa,uBAAA;AAAA,IACb,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,OAAO,EAAC;AAAA,IACR,eAAe,EAAC;AAAA,IAChB,MAAM,EAAC;AAAA,IACP,aAAa,EAAC;AAAA,IACd,WAAW;AAAC;AAEhB,CAAC;AAMM,MAAM,oBAAA,GAAuB;;;;"}
|
|
1
|
+
{"version":3,"file":"definition.esm.js","sources":["../../../src/components/Header/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 { HeaderOwnProps } from './types';\nimport styles from './Header.module.css';\n\n/**\n * Component definition for Header\n * @public\n */\nexport const HeaderDefinition = defineComponent<HeaderOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Header',\n content: 'bui-HeaderContent',\n breadcrumbs: 'bui-HeaderBreadcrumbs',\n tabsWrapper: 'bui-HeaderTabsWrapper',\n controls: 'bui-HeaderControls',\n },\n propDefs: {\n title: {},\n customActions: {},\n tabs: {},\n activeTabId: {},\n breadcrumbs: {},\n className: {},\n },\n});\n\n/**\n * @public\n * @deprecated Use {@link HeaderDefinition} instead.\n */\nexport const HeaderPageDefinition = HeaderDefinition;\n"],"names":[],"mappings":";;;;;;;;;;AAwBO,MAAM,gBAAA,GAAmB,iBAAgC,CAAE;AAAA,EAChE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,YAAA;AAAA,IACN,OAAA,EAAS,mBAAA;AAAA,IACT,WAAA,EAAa,uBAAA;AAAA,IACb,WAAA,EAAa,uBAAA;AAAA,IACb,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,OAAO,EAAC;AAAA,IACR,eAAe,EAAC;AAAA,IAChB,MAAM,EAAC;AAAA,IACP,aAAa,EAAC;AAAA,IACd,aAAa,EAAC;AAAA,IACd,WAAW;AAAC;AAEhB,CAAC;AAMM,MAAM,oBAAA,GAAuB;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.esm.js","sources":["../../../src/components/Link/Link.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { forwardRef, useRef } from 'react';\nimport { useLink } from 'react-aria';\nimport type { LinkProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { LinkDefinition } from './definition';\nimport { getNodeText } from '../../analytics/getNodeText';\n\nconst LinkInternal = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n const { ownProps, restProps, dataAttributes, analytics } = useDefinition(\n LinkDefinition,\n props,\n );\n const { classes, title, children } = ownProps;\n\n const internalRef = useRef<HTMLAnchorElement>(null);\n const linkRef = (ref || internalRef) as React.RefObject<HTMLAnchorElement>;\n\n const { linkProps } = useLink(restProps, linkRef);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n linkProps.onClick?.(e);\n const text =\n restProps['aria-label'] ??\n getNodeText(children) ??\n String(restProps.href ?? '');\n analytics.captureEvent('click', text, {\n attributes: { to: String(restProps.href ?? '') },\n });\n };\n\n return (\n <a\n {...linkProps}\n {...dataAttributes}\n {...(restProps as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n ref={linkRef}\n title={title}\n className={classes.root}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n});\n\nLinkInternal.displayName = 'LinkInternal';\n\n
|
|
1
|
+
{"version":3,"file":"Link.esm.js","sources":["../../../src/components/Link/Link.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { forwardRef, useRef } from 'react';\nimport { useLink } from 'react-aria';\nimport type { LinkProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { LinkDefinition } from './definition';\nimport { getNodeText } from '../../analytics/getNodeText';\n\nconst LinkInternal = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n const { ownProps, restProps, dataAttributes, analytics } = useDefinition(\n LinkDefinition,\n props,\n );\n const { classes, title, children } = ownProps;\n\n const internalRef = useRef<HTMLAnchorElement>(null);\n const linkRef = (ref || internalRef) as React.RefObject<HTMLAnchorElement>;\n\n const { linkProps } = useLink(restProps, linkRef);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n linkProps.onClick?.(e);\n const text =\n restProps['aria-label'] ??\n getNodeText(children) ??\n String(restProps.href ?? '');\n analytics.captureEvent('click', text, {\n attributes: { to: String(restProps.href ?? '') },\n });\n };\n\n return (\n <a\n {...linkProps}\n {...dataAttributes}\n {...(restProps as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n ref={linkRef}\n title={title}\n className={classes.root}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n});\n\nLinkInternal.displayName = 'LinkInternal';\n\n/**\n * A styled anchor element that supports analytics event tracking on click.\n *\n * @public\n */\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n return <LinkInternal {...props} ref={ref} />;\n});\n\nLink.displayName = 'Link';\n"],"names":[],"mappings":";;;;;;;AAuBA,MAAM,YAAA,GAAe,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC5E,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAgB,WAAU,GAAI,aAAA;AAAA,IACzD,cAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAO,QAAA,EAAS,GAAI,QAAA;AAErC,EAAA,MAAM,WAAA,GAAc,OAA0B,IAAI,CAAA;AAClD,EAAA,MAAM,UAAW,GAAA,IAAO,WAAA;AAExB,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,OAAA,CAAQ,WAAW,OAAO,CAAA;AAEhD,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAA2C;AAC9D,IAAA,SAAA,CAAU,UAAU,CAAC,CAAA;AACrB,IAAA,MAAM,IAAA,GACJ,SAAA,CAAU,YAAY,CAAA,IACtB,WAAA,CAAY,QAAQ,CAAA,IACpB,MAAA,CAAO,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAC7B,IAAA,SAAA,CAAU,YAAA,CAAa,SAAS,IAAA,EAAM;AAAA,MACpC,YAAY,EAAE,EAAA,EAAI,OAAO,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAAE,KAChD,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACE,GAAG,SAAA;AAAA,MACH,GAAG,cAAA;AAAA,MACH,GAAI,SAAA;AAAA,MACL,GAAA,EAAK,OAAA;AAAA,MACL,KAAA;AAAA,MACA,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,OAAA,EAAS,WAAA;AAAA,MAER;AAAA;AAAA,GACH;AAEJ,CAAC,CAAA;AAED,YAAA,CAAa,WAAA,GAAc,cAAA;AAOpB,MAAM,IAAA,GAAO,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC3E,EAAA,uBAAO,GAAA,CAAC,YAAA,EAAA,EAAc,GAAG,KAAA,EAAO,GAAA,EAAU,CAAA;AAC5C,CAAC;AAED,IAAA,CAAK,WAAA,GAAc,MAAA;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { Menu as Menu$1, Popover, Virtualizer, ListLayout, useFilter, Autocomplete, SearchField, Input, Button, ListBox, MenuItem as MenuItem$1, ListBoxItem, MenuSection as MenuSection$1, Header, Separator, MenuTrigger as MenuTrigger$1, SubmenuTrigger as SubmenuTrigger$1 } from 'react-aria-components';
|
|
3
3
|
import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
|
|
4
|
-
import { MenuDefinition,
|
|
4
|
+
import { MenuDefinition, MenuAutocompleteDefinition, MenuAutocompleteListboxDefinition, MenuItemDefinition, MenuListBoxDefinition, MenuListBoxItemDefinition, MenuSectionDefinition, MenuSeparatorDefinition, MenuEmptyStateDefinition } from './definition.esm.js';
|
|
5
5
|
import { RiCloseCircleLine, RiArrowRightSLine, RiCheckLine } from '@remixicon/react';
|
|
6
6
|
import { isInternalLink } from '../../utils/linkUtils.esm.js';
|
|
7
7
|
import { getNodeText } from '../../analytics/getNodeText.esm.js';
|
|
@@ -194,56 +194,33 @@ const MenuItem = (props) => {
|
|
|
194
194
|
props
|
|
195
195
|
);
|
|
196
196
|
const { classes, iconStart, children, href } = ownProps;
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
const text = restProps["aria-label"] ?? getNodeText(children) ?? String(href);
|
|
200
|
-
analytics.captureEvent("click", text, {
|
|
201
|
-
attributes: { to: String(href) }
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
if (href && !isInternalLink(href)) {
|
|
206
|
-
return /* @__PURE__ */ jsx(
|
|
207
|
-
MenuItem$1,
|
|
208
|
-
{
|
|
209
|
-
className: classes.root,
|
|
210
|
-
...dataAttributes,
|
|
211
|
-
textValue: typeof children === "string" ? children : void 0,
|
|
212
|
-
...restProps,
|
|
213
|
-
onAction: () => {
|
|
214
|
-
restProps.onAction?.();
|
|
215
|
-
handleAction();
|
|
216
|
-
window.open(href, "_blank", "noopener,noreferrer");
|
|
217
|
-
},
|
|
218
|
-
children: /* @__PURE__ */ jsxs("div", { className: classes.itemWrapper, children: [
|
|
219
|
-
/* @__PURE__ */ jsxs("div", { className: classes.itemContent, children: [
|
|
220
|
-
iconStart,
|
|
221
|
-
children
|
|
222
|
-
] }),
|
|
223
|
-
/* @__PURE__ */ jsx("div", { className: classes.itemArrow, children: /* @__PURE__ */ jsx(RiArrowRightSLine, {}) })
|
|
224
|
-
] })
|
|
225
|
-
}
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
return /* @__PURE__ */ jsx(
|
|
197
|
+
const isExternal = href && !isInternalLink(href);
|
|
198
|
+
return /* @__PURE__ */ jsxs(
|
|
229
199
|
MenuItem$1,
|
|
230
200
|
{
|
|
231
201
|
className: classes.root,
|
|
232
202
|
...dataAttributes,
|
|
233
203
|
href,
|
|
204
|
+
target: isExternal ? "_blank" : void 0,
|
|
205
|
+
rel: isExternal ? "noopener noreferrer" : void 0,
|
|
234
206
|
textValue: typeof children === "string" ? children : void 0,
|
|
235
207
|
...restProps,
|
|
236
208
|
onAction: () => {
|
|
237
209
|
restProps.onAction?.();
|
|
238
|
-
|
|
210
|
+
if (href) {
|
|
211
|
+
const text = restProps["aria-label"] ?? getNodeText(children) ?? String(href);
|
|
212
|
+
analytics.captureEvent("click", text, {
|
|
213
|
+
attributes: { to: String(href) }
|
|
214
|
+
});
|
|
215
|
+
}
|
|
239
216
|
},
|
|
240
|
-
children:
|
|
217
|
+
children: [
|
|
241
218
|
/* @__PURE__ */ jsxs("div", { className: classes.itemContent, children: [
|
|
242
219
|
iconStart,
|
|
243
220
|
children
|
|
244
221
|
] }),
|
|
245
222
|
/* @__PURE__ */ jsx("div", { className: classes.itemArrow, children: /* @__PURE__ */ jsx(RiArrowRightSLine, {}) })
|
|
246
|
-
]
|
|
223
|
+
]
|
|
247
224
|
}
|
|
248
225
|
);
|
|
249
226
|
};
|
|
@@ -259,10 +236,10 @@ const MenuListBoxItem = (props) => {
|
|
|
259
236
|
textValue: typeof children === "string" ? children : void 0,
|
|
260
237
|
className: classes.root,
|
|
261
238
|
...restProps,
|
|
262
|
-
children: /* @__PURE__ */
|
|
239
|
+
children: /* @__PURE__ */ jsxs("div", { className: classes.itemContent, children: [
|
|
263
240
|
/* @__PURE__ */ jsx("div", { className: classes.check, children: /* @__PURE__ */ jsx(RiCheckLine, {}) }),
|
|
264
241
|
children
|
|
265
|
-
] })
|
|
242
|
+
] })
|
|
266
243
|
}
|
|
267
244
|
);
|
|
268
245
|
};
|
|
@@ -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 Virtualizer,\n ListLayout,\n} from 'react-aria-components';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport {\n MenuDefinition,\n MenuListBoxDefinition,\n MenuAutocompleteDefinition,\n MenuAutocompleteListboxDefinition,\n MenuItemDefinition,\n MenuListBoxItemDefinition,\n MenuSectionDefinition,\n MenuSeparatorDefinition,\n MenuEmptyStateDefinition,\n} from './definition';\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 { isInternalLink } from '../../utils/linkUtils';\nimport { getNodeText } from '../../analytics/getNodeText';\nimport { Box } from '../Box';\nimport { BgReset } from '../../hooks/useBg';\n\n// The height will be used for virtualized menus. It should match the size set in CSS for each menu item.\nconst rowHeight = 32;\n\nconst MenuEmptyState = () => {\n const { ownProps } = useDefinition(MenuEmptyStateDefinition, {});\n\n return <div className={ownProps.classes.root}>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 { ownProps, restProps } = useDefinition(MenuDefinition, props);\n const { classes, placement, virtualized, maxWidth, maxHeight, style } =\n ownProps;\n\n let newMaxWidth = maxWidth || (virtualized ? '260px' : 'undefined');\n\n const menuContent = (\n <RAMenu\n className={classes.content}\n renderEmptyState={() => <MenuEmptyState />}\n style={{ width: newMaxWidth, maxHeight, ...style }}\n {...restProps}\n />\n );\n\n return (\n <RAPopover className={classes.root} placement={placement}>\n <BgReset>\n <Box bg=\"neutral\" className={classes.inner}>\n {virtualized ? (\n <Virtualizer\n layout={ListLayout}\n layoutOptions={{\n rowHeight,\n }}\n >\n {menuContent}\n </Virtualizer>\n ) : (\n menuContent\n )}\n </Box>\n </BgReset>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuListBox = (props: MenuListBoxProps<object>) => {\n const { ownProps, restProps } = useDefinition(MenuListBoxDefinition, props);\n const {\n classes,\n selectionMode,\n placement,\n virtualized,\n maxWidth,\n maxHeight,\n style,\n } = ownProps;\n let newMaxWidth = maxWidth || (virtualized ? '260px' : 'undefined');\n\n const listBoxContent = (\n <RAListBox\n className={classes.content}\n selectionMode={selectionMode}\n style={{ width: newMaxWidth, maxHeight, ...style }}\n {...restProps}\n />\n );\n\n return (\n <RAPopover className={classes.root} placement={placement}>\n <BgReset>\n <Box bg=\"neutral\" className={classes.inner}>\n {virtualized ? (\n <Virtualizer\n layout={ListLayout}\n layoutOptions={{\n rowHeight,\n }}\n >\n {listBoxContent}\n </Virtualizer>\n ) : (\n listBoxContent\n )}\n </Box>\n </BgReset>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuAutocomplete = (props: MenuAutocompleteProps<object>) => {\n const { ownProps, restProps } = useDefinition(\n MenuAutocompleteDefinition,\n props,\n );\n const {\n classes,\n placement,\n virtualized,\n maxWidth,\n maxHeight,\n style,\n placeholder,\n } = ownProps;\n const { contains } = useFilter({ sensitivity: 'base' });\n let newMaxWidth = maxWidth || (virtualized ? '260px' : 'undefined');\n\n const menuContent = (\n <RAMenu\n className={classes.content}\n renderEmptyState={() => <MenuEmptyState />}\n style={{ width: newMaxWidth, maxHeight, ...style }}\n {...restProps}\n />\n );\n\n return (\n <RAPopover className={classes.root} placement={placement}>\n <BgReset>\n <Box bg=\"neutral\" className={classes.inner}>\n <RAAutocomplete filter={contains}>\n <RASearchField\n className={classes.searchField}\n aria-label={placeholder || 'Search'}\n >\n <RAInput\n className={classes.searchFieldInput}\n placeholder={placeholder || 'Search...'}\n />\n <RAButton className={classes.searchFieldClear}>\n <RiCloseCircleLine />\n </RAButton>\n </RASearchField>\n {virtualized ? (\n <Virtualizer\n layout={ListLayout}\n layoutOptions={{\n rowHeight,\n }}\n >\n {menuContent}\n </Virtualizer>\n ) : (\n menuContent\n )}\n </RAAutocomplete>\n </Box>\n </BgReset>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuAutocompleteListbox = (\n props: MenuAutocompleteListBoxProps<object>,\n) => {\n const { ownProps, restProps } = useDefinition(\n MenuAutocompleteListboxDefinition,\n props,\n );\n const {\n classes,\n selectionMode,\n placement,\n virtualized,\n maxWidth,\n maxHeight,\n style,\n placeholder,\n } = ownProps;\n const { contains } = useFilter({ sensitivity: 'base' });\n let newMaxWidth = maxWidth || (virtualized ? '260px' : 'undefined');\n\n const listBoxContent = (\n <RAListBox\n className={classes.content}\n renderEmptyState={() => <MenuEmptyState />}\n selectionMode={selectionMode}\n style={{ width: newMaxWidth, maxHeight, ...style }}\n {...restProps}\n />\n );\n\n return (\n <RAPopover className={classes.root} placement={placement}>\n <BgReset>\n <Box bg=\"neutral\" className={classes.inner}>\n <RAAutocomplete filter={contains}>\n <RASearchField\n className={classes.searchField}\n aria-label={placeholder || 'Search'}\n >\n <RAInput\n className={classes.searchFieldInput}\n placeholder={placeholder || 'Search...'}\n />\n <RAButton className={classes.searchFieldClear}>\n <RiCloseCircleLine />\n </RAButton>\n </RASearchField>\n {virtualized ? (\n <Virtualizer\n layout={ListLayout}\n layoutOptions={{\n rowHeight,\n }}\n >\n {listBoxContent}\n </Virtualizer>\n ) : (\n listBoxContent\n )}\n </RAAutocomplete>\n </Box>\n </BgReset>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuItem = (props: MenuItemProps) => {\n const { ownProps, restProps, dataAttributes, analytics } = useDefinition(\n MenuItemDefinition,\n props,\n );\n const { classes, iconStart, children, href } = ownProps;\n\n const handleAction = () => {\n if (href) {\n const text =\n restProps['aria-label'] ?? getNodeText(children) ?? String(href);\n analytics.captureEvent('click', text, {\n attributes: { to: String(href) },\n });\n }\n };\n\n // External links open in new tab via window.open instead of client-side routing\n if (href && !isInternalLink(href)) {\n return (\n <RAMenuItem\n className={classes.root}\n {...dataAttributes}\n textValue={typeof children === 'string' ? children : undefined}\n {...restProps}\n onAction={() => {\n restProps.onAction?.();\n handleAction();\n window.open(href, '_blank', 'noopener,noreferrer');\n }}\n >\n <div className={classes.itemWrapper}>\n <div className={classes.itemContent}>\n {iconStart}\n {children}\n </div>\n <div className={classes.itemArrow}>\n <RiArrowRightSLine />\n </div>\n </div>\n </RAMenuItem>\n );\n }\n\n return (\n <RAMenuItem\n className={classes.root}\n {...dataAttributes}\n href={href}\n textValue={typeof children === 'string' ? children : undefined}\n {...restProps}\n onAction={() => {\n restProps.onAction?.();\n handleAction();\n }}\n >\n <div className={classes.itemWrapper}>\n <div className={classes.itemContent}>\n {iconStart}\n {children}\n </div>\n <div className={classes.itemArrow}>\n <RiArrowRightSLine />\n </div>\n </div>\n </RAMenuItem>\n );\n};\n\n/** @public */\nexport const MenuListBoxItem = (props: MenuListBoxItemProps) => {\n const { ownProps, restProps } = useDefinition(\n MenuListBoxItemDefinition,\n props,\n );\n const { classes, children } = ownProps;\n\n return (\n <RAListBoxItem\n textValue={typeof children === 'string' ? children : undefined}\n className={classes.root}\n {...restProps}\n >\n <div className={classes.itemWrapper}>\n <div className={classes.itemContent}>\n <div className={classes.check}>\n <RiCheckLine />\n </div>\n {children}\n </div>\n </div>\n </RAListBoxItem>\n );\n};\n\n/** @public */\nexport const MenuSection = (props: MenuSectionProps<object>) => {\n const { ownProps, restProps } = useDefinition(MenuSectionDefinition, props);\n const { classes, children, title } = ownProps;\n\n return (\n <RAMenuSection className={classes.root} {...restProps}>\n <RAMenuHeader className={classes.header}>{title}</RAMenuHeader>\n {children}\n </RAMenuSection>\n );\n};\n\n/** @public */\nexport const MenuSeparator = (props: MenuSeparatorProps) => {\n const { ownProps, restProps } = useDefinition(MenuSeparatorDefinition, props);\n\n return <RAMenuSeparator className={ownProps.classes.root} {...restProps} />;\n};\n"],"names":["RAMenuTrigger","RAMenuSubmenuTrigger","RAMenu","RAPopover","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 Virtualizer,\n ListLayout,\n} from 'react-aria-components';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport {\n MenuDefinition,\n MenuListBoxDefinition,\n MenuAutocompleteDefinition,\n MenuAutocompleteListboxDefinition,\n MenuItemDefinition,\n MenuListBoxItemDefinition,\n MenuSectionDefinition,\n MenuSeparatorDefinition,\n MenuEmptyStateDefinition,\n} from './definition';\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 { isInternalLink } from '../../utils/linkUtils';\nimport { getNodeText } from '../../analytics/getNodeText';\nimport { Box } from '../Box';\nimport { BgReset } from '../../hooks/useBg';\n\n// The height will be used for virtualized menus. It should match the size set in CSS for each menu item.\nconst rowHeight = 32;\n\nconst MenuEmptyState = () => {\n const { ownProps } = useDefinition(MenuEmptyStateDefinition, {});\n\n return <div className={ownProps.classes.root}>No results found.</div>;\n};\n\n/**\n * A wrapper that connects a trigger element to a dropdown menu, controlling its open and close state.\n *\n * @public\n */\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 { ownProps, restProps } = useDefinition(MenuDefinition, props);\n const { classes, placement, virtualized, maxWidth, maxHeight, style } =\n ownProps;\n\n let newMaxWidth = maxWidth || (virtualized ? '260px' : 'undefined');\n\n const menuContent = (\n <RAMenu\n className={classes.content}\n renderEmptyState={() => <MenuEmptyState />}\n style={{ width: newMaxWidth, maxHeight, ...style }}\n {...restProps}\n />\n );\n\n return (\n <RAPopover className={classes.root} placement={placement}>\n <BgReset>\n <Box bg=\"neutral\" className={classes.inner}>\n {virtualized ? (\n <Virtualizer\n layout={ListLayout}\n layoutOptions={{\n rowHeight,\n }}\n >\n {menuContent}\n </Virtualizer>\n ) : (\n menuContent\n )}\n </Box>\n </BgReset>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuListBox = (props: MenuListBoxProps<object>) => {\n const { ownProps, restProps } = useDefinition(MenuListBoxDefinition, props);\n const {\n classes,\n selectionMode,\n placement,\n virtualized,\n maxWidth,\n maxHeight,\n style,\n } = ownProps;\n let newMaxWidth = maxWidth || (virtualized ? '260px' : 'undefined');\n\n const listBoxContent = (\n <RAListBox\n className={classes.content}\n selectionMode={selectionMode}\n style={{ width: newMaxWidth, maxHeight, ...style }}\n {...restProps}\n />\n );\n\n return (\n <RAPopover className={classes.root} placement={placement}>\n <BgReset>\n <Box bg=\"neutral\" className={classes.inner}>\n {virtualized ? (\n <Virtualizer\n layout={ListLayout}\n layoutOptions={{\n rowHeight,\n }}\n >\n {listBoxContent}\n </Virtualizer>\n ) : (\n listBoxContent\n )}\n </Box>\n </BgReset>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuAutocomplete = (props: MenuAutocompleteProps<object>) => {\n const { ownProps, restProps } = useDefinition(\n MenuAutocompleteDefinition,\n props,\n );\n const {\n classes,\n placement,\n virtualized,\n maxWidth,\n maxHeight,\n style,\n placeholder,\n } = ownProps;\n const { contains } = useFilter({ sensitivity: 'base' });\n let newMaxWidth = maxWidth || (virtualized ? '260px' : 'undefined');\n\n const menuContent = (\n <RAMenu\n className={classes.content}\n renderEmptyState={() => <MenuEmptyState />}\n style={{ width: newMaxWidth, maxHeight, ...style }}\n {...restProps}\n />\n );\n\n return (\n <RAPopover className={classes.root} placement={placement}>\n <BgReset>\n <Box bg=\"neutral\" className={classes.inner}>\n <RAAutocomplete filter={contains}>\n <RASearchField\n className={classes.searchField}\n aria-label={placeholder || 'Search'}\n >\n <RAInput\n className={classes.searchFieldInput}\n placeholder={placeholder || 'Search...'}\n />\n <RAButton className={classes.searchFieldClear}>\n <RiCloseCircleLine />\n </RAButton>\n </RASearchField>\n {virtualized ? (\n <Virtualizer\n layout={ListLayout}\n layoutOptions={{\n rowHeight,\n }}\n >\n {menuContent}\n </Virtualizer>\n ) : (\n menuContent\n )}\n </RAAutocomplete>\n </Box>\n </BgReset>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuAutocompleteListbox = (\n props: MenuAutocompleteListBoxProps<object>,\n) => {\n const { ownProps, restProps } = useDefinition(\n MenuAutocompleteListboxDefinition,\n props,\n );\n const {\n classes,\n selectionMode,\n placement,\n virtualized,\n maxWidth,\n maxHeight,\n style,\n placeholder,\n } = ownProps;\n const { contains } = useFilter({ sensitivity: 'base' });\n let newMaxWidth = maxWidth || (virtualized ? '260px' : 'undefined');\n\n const listBoxContent = (\n <RAListBox\n className={classes.content}\n renderEmptyState={() => <MenuEmptyState />}\n selectionMode={selectionMode}\n style={{ width: newMaxWidth, maxHeight, ...style }}\n {...restProps}\n />\n );\n\n return (\n <RAPopover className={classes.root} placement={placement}>\n <BgReset>\n <Box bg=\"neutral\" className={classes.inner}>\n <RAAutocomplete filter={contains}>\n <RASearchField\n className={classes.searchField}\n aria-label={placeholder || 'Search'}\n >\n <RAInput\n className={classes.searchFieldInput}\n placeholder={placeholder || 'Search...'}\n />\n <RAButton className={classes.searchFieldClear}>\n <RiCloseCircleLine />\n </RAButton>\n </RASearchField>\n {virtualized ? (\n <Virtualizer\n layout={ListLayout}\n layoutOptions={{\n rowHeight,\n }}\n >\n {listBoxContent}\n </Virtualizer>\n ) : (\n listBoxContent\n )}\n </RAAutocomplete>\n </Box>\n </BgReset>\n </RAPopover>\n );\n};\n\n/** @public */\nexport const MenuItem = (props: MenuItemProps) => {\n const { ownProps, restProps, dataAttributes, analytics } = useDefinition(\n MenuItemDefinition,\n props,\n );\n const { classes, iconStart, children, href } = ownProps;\n\n const isExternal = href && !isInternalLink(href);\n\n return (\n <RAMenuItem\n className={classes.root}\n {...dataAttributes}\n href={href}\n target={isExternal ? '_blank' : undefined}\n rel={isExternal ? 'noopener noreferrer' : undefined}\n textValue={typeof children === 'string' ? children : undefined}\n {...restProps}\n onAction={() => {\n restProps.onAction?.();\n if (href) {\n const text =\n restProps['aria-label'] ?? getNodeText(children) ?? String(href);\n analytics.captureEvent('click', text, {\n attributes: { to: String(href) },\n });\n }\n }}\n >\n <div className={classes.itemContent}>\n {iconStart}\n {children}\n </div>\n <div className={classes.itemArrow}>\n <RiArrowRightSLine />\n </div>\n </RAMenuItem>\n );\n};\n\n/** @public */\nexport const MenuListBoxItem = (props: MenuListBoxItemProps) => {\n const { ownProps, restProps } = useDefinition(\n MenuListBoxItemDefinition,\n props,\n );\n const { classes, children } = ownProps;\n\n return (\n <RAListBoxItem\n textValue={typeof children === 'string' ? children : undefined}\n className={classes.root}\n {...restProps}\n >\n <div className={classes.itemContent}>\n <div className={classes.check}>\n <RiCheckLine />\n </div>\n {children}\n </div>\n </RAListBoxItem>\n );\n};\n\n/** @public */\nexport const MenuSection = (props: MenuSectionProps<object>) => {\n const { ownProps, restProps } = useDefinition(MenuSectionDefinition, props);\n const { classes, children, title } = ownProps;\n\n return (\n <RAMenuSection className={classes.root} {...restProps}>\n <RAMenuHeader className={classes.header}>{title}</RAMenuHeader>\n {children}\n </RAMenuSection>\n );\n};\n\n/** @public */\nexport const MenuSeparator = (props: MenuSeparatorProps) => {\n const { ownProps, restProps } = useDefinition(MenuSeparatorDefinition, props);\n\n return <RAMenuSeparator className={ownProps.classes.root} {...restProps} />;\n};\n"],"names":["RAMenuTrigger","RAMenuSubmenuTrigger","RAMenu","RAPopover","RAListBox","RAAutocomplete","RASearchField","RAInput","RAButton","RAMenuItem","RAListBoxItem","RAMenuSection","RAMenuHeader","RAMenuSeparator"],"mappings":"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"}
|