From a67670d240c6c5599a61dd9d825a8941cdb69da0 Mon Sep 17 00:00:00 2001 From: Johan Persson Date: Mon, 10 Nov 2025 16:35:28 +0100 Subject: [PATCH] refactor(ui): migrate to component-owned definitions Eliminates the central componentDefinitions registry in favor of component-owned definition files. Each of the 33 components now exports its own definition object. Changes: - Created definition.ts for all 33 components (Accordion, Avatar, Box, Button, etc.) - Updated useStyles hook to accept definition objects instead of string lookups - Removed central componentDefinitions file and related type utilities - Updated docs-ui to import and use component definitions directly - Added @backstage/ui/definitions subpath export to avoid importing component code in docs-ui, preventing Next.js SSR issues Breaking changes: - componentDefinitions object removed - ComponentDefinitionName type removed - ComponentClassNames type removed - useStyles now accepts ComponentDefinition object instead of string (internal) Migration: Component definitions are primarily for documenting the CSS class API for theming. If using definitions programmatically, migrate to either: - Use Backstage UI components directly as building blocks, or - Duplicate component CSS in your own stylesheets Signed-off-by: Johan Persson --- .changeset/little-dingos-study.md | 14 + docs-ui/src/components/Theming/index.tsx | 19 +- docs-ui/src/content/accordion.mdx | 3 +- docs-ui/src/content/avatar.mdx | 3 +- docs-ui/src/content/box.mdx | 3 +- docs-ui/src/content/button-icon.mdx | 3 +- docs-ui/src/content/button-link.mdx | 3 +- docs-ui/src/content/button.mdx | 3 +- docs-ui/src/content/card.mdx | 3 +- docs-ui/src/content/checkbox.mdx | 3 +- docs-ui/src/content/container.mdx | 3 +- docs-ui/src/content/dialog.mdx | 3 +- docs-ui/src/content/flex.mdx | 3 +- docs-ui/src/content/grid.mdx | 3 +- docs-ui/src/content/header-page.mdx | 3 +- docs-ui/src/content/header.mdx | 3 +- docs-ui/src/content/link.mdx | 3 +- docs-ui/src/content/menu.mdx | 3 +- docs-ui/src/content/password-field.mdx | 3 +- docs-ui/src/content/radio-group.mdx | 3 +- docs-ui/src/content/search-field.mdx | 3 +- docs-ui/src/content/select.mdx | 3 +- docs-ui/src/content/skeleton.mdx | 3 +- docs-ui/src/content/switch.mdx | 3 +- docs-ui/src/content/table.mdx | 3 +- docs-ui/src/content/tabs.mdx | 3 +- docs-ui/src/content/tag-group.mdx | 3 +- docs-ui/src/content/text-field.mdx | 3 +- docs-ui/src/content/text.mdx | 3 +- docs-ui/src/content/tooltip.mdx | 3 +- docs-ui/src/content/visually-hidden.mdx | 3 +- docs-ui/src/utils/definitions.ts | 1 + packages/ui/report.api.md | 859 +++++++++--------- .../ui/src/components/Accordion/Accordion.tsx | 9 +- .../ui/src/components/Accordion/definition.ts | 34 + packages/ui/src/components/Accordion/index.ts | 1 + packages/ui/src/components/Avatar/Avatar.tsx | 14 +- .../ui/src/components/Avatar/definition.ts | 32 + packages/ui/src/components/Avatar/index.ts | 1 + packages/ui/src/components/Box/Box.tsx | 3 +- packages/ui/src/components/Box/definition.ts | 51 ++ packages/ui/src/components/Box/index.tsx | 1 + packages/ui/src/components/Button/Button.tsx | 14 +- .../ui/src/components/Button/definition.ts | 34 + packages/ui/src/components/Button/index.ts | 1 + .../src/components/ButtonIcon/ButtonIcon.tsx | 18 +- .../src/components/ButtonIcon/definition.ts | 29 + .../ui/src/components/ButtonIcon/index.tsx | 1 + .../src/components/ButtonLink/ButtonLink.tsx | 18 +- .../src/components/ButtonLink/definition.ts | 27 + .../ui/src/components/ButtonLink/index.ts | 1 + packages/ui/src/components/Card/Card.tsx | 9 +- packages/ui/src/components/Card/definition.ts | 30 + packages/ui/src/components/Card/index.ts | 1 + .../ui/src/components/Checkbox/Checkbox.tsx | 3 +- .../ui/src/components/Checkbox/definition.ts | 31 + packages/ui/src/components/Checkbox/index.ts | 1 + .../ui/src/components/Container/Container.tsx | 3 +- .../ui/src/components/Container/definition.ts | 28 + .../ui/src/components/Container/index.tsx | 1 + packages/ui/src/components/Dialog/Dialog.tsx | 9 +- .../ui/src/components/Dialog/definition.ts | 32 + packages/ui/src/components/Dialog/index.ts | 1 + .../src/components/FieldError/FieldError.tsx | 3 +- .../src/components/FieldError/definition.ts | 27 + .../ui/src/components/FieldError/index.ts | 1 + .../src/components/FieldLabel/FieldLabel.tsx | 3 +- .../src/components/FieldLabel/definition.ts | 30 + .../ui/src/components/FieldLabel/index.ts | 1 + packages/ui/src/components/Flex/Flex.tsx | 3 +- packages/ui/src/components/Flex/definition.ts | 47 + packages/ui/src/components/Flex/index.ts | 1 + packages/ui/src/components/Grid/Grid.tsx | 5 +- packages/ui/src/components/Grid/definition.ts | 56 ++ packages/ui/src/components/Grid/index.ts | 1 + packages/ui/src/components/Header/Header.tsx | 3 +- .../src/components/Header/HeaderToolbar.tsx | 3 +- .../ui/src/components/Header/definition.ts | 33 + packages/ui/src/components/Header/index.tsx | 1 + .../src/components/HeaderPage/HeaderPage.tsx | 3 +- .../src/components/HeaderPage/definition.ts | 31 + .../ui/src/components/HeaderPage/index.tsx | 1 + packages/ui/src/components/Link/Link.tsx | 16 +- packages/ui/src/components/Link/definition.ts | 33 + packages/ui/src/components/Link/index.ts | 1 + packages/ui/src/components/Menu/Menu.tsx | 19 +- packages/ui/src/components/Menu/definition.ts | 42 + packages/ui/src/components/Menu/index.ts | 1 + .../PasswordField/PasswordField.tsx | 3 +- .../components/PasswordField/definition.ts | 34 + .../ui/src/components/PasswordField/index.ts | 1 + .../ui/src/components/Popover/definition.ts | 27 + packages/ui/src/components/Popover/index.ts | 17 + .../src/components/RadioGroup/RadioGroup.tsx | 5 +- .../src/components/RadioGroup/definition.ts | 29 + .../ui/src/components/RadioGroup/index.ts | 1 + .../components/SearchField/SearchField.tsx | 3 +- .../src/components/SearchField/definition.ts | 35 + .../ui/src/components/SearchField/index.ts | 1 + packages/ui/src/components/Select/Select.tsx | 17 +- .../src/components/Select/SelectContent.tsx | 3 +- .../src/components/Select/SelectListBox.tsx | 5 +- .../src/components/Select/SelectTrigger.tsx | 3 +- .../ui/src/components/Select/definition.ts | 42 + packages/ui/src/components/Select/index.ts | 1 + .../ui/src/components/Skeleton/Skeleton.tsx | 3 +- .../ui/src/components/Skeleton/definition.ts | 27 + packages/ui/src/components/Skeleton/index.tsx | 1 + packages/ui/src/components/Switch/Switch.tsx | 3 +- .../ui/src/components/Switch/definition.ts | 28 + packages/ui/src/components/Switch/index.tsx | 1 + .../src/components/Table/components/Cell.tsx | 5 +- .../Table/components/CellProfile.tsx | 12 +- .../components/Table/components/Column.tsx | 6 +- .../src/components/Table/components/Row.tsx | 6 +- .../src/components/Table/components/Table.tsx | 6 +- .../components/Table/components/TableBody.tsx | 6 +- .../Table/components/TableHeader.tsx | 6 +- .../ui/src/components/Table/definition.ts | 43 + packages/ui/src/components/Table/index.ts | 2 + packages/ui/src/components/Table/types.ts | 5 +- .../TablePagination/TablePagination.tsx | 3 +- .../components/TablePagination/definition.ts | 30 + .../src/components/TablePagination/index.ts | 1 + packages/ui/src/components/Tabs/Tabs.tsx | 9 +- .../ui/src/components/Tabs/TabsIndicators.tsx | 3 +- packages/ui/src/components/Tabs/definition.ts | 33 + packages/ui/src/components/Tabs/index.ts | 1 + .../ui/src/components/TagGroup/TagGroup.tsx | 5 +- .../ui/src/components/TagGroup/definition.ts | 31 + packages/ui/src/components/TagGroup/index.ts | 1 + packages/ui/src/components/Text/Text.tsx | 16 +- packages/ui/src/components/Text/definition.ts | 33 + packages/ui/src/components/Text/index.ts | 1 + .../ui/src/components/TextField/TextField.tsx | 3 +- .../ui/src/components/TextField/definition.ts | 36 + packages/ui/src/components/TextField/index.ts | 1 + .../ui/src/components/Tooltip/Tooltip.tsx | 3 +- .../ui/src/components/Tooltip/definition.ts | 28 + packages/ui/src/components/Tooltip/index.ts | 1 + .../VisuallyHidden/VisuallyHidden.tsx | 6 +- .../components/VisuallyHidden/definition.ts | 27 + .../ui/src/components/VisuallyHidden/index.ts | 1 + packages/ui/src/definitions.ts | 57 ++ packages/ui/src/hooks/useStyles.ts | 14 +- packages/ui/src/index.ts | 3 - packages/ui/src/types.ts | 15 - packages/ui/src/utils/componentDefinitions.ts | 425 --------- 148 files changed, 1915 insertions(+), 1042 deletions(-) create mode 100644 .changeset/little-dingos-study.md create mode 100644 docs-ui/src/utils/definitions.ts create mode 100644 packages/ui/src/components/Accordion/definition.ts create mode 100644 packages/ui/src/components/Avatar/definition.ts create mode 100644 packages/ui/src/components/Box/definition.ts create mode 100644 packages/ui/src/components/Button/definition.ts create mode 100644 packages/ui/src/components/ButtonIcon/definition.ts create mode 100644 packages/ui/src/components/ButtonLink/definition.ts create mode 100644 packages/ui/src/components/Card/definition.ts create mode 100644 packages/ui/src/components/Checkbox/definition.ts create mode 100644 packages/ui/src/components/Container/definition.ts create mode 100644 packages/ui/src/components/Dialog/definition.ts create mode 100644 packages/ui/src/components/FieldError/definition.ts create mode 100644 packages/ui/src/components/FieldLabel/definition.ts create mode 100644 packages/ui/src/components/Flex/definition.ts create mode 100644 packages/ui/src/components/Grid/definition.ts create mode 100644 packages/ui/src/components/Header/definition.ts create mode 100644 packages/ui/src/components/HeaderPage/definition.ts create mode 100644 packages/ui/src/components/Link/definition.ts create mode 100644 packages/ui/src/components/Menu/definition.ts create mode 100644 packages/ui/src/components/PasswordField/definition.ts create mode 100644 packages/ui/src/components/Popover/definition.ts create mode 100644 packages/ui/src/components/Popover/index.ts create mode 100644 packages/ui/src/components/RadioGroup/definition.ts create mode 100644 packages/ui/src/components/SearchField/definition.ts create mode 100644 packages/ui/src/components/Select/definition.ts create mode 100644 packages/ui/src/components/Skeleton/definition.ts create mode 100644 packages/ui/src/components/Switch/definition.ts create mode 100644 packages/ui/src/components/Table/definition.ts create mode 100644 packages/ui/src/components/TablePagination/definition.ts create mode 100644 packages/ui/src/components/Tabs/definition.ts create mode 100644 packages/ui/src/components/TagGroup/definition.ts create mode 100644 packages/ui/src/components/Text/definition.ts create mode 100644 packages/ui/src/components/TextField/definition.ts create mode 100644 packages/ui/src/components/Tooltip/definition.ts create mode 100644 packages/ui/src/components/VisuallyHidden/definition.ts create mode 100644 packages/ui/src/definitions.ts delete mode 100644 packages/ui/src/utils/componentDefinitions.ts diff --git a/.changeset/little-dingos-study.md b/.changeset/little-dingos-study.md new file mode 100644 index 0000000000..2defb8ed1f --- /dev/null +++ b/.changeset/little-dingos-study.md @@ -0,0 +1,14 @@ +--- +'@backstage/ui': minor +--- + +**BREAKING**: Removed central `componentDefinitions` object and related type utilities (`ComponentDefinitionName`, `ComponentClassNames`). + +Component definitions are primarily intended for documenting the CSS class API for theming purposes, not for programmatic use in JavaScript/TypeScript. + +**Migration Guide:** + +If you were using component definitions or class names to build custom components, we recommend migrating to either: + +- Use Backstage UI components directly as building blocks, or +- Duplicate the component CSS in your own stylesheets instead of relying on internal class names diff --git a/docs-ui/src/components/Theming/index.tsx b/docs-ui/src/components/Theming/index.tsx index fb669253a2..d06f51348b 100644 --- a/docs-ui/src/components/Theming/index.tsx +++ b/docs-ui/src/components/Theming/index.tsx @@ -1,18 +1,13 @@ import { MDXRemote } from 'next-mdx-remote-client/rsc'; import { formattedMDXComponents } from '@/mdx-components'; -import { Component } from '@/utils/changelog'; -import { componentDefinitions } from '../../../../packages/ui/src/utils/componentDefinitions'; -import type { DataAttributeValues } from '../../../../packages/ui/src/types'; +import type { + ComponentDefinition, + DataAttributeValues, +} from '../../../../packages/ui/src/types'; -export function Theming({ component }: { component: Component }) { - const componentDefinition = componentDefinitions[component]; - - if (!componentDefinition) { - return null; - } - - const classNames = componentDefinition.classNames; - const dataAttributes = componentDefinition.dataAttributes; +export function Theming({ definition }: { definition: ComponentDefinition }) { + const classNames = definition.classNames; + const dataAttributes = definition.dataAttributes; // Get the first class name const firstClassName = Object.values(classNames)[0]; diff --git a/docs-ui/src/content/accordion.mdx b/docs-ui/src/content/accordion.mdx index 2694f8d144..fc4bad1f8e 100644 --- a/docs-ui/src/content/accordion.mdx +++ b/docs-ui/src/content/accordion.mdx @@ -16,6 +16,7 @@ import { } from './accordion.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { AccordionDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/avatar.mdx b/docs-ui/src/content/avatar.mdx index 6e0b550101..047485c2cc 100644 --- a/docs-ui/src/content/avatar.mdx +++ b/docs-ui/src/content/avatar.mdx @@ -11,6 +11,7 @@ import { } from './avatar.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { AvatarDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/box.mdx b/docs-ui/src/content/box.mdx index d1a9dd43fe..66e99ec19a 100644 --- a/docs-ui/src/content/box.mdx +++ b/docs-ui/src/content/box.mdx @@ -12,6 +12,7 @@ import { import { spacingPropDefs } from '@/utils/propDefs'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { BoxDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/button-icon.mdx b/docs-ui/src/content/button-icon.mdx index fbc0c8c54c..b0595cc9bc 100644 --- a/docs-ui/src/content/button-icon.mdx +++ b/docs-ui/src/content/button-icon.mdx @@ -15,6 +15,7 @@ import { } from './button-icon.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { ButtonIconDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/button-link.mdx b/docs-ui/src/content/button-link.mdx index 5ce538838d..4f3f376aee 100644 --- a/docs-ui/src/content/button-link.mdx +++ b/docs-ui/src/content/button-link.mdx @@ -13,6 +13,7 @@ import { } from './button-link.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { ButtonLinkDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/button.mdx b/docs-ui/src/content/button.mdx index b60f32ff07..d161c97edf 100644 --- a/docs-ui/src/content/button.mdx +++ b/docs-ui/src/content/button.mdx @@ -16,6 +16,7 @@ import { import { ChangelogComponent } from '@/components/ChangelogComponent'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { ButtonDefinition } from '../utils/definitions'; - + diff --git a/docs-ui/src/content/card.mdx b/docs-ui/src/content/card.mdx index 06c3a5bc2e..c38a07e920 100644 --- a/docs-ui/src/content/card.mdx +++ b/docs-ui/src/content/card.mdx @@ -14,6 +14,7 @@ import { } from './card.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { CardDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/checkbox.mdx b/docs-ui/src/content/checkbox.mdx index 5770396ebb..c574e8fed4 100644 --- a/docs-ui/src/content/checkbox.mdx +++ b/docs-ui/src/content/checkbox.mdx @@ -10,6 +10,7 @@ import { } from './checkbox.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { CheckboxDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/container.mdx b/docs-ui/src/content/container.mdx index 05615cb1c2..56c2d5d405 100644 --- a/docs-ui/src/content/container.mdx +++ b/docs-ui/src/content/container.mdx @@ -11,6 +11,7 @@ import { } from './container.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { ContainerDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/dialog.mdx b/docs-ui/src/content/dialog.mdx index 4aa43c69de..e1e4ec436e 100644 --- a/docs-ui/src/content/dialog.mdx +++ b/docs-ui/src/content/dialog.mdx @@ -18,6 +18,7 @@ import { } from './dialog.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { DialogDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/flex.mdx b/docs-ui/src/content/flex.mdx index 89cd2e380a..36284f1f0b 100644 --- a/docs-ui/src/content/flex.mdx +++ b/docs-ui/src/content/flex.mdx @@ -14,6 +14,7 @@ import { import { spacingPropDefs } from '@/utils/propDefs'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { FlexDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/grid.mdx b/docs-ui/src/content/grid.mdx index 0ffdba6a66..5f179b9e14 100644 --- a/docs-ui/src/content/grid.mdx +++ b/docs-ui/src/content/grid.mdx @@ -16,6 +16,7 @@ import { } from './grid.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { GridDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/header-page.mdx b/docs-ui/src/content/header-page.mdx index d3f93058ee..12ef2c32ee 100644 --- a/docs-ui/src/content/header-page.mdx +++ b/docs-ui/src/content/header-page.mdx @@ -14,6 +14,7 @@ import { } from './header-page.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { HeaderPageDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/header.mdx b/docs-ui/src/content/header.mdx index af4e8010c5..eb505d7a62 100644 --- a/docs-ui/src/content/header.mdx +++ b/docs-ui/src/content/header.mdx @@ -13,6 +13,7 @@ import { } from './header.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { HeaderDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/link.mdx b/docs-ui/src/content/link.mdx index e0c1be353f..486c06b298 100644 --- a/docs-ui/src/content/link.mdx +++ b/docs-ui/src/content/link.mdx @@ -19,6 +19,7 @@ import { import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; import { ChangelogComponent } from '@/components/ChangelogComponent'; +import { LinkDefinition } from '../utils/definitions'; - + diff --git a/docs-ui/src/content/menu.mdx b/docs-ui/src/content/menu.mdx index 743d884809..9ede0885e2 100644 --- a/docs-ui/src/content/menu.mdx +++ b/docs-ui/src/content/menu.mdx @@ -27,6 +27,7 @@ import { import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; import { ChangelogComponent } from '@/components/ChangelogComponent'; +import { MenuDefinition } from '../utils/definitions'; - + diff --git a/docs-ui/src/content/password-field.mdx b/docs-ui/src/content/password-field.mdx index 14fbc9e34d..8dda2b4f2a 100644 --- a/docs-ui/src/content/password-field.mdx +++ b/docs-ui/src/content/password-field.mdx @@ -12,6 +12,7 @@ import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; import { ChangelogComponent } from '@/components/ChangelogComponent'; import { CodeBlock } from '@/components/CodeBlock'; +import { PasswordFieldDefinition } from '../utils/definitions'; - + diff --git a/docs-ui/src/content/radio-group.mdx b/docs-ui/src/content/radio-group.mdx index ab3d28ad81..ba9352c026 100644 --- a/docs-ui/src/content/radio-group.mdx +++ b/docs-ui/src/content/radio-group.mdx @@ -16,6 +16,7 @@ import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; import { ChangelogComponent } from '@/components/ChangelogComponent'; import { CodeBlock } from '@/components/CodeBlock'; +import { RadioGroupDefinition } from '../utils/definitions'; - + diff --git a/docs-ui/src/content/search-field.mdx b/docs-ui/src/content/search-field.mdx index 2a2d93f262..6b33feea42 100644 --- a/docs-ui/src/content/search-field.mdx +++ b/docs-ui/src/content/search-field.mdx @@ -13,6 +13,7 @@ import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; import { ChangelogComponent } from '@/components/ChangelogComponent'; import { CodeBlock } from '@/components/CodeBlock'; +import { SearchFieldDefinition } from '../utils/definitions'; - + diff --git a/docs-ui/src/content/select.mdx b/docs-ui/src/content/select.mdx index eb53e9ea35..436129d749 100644 --- a/docs-ui/src/content/select.mdx +++ b/docs-ui/src/content/select.mdx @@ -18,6 +18,7 @@ import { import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; import { ChangelogComponent } from '@/components/ChangelogComponent'; +import { SelectDefinition } from '../utils/definitions'; - + diff --git a/docs-ui/src/content/skeleton.mdx b/docs-ui/src/content/skeleton.mdx index f0d3fbc39a..07cd4b3332 100644 --- a/docs-ui/src/content/skeleton.mdx +++ b/docs-ui/src/content/skeleton.mdx @@ -12,6 +12,7 @@ import { import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; import { ChangelogComponent } from '@/components/ChangelogComponent'; +import { SkeletonDefinition } from '../utils/definitions'; - + diff --git a/docs-ui/src/content/switch.mdx b/docs-ui/src/content/switch.mdx index acf588e37d..965cc7832b 100644 --- a/docs-ui/src/content/switch.mdx +++ b/docs-ui/src/content/switch.mdx @@ -6,6 +6,7 @@ import { switchPropDefs, snippetUsage } from './switch.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; import { ChangelogComponent } from '@/components/ChangelogComponent'; +import { SwitchDefinition } from '../utils/definitions'; `} /> - + diff --git a/docs-ui/src/content/table.mdx b/docs-ui/src/content/table.mdx index 4ea5fd1677..d1a190e9dd 100644 --- a/docs-ui/src/content/table.mdx +++ b/docs-ui/src/content/table.mdx @@ -22,6 +22,7 @@ import { import { ChangelogComponent } from '@/components/ChangelogComponent'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { TableDefinition } from '../utils/definitions'; + diff --git a/docs-ui/src/content/tabs.mdx b/docs-ui/src/content/tabs.mdx index 26905d4733..1fc7448eba 100644 --- a/docs-ui/src/content/tabs.mdx +++ b/docs-ui/src/content/tabs.mdx @@ -13,6 +13,7 @@ import { } from './tabs.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { TabsDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/tag-group.mdx b/docs-ui/src/content/tag-group.mdx index 8d7fb3c3d0..88e60b31f5 100644 --- a/docs-ui/src/content/tag-group.mdx +++ b/docs-ui/src/content/tag-group.mdx @@ -15,6 +15,7 @@ import { } from './tag-group.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { TagGroupDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/text-field.mdx b/docs-ui/src/content/text-field.mdx index ad90783ffb..9f14a82975 100644 --- a/docs-ui/src/content/text-field.mdx +++ b/docs-ui/src/content/text-field.mdx @@ -10,6 +10,7 @@ import { } from './text-field.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { TextFieldDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; import { CodeBlock } from '@/components/CodeBlock'; @@ -59,6 +60,6 @@ Here's a simple TextField with a description. code={textFieldDescriptionSnippet} /> - + diff --git a/docs-ui/src/content/text.mdx b/docs-ui/src/content/text.mdx index 48b461aa8c..c987b8e5f7 100644 --- a/docs-ui/src/content/text.mdx +++ b/docs-ui/src/content/text.mdx @@ -14,6 +14,7 @@ import { } from './text.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { TextDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/tooltip.mdx b/docs-ui/src/content/tooltip.mdx index dd2add5308..8ebf6539d6 100644 --- a/docs-ui/src/content/tooltip.mdx +++ b/docs-ui/src/content/tooltip.mdx @@ -10,6 +10,7 @@ import { } from './tooltip.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { TooltipDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/content/visually-hidden.mdx b/docs-ui/src/content/visually-hidden.mdx index 26a609b245..72ffc7a1d4 100644 --- a/docs-ui/src/content/visually-hidden.mdx +++ b/docs-ui/src/content/visually-hidden.mdx @@ -10,6 +10,7 @@ import { } from './visually-hidden.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; +import { VisuallyHiddenDefinition } from '../utils/definitions'; import { ChangelogComponent } from '@/components/ChangelogComponent'; - + diff --git a/docs-ui/src/utils/definitions.ts b/docs-ui/src/utils/definitions.ts new file mode 100644 index 0000000000..d279d73775 --- /dev/null +++ b/docs-ui/src/utils/definitions.ts @@ -0,0 +1 @@ +export * from '../../../packages/ui/src/definitions'; diff --git a/packages/ui/report.api.md b/packages/ui/report.api.md index 4f6087b0f0..30910724eb 100644 --- a/packages/ui/report.api.md +++ b/packages/ui/report.api.md @@ -58,6 +58,20 @@ export const Accordion: ForwardRefExoticComponent< AccordionProps & RefAttributes >; +// @public +export const AccordionDefinition: { + readonly classNames: { + readonly root: 'bui-Accordion'; + readonly trigger: 'bui-AccordionTrigger'; + readonly triggerButton: 'bui-AccordionTriggerButton'; + readonly triggerTitle: 'bui-AccordionTriggerTitle'; + readonly triggerSubtitle: 'bui-AccordionTriggerSubtitle'; + readonly triggerIcon: 'bui-AccordionTriggerIcon'; + readonly panel: 'bui-AccordionPanel'; + readonly group: 'bui-AccordionGroup'; + }; +}; + // @public (undocumented) export const AccordionGroup: ForwardRefExoticComponent< AccordionGroupProps & RefAttributes @@ -112,6 +126,18 @@ export const Avatar: ForwardRefExoticComponent< AvatarProps & RefAttributes >; +// @public +export const AvatarDefinition: { + readonly classNames: { + readonly root: 'bui-AvatarRoot'; + readonly image: 'bui-AvatarImage'; + readonly fallback: 'bui-AvatarFallback'; + }; + readonly dataAttributes: { + readonly size: readonly ['small', 'medium', 'large']; + }; +}; + // @public (undocumented) export interface AvatarProps extends React.ComponentPropsWithoutRef<'div'> { name: string; @@ -139,6 +165,37 @@ export const Box: ForwardRefExoticComponent< BoxProps & RefAttributes >; +// @public +export const BoxDefinition: { + readonly classNames: { + readonly root: 'bui-Box'; + }; + readonly utilityProps: [ + 'm', + 'mb', + 'ml', + 'mr', + 'mt', + 'mx', + 'my', + 'p', + 'pb', + 'pl', + 'pr', + 'pt', + 'px', + 'py', + 'position', + 'display', + 'width', + 'minWidth', + 'maxWidth', + 'height', + 'minHeight', + 'maxHeight', + ]; +}; + // @public (undocumented) export interface BoxProps extends SpaceProps { // (undocumented) @@ -177,11 +234,34 @@ export const Button: ForwardRefExoticComponent< ButtonProps & RefAttributes >; +// @public +export const ButtonDefinition: { + readonly classNames: { + readonly root: 'bui-Button'; + readonly content: 'bui-ButtonContent'; + readonly spinner: 'bui-ButtonSpinner'; + }; + readonly dataAttributes: { + readonly size: readonly ['small', 'medium', 'large']; + readonly variant: readonly ['primary', 'secondary', 'tertiary']; + readonly loading: readonly [true, false]; + }; +}; + // @public (undocumented) export const ButtonIcon: ForwardRefExoticComponent< ButtonIconProps & RefAttributes >; +// @public +export const ButtonIconDefinition: { + readonly classNames: { + readonly root: 'bui-ButtonIcon'; + readonly content: 'bui-ButtonIconContent'; + readonly spinner: 'bui-ButtonIconSpinner'; + }; +}; + // @public export interface ButtonIconProps extends ButtonProps_2 { // (undocumented) @@ -203,6 +283,13 @@ export const ButtonLink: ForwardRefExoticComponent< ButtonLinkProps & RefAttributes >; +// @public +export const ButtonLinkDefinition: { + readonly classNames: { + readonly root: 'bui-ButtonLink'; + }; +}; + // @public export interface ButtonLinkProps extends LinkProps_2 { // (undocumented) @@ -257,6 +344,16 @@ export interface CardBodyProps extends React.HTMLAttributes { children?: React.ReactNode; } +// @public +export const CardDefinition: { + readonly classNames: { + readonly root: 'bui-Card'; + readonly header: 'bui-CardHeader'; + readonly body: 'bui-CardBody'; + readonly footer: 'bui-CardFooter'; + }; +}; + // @public export const CardFooter: ForwardRefExoticComponent< CardFooterProps & RefAttributes @@ -297,7 +394,7 @@ export const CellProfile: (props: CellProfileProps) => JSX_2.Element; // @public (undocumented) export interface CellProfileProps extends CellProps_2 { // (undocumented) - color?: 'primary' | 'secondary'; + color?: TextColors; // (undocumented) description?: string; // (undocumented) @@ -311,7 +408,7 @@ export interface CellProfileProps extends CellProps_2 { // @public (undocumented) export interface CellProps extends CellProps_2 { // (undocumented) - color?: 'primary' | 'secondary'; + color?: TextColors; // (undocumented) description?: string; // (undocumented) @@ -327,6 +424,17 @@ export const Checkbox: ForwardRefExoticComponent< CheckboxProps & RefAttributes >; +// @public +export const CheckboxDefinition: { + readonly classNames: { + readonly root: 'bui-Checkbox'; + readonly indicator: 'bui-CheckboxIndicator'; + }; + readonly dataAttributes: { + readonly selected: readonly [true, false]; + }; +}; + // @public (undocumented) export interface CheckboxProps extends CheckboxProps_2 { // (undocumented) @@ -361,10 +469,6 @@ export type Columns = | '12' | 'auto'; -// @public -export type ComponentClassNames = - (typeof componentDefinitions)[T]['classNames']; - // @public export interface ComponentDefinition { // (undocumented) @@ -375,431 +479,19 @@ export interface ComponentDefinition { utilityProps?: string[]; } -// @public -export type ComponentDefinitionName = keyof typeof componentDefinitions; - -// @public -export const componentDefinitions: { - readonly Avatar: { - readonly classNames: { - readonly root: 'bui-AvatarRoot'; - readonly image: 'bui-AvatarImage'; - readonly fallback: 'bui-AvatarFallback'; - }; - readonly dataAttributes: { - readonly size: readonly ['small', 'medium', 'large']; - }; - }; - readonly Box: { - readonly classNames: { - readonly root: 'bui-Box'; - }; - readonly utilityProps: [ - 'm', - 'mb', - 'ml', - 'mr', - 'mt', - 'mx', - 'my', - 'p', - 'pb', - 'pl', - 'pr', - 'pt', - 'px', - 'py', - 'position', - 'display', - 'width', - 'minWidth', - 'maxWidth', - 'height', - 'minHeight', - 'maxHeight', - ]; - }; - readonly Button: { - readonly classNames: { - readonly root: 'bui-Button'; - readonly content: 'bui-ButtonContent'; - readonly spinner: 'bui-ButtonSpinner'; - }; - readonly dataAttributes: { - readonly size: readonly ['small', 'medium', 'large']; - readonly variant: readonly ['primary', 'secondary', 'tertiary']; - readonly loading: readonly [true, false]; - }; - }; - readonly ButtonIcon: { - readonly classNames: { - readonly root: 'bui-ButtonIcon'; - readonly content: 'bui-ButtonIconContent'; - readonly spinner: 'bui-ButtonIconSpinner'; - }; - }; - readonly ButtonLink: { - readonly classNames: { - readonly root: 'bui-ButtonLink'; - }; - }; - readonly Card: { - readonly classNames: { - readonly root: 'bui-Card'; - readonly header: 'bui-CardHeader'; - readonly body: 'bui-CardBody'; - readonly footer: 'bui-CardFooter'; - }; - }; - readonly Checkbox: { - readonly classNames: { - readonly root: 'bui-Checkbox'; - readonly indicator: 'bui-CheckboxIndicator'; - }; - readonly dataAttributes: { - readonly selected: readonly [true, false]; - }; - }; - readonly Container: { - readonly classNames: { - readonly root: 'bui-Container'; - }; - readonly utilityProps: ['my', 'mt', 'mb', 'py', 'pt', 'pb', 'display']; - }; - readonly Dialog: { - readonly classNames: { - readonly overlay: 'bui-DialogOverlay'; - readonly dialog: 'bui-Dialog'; - readonly header: 'bui-DialogHeader'; - readonly headerTitle: 'bui-DialogHeaderTitle'; - readonly body: 'bui-DialogBody'; - readonly footer: 'bui-DialogFooter'; - }; - }; - readonly Accordion: { - readonly classNames: { - readonly root: 'bui-Accordion'; - readonly trigger: 'bui-AccordionTrigger'; - readonly triggerButton: 'bui-AccordionTriggerButton'; - readonly triggerTitle: 'bui-AccordionTriggerTitle'; - readonly triggerSubtitle: 'bui-AccordionTriggerSubtitle'; - readonly triggerIcon: 'bui-AccordionTriggerIcon'; - readonly panel: 'bui-AccordionPanel'; - readonly group: 'bui-AccordionGroup'; - }; - }; - readonly FieldError: { - readonly classNames: { - readonly root: 'bui-FieldError'; - }; - }; - readonly FieldLabel: { - readonly classNames: { - readonly root: 'bui-FieldLabelWrapper'; - readonly label: 'bui-FieldLabel'; - readonly secondaryLabel: 'bui-FieldSecondaryLabel'; - readonly description: 'bui-FieldDescription'; - }; - }; - readonly Flex: { - readonly classNames: { - readonly root: 'bui-Flex'; - }; - readonly utilityProps: [ - 'm', - 'mb', - 'ml', - 'mr', - 'mt', - 'mx', - 'my', - 'p', - 'pb', - 'pl', - 'pr', - 'pt', - 'px', - 'py', - 'gap', - 'align', - 'justify', - 'direction', - ]; - }; - readonly Grid: { - readonly classNames: { - readonly root: 'bui-Grid'; - }; - readonly utilityProps: [ - 'columns', - 'gap', - 'm', - 'mb', - 'ml', - 'mr', - 'mt', - 'mx', - 'my', - 'p', - 'pb', - 'pl', - 'pr', - 'pt', - 'px', - 'py', - ]; - }; - readonly GridItem: { - readonly classNames: { - readonly root: 'bui-GridItem'; - }; - readonly utilityProps: ['colSpan', 'colEnd', 'colStart', 'rowSpan']; - }; - readonly Header: { - readonly classNames: { - readonly toolbar: 'bui-HeaderToolbar'; - readonly toolbarWrapper: 'bui-HeaderToolbarWrapper'; - readonly toolbarContent: 'bui-HeaderToolbarContent'; - readonly toolbarControls: 'bui-HeaderToolbarControls'; - readonly toolbarIcon: 'bui-HeaderToolbarIcon'; - readonly toolbarName: 'bui-HeaderToolbarName'; - readonly tabsWrapper: 'bui-HeaderTabsWrapper'; - }; - }; - readonly HeaderPage: { - readonly classNames: { - readonly root: 'bui-HeaderPage'; - readonly content: 'bui-HeaderPageContent'; - readonly breadcrumbs: 'bui-HeaderPageBreadcrumbs'; - readonly tabsWrapper: 'bui-HeaderPageTabsWrapper'; - readonly controls: 'bui-HeaderPageControls'; - }; - }; - readonly Heading: { - readonly classNames: { - readonly root: 'bui-Heading'; - }; - readonly dataAttributes: { - readonly variant: readonly ['title1', 'title2', 'title3', 'subtitle']; - readonly color: readonly ['primary', 'secondary', 'muted']; - readonly truncate: readonly [true, false]; - }; - }; - readonly Icon: { - readonly classNames: { - readonly root: 'bui-Icon'; - }; - }; - readonly Link: { - readonly classNames: { - readonly root: 'bui-Link'; - }; - readonly dataAttributes: { - readonly variant: readonly ['subtitle', 'body', 'caption', 'label']; - readonly weight: readonly ['regular', 'bold']; - readonly color: readonly [ - 'primary', - 'secondary', - 'danger', - 'warning', - 'success', - ]; - readonly truncate: readonly [true, false]; - }; - }; - readonly List: { - readonly classNames: { - readonly root: 'bui-List'; - readonly row: 'bui-ListRow'; - readonly label: 'bui-ListLabel'; - }; - }; - readonly Menu: { - readonly classNames: { - readonly root: 'bui-Menu'; - readonly popover: 'bui-MenuPopover'; - readonly content: 'bui-MenuContent'; - readonly section: 'bui-MenuSection'; - readonly sectionHeader: 'bui-MenuSectionHeader'; - readonly item: 'bui-MenuItem'; - readonly itemListBox: 'bui-MenuItemListBox'; - readonly itemListBoxCheck: 'bui-MenuItemListBoxCheck'; - readonly itemWrapper: 'bui-MenuItemWrapper'; - readonly itemContent: 'bui-MenuItemContent'; - readonly itemArrow: 'bui-MenuItemArrow'; - readonly separator: 'bui-MenuSeparator'; - readonly searchField: 'bui-MenuSearchField'; - readonly searchFieldInput: 'bui-MenuSearchFieldInput'; - readonly searchFieldClear: 'bui-MenuSearchFieldClear'; - readonly emptyState: 'bui-MenuEmptyState'; - }; - }; - readonly PasswordField: { - readonly classNames: { - readonly root: 'bui-PasswordField'; - readonly inputWrapper: 'bui-PasswordFieldInputWrapper'; - readonly input: 'bui-PasswordFieldInput'; - readonly inputIcon: 'bui-PasswordFieldIcon'; - readonly inputVisibility: 'bui-PasswordFieldVisibility'; - }; - readonly dataAttributes: { - readonly size: readonly ['small', 'medium']; - }; - }; - readonly Popover: { - readonly classNames: { - readonly root: 'bui-Popover'; - }; - }; - readonly RadioGroup: { - readonly classNames: { - readonly root: 'bui-RadioGroup'; - readonly content: 'bui-RadioGroupContent'; - readonly radio: 'bui-Radio'; - }; - }; - readonly SearchField: { - readonly classNames: { - readonly root: 'bui-SearchField'; - readonly clear: 'bui-SearchFieldClear'; - readonly inputWrapper: 'bui-SearchFieldInputWrapper'; - readonly input: 'bui-SearchFieldInput'; - readonly inputIcon: 'bui-SearchFieldInputIcon'; - }; - readonly dataAttributes: { - readonly startCollapsed: readonly [true, false]; - readonly size: readonly ['small', 'medium']; - }; - }; - readonly Select: { - readonly classNames: { - readonly root: 'bui-Select'; - readonly popover: 'bui-SelectPopover'; - readonly trigger: 'bui-SelectTrigger'; - readonly chevron: 'bui-SelectTriggerChevron'; - readonly value: 'bui-SelectValue'; - readonly list: 'bui-SelectList'; - readonly item: 'bui-SelectItem'; - readonly itemIndicator: 'bui-SelectItemIndicator'; - readonly itemLabel: 'bui-SelectItemLabel'; - readonly searchWrapper: 'bui-SelectSearchWrapper'; - readonly search: 'bui-SelectSearch'; - readonly searchClear: 'bui-SelectSearchClear'; - readonly noResults: 'bui-SelectNoResults'; - }; - readonly dataAttributes: { - readonly size: readonly ['small', 'medium']; - }; - }; - readonly Skeleton: { - readonly classNames: { - readonly root: 'bui-Skeleton'; - }; - }; - readonly Switch: { - readonly classNames: { - readonly root: 'bui-Switch'; - readonly indicator: 'bui-SwitchIndicator'; - }; - }; - readonly Table: { - readonly classNames: { - readonly table: 'bui-Table'; - readonly header: 'bui-TableHeader'; - readonly body: 'bui-TableBody'; - readonly row: 'bui-TableRow'; - readonly head: 'bui-TableHead'; - readonly headContent: 'bui-TableHeadContent'; - readonly headSortButton: 'bui-TableHeadSortButton'; - readonly caption: 'bui-TableCaption'; - readonly cell: 'bui-TableCell'; - readonly cellContentWrapper: 'bui-TableCellContentWrapper'; - readonly cellContent: 'bui-TableCellContent'; - readonly cellIcon: 'bui-TableCellIcon'; - readonly cellProfileAvatar: 'bui-TableCellProfileAvatar'; - readonly cellProfileAvatarImage: 'bui-TableCellProfileAvatarImage'; - readonly cellProfileAvatarFallback: 'bui-TableCellProfileAvatarFallback'; - readonly cellProfileName: 'bui-TableCellProfileName'; - readonly cellProfileLink: 'bui-TableCellProfileLink'; - }; - }; - readonly TablePagination: { - readonly classNames: { - readonly root: 'bui-TablePagination'; - readonly left: 'bui-TablePaginationLeft'; - readonly right: 'bui-TablePaginationRight'; - readonly select: 'bui-TablePaginationSelect'; - }; - }; - readonly Tabs: { - readonly classNames: { - readonly tabs: 'bui-Tabs'; - readonly tabList: 'bui-TabList'; - readonly tabListWrapper: 'bui-TabListWrapper'; - readonly tab: 'bui-Tab'; - readonly tabActive: 'bui-TabActive'; - readonly tabHovered: 'bui-TabHovered'; - readonly panel: 'bui-TabPanel'; - }; - }; - readonly TagGroup: { - readonly classNames: { - readonly group: 'bui-TagGroup'; - readonly list: 'bui-TagList'; - readonly tag: 'bui-Tag'; - readonly tagIcon: 'bui-TagIcon'; - readonly tagRemoveButton: 'bui-TagRemoveButton'; - }; - }; - readonly Text: { - readonly classNames: { - readonly root: 'bui-Text'; - }; - readonly dataAttributes: { - readonly variant: readonly ['subtitle', 'body', 'caption', 'label']; - readonly weight: readonly ['regular', 'bold']; - readonly color: readonly [ - 'primary', - 'secondary', - 'danger', - 'warning', - 'success', - ]; - readonly truncate: readonly [true, false]; - }; - }; - readonly TextField: { - readonly classNames: { - readonly root: 'bui-TextField'; - readonly inputWrapper: 'bui-InputWrapper'; - readonly input: 'bui-Input'; - readonly inputIcon: 'bui-InputIcon'; - readonly inputAction: 'bui-InputAction'; - }; - readonly dataAttributes: { - readonly invalid: readonly [true, false]; - readonly disabled: readonly [true, false]; - readonly size: readonly ['small', 'medium']; - }; - }; - readonly Tooltip: { - readonly classNames: { - readonly tooltip: 'bui-Tooltip'; - readonly arrow: 'bui-TooltipArrow'; - }; - }; - readonly VisuallyHidden: { - readonly classNames: { - readonly root: 'bui-VisuallyHidden'; - }; - }; -}; - // @public (undocumented) export const Container: ForwardRefExoticComponent< ContainerProps & RefAttributes >; +// @public +export const ContainerDefinition: { + readonly classNames: { + readonly root: 'bui-Container'; + }; + readonly utilityProps: ['my', 'mt', 'mb', 'py', 'pt', 'pb', 'display']; +}; + // @public (undocumented) export interface ContainerProps { // (undocumented) @@ -846,6 +538,18 @@ export interface DialogBodyProps { className?: string; } +// @public +export const DialogDefinition: { + readonly classNames: { + readonly overlay: 'bui-DialogOverlay'; + readonly dialog: 'bui-Dialog'; + readonly header: 'bui-DialogHeader'; + readonly headerTitle: 'bui-DialogHeaderTitle'; + readonly body: 'bui-DialogBody'; + readonly footer: 'bui-DialogFooter'; + }; +}; + // @public (undocumented) export const DialogFooter: ForwardRefExoticComponent< Omit< @@ -894,6 +598,16 @@ export const FieldLabel: ForwardRefExoticComponent< FieldLabelProps & RefAttributes >; +// @public +export const FieldLabelDefinition: { + readonly classNames: { + readonly root: 'bui-FieldLabelWrapper'; + readonly label: 'bui-FieldLabel'; + readonly secondaryLabel: 'bui-FieldSecondaryLabel'; + readonly description: 'bui-FieldDescription'; + }; +}; + // @public (undocumented) export interface FieldLabelProps extends Pick, 'className'> { @@ -909,6 +623,33 @@ export const Flex: ForwardRefExoticComponent< FlexProps & RefAttributes >; +// @public +export const FlexDefinition: { + readonly classNames: { + readonly root: 'bui-Flex'; + }; + readonly utilityProps: [ + 'm', + 'mb', + 'ml', + 'mr', + 'mt', + 'mx', + 'my', + 'p', + 'pb', + 'pl', + 'pr', + 'pt', + 'px', + 'py', + 'gap', + 'align', + 'justify', + 'direction', + ]; +}; + // @public (undocumented) export type FlexDirection = 'row' | 'column'; @@ -941,6 +682,39 @@ export const Grid: { >; }; +// @public +export const GridDefinition: { + readonly classNames: { + readonly root: 'bui-Grid'; + }; + readonly utilityProps: [ + 'columns', + 'gap', + 'm', + 'mb', + 'ml', + 'mr', + 'mt', + 'mx', + 'my', + 'p', + 'pb', + 'pl', + 'pr', + 'pt', + 'px', + 'py', + ]; +}; + +// @public +export const GridItemDefinition: { + readonly classNames: { + readonly root: 'bui-GridItem'; + }; + readonly utilityProps: ['colSpan', 'colEnd', 'colStart', 'rowSpan']; +}; + // @public (undocumented) export interface GridItemProps { // (undocumented) @@ -976,6 +750,19 @@ export interface GridProps extends SpaceProps { // @public export const Header: (props: HeaderProps) => JSX_2.Element; +// @public +export const HeaderDefinition: { + readonly classNames: { + readonly toolbar: 'bui-HeaderToolbar'; + readonly toolbarWrapper: 'bui-HeaderToolbarWrapper'; + readonly toolbarContent: 'bui-HeaderToolbarContent'; + readonly toolbarControls: 'bui-HeaderToolbarControls'; + readonly toolbarIcon: 'bui-HeaderToolbarIcon'; + readonly toolbarName: 'bui-HeaderToolbarName'; + readonly tabsWrapper: 'bui-HeaderTabsWrapper'; + }; +}; + // @public export const HeaderPage: (props: HeaderPageProps) => JSX_2.Element; @@ -987,6 +774,17 @@ export interface HeaderPageBreadcrumb { label: string; } +// @public +export const HeaderPageDefinition: { + readonly classNames: { + readonly root: 'bui-HeaderPage'; + readonly content: 'bui-HeaderPageContent'; + readonly breadcrumbs: 'bui-HeaderPageBreadcrumbs'; + readonly tabsWrapper: 'bui-HeaderPageTabsWrapper'; + readonly controls: 'bui-HeaderPageControls'; + }; +}; + // @public export interface HeaderPageProps { // (undocumented) @@ -1044,6 +842,25 @@ export const Link: ForwardRefExoticComponent< LinkProps & RefAttributes >; +// @public +export const LinkDefinition: { + readonly classNames: { + readonly root: 'bui-Link'; + }; + readonly dataAttributes: { + readonly variant: readonly ['subtitle', 'body', 'caption', 'label']; + readonly weight: readonly ['regular', 'bold']; + readonly color: readonly [ + 'primary', + 'secondary', + 'danger', + 'warning', + 'success', + ]; + readonly truncate: readonly [true, false]; + }; +}; + // @public (undocumented) export interface LinkProps extends LinkProps_2 { // (undocumented) @@ -1104,6 +921,28 @@ export interface MenuAutocompleteProps virtualized?: boolean; } +// @public +export const MenuDefinition: { + readonly classNames: { + readonly root: 'bui-Menu'; + readonly popover: 'bui-MenuPopover'; + readonly content: 'bui-MenuContent'; + readonly section: 'bui-MenuSection'; + readonly sectionHeader: 'bui-MenuSectionHeader'; + readonly item: 'bui-MenuItem'; + readonly itemListBox: 'bui-MenuItemListBox'; + readonly itemListBoxCheck: 'bui-MenuItemListBoxCheck'; + readonly itemWrapper: 'bui-MenuItemWrapper'; + readonly itemContent: 'bui-MenuItemContent'; + readonly itemArrow: 'bui-MenuItemArrow'; + readonly separator: 'bui-MenuSeparator'; + readonly searchField: 'bui-MenuSearchField'; + readonly searchFieldInput: 'bui-MenuSearchFieldInput'; + readonly searchFieldClear: 'bui-MenuSearchFieldClear'; + readonly emptyState: 'bui-MenuEmptyState'; + }; +}; + // @public (undocumented) export const MenuItem: (props: MenuItemProps) => JSX_2.Element; @@ -1204,6 +1043,15 @@ export const RadioGroup: ForwardRefExoticComponent< RadioGroupProps & RefAttributes >; +// @public +export const RadioGroupDefinition: { + readonly classNames: { + readonly root: 'bui-RadioGroup'; + readonly content: 'bui-RadioGroupContent'; + readonly radio: 'bui-Radio'; + }; +}; + // @public (undocumented) export interface RadioGroupProps extends Omit, @@ -1226,6 +1074,21 @@ export const SearchField: ForwardRefExoticComponent< SearchFieldProps & RefAttributes >; +// @public +export const SearchFieldDefinition: { + readonly classNames: { + readonly root: 'bui-SearchField'; + readonly clear: 'bui-SearchFieldClear'; + readonly inputWrapper: 'bui-SearchFieldInputWrapper'; + readonly input: 'bui-SearchFieldInput'; + readonly inputIcon: 'bui-SearchFieldInputIcon'; + }; + readonly dataAttributes: { + readonly startCollapsed: readonly [true, false]; + readonly size: readonly ['small', 'medium']; + }; +}; + // @public (undocumented) export interface SearchFieldProps extends SearchFieldProps_2, @@ -1241,6 +1104,28 @@ export const Select: ForwardRefExoticComponent< SelectProps<'multiple' | 'single'> & RefAttributes >; +// @public +export const SelectDefinition: { + readonly classNames: { + readonly root: 'bui-Select'; + readonly popover: 'bui-SelectPopover'; + readonly trigger: 'bui-SelectTrigger'; + readonly chevron: 'bui-SelectTriggerChevron'; + readonly value: 'bui-SelectValue'; + readonly list: 'bui-SelectList'; + readonly item: 'bui-SelectItem'; + readonly itemIndicator: 'bui-SelectItemIndicator'; + readonly itemLabel: 'bui-SelectItemLabel'; + readonly searchWrapper: 'bui-SelectSearchWrapper'; + readonly search: 'bui-SelectSearch'; + readonly searchClear: 'bui-SelectSearchClear'; + readonly noResults: 'bui-SelectNoResults'; + }; + readonly dataAttributes: { + readonly size: readonly ['small', 'medium']; + }; +}; + // @public (undocumented) export interface SelectProps extends SelectProps_2, @@ -1256,6 +1141,13 @@ export interface SelectProps // @public (undocumented) export const Skeleton: (props: SkeletonProps) => JSX_2.Element; +// @public +export const SkeletonDefinition: { + readonly classNames: { + readonly root: 'bui-Skeleton'; + }; +}; + // @public (undocumented) export interface SkeletonProps extends ComponentProps<'div'> { // (undocumented) @@ -1329,6 +1221,14 @@ export const Switch: ForwardRefExoticComponent< SwitchProps & RefAttributes >; +// @public +export const SwitchDefinition: { + readonly classNames: { + readonly root: 'bui-Switch'; + readonly indicator: 'bui-SwitchIndicator'; + }; +}; + // @public (undocumented) export interface SwitchProps extends SwitchProps_2 { label?: string; @@ -1345,6 +1245,29 @@ export const TableBody: ( props: TableBodyProps, ) => JSX_2.Element; +// @public +export const TableDefinition: { + readonly classNames: { + readonly table: 'bui-Table'; + readonly header: 'bui-TableHeader'; + readonly body: 'bui-TableBody'; + readonly row: 'bui-TableRow'; + readonly head: 'bui-TableHead'; + readonly headContent: 'bui-TableHeadContent'; + readonly headSortButton: 'bui-TableHeadSortButton'; + readonly caption: 'bui-TableCaption'; + readonly cell: 'bui-TableCell'; + readonly cellContentWrapper: 'bui-TableCellContentWrapper'; + readonly cellContent: 'bui-TableCellContent'; + readonly cellIcon: 'bui-TableCellIcon'; + readonly cellProfileAvatar: 'bui-TableCellProfileAvatar'; + readonly cellProfileAvatarImage: 'bui-TableCellProfileAvatarImage'; + readonly cellProfileAvatarFallback: 'bui-TableCellProfileAvatarFallback'; + readonly cellProfileName: 'bui-TableCellProfileName'; + readonly cellProfileLink: 'bui-TableCellProfileLink'; + }; +}; + // @public (undocumented) export const TableHeader: ( props: TableHeaderProps, @@ -1353,6 +1276,16 @@ export const TableHeader: ( // @public export function TablePagination(props: TablePaginationProps): JSX_2.Element; +// @public +export const TablePaginationDefinition: { + readonly classNames: { + readonly root: 'bui-TablePagination'; + readonly left: 'bui-TablePaginationLeft'; + readonly right: 'bui-TablePaginationRight'; + readonly select: 'bui-TablePaginationSelect'; + }; +}; + // @public (undocumented) export interface TablePaginationProps extends React.HTMLAttributes { @@ -1399,6 +1332,19 @@ export interface TabProps extends TabProps_2 { // @public export const Tabs: (props: TabsProps) => JSX_2.Element | null; +// @public +export const TabsDefinition: { + readonly classNames: { + readonly tabs: 'bui-Tabs'; + readonly tabList: 'bui-TabList'; + readonly tabListWrapper: 'bui-TabListWrapper'; + readonly tab: 'bui-Tab'; + readonly tabActive: 'bui-TabActive'; + readonly tabHovered: 'bui-TabHovered'; + readonly panel: 'bui-TabPanel'; + }; +}; + // @public export interface TabsProps extends TabsProps_2 {} @@ -1410,6 +1356,17 @@ export const TagGroup: ( props: TagGroupProps, ) => JSX_2.Element; +// @public +export const TagGroupDefinition: { + readonly classNames: { + readonly group: 'bui-TagGroup'; + readonly list: 'bui-TagList'; + readonly tag: 'bui-Tag'; + readonly tagIcon: 'bui-TagIcon'; + readonly tagRemoveButton: 'bui-TagRemoveButton'; + }; +}; + // @public export interface TagGroupProps extends Omit, @@ -1438,11 +1395,46 @@ export type TextColors = 'primary' | 'secondary'; // @public (undocumented) export type TextColorStatus = 'danger' | 'warning' | 'success'; +// @public +export const TextDefinition: { + readonly classNames: { + readonly root: 'bui-Text'; + }; + readonly dataAttributes: { + readonly variant: readonly ['subtitle', 'body', 'caption', 'label']; + readonly weight: readonly ['regular', 'bold']; + readonly color: readonly [ + 'primary', + 'secondary', + 'danger', + 'warning', + 'success', + ]; + readonly truncate: readonly [true, false]; + }; +}; + // @public (undocumented) export const TextField: ForwardRefExoticComponent< TextFieldProps & RefAttributes >; +// @public +export const TextFieldDefinition: { + readonly classNames: { + readonly root: 'bui-TextField'; + readonly inputWrapper: 'bui-InputWrapper'; + readonly input: 'bui-Input'; + readonly inputIcon: 'bui-InputIcon'; + readonly inputAction: 'bui-InputAction'; + }; + readonly dataAttributes: { + readonly invalid: readonly [true, false]; + readonly disabled: readonly [true, false]; + readonly size: readonly ['small', 'medium']; + }; +}; + // @public (undocumented) export interface TextFieldProps extends TextFieldProps_2, @@ -1502,6 +1494,14 @@ export const Tooltip: ForwardRefExoticComponent< TooltipProps & RefAttributes >; +// @public +export const TooltipDefinition: { + readonly classNames: { + readonly tooltip: 'bui-Tooltip'; + readonly arrow: 'bui-TooltipArrow'; + }; +}; + // @public (undocumented) export interface TooltipProps extends Omit { // (undocumented) @@ -1597,6 +1597,13 @@ export interface UtilityProps extends SpaceProps { // @public export const VisuallyHidden: (props: VisuallyHiddenProps) => JSX_2.Element; +// @public +export const VisuallyHiddenDefinition: { + readonly classNames: { + readonly root: 'bui-VisuallyHidden'; + }; +}; + // @public export interface VisuallyHiddenProps extends ComponentProps<'div'> { // (undocumented) diff --git a/packages/ui/src/components/Accordion/Accordion.tsx b/packages/ui/src/components/Accordion/Accordion.tsx index 3f35ab7554..f31b923490 100644 --- a/packages/ui/src/components/Accordion/Accordion.tsx +++ b/packages/ui/src/components/Accordion/Accordion.tsx @@ -31,6 +31,7 @@ import type { AccordionGroupProps, } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { AccordionDefinition } from './definition'; import styles from './Accordion.module.css'; import { Flex } from '../Flex'; @@ -39,7 +40,7 @@ export const Accordion = forwardRef< React.ElementRef, AccordionProps >(({ className, ...props }, ref) => { - const { classNames, cleanedProps } = useStyles('Accordion', props); + const { classNames, cleanedProps } = useStyles(AccordionDefinition, props); return ( , AccordionTriggerProps >(({ className, title, subtitle, children, ...props }, ref) => { - const { classNames, cleanedProps } = useStyles('Accordion', props); + const { classNames, cleanedProps } = useStyles(AccordionDefinition, props); return ( , AccordionPanelProps >(({ className, ...props }, ref) => { - const { classNames, cleanedProps } = useStyles('Accordion', props); + const { classNames, cleanedProps } = useStyles(AccordionDefinition, props); return ( , AccordionGroupProps >(({ className, allowsMultiple = false, ...props }, ref) => { - const { classNames, cleanedProps } = useStyles('Accordion', props); + const { classNames, cleanedProps } = useStyles(AccordionDefinition, props); return ( ((props, ref) => { - const { classNames, dataAttributes, cleanedProps } = useStyles('Avatar', { - size: 'medium', - purpose: 'informative', - ...props, - }); + const { classNames, dataAttributes, cleanedProps } = useStyles( + AvatarDefinition, + { + size: 'medium', + purpose: 'informative', + ...props, + }, + ); const { className, src, name, purpose, ...rest } = cleanedProps; diff --git a/packages/ui/src/components/Avatar/definition.ts b/packages/ui/src/components/Avatar/definition.ts new file mode 100644 index 0000000000..8ad2c31bdc --- /dev/null +++ b/packages/ui/src/components/Avatar/definition.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Avatar + * @public + */ +export const AvatarDefinition = { + classNames: { + root: 'bui-AvatarRoot', + image: 'bui-AvatarImage', + fallback: 'bui-AvatarFallback', + }, + dataAttributes: { + size: ['small', 'medium', 'large'] as const, + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Avatar/index.ts b/packages/ui/src/components/Avatar/index.ts index d5ab42beb2..38e896bdb4 100644 --- a/packages/ui/src/components/Avatar/index.ts +++ b/packages/ui/src/components/Avatar/index.ts @@ -15,4 +15,5 @@ */ export { Avatar } from './Avatar'; +export { AvatarDefinition } from './definition'; export type { AvatarProps } from './types'; diff --git a/packages/ui/src/components/Box/Box.tsx b/packages/ui/src/components/Box/Box.tsx index fdcee3d382..34c337824b 100644 --- a/packages/ui/src/components/Box/Box.tsx +++ b/packages/ui/src/components/Box/Box.tsx @@ -19,11 +19,12 @@ import { BoxProps } from './types'; import clsx from 'clsx'; import { useStyles } from '../../hooks/useStyles'; import styles from './Box.module.css'; +import { BoxDefinition } from './definition'; /** @public */ export const Box = forwardRef((props, ref) => { const { classNames, utilityClasses, style, cleanedProps } = useStyles( - 'Box', + BoxDefinition, props, ); diff --git a/packages/ui/src/components/Box/definition.ts b/packages/ui/src/components/Box/definition.ts new file mode 100644 index 0000000000..f5b6fc6553 --- /dev/null +++ b/packages/ui/src/components/Box/definition.ts @@ -0,0 +1,51 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Box + * @public + */ +export const BoxDefinition = { + classNames: { + root: 'bui-Box', + }, + utilityProps: [ + 'm', + 'mb', + 'ml', + 'mr', + 'mt', + 'mx', + 'my', + 'p', + 'pb', + 'pl', + 'pr', + 'pt', + 'px', + 'py', + 'position', + 'display', + 'width', + 'minWidth', + 'maxWidth', + 'height', + 'minHeight', + 'maxHeight', + ], +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Box/index.tsx b/packages/ui/src/components/Box/index.tsx index d47e653dfd..a2b2861efb 100644 --- a/packages/ui/src/components/Box/index.tsx +++ b/packages/ui/src/components/Box/index.tsx @@ -14,4 +14,5 @@ * limitations under the License. */ export { Box } from './Box'; +export { BoxDefinition } from './definition'; export type * from './types'; diff --git a/packages/ui/src/components/Button/Button.tsx b/packages/ui/src/components/Button/Button.tsx index 45228ff6ef..f010e5e57d 100644 --- a/packages/ui/src/components/Button/Button.tsx +++ b/packages/ui/src/components/Button/Button.tsx @@ -20,16 +20,20 @@ import { Button as RAButton, ProgressBar } from 'react-aria-components'; import { RiLoader4Line } from '@remixicon/react'; import type { ButtonProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { ButtonDefinition } from './definition'; import styles from './Button.module.css'; /** @public */ export const Button = forwardRef( (props: ButtonProps, ref: Ref) => { - const { classNames, dataAttributes, cleanedProps } = useStyles('Button', { - size: 'small', - variant: 'primary', - ...props, - }); + const { classNames, dataAttributes, cleanedProps } = useStyles( + ButtonDefinition, + { + size: 'small', + variant: 'primary', + ...props, + }, + ); const { children, className, iconStart, iconEnd, loading, ...rest } = cleanedProps; diff --git a/packages/ui/src/components/Button/definition.ts b/packages/ui/src/components/Button/definition.ts new file mode 100644 index 0000000000..a017157774 --- /dev/null +++ b/packages/ui/src/components/Button/definition.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Button + * @public + */ +export const ButtonDefinition = { + classNames: { + root: 'bui-Button', + content: 'bui-ButtonContent', + spinner: 'bui-ButtonSpinner', + }, + dataAttributes: { + size: ['small', 'medium', 'large'] as const, + variant: ['primary', 'secondary', 'tertiary'] as const, + loading: [true, false] as const, + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Button/index.ts b/packages/ui/src/components/Button/index.ts index b9c497ae1f..e624fcedde 100644 --- a/packages/ui/src/components/Button/index.ts +++ b/packages/ui/src/components/Button/index.ts @@ -16,3 +16,4 @@ export * from './Button'; export * from './types'; +export { ButtonDefinition } from './definition'; diff --git a/packages/ui/src/components/ButtonIcon/ButtonIcon.tsx b/packages/ui/src/components/ButtonIcon/ButtonIcon.tsx index fecccd6a37..d3596da799 100644 --- a/packages/ui/src/components/ButtonIcon/ButtonIcon.tsx +++ b/packages/ui/src/components/ButtonIcon/ButtonIcon.tsx @@ -20,19 +20,25 @@ import { Button as RAButton, ProgressBar } from 'react-aria-components'; import { RiLoader4Line } from '@remixicon/react'; import type { ButtonIconProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { ButtonDefinition } from '../Button/definition'; +import { ButtonIconDefinition } from './definition'; import stylesButtonIcon from './ButtonIcon.module.css'; import stylesButton from '../Button/Button.module.css'; /** @public */ export const ButtonIcon = forwardRef( (props: ButtonIconProps, ref: Ref) => { - const { classNames, dataAttributes, cleanedProps } = useStyles('Button', { - size: 'small', - variant: 'primary', - ...props, - }); + const { classNames, dataAttributes, cleanedProps } = useStyles( + ButtonDefinition, + { + size: 'small', + variant: 'primary', + ...props, + }, + ); - const { classNames: classNamesButtonIcon } = useStyles('ButtonIcon'); + const { classNames: classNamesButtonIcon } = + useStyles(ButtonIconDefinition); const { className, icon, loading, ...rest } = cleanedProps; diff --git a/packages/ui/src/components/ButtonIcon/definition.ts b/packages/ui/src/components/ButtonIcon/definition.ts new file mode 100644 index 0000000000..48d0a558ab --- /dev/null +++ b/packages/ui/src/components/ButtonIcon/definition.ts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for ButtonIcon + * @public + */ +export const ButtonIconDefinition = { + classNames: { + root: 'bui-ButtonIcon', + content: 'bui-ButtonIconContent', + spinner: 'bui-ButtonIconSpinner', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/ButtonIcon/index.tsx b/packages/ui/src/components/ButtonIcon/index.tsx index 686fd844e8..acede912ad 100644 --- a/packages/ui/src/components/ButtonIcon/index.tsx +++ b/packages/ui/src/components/ButtonIcon/index.tsx @@ -15,4 +15,5 @@ */ export * from './ButtonIcon'; +export { ButtonIconDefinition } from './definition'; export * from './types'; diff --git a/packages/ui/src/components/ButtonLink/ButtonLink.tsx b/packages/ui/src/components/ButtonLink/ButtonLink.tsx index 28a67105bb..db3c95ee54 100644 --- a/packages/ui/src/components/ButtonLink/ButtonLink.tsx +++ b/packages/ui/src/components/ButtonLink/ButtonLink.tsx @@ -20,6 +20,8 @@ import { Link as RALink, RouterProvider } from 'react-aria-components'; import { useNavigate, useHref } from 'react-router-dom'; import type { ButtonLinkProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { ButtonDefinition } from '../Button/definition'; +import { ButtonLinkDefinition } from './definition'; import { isExternalLink } from '../../utils/isExternalLink'; import stylesButton from '../Button/Button.module.css'; @@ -28,13 +30,17 @@ export const ButtonLink = forwardRef( (props: ButtonLinkProps, ref: Ref) => { const navigate = useNavigate(); - const { classNames, dataAttributes, cleanedProps } = useStyles('Button', { - size: 'small', - variant: 'primary', - ...props, - }); + const { classNames, dataAttributes, cleanedProps } = useStyles( + ButtonDefinition, + { + size: 'small', + variant: 'primary', + ...props, + }, + ); - const { classNames: classNamesButtonLink } = useStyles('ButtonLink'); + const { classNames: classNamesButtonLink } = + useStyles(ButtonLinkDefinition); const { children, className, iconStart, iconEnd, href, ...rest } = cleanedProps; diff --git a/packages/ui/src/components/ButtonLink/definition.ts b/packages/ui/src/components/ButtonLink/definition.ts new file mode 100644 index 0000000000..daf3fae1ea --- /dev/null +++ b/packages/ui/src/components/ButtonLink/definition.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for ButtonLink + * @public + */ +export const ButtonLinkDefinition = { + classNames: { + root: 'bui-ButtonLink', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/ButtonLink/index.ts b/packages/ui/src/components/ButtonLink/index.ts index bbfc696c67..b98f84d489 100644 --- a/packages/ui/src/components/ButtonLink/index.ts +++ b/packages/ui/src/components/ButtonLink/index.ts @@ -15,4 +15,5 @@ */ export * from './ButtonLink'; +export { ButtonLinkDefinition } from './definition'; export * from './types'; diff --git a/packages/ui/src/components/Card/Card.tsx b/packages/ui/src/components/Card/Card.tsx index b942b70649..a3f4995588 100644 --- a/packages/ui/src/components/Card/Card.tsx +++ b/packages/ui/src/components/Card/Card.tsx @@ -17,6 +17,7 @@ import { forwardRef } from 'react'; import clsx from 'clsx'; import { useStyles } from '../../hooks/useStyles'; +import { CardDefinition } from './definition'; import type { CardProps, CardHeaderProps, @@ -31,7 +32,7 @@ import styles from './Card.module.css'; * @public */ export const Card = forwardRef((props, ref) => { - const { classNames, cleanedProps } = useStyles('Card', props); + const { classNames, cleanedProps } = useStyles(CardDefinition, props); const { className, ...rest } = cleanedProps; return ( @@ -50,7 +51,7 @@ export const Card = forwardRef((props, ref) => { */ export const CardHeader = forwardRef( (props, ref) => { - const { classNames, cleanedProps } = useStyles('Card', props); + const { classNames, cleanedProps } = useStyles(CardDefinition, props); const { className, ...rest } = cleanedProps; return ( @@ -74,7 +75,7 @@ export const CardHeader = forwardRef( */ export const CardBody = forwardRef( (props, ref) => { - const { classNames, cleanedProps } = useStyles('Card', props); + const { classNames, cleanedProps } = useStyles(CardDefinition, props); const { className, ...rest } = cleanedProps; return ( @@ -94,7 +95,7 @@ export const CardBody = forwardRef( */ export const CardFooter = forwardRef( (props, ref) => { - const { classNames, cleanedProps } = useStyles('Card', props); + const { classNames, cleanedProps } = useStyles(CardDefinition, props); const { className, ...rest } = cleanedProps; return ( diff --git a/packages/ui/src/components/Card/definition.ts b/packages/ui/src/components/Card/definition.ts new file mode 100644 index 0000000000..cd0c5f634b --- /dev/null +++ b/packages/ui/src/components/Card/definition.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Card + * @public + */ +export const CardDefinition = { + classNames: { + root: 'bui-Card', + header: 'bui-CardHeader', + body: 'bui-CardBody', + footer: 'bui-CardFooter', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Card/index.ts b/packages/ui/src/components/Card/index.ts index 4b710ee7f1..dc7dbd4ead 100644 --- a/packages/ui/src/components/Card/index.ts +++ b/packages/ui/src/components/Card/index.ts @@ -15,6 +15,7 @@ */ export { Card, CardHeader, CardBody, CardFooter } from './Card'; +export { CardDefinition } from './definition'; export type { CardProps, diff --git a/packages/ui/src/components/Checkbox/Checkbox.tsx b/packages/ui/src/components/Checkbox/Checkbox.tsx index 49019370a4..97a603daf2 100644 --- a/packages/ui/src/components/Checkbox/Checkbox.tsx +++ b/packages/ui/src/components/Checkbox/Checkbox.tsx @@ -18,6 +18,7 @@ import { forwardRef } from 'react'; import { Checkbox as RACheckbox } from 'react-aria-components'; import type { CheckboxProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { CheckboxDefinition } from './definition'; import clsx from 'clsx'; import styles from './Checkbox.module.css'; import { RiCheckLine } from '@remixicon/react'; @@ -25,7 +26,7 @@ import { RiCheckLine } from '@remixicon/react'; /** @public */ export const Checkbox = forwardRef( (props, ref) => { - const { classNames } = useStyles('Checkbox'); + const { classNames } = useStyles(CheckboxDefinition); const { className, children, ...rest } = props; return ( diff --git a/packages/ui/src/components/Checkbox/definition.ts b/packages/ui/src/components/Checkbox/definition.ts new file mode 100644 index 0000000000..022f2a0af1 --- /dev/null +++ b/packages/ui/src/components/Checkbox/definition.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Checkbox + * @public + */ +export const CheckboxDefinition = { + classNames: { + root: 'bui-Checkbox', + indicator: 'bui-CheckboxIndicator', + }, + dataAttributes: { + selected: [true, false] as const, + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Checkbox/index.ts b/packages/ui/src/components/Checkbox/index.ts index f6dfbf6beb..7c0cb5b414 100644 --- a/packages/ui/src/components/Checkbox/index.ts +++ b/packages/ui/src/components/Checkbox/index.ts @@ -14,4 +14,5 @@ * limitations under the License. */ export { Checkbox } from './Checkbox'; +export { CheckboxDefinition } from './definition'; export type { CheckboxProps } from './types'; diff --git a/packages/ui/src/components/Container/Container.tsx b/packages/ui/src/components/Container/Container.tsx index 9b15cd162e..7e3627f0b9 100644 --- a/packages/ui/src/components/Container/Container.tsx +++ b/packages/ui/src/components/Container/Container.tsx @@ -18,13 +18,14 @@ import { forwardRef } from 'react'; import { ContainerProps } from './types'; import clsx from 'clsx'; import { useStyles } from '../../hooks/useStyles'; +import { ContainerDefinition } from './definition'; import styles from './Container.module.css'; /** @public */ export const Container = forwardRef( (props, ref) => { const { classNames, utilityClasses, style, cleanedProps } = useStyles( - 'Container', + ContainerDefinition, props, ); diff --git a/packages/ui/src/components/Container/definition.ts b/packages/ui/src/components/Container/definition.ts new file mode 100644 index 0000000000..330e6adf2f --- /dev/null +++ b/packages/ui/src/components/Container/definition.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Container + * @public + */ +export const ContainerDefinition = { + classNames: { + root: 'bui-Container', + }, + utilityProps: ['my', 'mt', 'mb', 'py', 'pt', 'pb', 'display'], +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Container/index.tsx b/packages/ui/src/components/Container/index.tsx index 81614c352d..73d1a0ab6e 100644 --- a/packages/ui/src/components/Container/index.tsx +++ b/packages/ui/src/components/Container/index.tsx @@ -14,4 +14,5 @@ * limitations under the License. */ export { Container } from './Container'; +export { ContainerDefinition } from './definition'; export type { ContainerProps } from './types'; diff --git a/packages/ui/src/components/Dialog/Dialog.tsx b/packages/ui/src/components/Dialog/Dialog.tsx index 5dcd421b04..1c33588306 100644 --- a/packages/ui/src/components/Dialog/Dialog.tsx +++ b/packages/ui/src/components/Dialog/Dialog.tsx @@ -31,6 +31,7 @@ import type { import { RiCloseLine } from '@remixicon/react'; import { Button } from '../Button'; import { useStyles } from '../../hooks/useStyles'; +import { DialogDefinition } from './definition'; import { Flex } from '../Flex'; import styles from './Dialog.module.css'; @@ -42,7 +43,7 @@ export const DialogTrigger = (props: DialogTriggerProps) => { /** @public */ export const Dialog = forwardRef, DialogProps>( (props, ref) => { - const { classNames, cleanedProps } = useStyles('Dialog', props); + const { classNames, cleanedProps } = useStyles(DialogDefinition, props); const { className, children, width, height, style, ...rest } = cleanedProps; return ( @@ -84,7 +85,7 @@ export const DialogHeader = forwardRef< React.ElementRef<'div'>, DialogHeaderProps >((props, ref) => { - const { classNames, cleanedProps } = useStyles('Dialog', props); + const { classNames, cleanedProps } = useStyles(DialogDefinition, props); const { className, children, ...rest } = cleanedProps; return ( @@ -110,7 +111,7 @@ DialogHeader.displayName = 'DialogHeader'; /** @public */ export const DialogBody = forwardRef, DialogBodyProps>( (props, ref) => { - const { classNames, cleanedProps } = useStyles('Dialog', props); + const { classNames, cleanedProps } = useStyles(DialogDefinition, props); const { className, children, ...rest } = cleanedProps; return ( @@ -132,7 +133,7 @@ export const DialogFooter = forwardRef< React.ElementRef<'div'>, React.ComponentPropsWithoutRef<'div'> >((props, ref) => { - const { classNames, cleanedProps } = useStyles('Dialog', props); + const { classNames, cleanedProps } = useStyles(DialogDefinition, props); const { className, children, ...rest } = cleanedProps; return ( diff --git a/packages/ui/src/components/Dialog/definition.ts b/packages/ui/src/components/Dialog/definition.ts new file mode 100644 index 0000000000..d2fcb7bb4d --- /dev/null +++ b/packages/ui/src/components/Dialog/definition.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Dialog + * @public + */ +export const DialogDefinition = { + classNames: { + overlay: 'bui-DialogOverlay', + dialog: 'bui-Dialog', + header: 'bui-DialogHeader', + headerTitle: 'bui-DialogHeaderTitle', + body: 'bui-DialogBody', + footer: 'bui-DialogFooter', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Dialog/index.ts b/packages/ui/src/components/Dialog/index.ts index 8db1b29ff8..57dc8aae4b 100644 --- a/packages/ui/src/components/Dialog/index.ts +++ b/packages/ui/src/components/Dialog/index.ts @@ -14,4 +14,5 @@ * limitations under the License. */ export * from './Dialog'; +export { DialogDefinition } from './definition'; export * from './types'; diff --git a/packages/ui/src/components/FieldError/FieldError.tsx b/packages/ui/src/components/FieldError/FieldError.tsx index 4c4bfb9455..0016486fe7 100644 --- a/packages/ui/src/components/FieldError/FieldError.tsx +++ b/packages/ui/src/components/FieldError/FieldError.tsx @@ -22,11 +22,12 @@ import { import clsx from 'clsx'; import styles from './FieldError.module.css'; import { useStyles } from '../../hooks/useStyles'; +import { FieldErrorDefinition } from './definition'; /** @public */ export const FieldError = forwardRef( (props: FieldErrorProps, ref) => { - const { classNames, cleanedProps } = useStyles('FieldError', props); + const { classNames, cleanedProps } = useStyles(FieldErrorDefinition, props); const { className, ...rest } = cleanedProps; return ( diff --git a/packages/ui/src/components/FieldError/definition.ts b/packages/ui/src/components/FieldError/definition.ts new file mode 100644 index 0000000000..d7174dfc99 --- /dev/null +++ b/packages/ui/src/components/FieldError/definition.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for FieldError + * @public + */ +export const FieldErrorDefinition = { + classNames: { + root: 'bui-FieldError', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/FieldError/index.ts b/packages/ui/src/components/FieldError/index.ts index 5b61f83ace..1d3abf8398 100644 --- a/packages/ui/src/components/FieldError/index.ts +++ b/packages/ui/src/components/FieldError/index.ts @@ -15,3 +15,4 @@ */ export * from './FieldError'; +export { FieldErrorDefinition } from './definition'; diff --git a/packages/ui/src/components/FieldLabel/FieldLabel.tsx b/packages/ui/src/components/FieldLabel/FieldLabel.tsx index 5b27dd876f..3c685f9479 100644 --- a/packages/ui/src/components/FieldLabel/FieldLabel.tsx +++ b/packages/ui/src/components/FieldLabel/FieldLabel.tsx @@ -17,13 +17,14 @@ import { Label } from 'react-aria-components'; import { forwardRef } from 'react'; import type { FieldLabelProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { FieldLabelDefinition } from './definition'; import styles from './FieldLabel.module.css'; import clsx from 'clsx'; /** @public */ export const FieldLabel = forwardRef( (props: FieldLabelProps, ref) => { - const { classNames, cleanedProps } = useStyles('FieldLabel', props); + const { classNames, cleanedProps } = useStyles(FieldLabelDefinition, props); const { className, label, diff --git a/packages/ui/src/components/FieldLabel/definition.ts b/packages/ui/src/components/FieldLabel/definition.ts new file mode 100644 index 0000000000..d6833a9478 --- /dev/null +++ b/packages/ui/src/components/FieldLabel/definition.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for FieldLabel + * @public + */ +export const FieldLabelDefinition = { + classNames: { + root: 'bui-FieldLabelWrapper', + label: 'bui-FieldLabel', + secondaryLabel: 'bui-FieldSecondaryLabel', + description: 'bui-FieldDescription', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/FieldLabel/index.ts b/packages/ui/src/components/FieldLabel/index.ts index b9cebb1bf7..0b4a8adf5f 100644 --- a/packages/ui/src/components/FieldLabel/index.ts +++ b/packages/ui/src/components/FieldLabel/index.ts @@ -15,4 +15,5 @@ */ export * from './FieldLabel'; +export { FieldLabelDefinition } from './definition'; export * from './types'; diff --git a/packages/ui/src/components/Flex/Flex.tsx b/packages/ui/src/components/Flex/Flex.tsx index 27564539bd..878bcfe0ea 100644 --- a/packages/ui/src/components/Flex/Flex.tsx +++ b/packages/ui/src/components/Flex/Flex.tsx @@ -18,12 +18,13 @@ import { forwardRef } from 'react'; import { FlexProps } from './types'; import clsx from 'clsx'; import { useStyles } from '../../hooks/useStyles'; +import { FlexDefinition } from './definition'; import styles from './Flex.module.css'; /** @public */ export const Flex = forwardRef((props, ref) => { const { classNames, utilityClasses, style, cleanedProps } = useStyles( - 'Flex', + FlexDefinition, { gap: '4', ...props }, ); diff --git a/packages/ui/src/components/Flex/definition.ts b/packages/ui/src/components/Flex/definition.ts new file mode 100644 index 0000000000..d6902e2f47 --- /dev/null +++ b/packages/ui/src/components/Flex/definition.ts @@ -0,0 +1,47 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Flex + * @public + */ +export const FlexDefinition = { + classNames: { + root: 'bui-Flex', + }, + utilityProps: [ + 'm', + 'mb', + 'ml', + 'mr', + 'mt', + 'mx', + 'my', + 'p', + 'pb', + 'pl', + 'pr', + 'pt', + 'px', + 'py', + 'gap', + 'align', + 'justify', + 'direction', + ], +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Flex/index.ts b/packages/ui/src/components/Flex/index.ts index 4e4c883119..c9c5890ad9 100644 --- a/packages/ui/src/components/Flex/index.ts +++ b/packages/ui/src/components/Flex/index.ts @@ -14,4 +14,5 @@ * limitations under the License. */ export { Flex } from './Flex'; +export { FlexDefinition } from './definition'; export type { FlexProps } from './types'; diff --git a/packages/ui/src/components/Grid/Grid.tsx b/packages/ui/src/components/Grid/Grid.tsx index 61cd2fb7c7..aa30d25fc0 100644 --- a/packages/ui/src/components/Grid/Grid.tsx +++ b/packages/ui/src/components/Grid/Grid.tsx @@ -18,11 +18,12 @@ import { forwardRef } from 'react'; import clsx from 'clsx'; import type { GridItemProps, GridProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { GridDefinition, GridItemDefinition } from './definition'; import styles from './Grid.module.css'; const GridRoot = forwardRef((props, ref) => { const { classNames, utilityClasses, style, cleanedProps } = useStyles( - 'Grid', + GridDefinition, { columns: 'auto', gap: '4', ...props }, ); @@ -45,7 +46,7 @@ const GridRoot = forwardRef((props, ref) => { const GridItem = forwardRef((props, ref) => { const { classNames, utilityClasses, style, cleanedProps } = useStyles( - 'GridItem', + GridItemDefinition, props, ); diff --git a/packages/ui/src/components/Grid/definition.ts b/packages/ui/src/components/Grid/definition.ts new file mode 100644 index 0000000000..201ef4dc66 --- /dev/null +++ b/packages/ui/src/components/Grid/definition.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Grid + * @public + */ +export const GridDefinition = { + classNames: { + root: 'bui-Grid', + }, + utilityProps: [ + 'columns', + 'gap', + 'm', + 'mb', + 'ml', + 'mr', + 'mt', + 'mx', + 'my', + 'p', + 'pb', + 'pl', + 'pr', + 'pt', + 'px', + 'py', + ], +} as const satisfies ComponentDefinition; + +/** + * Component definition for GridItem + * @public + */ +export const GridItemDefinition = { + classNames: { + root: 'bui-GridItem', + }, + utilityProps: ['colSpan', 'colEnd', 'colStart', 'rowSpan'], +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Grid/index.ts b/packages/ui/src/components/Grid/index.ts index 870ab55856..aa95e3370e 100644 --- a/packages/ui/src/components/Grid/index.ts +++ b/packages/ui/src/components/Grid/index.ts @@ -15,4 +15,5 @@ */ export { Grid } from './Grid'; +export { GridDefinition, GridItemDefinition } from './definition'; export type { GridProps, GridItemProps } from './types'; diff --git a/packages/ui/src/components/Header/Header.tsx b/packages/ui/src/components/Header/Header.tsx index 6f42820be4..56ec200e29 100644 --- a/packages/ui/src/components/Header/Header.tsx +++ b/packages/ui/src/components/Header/Header.tsx @@ -18,6 +18,7 @@ import type { HeaderProps } from './types'; import { HeaderToolbar } from './HeaderToolbar'; import { Tabs, TabList, Tab } from '../Tabs'; import { useStyles } from '../../hooks/useStyles'; +import { HeaderDefinition } from './definition'; import { type NavigateOptions } from 'react-router-dom'; import styles from './Header.module.css'; import clsx from 'clsx'; @@ -34,7 +35,7 @@ declare module 'react-aria-components' { * @public */ export const Header = (props: HeaderProps) => { - const { classNames, cleanedProps } = useStyles('Header', props); + const { classNames, cleanedProps } = useStyles(HeaderDefinition, props); const { className, tabs, diff --git a/packages/ui/src/components/Header/HeaderToolbar.tsx b/packages/ui/src/components/Header/HeaderToolbar.tsx index 373f3462be..6ba03ab3a6 100644 --- a/packages/ui/src/components/Header/HeaderToolbar.tsx +++ b/packages/ui/src/components/Header/HeaderToolbar.tsx @@ -16,6 +16,7 @@ import { Link } from 'react-aria-components'; import { useStyles } from '../../hooks/useStyles'; +import { HeaderDefinition } from './definition'; import { useRef } from 'react'; import { RiShapesLine } from '@remixicon/react'; import type { HeaderToolbarProps } from './types'; @@ -29,7 +30,7 @@ import clsx from 'clsx'; * @internal */ export const HeaderToolbar = (props: HeaderToolbarProps) => { - const { classNames, cleanedProps } = useStyles('Header', props); + const { classNames, cleanedProps } = useStyles(HeaderDefinition, props); const { className, icon, title, titleLink, customActions, hasTabs } = cleanedProps; diff --git a/packages/ui/src/components/Header/definition.ts b/packages/ui/src/components/Header/definition.ts new file mode 100644 index 0000000000..5969d7d8fa --- /dev/null +++ b/packages/ui/src/components/Header/definition.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Header + * @public + */ +export const HeaderDefinition = { + classNames: { + toolbar: 'bui-HeaderToolbar', + toolbarWrapper: 'bui-HeaderToolbarWrapper', + toolbarContent: 'bui-HeaderToolbarContent', + toolbarControls: 'bui-HeaderToolbarControls', + toolbarIcon: 'bui-HeaderToolbarIcon', + toolbarName: 'bui-HeaderToolbarName', + tabsWrapper: 'bui-HeaderTabsWrapper', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Header/index.tsx b/packages/ui/src/components/Header/index.tsx index b0ae2821b2..60685cfaa6 100644 --- a/packages/ui/src/components/Header/index.tsx +++ b/packages/ui/src/components/Header/index.tsx @@ -15,4 +15,5 @@ */ export { Header } from './Header'; +export { HeaderDefinition } from './definition'; export type { HeaderProps, HeaderTab } from './types'; diff --git a/packages/ui/src/components/HeaderPage/HeaderPage.tsx b/packages/ui/src/components/HeaderPage/HeaderPage.tsx index 6fcbbe258b..efa7ea8d58 100644 --- a/packages/ui/src/components/HeaderPage/HeaderPage.tsx +++ b/packages/ui/src/components/HeaderPage/HeaderPage.tsx @@ -19,6 +19,7 @@ import { Text } from '../Text'; import { RiArrowRightSLine } from '@remixicon/react'; import { Tabs, TabList, Tab } from '../Tabs'; import { useStyles } from '../../hooks/useStyles'; +import { HeaderPageDefinition } from './definition'; import { Container } from '../Container'; import { Link } from '../Link'; import { Fragment } from 'react/jsx-runtime'; @@ -31,7 +32,7 @@ import clsx from 'clsx'; * @public */ export const HeaderPage = (props: HeaderPageProps) => { - const { classNames, cleanedProps } = useStyles('HeaderPage', props); + const { classNames, cleanedProps } = useStyles(HeaderPageDefinition, props); const { className, title, tabs, customActions, breadcrumbs } = cleanedProps; return ( diff --git a/packages/ui/src/components/HeaderPage/definition.ts b/packages/ui/src/components/HeaderPage/definition.ts new file mode 100644 index 0000000000..be93aaae6a --- /dev/null +++ b/packages/ui/src/components/HeaderPage/definition.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for HeaderPage + * @public + */ +export const HeaderPageDefinition = { + classNames: { + root: 'bui-HeaderPage', + content: 'bui-HeaderPageContent', + breadcrumbs: 'bui-HeaderPageBreadcrumbs', + tabsWrapper: 'bui-HeaderPageTabsWrapper', + controls: 'bui-HeaderPageControls', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/HeaderPage/index.tsx b/packages/ui/src/components/HeaderPage/index.tsx index 040d226a1f..7b277149f1 100644 --- a/packages/ui/src/components/HeaderPage/index.tsx +++ b/packages/ui/src/components/HeaderPage/index.tsx @@ -15,4 +15,5 @@ */ export { HeaderPage } from './HeaderPage'; +export { HeaderPageDefinition } from './definition'; export type { HeaderPageProps, HeaderPageBreadcrumb } from './types'; diff --git a/packages/ui/src/components/Link/Link.tsx b/packages/ui/src/components/Link/Link.tsx index c121fd9551..56b0cae5bb 100644 --- a/packages/ui/src/components/Link/Link.tsx +++ b/packages/ui/src/components/Link/Link.tsx @@ -18,6 +18,7 @@ import { forwardRef } from 'react'; import { Link as AriaLink, RouterProvider } from 'react-aria-components'; import clsx from 'clsx'; import { useStyles } from '../../hooks/useStyles'; +import { LinkDefinition } from './definition'; import type { LinkProps } from './types'; import { useNavigate, useHref } from 'react-router-dom'; import { isExternalLink } from '../../utils/isExternalLink'; @@ -26,12 +27,15 @@ import styles from './Link.module.css'; /** @public */ export const Link = forwardRef((props, ref) => { const navigate = useNavigate(); - const { classNames, dataAttributes, cleanedProps } = useStyles('Link', { - variant: 'body', - weight: 'regular', - color: 'primary', - ...props, - }); + const { classNames, dataAttributes, cleanedProps } = useStyles( + LinkDefinition, + { + variant: 'body', + weight: 'regular', + color: 'primary', + ...props, + }, + ); const { className, href, ...restProps } = cleanedProps; diff --git a/packages/ui/src/components/Link/definition.ts b/packages/ui/src/components/Link/definition.ts new file mode 100644 index 0000000000..cece929f11 --- /dev/null +++ b/packages/ui/src/components/Link/definition.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Link + * @public + */ +export const LinkDefinition = { + classNames: { + root: 'bui-Link', + }, + dataAttributes: { + variant: ['subtitle', 'body', 'caption', 'label'] as const, + weight: ['regular', 'bold'] as const, + color: ['primary', 'secondary', 'danger', 'warning', 'success'] as const, + truncate: [true, false] as const, + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Link/index.ts b/packages/ui/src/components/Link/index.ts index 1b38e89d62..7c17668029 100644 --- a/packages/ui/src/components/Link/index.ts +++ b/packages/ui/src/components/Link/index.ts @@ -15,4 +15,5 @@ */ export { Link } from './Link'; +export { LinkDefinition } from './definition'; export type { LinkProps } from './types'; diff --git a/packages/ui/src/components/Menu/Menu.tsx b/packages/ui/src/components/Menu/Menu.tsx index 6edbeaca20..12048776be 100644 --- a/packages/ui/src/components/Menu/Menu.tsx +++ b/packages/ui/src/components/Menu/Menu.tsx @@ -36,6 +36,7 @@ import { OverlayTriggerStateContext, } from 'react-aria-components'; import { useStyles } from '../../hooks/useStyles'; +import { MenuDefinition } from './definition'; import type { MenuTriggerProps, SubmenuTriggerProps, @@ -63,7 +64,7 @@ import clsx from 'clsx'; const rowHeight = 32; const MenuEmptyState = () => { - const { classNames } = useStyles('Menu'); + const { classNames } = useStyles(MenuDefinition); return (
@@ -84,7 +85,7 @@ export const SubmenuTrigger = (props: SubmenuTriggerProps) => { /** @public */ export const Menu = (props: MenuProps) => { - const { classNames, cleanedProps } = useStyles('Menu', props); + const { classNames, cleanedProps } = useStyles(MenuDefinition, props); const { className, placement = 'bottom start', @@ -166,7 +167,7 @@ export const Menu = (props: MenuProps) => { /** @public */ export const MenuListBox = (props: MenuListBoxProps) => { - const { classNames, cleanedProps } = useStyles('Menu', props); + const { classNames, cleanedProps } = useStyles(MenuDefinition, props); const { className, selectionMode = 'single', @@ -215,7 +216,7 @@ export const MenuListBox = (props: MenuListBoxProps) => { /** @public */ export const MenuAutocomplete = (props: MenuAutocompleteProps) => { - const { classNames, cleanedProps } = useStyles('Menu', props); + const { classNames, cleanedProps } = useStyles(MenuDefinition, props); const { className, placement = 'bottom start', @@ -294,7 +295,7 @@ export const MenuAutocomplete = (props: MenuAutocompleteProps) => { export const MenuAutocompleteListbox = ( props: MenuAutocompleteListBoxProps, ) => { - const { classNames, cleanedProps } = useStyles('Menu', props); + const { classNames, cleanedProps } = useStyles(MenuDefinition, props); const { className, selectionMode = 'single', @@ -370,7 +371,7 @@ export const MenuAutocompleteListbox = ( /** @public */ export const MenuItem = (props: MenuItemProps) => { - const { classNames, cleanedProps } = useStyles('Menu', props); + const { classNames, cleanedProps } = useStyles(MenuDefinition, props); const { className, iconStart, @@ -449,7 +450,7 @@ export const MenuItem = (props: MenuItemProps) => { /** @public */ export const MenuListBoxItem = (props: MenuListBoxItemProps) => { - const { classNames, cleanedProps } = useStyles('Menu', props); + const { classNames, cleanedProps } = useStyles(MenuDefinition, props); const { children, className, ...rest } = cleanedProps; return ( @@ -490,7 +491,7 @@ export const MenuListBoxItem = (props: MenuListBoxItemProps) => { /** @public */ export const MenuSection = (props: MenuSectionProps) => { - const { classNames, cleanedProps } = useStyles('Menu', props); + const { classNames, cleanedProps } = useStyles(MenuDefinition, props); const { children, className, title, ...rest } = cleanedProps; return ( @@ -517,7 +518,7 @@ export const MenuSection = (props: MenuSectionProps) => { /** @public */ export const MenuSeparator = (props: MenuSeparatorProps) => { - const { classNames, cleanedProps } = useStyles('Menu', props); + const { classNames, cleanedProps } = useStyles(MenuDefinition, props); const { className, ...rest } = cleanedProps; return ( diff --git a/packages/ui/src/components/Menu/definition.ts b/packages/ui/src/components/Menu/definition.ts new file mode 100644 index 0000000000..e4ba0d83ab --- /dev/null +++ b/packages/ui/src/components/Menu/definition.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Menu + * @public + */ +export const MenuDefinition = { + classNames: { + root: 'bui-Menu', + popover: 'bui-MenuPopover', + content: 'bui-MenuContent', + section: 'bui-MenuSection', + sectionHeader: 'bui-MenuSectionHeader', + item: 'bui-MenuItem', + itemListBox: 'bui-MenuItemListBox', + itemListBoxCheck: 'bui-MenuItemListBoxCheck', + itemWrapper: 'bui-MenuItemWrapper', + itemContent: 'bui-MenuItemContent', + itemArrow: 'bui-MenuItemArrow', + separator: 'bui-MenuSeparator', + searchField: 'bui-MenuSearchField', + searchFieldInput: 'bui-MenuSearchFieldInput', + searchFieldClear: 'bui-MenuSearchFieldClear', + emptyState: 'bui-MenuEmptyState', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Menu/index.ts b/packages/ui/src/components/Menu/index.ts index 00237712df..f42de8a7eb 100644 --- a/packages/ui/src/components/Menu/index.ts +++ b/packages/ui/src/components/Menu/index.ts @@ -26,6 +26,7 @@ export { MenuSection, MenuSeparator, } from './Menu'; +export { MenuDefinition } from './definition'; export type { MenuTriggerProps, SubmenuTriggerProps, diff --git a/packages/ui/src/components/PasswordField/PasswordField.tsx b/packages/ui/src/components/PasswordField/PasswordField.tsx index 412128ca32..c2cfdd1081 100644 --- a/packages/ui/src/components/PasswordField/PasswordField.tsx +++ b/packages/ui/src/components/PasswordField/PasswordField.tsx @@ -26,6 +26,7 @@ import { FieldError } from '../FieldError'; import type { PasswordFieldProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { PasswordFieldDefinition } from './definition'; import { RiEyeLine, RiEyeOffLine } from '@remixicon/react'; import stylesPasswordField from './PasswordField.module.css'; @@ -50,7 +51,7 @@ export const PasswordField = forwardRef( classNames: classNamesPasswordField, dataAttributes, cleanedProps, - } = useStyles('PasswordField', { + } = useStyles(PasswordFieldDefinition, { size: 'small', ...props, }); diff --git a/packages/ui/src/components/PasswordField/definition.ts b/packages/ui/src/components/PasswordField/definition.ts new file mode 100644 index 0000000000..11272494b4 --- /dev/null +++ b/packages/ui/src/components/PasswordField/definition.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for PasswordField + * @public + */ +export const PasswordFieldDefinition = { + classNames: { + root: 'bui-PasswordField', + inputWrapper: 'bui-PasswordFieldInputWrapper', + input: 'bui-PasswordFieldInput', + inputIcon: 'bui-PasswordFieldIcon', + inputVisibility: 'bui-PasswordFieldVisibility', + }, + dataAttributes: { + size: ['small', 'medium'] as const, + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/PasswordField/index.ts b/packages/ui/src/components/PasswordField/index.ts index df7874e1c2..705bf68c04 100644 --- a/packages/ui/src/components/PasswordField/index.ts +++ b/packages/ui/src/components/PasswordField/index.ts @@ -15,4 +15,5 @@ */ export * from './PasswordField'; +export { PasswordFieldDefinition } from './definition'; export * from './types'; diff --git a/packages/ui/src/components/Popover/definition.ts b/packages/ui/src/components/Popover/definition.ts new file mode 100644 index 0000000000..8b85180973 --- /dev/null +++ b/packages/ui/src/components/Popover/definition.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Popover + * @public + */ +export const PopoverDefinition = { + classNames: { + root: 'bui-Popover', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Popover/index.ts b/packages/ui/src/components/Popover/index.ts new file mode 100644 index 0000000000..1e31b8657b --- /dev/null +++ b/packages/ui/src/components/Popover/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { PopoverDefinition } from './definition'; diff --git a/packages/ui/src/components/RadioGroup/RadioGroup.tsx b/packages/ui/src/components/RadioGroup/RadioGroup.tsx index 355e181f37..de6cc3793b 100644 --- a/packages/ui/src/components/RadioGroup/RadioGroup.tsx +++ b/packages/ui/src/components/RadioGroup/RadioGroup.tsx @@ -23,6 +23,7 @@ import clsx from 'clsx'; import { FieldLabel } from '../FieldLabel'; import { FieldError } from '../FieldError'; import { useStyles } from '../../hooks/useStyles'; +import { RadioGroupDefinition } from './definition'; import styles from './RadioGroup.module.css'; import type { RadioGroupProps, RadioProps } from './types'; @@ -30,7 +31,7 @@ import type { RadioGroupProps, RadioProps } from './types'; /** @public */ export const RadioGroup = forwardRef( (props, ref) => { - const { classNames, cleanedProps } = useStyles('RadioGroup', props); + const { classNames, cleanedProps } = useStyles(RadioGroupDefinition, props); const { className, label, @@ -83,7 +84,7 @@ RadioGroup.displayName = 'RadioGroup'; export const Radio = forwardRef((props, ref) => { const { className, ...rest } = props; - const { classNames } = useStyles('RadioGroup'); + const { classNames } = useStyles(RadioGroupDefinition); return ( ( }, [label, ariaLabel, ariaLabelledBy]); const { classNames, dataAttributes, style, cleanedProps } = useStyles( - 'SearchField', + SearchFieldDefinition, { size: 'small', placeholder: 'Search', diff --git a/packages/ui/src/components/SearchField/definition.ts b/packages/ui/src/components/SearchField/definition.ts new file mode 100644 index 0000000000..7de1411bb4 --- /dev/null +++ b/packages/ui/src/components/SearchField/definition.ts @@ -0,0 +1,35 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for SearchField + * @public + */ +export const SearchFieldDefinition = { + classNames: { + root: 'bui-SearchField', + clear: 'bui-SearchFieldClear', + inputWrapper: 'bui-SearchFieldInputWrapper', + input: 'bui-SearchFieldInput', + inputIcon: 'bui-SearchFieldInputIcon', + }, + dataAttributes: { + startCollapsed: [true, false] as const, + size: ['small', 'medium'] as const, + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/SearchField/index.ts b/packages/ui/src/components/SearchField/index.ts index 288c3fe44a..9e01b47fc1 100644 --- a/packages/ui/src/components/SearchField/index.ts +++ b/packages/ui/src/components/SearchField/index.ts @@ -16,3 +16,4 @@ export * from './SearchField'; export * from './types'; +export { SearchFieldDefinition } from './definition'; diff --git a/packages/ui/src/components/Select/Select.tsx b/packages/ui/src/components/Select/Select.tsx index 0b133d07c5..04231d1cd9 100644 --- a/packages/ui/src/components/Select/Select.tsx +++ b/packages/ui/src/components/Select/Select.tsx @@ -19,6 +19,8 @@ import { Select as AriaSelect, Popover } from 'react-aria-components'; import clsx from 'clsx'; import { SelectProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { SelectDefinition } from './definition'; +import { PopoverDefinition } from '../Popover/definition'; import { FieldLabel } from '../FieldLabel'; import { FieldError } from '../FieldError'; import styles from './Select.module.css'; @@ -31,12 +33,15 @@ export const Select = forwardRef< HTMLDivElement, SelectProps<'single' | 'multiple'> >((props, ref) => { - const { classNames: popoverClassNames } = useStyles('Popover'); - const { classNames, dataAttributes, cleanedProps } = useStyles('Select', { - size: 'small', - placeholder: 'Select an option', - ...props, - }); + const { classNames: popoverClassNames } = useStyles(PopoverDefinition); + const { classNames, dataAttributes, cleanedProps } = useStyles( + SelectDefinition, + { + size: 'small', + placeholder: 'Select an option', + ...props, + }, + ); const { className, diff --git a/packages/ui/src/components/Select/SelectContent.tsx b/packages/ui/src/components/Select/SelectContent.tsx index 42070321a3..7f63ad2a0a 100644 --- a/packages/ui/src/components/Select/SelectContent.tsx +++ b/packages/ui/src/components/Select/SelectContent.tsx @@ -24,6 +24,7 @@ import { useFilter } from 'react-aria'; import { RiCloseCircleLine } from '@remixicon/react'; import clsx from 'clsx'; import { useStyles } from '../../hooks/useStyles'; +import { SelectDefinition } from './definition'; import { SelectListBox } from './SelectListBox'; import styles from './Select.module.css'; import type { Option } from './types'; @@ -40,7 +41,7 @@ export function SelectContent({ options, }: SelectContentProps) { const { contains } = useFilter({ sensitivity: 'base' }); - const { classNames } = useStyles('Select'); + const { classNames } = useStyles(SelectDefinition); if (!searchable) { return ; diff --git a/packages/ui/src/components/Select/SelectListBox.tsx b/packages/ui/src/components/Select/SelectListBox.tsx index aa050ba766..3b14292729 100644 --- a/packages/ui/src/components/Select/SelectListBox.tsx +++ b/packages/ui/src/components/Select/SelectListBox.tsx @@ -18,6 +18,7 @@ import { ListBox, ListBoxItem, Text } from 'react-aria-components'; import { RiCheckLine } from '@remixicon/react'; import clsx from 'clsx'; import { useStyles } from '../../hooks/useStyles'; +import { SelectDefinition } from './definition'; import styles from './Select.module.css'; import type { Option } from './types'; @@ -26,7 +27,7 @@ interface SelectListBoxProps { } const NoResults = () => { - const { classNames } = useStyles('Select'); + const { classNames } = useStyles(SelectDefinition); return (
@@ -36,7 +37,7 @@ const NoResults = () => { }; export function SelectListBox({ options, ...props }: SelectListBoxProps) { - const { classNames } = useStyles('Select', props); + const { classNames } = useStyles(SelectDefinition, props); return ( diff --git a/packages/ui/src/components/Select/definition.ts b/packages/ui/src/components/Select/definition.ts new file mode 100644 index 0000000000..5a085cc770 --- /dev/null +++ b/packages/ui/src/components/Select/definition.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Select + * @public + */ +export const SelectDefinition = { + classNames: { + root: 'bui-Select', + popover: 'bui-SelectPopover', + trigger: 'bui-SelectTrigger', + chevron: 'bui-SelectTriggerChevron', + value: 'bui-SelectValue', + list: 'bui-SelectList', + item: 'bui-SelectItem', + itemIndicator: 'bui-SelectItemIndicator', + itemLabel: 'bui-SelectItemLabel', + searchWrapper: 'bui-SelectSearchWrapper', + search: 'bui-SelectSearch', + searchClear: 'bui-SelectSearchClear', + noResults: 'bui-SelectNoResults', + }, + dataAttributes: { + size: ['small', 'medium'] as const, + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Select/index.ts b/packages/ui/src/components/Select/index.ts index 2cddf1fe62..786cc4d03f 100644 --- a/packages/ui/src/components/Select/index.ts +++ b/packages/ui/src/components/Select/index.ts @@ -16,3 +16,4 @@ export * from './Select'; export * from './types'; +export { SelectDefinition } from './definition'; diff --git a/packages/ui/src/components/Skeleton/Skeleton.tsx b/packages/ui/src/components/Skeleton/Skeleton.tsx index ca2f4ae493..c85a9b23cb 100644 --- a/packages/ui/src/components/Skeleton/Skeleton.tsx +++ b/packages/ui/src/components/Skeleton/Skeleton.tsx @@ -15,13 +15,14 @@ */ import { useStyles } from '../../hooks/useStyles'; +import { SkeletonDefinition } from './definition'; import { SkeletonProps } from './types'; import styles from './Skeleton.module.css'; import clsx from 'clsx'; /** @public */ export const Skeleton = (props: SkeletonProps) => { - const { classNames, cleanedProps } = useStyles('Skeleton', { + const { classNames, cleanedProps } = useStyles(SkeletonDefinition, { width: 80, height: 24, rounded: false, diff --git a/packages/ui/src/components/Skeleton/definition.ts b/packages/ui/src/components/Skeleton/definition.ts new file mode 100644 index 0000000000..42c4d6c444 --- /dev/null +++ b/packages/ui/src/components/Skeleton/definition.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Skeleton + * @public + */ +export const SkeletonDefinition = { + classNames: { + root: 'bui-Skeleton', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Skeleton/index.tsx b/packages/ui/src/components/Skeleton/index.tsx index f1e76b1851..ab44364f8b 100644 --- a/packages/ui/src/components/Skeleton/index.tsx +++ b/packages/ui/src/components/Skeleton/index.tsx @@ -16,3 +16,4 @@ export { Skeleton } from './Skeleton'; export type { SkeletonProps } from './types'; +export { SkeletonDefinition } from './definition'; diff --git a/packages/ui/src/components/Switch/Switch.tsx b/packages/ui/src/components/Switch/Switch.tsx index ffc1fdef05..b50db839df 100644 --- a/packages/ui/src/components/Switch/Switch.tsx +++ b/packages/ui/src/components/Switch/Switch.tsx @@ -18,13 +18,14 @@ import { forwardRef } from 'react'; import { Switch as AriaSwitch } from 'react-aria-components'; import type { SwitchProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { SwitchDefinition } from './definition'; import styles from './Switch.module.css'; import clsx from 'clsx'; /** @public */ export const Switch = forwardRef( (props, ref) => { - const { classNames, cleanedProps } = useStyles('Switch', props); + const { classNames, cleanedProps } = useStyles(SwitchDefinition, props); const { className, label, ...rest } = cleanedProps; return ( diff --git a/packages/ui/src/components/Switch/definition.ts b/packages/ui/src/components/Switch/definition.ts new file mode 100644 index 0000000000..c8dd004991 --- /dev/null +++ b/packages/ui/src/components/Switch/definition.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Switch + * @public + */ +export const SwitchDefinition = { + classNames: { + root: 'bui-Switch', + indicator: 'bui-SwitchIndicator', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Switch/index.tsx b/packages/ui/src/components/Switch/index.tsx index 171969809d..72c08f5cb0 100644 --- a/packages/ui/src/components/Switch/index.tsx +++ b/packages/ui/src/components/Switch/index.tsx @@ -16,3 +16,4 @@ export * from './Switch'; export * from './types'; +export { SwitchDefinition } from './definition'; diff --git a/packages/ui/src/components/Table/components/Cell.tsx b/packages/ui/src/components/Table/components/Cell.tsx index ad0a92cb94..65be8482a7 100644 --- a/packages/ui/src/components/Table/components/Cell.tsx +++ b/packages/ui/src/components/Table/components/Cell.tsx @@ -20,12 +20,13 @@ import { Link } from '../../Link'; import { Cell as ReactAriaCell } from 'react-aria-components'; import type { CellProps } from '../types'; import { useStyles } from '../../../hooks/useStyles'; +import { TableDefinition } from '../definition'; import styles from '../Table.module.css'; /** @public */ const Cell = (props: CellProps) => { - const { classNames, cleanedProps } = useStyles<'Table', CellProps>('Table', { - color: 'primary', + const { classNames, cleanedProps } = useStyles(TableDefinition, { + color: 'primary' as const, ...props, }); const { className, title, description, color, leadingIcon, href, ...rest } = diff --git a/packages/ui/src/components/Table/components/CellProfile.tsx b/packages/ui/src/components/Table/components/CellProfile.tsx index 3f665dec02..4abef56e01 100644 --- a/packages/ui/src/components/Table/components/CellProfile.tsx +++ b/packages/ui/src/components/Table/components/CellProfile.tsx @@ -20,18 +20,16 @@ import { Text } from '../../Text/Text'; import { Link } from '../../Link/Link'; import { Avatar } from '../../Avatar'; import { useStyles } from '../../../hooks/useStyles'; +import { TableDefinition } from '../definition'; import { Cell as ReactAriaCell } from 'react-aria-components'; import styles from '../Table.module.css'; /** @public */ export const CellProfile = (props: CellProfileProps) => { - const { classNames, cleanedProps } = useStyles<'Table', CellProfileProps>( - 'Table', - { - color: 'primary', - ...props, - }, - ); + const { classNames, cleanedProps } = useStyles(TableDefinition, { + color: 'primary' as const, + ...props, + }); const { className, src, name, href, description, color, ...rest } = cleanedProps; diff --git a/packages/ui/src/components/Table/components/Column.tsx b/packages/ui/src/components/Table/components/Column.tsx index 6ebd263d3f..f534da565a 100644 --- a/packages/ui/src/components/Table/components/Column.tsx +++ b/packages/ui/src/components/Table/components/Column.tsx @@ -16,6 +16,7 @@ import { Column as ReactAriaColumn } from 'react-aria-components'; import { useStyles } from '../../../hooks/useStyles'; +import { TableDefinition } from '../definition'; import styles from '../Table.module.css'; import clsx from 'clsx'; import { ColumnProps } from '../types'; @@ -23,10 +24,7 @@ import { RiArrowUpLine, RiArrowDownLine } from '@remixicon/react'; /** @public */ export const Column = (props: ColumnProps) => { - const { classNames, cleanedProps } = useStyles<'Table', ColumnProps>( - 'Table', - props, - ); + const { classNames, cleanedProps } = useStyles(TableDefinition, props); const { children, ...rest } = cleanedProps; return ( diff --git a/packages/ui/src/components/Table/components/Row.tsx b/packages/ui/src/components/Table/components/Row.tsx index 70c8330e68..106f97baff 100644 --- a/packages/ui/src/components/Table/components/Row.tsx +++ b/packages/ui/src/components/Table/components/Row.tsx @@ -24,6 +24,7 @@ import { RouterProvider, } from 'react-aria-components'; import { useStyles } from '../../../hooks/useStyles'; +import { TableDefinition } from '../definition'; import { useNavigate } from 'react-router-dom'; import { useHref } from 'react-router-dom'; import { isExternalLink } from '../../../utils/isExternalLink'; @@ -32,10 +33,7 @@ import clsx from 'clsx'; /** @public */ export function Row(props: RowProps) { - const { classNames, cleanedProps } = useStyles<'Table', RowProps>( - 'Table', - props, - ); + const { classNames, cleanedProps } = useStyles(TableDefinition, props); const { id, columns, children, href, ...rest } = cleanedProps; const navigate = useNavigate(); const isExternal = isExternalLink(href); diff --git a/packages/ui/src/components/Table/components/Table.tsx b/packages/ui/src/components/Table/components/Table.tsx index a430b9cff2..ffd0ab231d 100644 --- a/packages/ui/src/components/Table/components/Table.tsx +++ b/packages/ui/src/components/Table/components/Table.tsx @@ -15,6 +15,7 @@ */ import { useStyles } from '../../../hooks/useStyles'; +import { TableDefinition } from '../definition'; import { Table as ReactAriaTable, type TableProps, @@ -24,10 +25,7 @@ import clsx from 'clsx'; /** @public */ export const Table = (props: TableProps) => { - const { classNames, cleanedProps } = useStyles<'Table', TableProps>( - 'Table', - props, - ); + const { classNames, cleanedProps } = useStyles(TableDefinition, props); return ( (props: TableBodyProps) => { - const { classNames, cleanedProps } = useStyles<'Table', TableBodyProps>( - 'Table', - props, - ); + const { classNames, cleanedProps } = useStyles(TableDefinition, props); return ( (props: TableHeaderProps) => { let { selectionBehavior, selectionMode, allowsDragging } = useTableOptions(); - const { classNames, cleanedProps } = useStyles<'Table', TableHeaderProps>( - 'Table', - props, - ); + const { classNames, cleanedProps } = useStyles(TableDefinition, props); const { columns, children, ...rest } = cleanedProps; return ( diff --git a/packages/ui/src/components/Table/definition.ts b/packages/ui/src/components/Table/definition.ts new file mode 100644 index 0000000000..8ec9dfb1f0 --- /dev/null +++ b/packages/ui/src/components/Table/definition.ts @@ -0,0 +1,43 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Table + * @public + */ +export const TableDefinition = { + classNames: { + table: 'bui-Table', + header: 'bui-TableHeader', + body: 'bui-TableBody', + row: 'bui-TableRow', + head: 'bui-TableHead', + headContent: 'bui-TableHeadContent', + headSortButton: 'bui-TableHeadSortButton', + caption: 'bui-TableCaption', + cell: 'bui-TableCell', + cellContentWrapper: 'bui-TableCellContentWrapper', + cellContent: 'bui-TableCellContent', + cellIcon: 'bui-TableCellIcon', + cellProfileAvatar: 'bui-TableCellProfileAvatar', + cellProfileAvatarImage: 'bui-TableCellProfileAvatarImage', + cellProfileAvatarFallback: 'bui-TableCellProfileAvatarFallback', + cellProfileName: 'bui-TableCellProfileName', + cellProfileLink: 'bui-TableCellProfileLink', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Table/index.ts b/packages/ui/src/components/Table/index.ts index fb4ec6147d..8d6603ee00 100644 --- a/packages/ui/src/components/Table/index.ts +++ b/packages/ui/src/components/Table/index.ts @@ -30,3 +30,5 @@ export type { UseTablePagination, UseTablePaginationConfig, } from './hooks/types'; + +export { TableDefinition } from './definition'; diff --git a/packages/ui/src/components/Table/types.ts b/packages/ui/src/components/Table/types.ts index 293e76fdca..be9e860a0c 100644 --- a/packages/ui/src/components/Table/types.ts +++ b/packages/ui/src/components/Table/types.ts @@ -18,12 +18,13 @@ import { CellProps as ReactAriaCellProps, ColumnProps as AriaColumnProps, } from 'react-aria-components'; +import type { TextColors } from '../../types'; /** @public */ export interface CellProps extends ReactAriaCellProps { title: string; description?: string; - color?: 'primary' | 'secondary'; + color?: TextColors; leadingIcon?: React.ReactNode | null; href?: string; } @@ -34,7 +35,7 @@ export interface CellProfileProps extends ReactAriaCellProps { name?: string; href?: string; description?: string; - color?: 'primary' | 'secondary'; + color?: TextColors; } /** @public */ diff --git a/packages/ui/src/components/TablePagination/TablePagination.tsx b/packages/ui/src/components/TablePagination/TablePagination.tsx index ebd585a0c3..fd891be073 100644 --- a/packages/ui/src/components/TablePagination/TablePagination.tsx +++ b/packages/ui/src/components/TablePagination/TablePagination.tsx @@ -18,6 +18,7 @@ import clsx from 'clsx'; import { Text, ButtonIcon, Select } from '../..'; import type { TablePaginationProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { TablePaginationDefinition } from './definition'; import styles from './TablePagination.module.css'; import { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react'; @@ -27,7 +28,7 @@ import { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react'; * @public */ export function TablePagination(props: TablePaginationProps) { - const { classNames, cleanedProps } = useStyles('TablePagination', { + const { classNames, cleanedProps } = useStyles(TablePaginationDefinition, { showPageSizeOptions: true, ...props, }); diff --git a/packages/ui/src/components/TablePagination/definition.ts b/packages/ui/src/components/TablePagination/definition.ts new file mode 100644 index 0000000000..d72a706da1 --- /dev/null +++ b/packages/ui/src/components/TablePagination/definition.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for TablePagination + * @public + */ +export const TablePaginationDefinition = { + classNames: { + root: 'bui-TablePagination', + left: 'bui-TablePaginationLeft', + right: 'bui-TablePaginationRight', + select: 'bui-TablePaginationSelect', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/TablePagination/index.ts b/packages/ui/src/components/TablePagination/index.ts index 9fb26ad728..42642fb162 100644 --- a/packages/ui/src/components/TablePagination/index.ts +++ b/packages/ui/src/components/TablePagination/index.ts @@ -16,3 +16,4 @@ export { TablePagination } from './TablePagination'; export type { TablePaginationProps } from './types'; +export { TablePaginationDefinition } from './definition'; diff --git a/packages/ui/src/components/Tabs/Tabs.tsx b/packages/ui/src/components/Tabs/Tabs.tsx index f627199b4b..5c44fae8af 100644 --- a/packages/ui/src/components/Tabs/Tabs.tsx +++ b/packages/ui/src/components/Tabs/Tabs.tsx @@ -42,6 +42,7 @@ import { TabProps as AriaTabProps, } from 'react-aria-components'; import { useStyles } from '../../hooks/useStyles'; +import { TabsDefinition } from './definition'; import styles from './Tabs.module.css'; import clsx from 'clsx'; @@ -84,7 +85,7 @@ const isTabActive = ( * @public */ export const Tabs = (props: TabsProps) => { - const { classNames, cleanedProps } = useStyles('Tabs', props); + const { classNames, cleanedProps } = useStyles(TabsDefinition, props); const { className, children, ...rest } = cleanedProps; const tabsRef = useRef(null); const tabRefs = useRef>(new Map()); @@ -168,7 +169,7 @@ export const Tabs = (props: TabsProps) => { * @public */ export const TabList = (props: TabListProps) => { - const { classNames, cleanedProps } = useStyles('Tabs', props); + const { classNames, cleanedProps } = useStyles(TabsDefinition, props); const { className, children, ...rest } = cleanedProps; const { setHoveredKey, tabRefs, tabsRef, hoveredKey, prevHoveredKey } = useTabsContext(); @@ -219,7 +220,7 @@ export const TabList = (props: TabListProps) => { * @public */ export const Tab = (props: TabProps) => { - const { classNames, cleanedProps } = useStyles('Tabs', props); + const { classNames, cleanedProps } = useStyles(TabsDefinition, props); const { className, href, @@ -249,7 +250,7 @@ export const Tab = (props: TabProps) => { * @public */ export const TabPanel = (props: TabPanelProps) => { - const { classNames, cleanedProps } = useStyles('Tabs', props); + const { classNames, cleanedProps } = useStyles(TabsDefinition, props); const { className, children, ...rest } = cleanedProps; return ( diff --git a/packages/ui/src/components/Tabs/TabsIndicators.tsx b/packages/ui/src/components/Tabs/TabsIndicators.tsx index 6347c5c55c..2aa4f72508 100644 --- a/packages/ui/src/components/Tabs/TabsIndicators.tsx +++ b/packages/ui/src/components/Tabs/TabsIndicators.tsx @@ -16,6 +16,7 @@ import { TabListStateContext } from 'react-aria-components'; import { useStyles } from '../../hooks/useStyles'; +import { TabsDefinition } from './definition'; import { useContext, useEffect, useCallback, useRef } from 'react'; import type { TabsIndicatorsProps } from './types'; import styles from './Tabs.module.css'; @@ -28,7 +29,7 @@ import clsx from 'clsx'; */ export const TabsIndicators = (props: TabsIndicatorsProps) => { const { tabRefs, tabsRef, hoveredKey, prevHoveredKey } = props; - const { classNames } = useStyles('Tabs'); + const { classNames } = useStyles(TabsDefinition); const state = useContext(TabListStateContext); const prevSelectedKey = useRef(null); diff --git a/packages/ui/src/components/Tabs/definition.ts b/packages/ui/src/components/Tabs/definition.ts new file mode 100644 index 0000000000..10e9247372 --- /dev/null +++ b/packages/ui/src/components/Tabs/definition.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Tabs + * @public + */ +export const TabsDefinition = { + classNames: { + tabs: 'bui-Tabs', + tabList: 'bui-TabList', + tabListWrapper: 'bui-TabListWrapper', + tab: 'bui-Tab', + tabActive: 'bui-TabActive', + tabHovered: 'bui-TabHovered', + panel: 'bui-TabPanel', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Tabs/index.ts b/packages/ui/src/components/Tabs/index.ts index 38a6f20ea7..009d515294 100644 --- a/packages/ui/src/components/Tabs/index.ts +++ b/packages/ui/src/components/Tabs/index.ts @@ -22,3 +22,4 @@ export type { TabProps, TabMatchStrategy, } from './types'; +export { TabsDefinition } from './definition'; diff --git a/packages/ui/src/components/TagGroup/TagGroup.tsx b/packages/ui/src/components/TagGroup/TagGroup.tsx index 04f3027f02..54557e5849 100644 --- a/packages/ui/src/components/TagGroup/TagGroup.tsx +++ b/packages/ui/src/components/TagGroup/TagGroup.tsx @@ -26,6 +26,7 @@ import type { ReactNode } from 'react'; import { RiCloseCircleLine } from '@remixicon/react'; import clsx from 'clsx'; import { useStyles } from '../../hooks/useStyles'; +import { TagGroupDefinition } from './definition'; import { isExternalLink } from '../../utils/isExternalLink'; import { useNavigate, useHref } from 'react-router-dom'; import styles from './TagGroup.module.css'; @@ -36,7 +37,7 @@ import styles from './TagGroup.module.css'; * @public */ export const TagGroup = (props: TagGroupProps) => { - const { classNames, cleanedProps } = useStyles('TagGroup', props); + const { classNames, cleanedProps } = useStyles(TagGroupDefinition, props); const { items, children, renderEmptyState, ...rest } = cleanedProps; return ( @@ -61,7 +62,7 @@ export const TagGroup = (props: TagGroupProps) => { * @public */ export const Tag = (props: TagProps) => { - const { classNames, cleanedProps } = useStyles('TagGroup', { + const { classNames, cleanedProps } = useStyles(TagGroupDefinition, { size: 'small', ...props, }); diff --git a/packages/ui/src/components/TagGroup/definition.ts b/packages/ui/src/components/TagGroup/definition.ts new file mode 100644 index 0000000000..8ad3d17805 --- /dev/null +++ b/packages/ui/src/components/TagGroup/definition.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for TagGroup + * @public + */ +export const TagGroupDefinition = { + classNames: { + group: 'bui-TagGroup', + list: 'bui-TagList', + tag: 'bui-Tag', + tagIcon: 'bui-TagIcon', + tagRemoveButton: 'bui-TagRemoveButton', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/TagGroup/index.ts b/packages/ui/src/components/TagGroup/index.ts index b7434ce574..7c58cf69fc 100644 --- a/packages/ui/src/components/TagGroup/index.ts +++ b/packages/ui/src/components/TagGroup/index.ts @@ -16,3 +16,4 @@ export { TagGroup, Tag } from './TagGroup'; export type { TagGroupProps, TagProps } from './types'; +export { TagGroupDefinition } from './definition'; diff --git a/packages/ui/src/components/Text/Text.tsx b/packages/ui/src/components/Text/Text.tsx index 5b09d10663..857ae3ef0e 100644 --- a/packages/ui/src/components/Text/Text.tsx +++ b/packages/ui/src/components/Text/Text.tsx @@ -20,6 +20,7 @@ import type { ElementType } from 'react'; import type { TextProps } from './types'; import { useStyles } from '../../hooks/useStyles'; import styles from './Text.module.css'; +import { TextDefinition } from './definition'; function TextComponent( props: TextProps, @@ -27,12 +28,15 @@ function TextComponent( ) { const Component = props.as || 'span'; - const { classNames, dataAttributes, cleanedProps } = useStyles('Text', { - variant: 'body-medium', - weight: 'regular', - color: 'primary', - ...props, - }); + const { classNames, dataAttributes, cleanedProps } = useStyles( + TextDefinition, + { + variant: 'body-medium', + weight: 'regular', + color: 'primary', + ...props, + }, + ); const { className, truncate, ...restProps } = cleanedProps; diff --git a/packages/ui/src/components/Text/definition.ts b/packages/ui/src/components/Text/definition.ts new file mode 100644 index 0000000000..dbbfd6b72a --- /dev/null +++ b/packages/ui/src/components/Text/definition.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Text + * @public + */ +export const TextDefinition = { + classNames: { + root: 'bui-Text', + }, + dataAttributes: { + variant: ['subtitle', 'body', 'caption', 'label'] as const, + weight: ['regular', 'bold'] as const, + color: ['primary', 'secondary', 'danger', 'warning', 'success'] as const, + truncate: [true, false] as const, + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Text/index.ts b/packages/ui/src/components/Text/index.ts index 423288a8a4..df6ac23eb4 100644 --- a/packages/ui/src/components/Text/index.ts +++ b/packages/ui/src/components/Text/index.ts @@ -16,3 +16,4 @@ export * from './Text'; export * from './types'; +export { TextDefinition } from './definition'; diff --git a/packages/ui/src/components/TextField/TextField.tsx b/packages/ui/src/components/TextField/TextField.tsx index 632f5e9f86..24c038fdb8 100644 --- a/packages/ui/src/components/TextField/TextField.tsx +++ b/packages/ui/src/components/TextField/TextField.tsx @@ -21,6 +21,7 @@ import { FieldLabel } from '../FieldLabel'; import { FieldError } from '../FieldError'; import type { TextFieldProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { TextFieldDefinition } from './definition'; import styles from './TextField.module.css'; /** @public */ @@ -41,7 +42,7 @@ export const TextField = forwardRef( }, [label, ariaLabel, ariaLabelledBy]); const { classNames, dataAttributes, style, cleanedProps } = useStyles( - 'TextField', + TextFieldDefinition, { size: 'small', ...props, diff --git a/packages/ui/src/components/TextField/definition.ts b/packages/ui/src/components/TextField/definition.ts new file mode 100644 index 0000000000..c1cab8095d --- /dev/null +++ b/packages/ui/src/components/TextField/definition.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for TextField + * @public + */ +export const TextFieldDefinition = { + classNames: { + root: 'bui-TextField', + inputWrapper: 'bui-InputWrapper', + input: 'bui-Input', + inputIcon: 'bui-InputIcon', + inputAction: 'bui-InputAction', + }, + dataAttributes: { + invalid: [true, false] as const, + disabled: [true, false] as const, + size: ['small', 'medium'] as const, + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/TextField/index.ts b/packages/ui/src/components/TextField/index.ts index 95a838fb46..a9d061047d 100644 --- a/packages/ui/src/components/TextField/index.ts +++ b/packages/ui/src/components/TextField/index.ts @@ -16,3 +16,4 @@ export * from './TextField'; export * from './types'; +export { TextFieldDefinition } from './definition'; diff --git a/packages/ui/src/components/Tooltip/Tooltip.tsx b/packages/ui/src/components/Tooltip/Tooltip.tsx index fc8b25547b..9099f1eef2 100644 --- a/packages/ui/src/components/Tooltip/Tooltip.tsx +++ b/packages/ui/src/components/Tooltip/Tooltip.tsx @@ -24,6 +24,7 @@ import { import clsx from 'clsx'; import { TooltipProps } from './types'; import { useStyles } from '../../hooks/useStyles'; +import { TooltipDefinition } from './definition'; import styles from './Tooltip.module.css'; /** @public */ @@ -36,7 +37,7 @@ export const TooltipTrigger = (props: TooltipTriggerComponentProps) => { /** @public */ export const Tooltip = forwardRef( (props, ref) => { - const { classNames, cleanedProps } = useStyles('Tooltip', props); + const { classNames, cleanedProps } = useStyles(TooltipDefinition, props); const { className, children, ...rest } = cleanedProps; return ( diff --git a/packages/ui/src/components/Tooltip/definition.ts b/packages/ui/src/components/Tooltip/definition.ts new file mode 100644 index 0000000000..a5b3d61ea8 --- /dev/null +++ b/packages/ui/src/components/Tooltip/definition.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for Tooltip + * @public + */ +export const TooltipDefinition = { + classNames: { + tooltip: 'bui-Tooltip', + arrow: 'bui-TooltipArrow', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/Tooltip/index.ts b/packages/ui/src/components/Tooltip/index.ts index 613631091b..43bd385c65 100644 --- a/packages/ui/src/components/Tooltip/index.ts +++ b/packages/ui/src/components/Tooltip/index.ts @@ -16,3 +16,4 @@ export { TooltipTrigger, Tooltip } from './Tooltip'; export type { TooltipProps } from './types'; +export { TooltipDefinition } from './definition'; diff --git a/packages/ui/src/components/VisuallyHidden/VisuallyHidden.tsx b/packages/ui/src/components/VisuallyHidden/VisuallyHidden.tsx index 305f8fc424..cfc796ef9e 100644 --- a/packages/ui/src/components/VisuallyHidden/VisuallyHidden.tsx +++ b/packages/ui/src/components/VisuallyHidden/VisuallyHidden.tsx @@ -15,6 +15,7 @@ */ import { useStyles } from '../../hooks/useStyles'; +import { VisuallyHiddenDefinition } from './definition'; import { VisuallyHiddenProps } from './types'; import styles from './VisuallyHidden.module.css'; import clsx from 'clsx'; @@ -29,7 +30,10 @@ import clsx from 'clsx'; * @public */ export const VisuallyHidden = (props: VisuallyHiddenProps) => { - const { classNames, cleanedProps } = useStyles('VisuallyHidden', props); + const { classNames, cleanedProps } = useStyles( + VisuallyHiddenDefinition, + props, + ); const { className, ...rest } = cleanedProps; return ( diff --git a/packages/ui/src/components/VisuallyHidden/definition.ts b/packages/ui/src/components/VisuallyHidden/definition.ts new file mode 100644 index 0000000000..5be52f89ec --- /dev/null +++ b/packages/ui/src/components/VisuallyHidden/definition.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ComponentDefinition } from '../../types'; + +/** + * Component definition for VisuallyHidden + * @public + */ +export const VisuallyHiddenDefinition = { + classNames: { + root: 'bui-VisuallyHidden', + }, +} as const satisfies ComponentDefinition; diff --git a/packages/ui/src/components/VisuallyHidden/index.ts b/packages/ui/src/components/VisuallyHidden/index.ts index 6946ec00e5..c3668df403 100644 --- a/packages/ui/src/components/VisuallyHidden/index.ts +++ b/packages/ui/src/components/VisuallyHidden/index.ts @@ -16,3 +16,4 @@ export { VisuallyHidden } from './VisuallyHidden'; export type { VisuallyHiddenProps } from './types'; +export { VisuallyHiddenDefinition } from './definition'; diff --git a/packages/ui/src/definitions.ts b/packages/ui/src/definitions.ts new file mode 100644 index 0000000000..a0dc412697 --- /dev/null +++ b/packages/ui/src/definitions.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Component definitions barrel export + * @packageDocumentation + */ + +export { AccordionDefinition } from './components/Accordion/definition'; +export { AvatarDefinition } from './components/Avatar/definition'; +export { BoxDefinition } from './components/Box/definition'; +export { ButtonDefinition } from './components/Button/definition'; +export { ButtonIconDefinition } from './components/ButtonIcon/definition'; +export { ButtonLinkDefinition } from './components/ButtonLink/definition'; +export { CardDefinition } from './components/Card/definition'; +export { CheckboxDefinition } from './components/Checkbox/definition'; +export { ContainerDefinition } from './components/Container/definition'; +export { DialogDefinition } from './components/Dialog/definition'; +export { FieldErrorDefinition } from './components/FieldError/definition'; +export { FieldLabelDefinition } from './components/FieldLabel/definition'; +export { FlexDefinition } from './components/Flex/definition'; +export { + GridDefinition, + GridItemDefinition, +} from './components/Grid/definition'; +export { HeaderDefinition } from './components/Header/definition'; +export { HeaderPageDefinition } from './components/HeaderPage/definition'; +export { LinkDefinition } from './components/Link/definition'; +export { MenuDefinition } from './components/Menu/definition'; +export { PasswordFieldDefinition } from './components/PasswordField/definition'; +export { PopoverDefinition } from './components/Popover/definition'; +export { RadioGroupDefinition } from './components/RadioGroup/definition'; +export { SearchFieldDefinition } from './components/SearchField/definition'; +export { SelectDefinition } from './components/Select/definition'; +export { SkeletonDefinition } from './components/Skeleton/definition'; +export { SwitchDefinition } from './components/Switch/definition'; +export { TableDefinition } from './components/Table/definition'; +export { TablePaginationDefinition } from './components/TablePagination/definition'; +export { TabsDefinition } from './components/Tabs/definition'; +export { TagGroupDefinition } from './components/TagGroup/definition'; +export { TextDefinition } from './components/Text/definition'; +export { TextFieldDefinition } from './components/TextField/definition'; +export { TooltipDefinition } from './components/Tooltip/definition'; +export { VisuallyHiddenDefinition } from './components/VisuallyHidden/definition'; diff --git a/packages/ui/src/hooks/useStyles.ts b/packages/ui/src/hooks/useStyles.ts index b141eca582..cc05f5f362 100644 --- a/packages/ui/src/hooks/useStyles.ts +++ b/packages/ui/src/hooks/useStyles.ts @@ -14,8 +14,7 @@ * limitations under the License. */ import { useBreakpoint, breakpoints } from './useBreakpoint'; -import { componentDefinitions } from '../utils/componentDefinitions'; -import type { ComponentDefinitionName, ComponentClassNames } from '../types'; +import type { ComponentDefinition } from '../types'; import { utilityClassMap } from '../utils/utilityClassMap'; /** @@ -55,26 +54,25 @@ function resolveResponsiveValue( /** * React hook to get class names and data attributes for a component with responsive support - * @param componentName - The name of the component + * @param componentDefinition - The component's definition object * @param props - All component props * @returns Object with classNames, dataAttributes, utilityClasses, style, and cleanedProps */ export function useStyles< - T extends ComponentDefinitionName, + T extends ComponentDefinition, P extends Record = Record, >( - componentName: T, + componentDefinition: T, props: P = {} as P, ): { - classNames: ComponentClassNames; + classNames: T['classNames']; dataAttributes: Record; utilityClasses: string; style: React.CSSProperties; cleanedProps: P; } { const { breakpoint } = useBreakpoint(); - const componentDefinition = componentDefinitions[componentName]; - const classNames = componentDefinition.classNames as ComponentClassNames; + const classNames = componentDefinition.classNames; const utilityPropNames = ('utilityProps' in componentDefinition ? componentDefinition.utilityProps diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index baa4c3e5dc..03ae3245e3 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -59,6 +59,3 @@ export * from './types'; // Hooks export { useBreakpoint } from './hooks/useBreakpoint'; - -// Component Definitions -export * from './utils/componentDefinitions'; diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts index db23974186..7166194091 100644 --- a/packages/ui/src/types.ts +++ b/packages/ui/src/types.ts @@ -14,8 +14,6 @@ * limitations under the License. */ -import { componentDefinitions } from './utils/componentDefinitions'; - /** @public */ export type Breakpoint = 'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'; @@ -175,16 +173,3 @@ export interface ComponentDefinition { dataAttributes?: DataAttributesMap; utilityProps?: string[]; } - -/** - * Type utilities for extracting information from the component styles - * @public - */ -export type ComponentDefinitionName = keyof typeof componentDefinitions; - -/** - * Helper type to extract class names for a component - * @public - */ -export type ComponentClassNames = - (typeof componentDefinitions)[T]['classNames']; diff --git a/packages/ui/src/utils/componentDefinitions.ts b/packages/ui/src/utils/componentDefinitions.ts deleted file mode 100644 index cc45dbefe1..0000000000 --- a/packages/ui/src/utils/componentDefinitions.ts +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { ComponentDefinition } from '../types'; - -/** - * Component definitions for the Backstage UI library - * @public - */ -export const componentDefinitions = { - Avatar: { - classNames: { - root: 'bui-AvatarRoot', - image: 'bui-AvatarImage', - fallback: 'bui-AvatarFallback', - }, - dataAttributes: { - size: ['small', 'medium', 'large'] as const, - }, - }, - Box: { - classNames: { - root: 'bui-Box', - }, - utilityProps: [ - 'm', - 'mb', - 'ml', - 'mr', - 'mt', - 'mx', - 'my', - 'p', - 'pb', - 'pl', - 'pr', - 'pt', - 'px', - 'py', - 'position', - 'display', - 'width', - 'minWidth', - 'maxWidth', - 'height', - 'minHeight', - 'maxHeight', - ], - }, - Button: { - classNames: { - root: 'bui-Button', - content: 'bui-ButtonContent', - spinner: 'bui-ButtonSpinner', - }, - dataAttributes: { - size: ['small', 'medium', 'large'] as const, - variant: ['primary', 'secondary', 'tertiary'] as const, - loading: [true, false] as const, - }, - }, - ButtonIcon: { - classNames: { - root: 'bui-ButtonIcon', - content: 'bui-ButtonIconContent', - spinner: 'bui-ButtonIconSpinner', - }, - }, - ButtonLink: { - classNames: { - root: 'bui-ButtonLink', - }, - }, - Card: { - classNames: { - root: 'bui-Card', - header: 'bui-CardHeader', - body: 'bui-CardBody', - footer: 'bui-CardFooter', - }, - }, - Checkbox: { - classNames: { - root: 'bui-Checkbox', - indicator: 'bui-CheckboxIndicator', - }, - dataAttributes: { - selected: [true, false] as const, - }, - }, - Container: { - classNames: { - root: 'bui-Container', - }, - utilityProps: ['my', 'mt', 'mb', 'py', 'pt', 'pb', 'display'], - }, - Dialog: { - classNames: { - overlay: 'bui-DialogOverlay', - dialog: 'bui-Dialog', - header: 'bui-DialogHeader', - headerTitle: 'bui-DialogHeaderTitle', - body: 'bui-DialogBody', - footer: 'bui-DialogFooter', - }, - }, - Accordion: { - classNames: { - root: 'bui-Accordion', - trigger: 'bui-AccordionTrigger', - triggerButton: 'bui-AccordionTriggerButton', - triggerTitle: 'bui-AccordionTriggerTitle', - triggerSubtitle: 'bui-AccordionTriggerSubtitle', - triggerIcon: 'bui-AccordionTriggerIcon', - panel: 'bui-AccordionPanel', - group: 'bui-AccordionGroup', - }, - }, - FieldError: { - classNames: { - root: 'bui-FieldError', - }, - }, - FieldLabel: { - classNames: { - root: 'bui-FieldLabelWrapper', - label: 'bui-FieldLabel', - secondaryLabel: 'bui-FieldSecondaryLabel', - description: 'bui-FieldDescription', - }, - }, - Flex: { - classNames: { - root: 'bui-Flex', - }, - utilityProps: [ - 'm', - 'mb', - 'ml', - 'mr', - 'mt', - 'mx', - 'my', - 'p', - 'pb', - 'pl', - 'pr', - 'pt', - 'px', - 'py', - 'gap', - 'align', - 'justify', - 'direction', - ], - }, - Grid: { - classNames: { - root: 'bui-Grid', - }, - utilityProps: [ - 'columns', - 'gap', - 'm', - 'mb', - 'ml', - 'mr', - 'mt', - 'mx', - 'my', - 'p', - 'pb', - 'pl', - 'pr', - 'pt', - 'px', - 'py', - ], - }, - GridItem: { - classNames: { - root: 'bui-GridItem', - }, - utilityProps: ['colSpan', 'colEnd', 'colStart', 'rowSpan'], - }, - Header: { - classNames: { - toolbar: 'bui-HeaderToolbar', - toolbarWrapper: 'bui-HeaderToolbarWrapper', - toolbarContent: 'bui-HeaderToolbarContent', - toolbarControls: 'bui-HeaderToolbarControls', - toolbarIcon: 'bui-HeaderToolbarIcon', - toolbarName: 'bui-HeaderToolbarName', - tabsWrapper: 'bui-HeaderTabsWrapper', - }, - }, - HeaderPage: { - classNames: { - root: 'bui-HeaderPage', - content: 'bui-HeaderPageContent', - breadcrumbs: 'bui-HeaderPageBreadcrumbs', - tabsWrapper: 'bui-HeaderPageTabsWrapper', - controls: 'bui-HeaderPageControls', - }, - }, - Heading: { - classNames: { - root: 'bui-Heading', - }, - dataAttributes: { - variant: ['title1', 'title2', 'title3', 'subtitle'] as const, - color: ['primary', 'secondary', 'muted'] as const, - truncate: [true, false] as const, - }, - }, - Icon: { - classNames: { - root: 'bui-Icon', - }, - }, - Link: { - classNames: { - root: 'bui-Link', - }, - dataAttributes: { - variant: ['subtitle', 'body', 'caption', 'label'] as const, - weight: ['regular', 'bold'] as const, - color: ['primary', 'secondary', 'danger', 'warning', 'success'] as const, - truncate: [true, false] as const, - }, - }, - List: { - classNames: { - root: 'bui-List', - row: 'bui-ListRow', - label: 'bui-ListLabel', - }, - }, - Menu: { - classNames: { - root: 'bui-Menu', - popover: 'bui-MenuPopover', - content: 'bui-MenuContent', - section: 'bui-MenuSection', - sectionHeader: 'bui-MenuSectionHeader', - item: 'bui-MenuItem', - itemListBox: 'bui-MenuItemListBox', - itemListBoxCheck: 'bui-MenuItemListBoxCheck', - itemWrapper: 'bui-MenuItemWrapper', - itemContent: 'bui-MenuItemContent', - itemArrow: 'bui-MenuItemArrow', - separator: 'bui-MenuSeparator', - searchField: 'bui-MenuSearchField', - searchFieldInput: 'bui-MenuSearchFieldInput', - searchFieldClear: 'bui-MenuSearchFieldClear', - emptyState: 'bui-MenuEmptyState', - }, - }, - PasswordField: { - classNames: { - root: 'bui-PasswordField', - inputWrapper: 'bui-PasswordFieldInputWrapper', - input: 'bui-PasswordFieldInput', - inputIcon: 'bui-PasswordFieldIcon', - inputVisibility: 'bui-PasswordFieldVisibility', - }, - dataAttributes: { - size: ['small', 'medium'] as const, - }, - }, - Popover: { - classNames: { - root: 'bui-Popover', - }, - }, - RadioGroup: { - classNames: { - root: 'bui-RadioGroup', - content: 'bui-RadioGroupContent', - radio: 'bui-Radio', - }, - }, - SearchField: { - classNames: { - root: 'bui-SearchField', - clear: 'bui-SearchFieldClear', - inputWrapper: 'bui-SearchFieldInputWrapper', - input: 'bui-SearchFieldInput', - inputIcon: 'bui-SearchFieldInputIcon', - }, - dataAttributes: { - startCollapsed: [true, false] as const, - size: ['small', 'medium'] as const, - }, - }, - Select: { - classNames: { - root: 'bui-Select', - popover: 'bui-SelectPopover', - trigger: 'bui-SelectTrigger', - chevron: 'bui-SelectTriggerChevron', - value: 'bui-SelectValue', - list: 'bui-SelectList', - item: 'bui-SelectItem', - itemIndicator: 'bui-SelectItemIndicator', - itemLabel: 'bui-SelectItemLabel', - searchWrapper: 'bui-SelectSearchWrapper', - search: 'bui-SelectSearch', - searchClear: 'bui-SelectSearchClear', - noResults: 'bui-SelectNoResults', - }, - dataAttributes: { - size: ['small', 'medium'] as const, - }, - }, - Skeleton: { - classNames: { - root: 'bui-Skeleton', - }, - }, - Switch: { - classNames: { - root: 'bui-Switch', - indicator: 'bui-SwitchIndicator', - }, - }, - Table: { - classNames: { - table: 'bui-Table', - header: 'bui-TableHeader', - body: 'bui-TableBody', - row: 'bui-TableRow', - head: 'bui-TableHead', - headContent: 'bui-TableHeadContent', - headSortButton: 'bui-TableHeadSortButton', - caption: 'bui-TableCaption', - cell: 'bui-TableCell', - cellContentWrapper: 'bui-TableCellContentWrapper', - cellContent: 'bui-TableCellContent', - cellIcon: 'bui-TableCellIcon', - cellProfileAvatar: 'bui-TableCellProfileAvatar', - cellProfileAvatarImage: 'bui-TableCellProfileAvatarImage', - cellProfileAvatarFallback: 'bui-TableCellProfileAvatarFallback', - cellProfileName: 'bui-TableCellProfileName', - cellProfileLink: 'bui-TableCellProfileLink', - }, - }, - TablePagination: { - classNames: { - root: 'bui-TablePagination', - left: 'bui-TablePaginationLeft', - right: 'bui-TablePaginationRight', - select: 'bui-TablePaginationSelect', - }, - }, - Tabs: { - classNames: { - tabs: 'bui-Tabs', - tabList: 'bui-TabList', - tabListWrapper: 'bui-TabListWrapper', - tab: 'bui-Tab', - tabActive: 'bui-TabActive', - tabHovered: 'bui-TabHovered', - panel: 'bui-TabPanel', - }, - }, - TagGroup: { - classNames: { - group: 'bui-TagGroup', - list: 'bui-TagList', - tag: 'bui-Tag', - tagIcon: 'bui-TagIcon', - tagRemoveButton: 'bui-TagRemoveButton', - }, - }, - Text: { - classNames: { - root: 'bui-Text', - }, - dataAttributes: { - variant: ['subtitle', 'body', 'caption', 'label'] as const, - weight: ['regular', 'bold'] as const, - color: ['primary', 'secondary', 'danger', 'warning', 'success'] as const, - truncate: [true, false] as const, - }, - }, - TextField: { - classNames: { - root: 'bui-TextField', - inputWrapper: 'bui-InputWrapper', - input: 'bui-Input', - inputIcon: 'bui-InputIcon', - inputAction: 'bui-InputAction', - }, - dataAttributes: { - invalid: [true, false] as const, - disabled: [true, false] as const, - size: ['small', 'medium'] as const, - }, - }, - Tooltip: { - classNames: { - tooltip: 'bui-Tooltip', - arrow: 'bui-TooltipArrow', - }, - }, - VisuallyHidden: { - classNames: { - root: 'bui-VisuallyHidden', - }, - }, -} as const satisfies Record;