@backstage/ui 0.13.0-next.2 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +243 -0
  2. package/dist/components/Accordion/Accordion.module.css.esm.js +2 -2
  3. package/dist/components/Button/Button.module.css.esm.js +2 -2
  4. package/dist/components/ButtonIcon/ButtonIcon.module.css.esm.js +2 -2
  5. package/dist/components/ButtonLink/ButtonLink.esm.js +2 -3
  6. package/dist/components/ButtonLink/ButtonLink.esm.js.map +1 -1
  7. package/dist/components/ButtonLink/ButtonLink.module.css.esm.js +2 -2
  8. package/dist/components/Card/Card.esm.js +1 -1
  9. package/dist/components/Card/Card.esm.js.map +1 -1
  10. package/dist/components/Card/Card.module.css.esm.js +2 -2
  11. package/dist/components/Checkbox/Checkbox.esm.js +12 -3
  12. package/dist/components/Checkbox/Checkbox.esm.js.map +1 -1
  13. package/dist/components/Checkbox/Checkbox.module.css.esm.js +2 -2
  14. package/dist/components/Checkbox/definition.esm.js +0 -2
  15. package/dist/components/Checkbox/definition.esm.js.map +1 -1
  16. package/dist/components/Container/Container.module.css.esm.js +2 -2
  17. package/dist/components/Dialog/Dialog.esm.js +3 -1
  18. package/dist/components/Dialog/Dialog.esm.js.map +1 -1
  19. package/dist/components/Dialog/Dialog.module.css.esm.js +2 -2
  20. package/dist/components/Header/Header.module.css.esm.js +2 -2
  21. package/dist/components/Header/definition.esm.js +5 -5
  22. package/dist/components/Header/definition.esm.js.map +1 -1
  23. package/dist/components/Link/Link.esm.js +1 -2
  24. package/dist/components/Link/Link.esm.js.map +1 -1
  25. package/dist/components/List/List.esm.js +70 -0
  26. package/dist/components/List/List.esm.js.map +1 -0
  27. package/dist/components/List/List.module.css.esm.js +8 -0
  28. package/dist/components/List/List.module.css.esm.js.map +1 -0
  29. package/dist/components/List/definition.esm.js +44 -0
  30. package/dist/components/List/definition.esm.js.map +1 -0
  31. package/dist/components/Menu/Menu.esm.js +5 -7
  32. package/dist/components/Menu/Menu.esm.js.map +1 -1
  33. package/dist/components/Menu/Menu.module.css.esm.js +2 -2
  34. package/dist/components/PluginHeader/PluginHeader.esm.js +37 -7
  35. package/dist/components/PluginHeader/PluginHeader.esm.js.map +1 -1
  36. package/dist/components/SearchAutocomplete/SearchAutocomplete.esm.js +164 -0
  37. package/dist/components/SearchAutocomplete/SearchAutocomplete.esm.js.map +1 -0
  38. package/dist/components/SearchAutocomplete/SearchAutocomplete.module.css.esm.js +8 -0
  39. package/dist/components/SearchAutocomplete/SearchAutocomplete.module.css.esm.js.map +1 -0
  40. package/dist/components/SearchAutocomplete/definition.esm.js +52 -0
  41. package/dist/components/SearchAutocomplete/definition.esm.js.map +1 -0
  42. package/dist/components/Select/Select.module.css.esm.js +2 -2
  43. package/dist/components/Table/Table.module.css.esm.js +2 -2
  44. package/dist/components/Table/components/Row.esm.js +21 -9
  45. package/dist/components/Table/components/Row.esm.js.map +1 -1
  46. package/dist/components/Table/components/Table.esm.js +80 -68
  47. package/dist/components/Table/components/Table.esm.js.map +1 -1
  48. package/dist/components/Table/components/TableBodySkeleton.esm.js +33 -0
  49. package/dist/components/Table/components/TableBodySkeleton.esm.js.map +1 -0
  50. package/dist/components/Table/components/TableHeader.esm.js +2 -2
  51. package/dist/components/Table/components/TableHeader.esm.js.map +1 -1
  52. package/dist/components/Table/components/TableRoot.esm.js +1 -1
  53. package/dist/components/Table/components/TableRoot.esm.js.map +1 -1
  54. package/dist/components/Table/definition.esm.js +14 -2
  55. package/dist/components/Table/definition.esm.js.map +1 -1
  56. package/dist/components/Table/hooks/useCompletePagination.esm.js +14 -6
  57. package/dist/components/Table/hooks/useCompletePagination.esm.js.map +1 -1
  58. package/dist/components/Tabs/Tabs.esm.js +3 -5
  59. package/dist/components/Tabs/Tabs.esm.js.map +1 -1
  60. package/dist/components/TagGroup/TagGroup.esm.js +2 -5
  61. package/dist/components/TagGroup/TagGroup.esm.js.map +1 -1
  62. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.module.css.esm.js +2 -2
  63. package/dist/css/styles.css +4 -3
  64. package/dist/index.d.ts +337 -41
  65. package/dist/index.esm.js +5 -1
  66. package/dist/index.esm.js.map +1 -1
  67. package/dist/provider/BUIProvider.esm.js +28 -0
  68. package/dist/provider/BUIProvider.esm.js.map +1 -0
  69. package/dist/utils/{isExternalLink.esm.js → linkUtils.esm.js} +5 -2
  70. package/dist/utils/linkUtils.esm.js.map +1 -0
  71. package/package.json +4 -4
  72. package/dist/analytics/BUIProvider.esm.js +0 -18
  73. package/dist/analytics/BUIProvider.esm.js.map +0 -1
  74. package/dist/components/InternalLinkProvider/InternalLinkProvider.esm.js +0 -55
  75. package/dist/components/InternalLinkProvider/InternalLinkProvider.esm.js.map +0 -1
  76. package/dist/utils/isExternalLink.esm.js.map +0 -1
@@ -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 useMemo,\n Children,\n cloneElement,\n isValidElement,\n createContext,\n useContext,\n useEffect,\n useCallback,\n} from 'react';\nimport type { ReactNode } from 'react';\nimport type {\n TabsProps,\n TabListProps,\n TabPanelProps,\n TabsContextValue,\n TabProps,\n} from './types';\nimport { useLocation } 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 TabProps as AriaTabProps,\n} from 'react-aria-components';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport {\n TabsDefinition,\n TabListDefinition,\n TabDefinition,\n TabPanelDefinition,\n} from './definition';\nimport {\n isInternalLink,\n createRoutingRegistration,\n} from '../InternalLinkProvider';\nimport { getNodeText } from '../../analytics/getNodeText';\n\nconst { RoutingProvider, useRoutingRegistrationEffect } =\n createRoutingRegistration();\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\ntype TabSelectionContextValue = {\n registerRoutedTab: (id: string) => void;\n unregisterRoutedTab: (id: string) => void;\n registerActiveTab: (id: string, segmentCount: number) => void;\n unregisterActiveTab: (id: string) => void;\n};\n\nconst TabSelectionContext = createContext<TabSelectionContextValue | null>(\n null,\n);\n\n/**\n * Strips query params and hash from a href, leaving only the pathname.\n * Tab matching always compares against location.pathname which never includes them.\n */\nconst hrefPathname = (href: string) => href.split('?')[0].split('#')[0];\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 const pathname = hrefPathname(tabHref);\n\n if (matchStrategy === 'exact') {\n return pathname === currentPathname;\n }\n\n // Prefix matching - similar to WorkaroundNavLink behavior\n if (pathname === 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(`${pathname}/`);\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const Tabs = (props: TabsProps) => {\n const { ownProps, restProps } = useDefinition(TabsDefinition, props);\n const { classes, children } = ownProps;\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\n // State for tracking routed tabs (tabs with hrefs)\n const [routedTabs, setRoutedTabs] = useState<Set<string>>(() => new Set());\n\n // State for tracking active tabs reported by TabRouteRegistration components\n const [activeTabs, setActiveTabs] = useState<Map<string, number>>(\n () => new Map(),\n );\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 // Compute the selected tab based on active tabs with highest segment count\n const selectedTabId = useMemo(() => {\n // No routed tabs - let React Aria handle selection (uncontrolled mode)\n if (routedTabs.size === 0) {\n return undefined;\n }\n\n // Has routed tabs but none are active - use empty string for no selection\n // (React Aria has a bug with null that causes infinite loops)\n if (activeTabs.size === 0) {\n return '';\n }\n\n let selectedId: string | undefined;\n let maxSegments = -1;\n\n activeTabs.forEach((segmentCount, id) => {\n // Pick tab with highest segment count, first one wins on tie\n if (segmentCount > maxSegments) {\n maxSegments = segmentCount;\n selectedId = id;\n }\n });\n\n return selectedId;\n }, [routedTabs, activeTabs]);\n\n const registerRoutedTab = useCallback((id: string) => {\n setRoutedTabs(prev => new Set(prev).add(id));\n }, []);\n\n const unregisterRoutedTab = useCallback((id: string) => {\n setRoutedTabs(prev => {\n const next = new Set(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n const registerActiveTab = useCallback((id: string, segmentCount: number) => {\n setActiveTabs(prev => new Map(prev).set(id, segmentCount));\n }, []);\n\n const unregisterActiveTab = useCallback((id: string) => {\n setActiveTabs(prev => {\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n if (!children) return null;\n\n const tabsContextValue: TabsContextValue = {\n tabsRef,\n tabRefs,\n hoveredKey,\n prevHoveredKey,\n setHoveredKey,\n setTabRef,\n };\n\n const selectionContextValue: TabSelectionContextValue = useMemo(\n () => ({\n registerRoutedTab,\n unregisterRoutedTab,\n registerActiveTab,\n unregisterActiveTab,\n }),\n [\n registerRoutedTab,\n unregisterRoutedTab,\n registerActiveTab,\n unregisterActiveTab,\n ],\n );\n\n return (\n <RoutingProvider>\n <TabsContext.Provider value={tabsContextValue}>\n <TabSelectionContext.Provider value={selectionContextValue}>\n <AriaTabs\n className={classes.root}\n keyboardActivation=\"manual\"\n selectedKey={selectedTabId}\n ref={tabsRef}\n {...restProps}\n >\n {children as ReactNode}\n </AriaTabs>\n </TabSelectionContext.Provider>\n </TabsContext.Provider>\n </RoutingProvider>\n );\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const TabList = (props: TabListProps) => {\n const { ownProps, restProps } = useDefinition(TabListDefinition, props);\n const { classes, children } = ownProps;\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={classes.root}>\n <AriaTabList\n className={classes.tabList}\n aria-label=\"Toolbar tabs\"\n {...restProps}\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 * Internal component for tabs with internal hrefs.\n * Handles routing registration and active tab tracking.\n * Separated to avoid conditional hook usage in Tab component.\n * @internal\n */\nfunction RoutedTabEffects({\n id,\n href,\n matchStrategy = 'exact',\n}: {\n id: string;\n href: string;\n matchStrategy?: 'exact' | 'prefix';\n}) {\n const selectionCtx = useContext(TabSelectionContext);\n const location = useLocation();\n\n // Register with RoutingProvider for conditional RouterProvider wrapping\n useRoutingRegistrationEffect(href);\n\n // Register as a routed tab (for controlled vs uncontrolled mode)\n useEffect(() => {\n if (selectionCtx) {\n selectionCtx.registerRoutedTab(id);\n return () => selectionCtx.unregisterRoutedTab(id);\n }\n return undefined;\n }, [id, selectionCtx]);\n\n // Register as active tab when URL matches (for tab selection)\n const isActive = isTabActive(href, location.pathname, matchStrategy);\n const segmentCount = hrefPathname(href).split('/').filter(Boolean).length;\n\n useEffect(() => {\n if (isActive && selectionCtx) {\n selectionCtx.registerActiveTab(id, segmentCount);\n return () => selectionCtx.unregisterActiveTab(id);\n }\n return undefined;\n }, [isActive, id, segmentCount, selectionCtx]);\n\n return null;\n}\n\n/**\n * A component that renders a tab.\n *\n * @public\n */\nexport const Tab = (props: TabProps) => {\n const { ownProps, restProps, analytics } = useDefinition(\n TabDefinition,\n props,\n );\n const { classes, matchStrategy, href, id } = ownProps;\n const { setTabRef } = useTabsContext();\n\n const handlePress = () => {\n if (href) {\n const text =\n restProps['aria-label'] ??\n getNodeText(restProps.children) ??\n String(href);\n analytics.captureEvent('click', text, {\n attributes: { to: String(href) },\n });\n }\n };\n\n return (\n <>\n {isInternalLink(href) && (\n <RoutedTabEffects\n id={id as string}\n href={href}\n matchStrategy={matchStrategy}\n />\n )}\n <AriaTab\n id={id}\n className={classes.root}\n ref={el => setTabRef(id as string, el as HTMLDivElement)}\n href={href}\n {...restProps}\n onPress={e => {\n restProps.onPress?.(e);\n handlePress();\n }}\n />\n </>\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 { ownProps, restProps } = useDefinition(TabPanelDefinition, props);\n\n return <AriaTabPanel className={ownProps.classes.root} {...restProps} />;\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 useMemo,\n Children,\n cloneElement,\n isValidElement,\n createContext,\n useContext,\n useEffect,\n useCallback,\n} from 'react';\nimport type { ReactNode } from 'react';\nimport type {\n TabsProps,\n TabListProps,\n TabPanelProps,\n TabsContextValue,\n TabProps,\n} from './types';\nimport { useLocation } 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 TabProps as AriaTabProps,\n} from 'react-aria-components';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport {\n TabsDefinition,\n TabListDefinition,\n TabDefinition,\n TabPanelDefinition,\n} from './definition';\nimport { isInternalLink } from '../../utils/linkUtils';\nimport { getNodeText } from '../../analytics/getNodeText';\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\ntype TabSelectionContextValue = {\n registerRoutedTab: (id: string) => void;\n unregisterRoutedTab: (id: string) => void;\n registerActiveTab: (id: string, segmentCount: number) => void;\n unregisterActiveTab: (id: string) => void;\n};\n\nconst TabSelectionContext = createContext<TabSelectionContextValue | null>(\n null,\n);\n\n/**\n * Strips query params and hash from a href, leaving only the pathname.\n * Tab matching always compares against location.pathname which never includes them.\n */\nconst hrefPathname = (href: string) => href.split('?')[0].split('#')[0];\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 const pathname = hrefPathname(tabHref);\n\n if (matchStrategy === 'exact') {\n return pathname === currentPathname;\n }\n\n // Prefix matching - similar to WorkaroundNavLink behavior\n if (pathname === 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(`${pathname}/`);\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const Tabs = (props: TabsProps) => {\n const { ownProps, restProps } = useDefinition(TabsDefinition, props);\n const { classes, children } = ownProps;\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\n // State for tracking routed tabs (tabs with hrefs)\n const [routedTabs, setRoutedTabs] = useState<Set<string>>(() => new Set());\n\n // State for tracking active tabs reported by TabRouteRegistration components\n const [activeTabs, setActiveTabs] = useState<Map<string, number>>(\n () => new Map(),\n );\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 // Compute the selected tab based on active tabs with highest segment count\n const selectedTabId = useMemo(() => {\n // No routed tabs - let React Aria handle selection (uncontrolled mode)\n if (routedTabs.size === 0) {\n return undefined;\n }\n\n // Has routed tabs but none are active - use empty string for no selection\n // (React Aria has a bug with null that causes infinite loops)\n if (activeTabs.size === 0) {\n return '';\n }\n\n let selectedId: string | undefined;\n let maxSegments = -1;\n\n activeTabs.forEach((segmentCount, id) => {\n // Pick tab with highest segment count, first one wins on tie\n if (segmentCount > maxSegments) {\n maxSegments = segmentCount;\n selectedId = id;\n }\n });\n\n return selectedId;\n }, [routedTabs, activeTabs]);\n\n const registerRoutedTab = useCallback((id: string) => {\n setRoutedTabs(prev => new Set(prev).add(id));\n }, []);\n\n const unregisterRoutedTab = useCallback((id: string) => {\n setRoutedTabs(prev => {\n const next = new Set(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n const registerActiveTab = useCallback((id: string, segmentCount: number) => {\n setActiveTabs(prev => new Map(prev).set(id, segmentCount));\n }, []);\n\n const unregisterActiveTab = useCallback((id: string) => {\n setActiveTabs(prev => {\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n if (!children) return null;\n\n const tabsContextValue: TabsContextValue = {\n tabsRef,\n tabRefs,\n hoveredKey,\n prevHoveredKey,\n setHoveredKey,\n setTabRef,\n };\n\n const selectionContextValue: TabSelectionContextValue = useMemo(\n () => ({\n registerRoutedTab,\n unregisterRoutedTab,\n registerActiveTab,\n unregisterActiveTab,\n }),\n [\n registerRoutedTab,\n unregisterRoutedTab,\n registerActiveTab,\n unregisterActiveTab,\n ],\n );\n\n return (\n <TabsContext.Provider value={tabsContextValue}>\n <TabSelectionContext.Provider value={selectionContextValue}>\n <AriaTabs\n className={classes.root}\n keyboardActivation=\"manual\"\n selectedKey={selectedTabId}\n ref={tabsRef}\n {...restProps}\n >\n {children as ReactNode}\n </AriaTabs>\n </TabSelectionContext.Provider>\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 { ownProps, restProps } = useDefinition(TabListDefinition, props);\n const { classes, children } = ownProps;\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={classes.root}>\n <AriaTabList\n className={classes.tabList}\n aria-label=\"Toolbar tabs\"\n {...restProps}\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 * Internal component for tabs with internal hrefs.\n * Handles routing registration and active tab tracking.\n * Separated to avoid conditional hook usage in Tab component.\n * @internal\n */\nfunction RoutedTabEffects({\n id,\n href,\n matchStrategy = 'exact',\n}: {\n id: string;\n href: string;\n matchStrategy?: 'exact' | 'prefix';\n}) {\n const selectionCtx = useContext(TabSelectionContext);\n const location = useLocation();\n\n // Register as a routed tab (for controlled vs uncontrolled mode)\n useEffect(() => {\n if (selectionCtx) {\n selectionCtx.registerRoutedTab(id);\n return () => selectionCtx.unregisterRoutedTab(id);\n }\n return undefined;\n }, [id, selectionCtx]);\n\n // Register as active tab when URL matches (for tab selection)\n const isActive = isTabActive(href, location.pathname, matchStrategy);\n const segmentCount = hrefPathname(href).split('/').filter(Boolean).length;\n\n useEffect(() => {\n if (isActive && selectionCtx) {\n selectionCtx.registerActiveTab(id, segmentCount);\n return () => selectionCtx.unregisterActiveTab(id);\n }\n return undefined;\n }, [isActive, id, segmentCount, selectionCtx]);\n\n return null;\n}\n\n/**\n * A component that renders a tab.\n *\n * @public\n */\nexport const Tab = (props: TabProps) => {\n const { ownProps, restProps, analytics } = useDefinition(\n TabDefinition,\n props,\n );\n const { classes, matchStrategy, href, id } = ownProps;\n const { setTabRef } = useTabsContext();\n\n const handlePress = () => {\n if (href) {\n const text =\n restProps['aria-label'] ??\n getNodeText(restProps.children) ??\n String(href);\n analytics.captureEvent('click', text, {\n attributes: { to: String(href) },\n });\n }\n };\n\n return (\n <>\n {isInternalLink(href) && (\n <RoutedTabEffects\n id={id as string}\n href={href}\n matchStrategy={matchStrategy}\n />\n )}\n <AriaTab\n id={id}\n className={classes.root}\n ref={el => setTabRef(id as string, el as HTMLDivElement)}\n href={href}\n {...restProps}\n onPress={e => {\n restProps.onPress?.(e);\n handlePress();\n }}\n />\n </>\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 { ownProps, restProps } = useDefinition(TabPanelDefinition, props);\n\n return <AriaTabPanel className={ownProps.classes.root} {...restProps} />;\n};\n"],"names":["AriaTabs","AriaTabList","AriaTab","AriaTabPanel"],"mappings":"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"}
@@ -4,14 +4,12 @@ import { forwardRef } from 'react';
4
4
  import { RiCloseCircleLine } from '@remixicon/react';
5
5
  import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
6
6
  import { TagDefinition, TagGroupDefinition } from './definition.esm.js';
7
- import { createRoutingRegistration } from '../InternalLinkProvider/InternalLinkProvider.esm.js';
8
7
  import { getNodeText } from '../../analytics/getNodeText.esm.js';
9
8
 
10
- const { RoutingProvider, useRoutingRegistrationEffect } = createRoutingRegistration();
11
9
  const TagGroup = (props) => {
12
10
  const { ownProps, restProps } = useDefinition(TagGroupDefinition, props);
13
11
  const { classes, items, children, renderEmptyState } = ownProps;
14
- return /* @__PURE__ */ jsx(RoutingProvider, { children: /* @__PURE__ */ jsx(TagGroup$1, { className: classes.root, ...restProps, children: /* @__PURE__ */ jsx(
12
+ return /* @__PURE__ */ jsx(TagGroup$1, { className: classes.root, ...restProps, children: /* @__PURE__ */ jsx(
15
13
  TagList,
16
14
  {
17
15
  className: classes.list,
@@ -19,7 +17,7 @@ const TagGroup = (props) => {
19
17
  renderEmptyState,
20
18
  children
21
19
  }
22
- ) }) });
20
+ ) });
23
21
  };
24
22
  const Tag = forwardRef((props, ref) => {
25
23
  const { ownProps, restProps, dataAttributes, analytics } = useDefinition(
@@ -28,7 +26,6 @@ const Tag = forwardRef((props, ref) => {
28
26
  );
29
27
  const { classes, children, icon, href } = ownProps;
30
28
  const textValue = typeof children === "string" ? children : void 0;
31
- useRoutingRegistrationEffect(href);
32
29
  const handlePress = () => {
33
30
  if (href) {
34
31
  const text = props["aria-label"] ?? textValue ?? getNodeText(children) ?? String(href);
@@ -1 +1 @@
1
- {"version":3,"file":"TagGroup.esm.js","sources":["../../../src/components/TagGroup/TagGroup.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 type { TagProps, TagGroupProps } from './types';\nimport {\n TagGroup as ReactAriaTagGroup,\n TagList as ReactAriaTagList,\n Tag as ReactAriaTag,\n Button as ReactAriaButton,\n} from 'react-aria-components';\nimport { forwardRef, type ReactNode } from 'react';\nimport { RiCloseCircleLine } from '@remixicon/react';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { TagGroupDefinition, TagDefinition } from './definition';\nimport { createRoutingRegistration } from '../InternalLinkProvider';\nimport { getNodeText } from '../../analytics/getNodeText';\n\nconst { RoutingProvider, useRoutingRegistrationEffect } =\n createRoutingRegistration();\n\n/**\n * A component that renders a list of tags.\n *\n * @public\n */\nexport const TagGroup = <T extends object>(props: TagGroupProps<T>) => {\n const { ownProps, restProps } = useDefinition(TagGroupDefinition, props);\n const { classes, items, children, renderEmptyState } = ownProps;\n\n return (\n <RoutingProvider>\n <ReactAriaTagGroup className={classes.root} {...restProps}>\n <ReactAriaTagList\n className={classes.list}\n items={items}\n renderEmptyState={renderEmptyState}\n >\n {children}\n </ReactAriaTagList>\n </ReactAriaTagGroup>\n </RoutingProvider>\n );\n};\n\n/**\n * A component that renders a tag.\n *\n * @public\n */\nexport const Tag = forwardRef<HTMLDivElement, TagProps>((props, ref) => {\n const { ownProps, restProps, dataAttributes, analytics } = useDefinition(\n TagDefinition,\n props,\n );\n const { classes, children, icon, href } = ownProps;\n const textValue = typeof children === 'string' ? children : undefined;\n\n useRoutingRegistrationEffect(href);\n\n const handlePress = () => {\n if (href) {\n const text =\n (props as React.AriaAttributes)['aria-label'] ??\n textValue ??\n getNodeText(children) ??\n String(href);\n analytics.captureEvent('click', text, {\n attributes: { to: String(href) },\n });\n }\n };\n\n return (\n <ReactAriaTag\n ref={ref}\n textValue={textValue}\n className={classes.root}\n href={href}\n {...dataAttributes}\n {...restProps}\n onPress={e => {\n restProps.onPress?.(e);\n handlePress();\n }}\n >\n {({ allowsRemoving }) => (\n <>\n {icon && <span className={classes.icon}>{icon}</span>}\n {children as ReactNode}\n {allowsRemoving && (\n <ReactAriaButton className={classes.removeButton} slot=\"remove\">\n <RiCloseCircleLine size={16} />\n </ReactAriaButton>\n )}\n </>\n )}\n </ReactAriaTag>\n );\n});\n"],"names":["ReactAriaTagGroup","ReactAriaTagList","ReactAriaTag","ReactAriaButton"],"mappings":";;;;;;;;;AA8BA,MAAM,EAAE,eAAA,EAAiB,4BAAA,EAA6B,GACpD,yBAAA,EAA0B;AAOrB,MAAM,QAAA,GAAW,CAAmB,KAAA,KAA4B;AACrE,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAU,GAAI,aAAA,CAAc,oBAAoB,KAAK,CAAA;AACvE,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAO,QAAA,EAAU,kBAAiB,GAAI,QAAA;AAEvD,EAAA,uBACE,GAAA,CAAC,mBACC,QAAA,kBAAA,GAAA,CAACA,UAAA,EAAA,EAAkB,WAAW,OAAA,CAAQ,IAAA,EAAO,GAAG,SAAA,EAC9C,QAAA,kBAAA,GAAA;AAAA,IAACC,OAAA;AAAA,IAAA;AAAA,MACC,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,KAAA;AAAA,MACA,gBAAA;AAAA,MAEC;AAAA;AAAA,KAEL,CAAA,EACF,CAAA;AAEJ;AAOO,MAAM,GAAA,GAAM,UAAA,CAAqC,CAAC,KAAA,EAAO,GAAA,KAAQ;AACtE,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAgB,WAAU,GAAI,aAAA;AAAA,IACzD,aAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAU,IAAA,EAAM,MAAK,GAAI,QAAA;AAC1C,EAAA,MAAM,SAAA,GAAY,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,MAAA;AAE5D,EAAA,4BAAA,CAA6B,IAAI,CAAA;AAEjC,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,MAAM,IAAA,GACH,MAA+B,YAAY,CAAA,IAC5C,aACA,WAAA,CAAY,QAAQ,CAAA,IACpB,MAAA,CAAO,IAAI,CAAA;AACb,MAAA,SAAA,CAAU,YAAA,CAAa,SAAS,IAAA,EAAM;AAAA,QACpC,UAAA,EAAY,EAAE,EAAA,EAAI,MAAA,CAAO,IAAI,CAAA;AAAE,OAChC,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAACC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,IAAA;AAAA,MACC,GAAG,cAAA;AAAA,MACH,GAAG,SAAA;AAAA,MACJ,SAAS,CAAA,CAAA,KAAK;AACZ,QAAA,SAAA,CAAU,UAAU,CAAC,CAAA;AACrB,QAAA,WAAA,EAAY;AAAA,MACd,CAAA;AAAA,MAEC,QAAA,EAAA,CAAC,EAAE,cAAA,EAAe,qBACjB,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,OAAA,CAAQ,MAAO,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,QAC7C,QAAA;AAAA,QACA,cAAA,oBACC,GAAA,CAACC,MAAA,EAAA,EAAgB,SAAA,EAAW,OAAA,CAAQ,YAAA,EAAc,IAAA,EAAK,QAAA,EACrD,QAAA,kBAAA,GAAA,CAAC,iBAAA,EAAA,EAAkB,IAAA,EAAM,EAAA,EAAI,CAAA,EAC/B;AAAA,OAAA,EAEJ;AAAA;AAAA,GAEJ;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"TagGroup.esm.js","sources":["../../../src/components/TagGroup/TagGroup.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 type { TagProps, TagGroupProps } from './types';\nimport {\n TagGroup as ReactAriaTagGroup,\n TagList as ReactAriaTagList,\n Tag as ReactAriaTag,\n Button as ReactAriaButton,\n} from 'react-aria-components';\nimport { forwardRef, type ReactNode } from 'react';\nimport { RiCloseCircleLine } from '@remixicon/react';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { TagGroupDefinition, TagDefinition } from './definition';\nimport { getNodeText } from '../../analytics/getNodeText';\n\n/**\n * A component that renders a list of tags.\n *\n * @public\n */\nexport const TagGroup = <T extends object>(props: TagGroupProps<T>) => {\n const { ownProps, restProps } = useDefinition(TagGroupDefinition, props);\n const { classes, items, children, renderEmptyState } = ownProps;\n\n return (\n <ReactAriaTagGroup className={classes.root} {...restProps}>\n <ReactAriaTagList\n className={classes.list}\n items={items}\n renderEmptyState={renderEmptyState}\n >\n {children}\n </ReactAriaTagList>\n </ReactAriaTagGroup>\n );\n};\n\n/**\n * A component that renders a tag.\n *\n * @public\n */\nexport const Tag = forwardRef<HTMLDivElement, TagProps>((props, ref) => {\n const { ownProps, restProps, dataAttributes, analytics } = useDefinition(\n TagDefinition,\n props,\n );\n const { classes, children, icon, href } = ownProps;\n const textValue = typeof children === 'string' ? children : undefined;\n\n const handlePress = () => {\n if (href) {\n const text =\n (props as React.AriaAttributes)['aria-label'] ??\n textValue ??\n getNodeText(children) ??\n String(href);\n analytics.captureEvent('click', text, {\n attributes: { to: String(href) },\n });\n }\n };\n\n return (\n <ReactAriaTag\n ref={ref}\n textValue={textValue}\n className={classes.root}\n href={href}\n {...dataAttributes}\n {...restProps}\n onPress={e => {\n restProps.onPress?.(e);\n handlePress();\n }}\n >\n {({ allowsRemoving }) => (\n <>\n {icon && <span className={classes.icon}>{icon}</span>}\n {children as ReactNode}\n {allowsRemoving && (\n <ReactAriaButton className={classes.removeButton} slot=\"remove\">\n <RiCloseCircleLine size={16} />\n </ReactAriaButton>\n )}\n </>\n )}\n </ReactAriaTag>\n );\n});\n"],"names":["ReactAriaTagGroup","ReactAriaTagList","ReactAriaTag","ReactAriaButton"],"mappings":";;;;;;;;AAkCO,MAAM,QAAA,GAAW,CAAmB,KAAA,KAA4B;AACrE,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAU,GAAI,aAAA,CAAc,oBAAoB,KAAK,CAAA;AACvE,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAO,QAAA,EAAU,kBAAiB,GAAI,QAAA;AAEvD,EAAA,2BACGA,UAAA,EAAA,EAAkB,SAAA,EAAW,OAAA,CAAQ,IAAA,EAAO,GAAG,SAAA,EAC9C,QAAA,kBAAA,GAAA;AAAA,IAACC,OAAA;AAAA,IAAA;AAAA,MACC,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,KAAA;AAAA,MACA,gBAAA;AAAA,MAEC;AAAA;AAAA,GACH,EACF,CAAA;AAEJ;AAOO,MAAM,GAAA,GAAM,UAAA,CAAqC,CAAC,KAAA,EAAO,GAAA,KAAQ;AACtE,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAgB,WAAU,GAAI,aAAA;AAAA,IACzD,aAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAU,IAAA,EAAM,MAAK,GAAI,QAAA;AAC1C,EAAA,MAAM,SAAA,GAAY,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,MAAA;AAE5D,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,MAAM,IAAA,GACH,MAA+B,YAAY,CAAA,IAC5C,aACA,WAAA,CAAY,QAAQ,CAAA,IACpB,MAAA,CAAO,IAAI,CAAA;AACb,MAAA,SAAA,CAAU,YAAA,CAAa,SAAS,IAAA,EAAM;AAAA,QACpC,UAAA,EAAY,EAAE,EAAA,EAAI,MAAA,CAAO,IAAI,CAAA;AAAE,OAChC,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAACC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,IAAA;AAAA,MACC,GAAG,cAAA;AAAA,MACH,GAAG,SAAA;AAAA,MACJ,SAAS,CAAA,CAAA,KAAK;AACZ,QAAA,SAAA,CAAU,UAAU,CAAC,CAAA;AACrB,QAAA,WAAA,EAAY;AAAA,MACd,CAAA;AAAA,MAEC,QAAA,EAAA,CAAC,EAAE,cAAA,EAAe,qBACjB,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,OAAA,CAAQ,MAAO,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,QAC7C,QAAA;AAAA,QACA,cAAA,oBACC,GAAA,CAACC,MAAA,EAAA,EAAgB,SAAA,EAAW,OAAA,CAAQ,YAAA,EAAc,IAAA,EAAK,QAAA,EACrD,QAAA,kBAAA,GAAA,CAAC,iBAAA,EAAA,EAAkB,IAAA,EAAM,EAAA,EAAI,CAAA,EAC/B;AAAA,OAAA,EAEJ;AAAA;AAAA,GAEJ;AAEJ,CAAC;;;;"}
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
2
 
3
- var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9 {\n display: inline-flex;\n align-items: center;\n flex-wrap: nowrap;\n border-radius: var(--bui-radius-2);\n overflow: hidden;\n box-shadow: inset 0 0 0 1px var(--bui-border-2);\n width: fit-content;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9[data-orientation='vertical'] {\n flex-direction: column;\n align-items: stretch;\n width: fit-content;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9 > .bui-ToggleButton {\n border-radius: 0;\n margin: 0;\n box-shadow: none;\n border: 0;\n }\n\n /* Horizontal radius rules (default orientation) */\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9:not([data-orientation='vertical'])\n > .bui-ToggleButton {\n border-radius: 0;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9:not([data-orientation='vertical'])\n > .bui-ToggleButton:first-child {\n border-radius: var(--bui-radius-2) 0 0 var(--bui-radius-2);\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9:not([data-orientation='vertical'])\n > .bui-ToggleButton:last-child {\n border-radius: 0 var(--bui-radius-2) var(--bui-radius-2) 0;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9:not([data-orientation='vertical'])\n > .bui-ToggleButton:only-child {\n border-radius: var(--bui-radius-2);\n }\n\n /* Horizontal dividers */\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9:not([data-orientation='vertical'])\n .bui-ToggleButton\n + .bui-ToggleButton {\n border-left: 1px solid var(--bui-border-2);\n }\n\n /* Vertical dividers */\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9[data-orientation='vertical']\n .bui-ToggleButton {\n width: 100%;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9[data-orientation='vertical']\n .bui-ToggleButton\n + .bui-ToggleButton {\n border-top: 1px solid var(--bui-border-2);\n }\n\n /* Vertical radius rules */\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9[data-orientation='vertical']\n > .bui-ToggleButton {\n border-radius: 0;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9[data-orientation='vertical']\n > .bui-ToggleButton:first-child {\n border-radius: var(--bui-radius-2) var(--bui-radius-2) 0 0;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9[data-orientation='vertical']\n > .bui-ToggleButton:last-child {\n border-radius: 0 0 var(--bui-radius-2) var(--bui-radius-2);\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9[data-orientation='vertical']\n > .bui-ToggleButton:only-child {\n border-radius: var(--bui-radius-2);\n }\n\n /* Focus ring on group surface */\n .ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9:focus-visible {\n outline: 2px solid var(--bui-ring);\n outline-offset: 2px;\n }\n}\n";
4
- var styles = {"bui-ToggleButtonGroup":"ToggleButtonGroup_bui-ToggleButtonGroup__dea0d4d0f9"};
3
+ var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95 {\n display: inline-flex;\n align-items: center;\n flex-wrap: nowrap;\n border-radius: var(--bui-radius-2);\n overflow: hidden;\n box-shadow: inset 0 0 0 1px var(--bui-border-2);\n width: fit-content;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95[data-orientation='vertical'] {\n flex-direction: column;\n align-items: stretch;\n width: fit-content;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95 > .bui-ToggleButton {\n border-radius: 0;\n margin: 0;\n box-shadow: none;\n border: 0;\n }\n\n /* Horizontal radius rules (default orientation) */\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95:not([data-orientation='vertical'])\n > .bui-ToggleButton {\n border-radius: 0;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95:not([data-orientation='vertical'])\n > .bui-ToggleButton:first-child {\n border-radius: var(--bui-radius-2) 0 0 var(--bui-radius-2);\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95:not([data-orientation='vertical'])\n > .bui-ToggleButton:last-child {\n border-radius: 0 var(--bui-radius-2) var(--bui-radius-2) 0;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95:not([data-orientation='vertical'])\n > .bui-ToggleButton:only-child {\n border-radius: var(--bui-radius-2);\n }\n\n /* Horizontal dividers */\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95:not([data-orientation='vertical'])\n .bui-ToggleButton\n + .bui-ToggleButton {\n border-left: 1px solid var(--bui-border-2);\n }\n\n /* Vertical dividers */\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95[data-orientation='vertical']\n .bui-ToggleButton {\n width: 100%;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95[data-orientation='vertical']\n .bui-ToggleButton\n + .bui-ToggleButton {\n border-top: 1px solid var(--bui-border-2);\n }\n\n /* Vertical radius rules */\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95[data-orientation='vertical']\n > .bui-ToggleButton {\n border-radius: 0;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95[data-orientation='vertical']\n > .bui-ToggleButton:first-child {\n border-radius: var(--bui-radius-2) var(--bui-radius-2) 0 0;\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95[data-orientation='vertical']\n > .bui-ToggleButton:last-child {\n border-radius: 0 0 var(--bui-radius-2) var(--bui-radius-2);\n }\n\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95[data-orientation='vertical']\n > .bui-ToggleButton:only-child {\n border-radius: var(--bui-radius-2);\n }\n\n /* Focus ring on group surface */\n .ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95[data-focus-visible] {\n outline: 2px solid var(--bui-ring);\n outline-offset: 2px;\n }\n}\n";
4
+ var styles = {"bui-ToggleButtonGroup":"ToggleButtonGroup_bui-ToggleButtonGroup__c00f226c95"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { styles as default };
@@ -33,8 +33,9 @@
33
33
  * limitations under the License.
34
34
  */
35
35
  @layer tokens {
36
- /* Light theme tokens */
37
- :root {
36
+ /* Light theme tokens (also used for nested light theme switching) */
37
+ :root,
38
+ [data-theme-mode='light'] {
38
39
  /* Font families */
39
40
  --bui-font-regular: system-ui;
40
41
  --bui-font-monospace: ui-monospace, 'Menlo', 'Monaco', 'Consolas',
@@ -137,7 +138,7 @@
137
138
  --bui-fg-info-on-bg: #173da6;
138
139
  --bui-fg-danger: #ec3b18;
139
140
  --bui-fg-warning: #ef7a32;
140
- --bui-fg-success: #1ed760;
141
+ --bui-fg-success: #1aaf4f;
141
142
  --bui-fg-info: #0d74ce;
142
143
 
143
144
  /* Border colors */