diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index e3e8fc8563..d44263244b 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -8,7 +8,7 @@ -Closes # +Closes [HDS-xxxx](https://helsinkisolutionoffice.atlassian.net/browse/HDS-xxxx) ## Motivation and Context @@ -17,10 +17,12 @@ Closes # ## How Has This Been Tested? ## Demos: + Links to demos are in the comments ## Screenshots (if appropriate): ## Add to changelog -- [ ] Added needed line to changelog + +- [ ] Added needed line to changelog diff --git a/.github/workflows/hds-demo-preview-clean.yml b/.github/workflows/hds-demo-preview-clean.yml index 27068529ea..44266bb014 100644 --- a/.github/workflows/hds-demo-preview-clean.yml +++ b/.github/workflows/hds-demo-preview-clean.yml @@ -5,11 +5,12 @@ on: branches: - development - release-* + - 'feature/*' types: - closed jobs: - build_and_publish_demo: + build_and_publish_demo: if: github.event.pull_request.draft == false runs-on: ubuntu-latest diff --git a/.github/workflows/hds-demo-preview.yml b/.github/workflows/hds-demo-preview.yml index 3faa864ab6..d5bcf9fce9 100644 --- a/.github/workflows/hds-demo-preview.yml +++ b/.github/workflows/hds-demo-preview.yml @@ -5,14 +5,15 @@ on: branches: - development - release-* + - 'feature/*' push: branches: - development - release-* - + - 'feature/*' jobs: - build_and_publish_demo: + build_and_publish_demo: if: github.event.pull_request.draft == false runs-on: ubuntu-latest @@ -38,7 +39,7 @@ jobs: - name: get yarn cache directory path id: yarn-cache-dir-path run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - + - name: restore yarn cache uses: actions/cache@v4 id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) @@ -113,7 +114,7 @@ jobs: - name: Copy build results run: cp -r ./site/public/* ./hds-demo/docs/$DEMO_NAME - - name: Commit + - name: Commit run: | git config --global user.email "hds@hel.fi" git config --global user.name "Github Actions" @@ -121,6 +122,7 @@ jobs: git add . git commit -m "Updated preview to $DEMO_NAME" git status + git pull --rebase git push working-directory: ./hds-demo @@ -135,5 +137,3 @@ jobs: [Docs](https://city-of-helsinki.github.io/hds-demo/${{ env.DEMO_NAME }}) [Core Storybook](https://city-of-helsinki.github.io/hds-demo/${{ env.DEMO_NAME }}/storybook/core) [React Storybook](https://city-of-helsinki.github.io/hds-demo/${{ env.DEMO_NAME }}/storybook/react) - - diff --git a/.github/workflows/update-icon-library.yml b/.github/workflows/update-icon-library.yml index 3efa620ba0..025394a0b4 100644 --- a/.github/workflows/update-icon-library.yml +++ b/.github/workflows/update-icon-library.yml @@ -118,6 +118,7 @@ jobs: # Update docsite icon list - name: Run curl to get data from figma + if: steps.build_checker.outputs.SKIP_REST_STEPS != 'true' run: | curl -H "X-FIGMA-TOKEN: ${API_KEY}" "https://api.figma.com/v1/files/${FILE_KEY}/nodes?ids=${NODE_ID}&depth=2" | \ jq --arg nodeid $NODE_ID '.nodes[$nodeid].document.children | .[] | {group: .name?, icon: .children[]?.name?}' | \ @@ -127,6 +128,7 @@ jobs: working-directory: ./site - name: regenerate iconlist + if: steps.build_checker.outputs.SKIP_REST_STEPS != 'true' run: | yarn iconlist working-directory: ./site @@ -138,4 +140,7 @@ jobs: git config --global user.name "Github Actions" git add . git commit -m 'Updated icon library' - git push \ No newline at end of file + git push + + - name: End + run: echo "Done!" \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a2475d9b1f..60d1b9a356 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,91 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.10.0] - Sep, 04, 2024 + +### React + +#### Added + +- [ssr] getCriticalHdsRulesSync, a syncronous version of the getCriticalHdsRules + +#### Changed + +- [Accordion] Component accepts all div element properties +- [Breadcrumb] Component accepts all nav element properties +- [Button] Component accepts all button element properties +- [Card] Component accepts all div element properties +- [Checkbox] Component accepts all input element properties +- [Columns] Component accepts all div element properties +- [DateInput] Component accepts all input element properties +- [Dialog] Component and its subcomponents accept all native elements properties +- [FileInput] Component accepts all div element properties +- [ErrorSummary] Component accepts all div element properties +- [Fieldset] Component accepts all fieldset element properties +- [Footer] Component and its subcomponents accept all native elements properties +- [Header] Component and its subcomponents accept all native elements properties +- [Hero] Component and its subcomponents accept all native elements properties +- [Highlight] Component accepts all figure element properties +- [ImageWithCard] Component accepts all div element properties +- [Koros] Component accepts all div element properties +- [Logo] Component accepts all img element properties +- [Notification] Component accepts all div element properties +- [SearchInput] Component and its subcomponents accept all native elements properties +- [Pagination] Component accepts all nav element properties +- [Section] Component accepts all div element properties +- [StatusLabel] Component accepts all span element properties +- [StepByStep] Component accepts all div element properties +- [Stepper] Component accepts all div element properties +- [Tabs] Component accepts all div element properties +- [Tags] Component accepts all div element properties +- [TextInput] Component accepts all input element properties +- [ToggleButton] Component accepts all button element properties +- [ToolTip] Component accepts all div element properties +- [BreadCrumb] ariaLabel is marked deprecated and aria-label should be used. +- [Footer.Base] ariaLabel is marked deprecated and aria-label should be used. +- [Footer.Custom] ariaLabel is marked deprecated and aria-label should be used. +- [Footer.Link] ariaLabel is marked deprecated and aria-label should be used. +- [Footer.Navigation] ariaLabel is marked deprecated and aria-label should be used. +- [Footer.Utilities] ariaLabel is marked deprecated and aria-label should be used. +- [Footer] ariaLabel is marked deprecated and aria-label should be used. +- [Header.ActionBar] ariaLabel is marked deprecated and aria-label should be used. +- [Header.ActionBarItem] ariaLabel is marked deprecated and aria-label should be used. +- [Header.LanguageSelector] ariaLabel is marked deprecated and aria-label should be used. +- [Header.NavigationMenu] ariaLabel is marked deprecated and aria-label should be used. +- [Header.HeaderUniversalBar] ariaLabel is marked deprecated and aria-label should be used. +- [Link] ariaLabel is marked deprecated and aria-label should be used. +- [Logo] dataTestId is marked deprecated and data-testid should be used. +- [Notification] dataTestId is marked deprecated and data-testid should be used. +- [Pagination] dataTestId is marked deprecated and data-testid should be used. +- [SideNavigation] ariaLabel is marked deprecated and aria-label should be used. +- [StatusLabel] dataTestId is marked deprecated and data-testid should be used. +- [Step] dataTestId is marked deprecated and data-testid should be used. +- [Stepper] dataTestId is marked deprecated and data-testid should be used. +- [Icon] ariaLabel, ariaLabelledby and ariaHidden are marked deprecated and aria-\* should be used. +- [Skiplink] ariaLabel is marked deprecated and aria-label should be used. +- [Table] dataTestId is marked deprecated and data-testid should be used. + +#### Fixed + +- [Header] Fixed an issue with ActionBarItem dropdowns not inside the menu in mobile +- [Header] Fix broken layout in mobile menu animations +- [Dialog] Fix broken scrolling and zooming in mobile devices + +### Documentation + +#### Added + +- [ssr] Solution to use HDS styles with Next.js app router. + +#### Changed + +- [ssr] Improved documentation about using HDS styles with Next.js pages router. +- [Header] Added more detailed documentation. + +#### Fixed + +- [Grids] Fixed breakpoint-xs margin value from 12px to 16px to match implementation + ## [3.9.0] - June, 2nd, 2024 ### React @@ -55,6 +140,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Figma #### Added + - [Header] New functionalities for Actionbar: Action items can have an option for dropdown menus. For now only Logged in user has custom user menu and button (Header.Login) - [Header] In mobile breakpoints (XS-M) login button and logged-in user menu jump inside the Header.Mobilemenu that has a special accordion menu for dropdown. - [Header] Added missing Breadcrumbs to dark theme. @@ -64,11 +150,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [PhoneInput, PasswordInput] Added missing read-only focus ring. #### Fixed + - [Header] Mobilemenu link 2nd level names changed to Second level. - [Header] Mobilemenu now aligned to right border. Menu button should always be the rightmost element in mobile breakpoints. - [Hero] Flipped image 180 degrees in imageLeft, imageRight, imageBottom in XS size and diagonalKoros in all sizes. #### Changed + - [Header] Login button now has sign-in icon instead of user - old Login actionitem is removed, please use Header.Login. - [Header] Breakpoint width numbers added to property names to match Footer - [Header] Nested instances revealed diff --git a/e2e/package.json b/e2e/package.json index e405ffacdf..70818fa4df 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -2,7 +2,7 @@ "name": "e2e", "private": true, "description": "e2e tests using Playwright", - "version": "3.9.0", + "version": "3.10.0", "scripts": { "inst": "yarn playwright install", "ci": "npx playwright test", diff --git a/packages/core/package.json b/packages/core/package.json index d9c4da28e2..886ce36bc4 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "hds-core", - "version": "3.9.0", + "version": "3.10.0", "description": "Core styles for the Helsinki Design System", "homepage": "https://github.com/City-of-Helsinki/helsinki-design-system#readme", "license": "MIT", @@ -32,7 +32,7 @@ "@storybook/manager-webpack5": "^6.5.16", "copyfiles": "2.2.0", "cssnano": "4.1.10", - "hds-design-tokens": "3.9.0", + "hds-design-tokens": "3.10.0", "postcss": "8.2.15", "postcss-cli": "8.3.1", "postcss-import": "12.0.1", diff --git a/packages/design-tokens/package.json b/packages/design-tokens/package.json index 3a25b0ce26..0dee3a5100 100644 --- a/packages/design-tokens/package.json +++ b/packages/design-tokens/package.json @@ -1,6 +1,6 @@ { "name": "hds-design-tokens", - "version": "3.9.0", + "version": "3.10.0", "description": "Design tokens for the Helsinki Design System", "homepage": "https://github.com/City-of-Helsinki/helsinki-design-system#readme", "license": "MIT", diff --git a/packages/hds-js/package.json b/packages/hds-js/package.json index 30d85518a0..305816eb7e 100644 --- a/packages/hds-js/package.json +++ b/packages/hds-js/package.json @@ -1,6 +1,6 @@ { "name": "hds-js", - "version": "3.9.0", + "version": "3.10.0", "description": "Vanilla js for the Helsinki Design System", "homepage": "https://github.com/City-of-Helsinki/helsinki-design-system#readme", "license": "MIT", diff --git a/packages/react/.eslintrc.json b/packages/react/.eslintrc.json index 04f839ed12..c0094512a0 100644 --- a/packages/react/.eslintrc.json +++ b/packages/react/.eslintrc.json @@ -90,7 +90,33 @@ } ], "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "error" + "@typescript-eslint/no-unused-vars": "error", + "react/forbid-component-props": [ + "error", + { + "forbid": [ + { + "propNamePattern": "aria[A-Z][a-z]*", + "message": "Use native 'aria-*' props instead of creating new props like ariaLabel'." + }, + { + "propNamePattern": "{dataTestId,data-test-id}", + "message": "The 'data-testid' is the only acceptable format for test ids. Jest supports only this." + } + ] + } + ], + "@typescript-eslint/naming-convention": [ + "error", + { + "selector": "typeProperty", + "format": null, + "custom": { + "regex": "(aria[A-Z][a-z]+|dataTestId|data-test-id)", + "match": false + } + } + ] }, "settings": { "react": { diff --git a/packages/react/.loki/reference/chrome_iphone7_Components_Login_Callback.png b/packages/react/.loki/reference/chrome_iphone7_Components_Login_Callback.png index dc92631c64..eea85c2584 100644 Binary files a/packages/react/.loki/reference/chrome_iphone7_Components_Login_Callback.png and b/packages/react/.loki/reference/chrome_iphone7_Components_Login_Callback.png differ diff --git a/packages/react/.loki/reference/chrome_laptop_Components_Login_Callback.png b/packages/react/.loki/reference/chrome_laptop_Components_Login_Callback.png index a4e62292a3..e46216f2d8 100644 Binary files a/packages/react/.loki/reference/chrome_laptop_Components_Login_Callback.png and b/packages/react/.loki/reference/chrome_laptop_Components_Login_Callback.png differ diff --git a/packages/react/package.json b/packages/react/package.json index 55887fa760..650fea78bd 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "hds-react", - "version": "3.9.0", + "version": "3.10.0", "description": "React components for the Helsinki Design System", "homepage": "https://github.com/City-of-Helsinki/helsinki-design-system#readme", "license": "MIT", @@ -87,7 +87,7 @@ "eslint-plugin-jest": "^27.6.3", "eslint-plugin-jsx-a11y": "^6.6.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react": "^7.35.0", "eslint-plugin-react-hooks": "^4.6.0", "identity-obj-proxy": "3.0.0", "inquirer": "7.1.0", @@ -138,7 +138,7 @@ "date-fns": "2.16.1", "downshift": "6.0.6", "graphql": "^16.8.1", - "hds-core": "3.9.0", + "hds-core": "3.10.0", "http-status-typed": "^1.0.1", "jwt-decode": "^3.1.2", "kashe": "1.0.4", diff --git a/packages/react/src/components/accordion/Accordion.stories.tsx b/packages/react/src/components/accordion/Accordion.stories.tsx index 3941d76db7..0f755a21e0 100644 --- a/packages/react/src/components/accordion/Accordion.stories.tsx +++ b/packages/react/src/components/accordion/Accordion.stories.tsx @@ -4,7 +4,7 @@ import { IconAngleDown, IconAngleUp } from '../../icons'; import { Button } from '../button'; import { Card } from '../card'; import { Select } from '../dropdown/select'; -import { Accordion } from './Accordion'; +import { Accordion, AccordionProps } from './Accordion'; import { useAccordion } from './useAccordion'; export default { @@ -22,18 +22,18 @@ export default { }, }; -export const Default = (args) => ; +export const Default = (args: AccordionProps) => ; -export const Small = (args) => ; +export const Small = (args: AccordionProps) => ; -export const Medium = (args) => ; +export const Medium = (args: AccordionProps) => ; -export const Large = (args) => ; +export const Large = (args: AccordionProps) => ; -export const WithoutCloseButton = (args) => ; +export const WithoutCloseButton = (args: AccordionProps) => ; WithoutCloseButton.storyName = 'Without close button'; -export const StackedAccordionCards = (args) => ( +export const StackedAccordionCards = (args: AccordionProps) => ( <>

Stacked Accordions in Cards

@@ -44,10 +44,10 @@ export const StackedAccordionCards = (args) => ( StackedAccordionCards.storyName = 'Stacked cards'; -export const InitiallyOpen = (args) => ; +export const InitiallyOpen = (args: AccordionProps) => ; InitiallyOpen.storyName = 'Initially open'; -export const CardAccordion = (args) => ( +export const CardAccordion = (args: AccordionProps) => ( <>

Card

@@ -64,7 +64,7 @@ CardAccordion.args = { style: { marginBottom: 'var(--spacing-m)', maxWidth: '360px' }, }; -export const CustomTheme = (args) => ( +export const CustomTheme = (args: AccordionProps) => ( <> ( '--header-line-height': 'var(--lineheight-s)', '--header-letter-spacing': '-0.4px', '--button-size': '28px', - '--button-border-color-hover': 'var(--color-coat-of-arms)', + '--close-button-border-color-hover': 'var(--color-coat-of-arms)', '--content-font-color': 'var(--color-black-90)', '--content-font-size': 'var(--fontsize-body-m)', '--content-line-height': 'var(--lineheight-l)', @@ -102,7 +102,7 @@ export const CustomTheme = (args) => ( '--header-letter-spacing': '0.2px', '--header-line-height': '1.4', '--button-size': '28px', - '--button-border-color-hover': 'var(--color-white)', + '--close-button-border-color-hover': 'var(--color-white)', '--content-font-color': 'var(--color-white)', '--content-font-size': 'var(--fontsize-body-m)', '--content-line-height': 'var(--lineheight-l)', diff --git a/packages/react/src/components/accordion/Accordion.test.tsx b/packages/react/src/components/accordion/Accordion.test.tsx index 0d0398ccba..06eb77f643 100644 --- a/packages/react/src/components/accordion/Accordion.test.tsx +++ b/packages/react/src/components/accordion/Accordion.test.tsx @@ -4,6 +4,7 @@ import { axe } from 'jest-axe'; import userEvent from '@testing-library/user-event'; import { Accordion } from './Accordion'; +import { getElementAttributesMisMatches, getCommonElementTestProps } from '../../utils/testHelpers'; describe(' spec', () => { afterAll(() => { @@ -21,6 +22,17 @@ describe(' spec', () => { expect(results).toHaveNoViolations(); }); + it('Native html props are passed to the element', async () => { + const divProps = { ...getCommonElementTestProps('div') }; + const { getByTestId } = render( + + Bar + , + ); + const element = getByTestId(divProps['data-testid']); + expect(getElementAttributesMisMatches(element, divProps)).toHaveLength(0); + }); + it('should open the accordion when accordion header is clicked', async () => { const { container } = render( diff --git a/packages/react/src/components/accordion/Accordion.tsx b/packages/react/src/components/accordion/Accordion.tsx index 43a29b948b..198cd63ae9 100644 --- a/packages/react/src/components/accordion/Accordion.tsx +++ b/packages/react/src/components/accordion/Accordion.tsx @@ -9,35 +9,60 @@ import { useAccordion } from './useAccordion'; import { useTheme } from '../../hooks/useTheme'; import { Button } from '../button'; import useHasMounted from '../../hooks/useHasMounted'; +import { AllElementPropsWithoutRef } from '../../utils/elementTypings'; export interface AccordionCustomTheme { '--background-color'?: string; '--border-color'?: string; '--padding-horizontal'?: string; '--padding-vertical'?: string; + /** + * @deprecated Will be replaced with --header-color in the next major release + */ '--header-font-color'?: string; '--header-font-size'?: string; + '--header-font-weight'?: string; + '--header-letter-spacing'?: string; '--header-line-height'?: string; + /** + * @deprecated Will be replaced with --icon-size in the next major release + */ '--button-size'?: string; + /** + * @deprecated Will be replaced with --header-outline-color-focus in the next major release + */ '--header-focus-outline-color'?: string; + '--content-font-color'?: string; '--content-font-size'?: string; '--content-line-height'?: string; '--close-button-background-color-disabled'?: string; '--close-button-background-color-focus'?: string; + /** + * @deprecated Will be removed in the next major release + */ '--close-button-background-color-hover-focus'?: string; '--close-button-background-color-hover'?: string; '--close-button-background-color'?: string; '--close-button-border-color-active'?: string; '--close-button-border-color-disabled'?: string; '--close-button-border-color-focus'?: string; + /** + * @deprecated Will be removed in the next major release + */ '--close-button-border-color-hover-focus'?: string; '--close-button-border-color-hover'?: string; '--close-button-border-color'?: string; '--close-button-color-disabled'?: string; '--close-button-color-focus'?: string; + /** + * @deprecated Will be removed in the next major release + */ '--close-button-color-hover-focus'?: string; '--close-button-color-hover'?: string; '--close-button-color'?: string; + /** + * @deprecated Will be replaced with --close-button-outline-color-focus in the next major release + */ '--close-button-focus-outline-color'?: string; } @@ -115,7 +140,7 @@ export type CardAccordionProps = Omit & card: true; }; -export type AccordionProps = CommonAccordionProps | CardAccordionProps; +export type AccordionProps = AllElementPropsWithoutRef<'div'> & (CommonAccordionProps | CardAccordionProps); const getCloseMessage = (language: Language): string => { return { @@ -138,14 +163,13 @@ export const Accordion = ({ initiallyOpen = false, language = 'fi', size = 'm', - style, theme, + ...rest }: AccordionProps) => { const headerRef = useRef(null); const [beforeCloseButtonClick, setBeforeCloseButtonClick] = useState(false); // Create a unique id if not provided via prop const [accordionId] = useState(id || uniqueId('accordion-')); - // Custom themes const sovereignThemeVariables = theme && { '--background-color': theme['--background-color'], @@ -240,6 +264,7 @@ export const Accordion = ({ return (
diff --git a/packages/react/src/components/breadcrumb/Breadcrumb.stories.tsx b/packages/react/src/components/breadcrumb/Breadcrumb.stories.tsx index 9bc6bc9f75..e99cd9e302 100644 --- a/packages/react/src/components/breadcrumb/Breadcrumb.stories.tsx +++ b/packages/react/src/components/breadcrumb/Breadcrumb.stories.tsx @@ -1,7 +1,8 @@ +/* eslint-disable react/forbid-component-props */ import React from 'react'; import { Header } from '../header/Header'; -import { Breadcrumb } from './Breadcrumb'; +import { Breadcrumb, BreadcrumbProps } from './Breadcrumb'; import { Link } from '../link'; import { LanguageOption } from '../header/LanguageContext'; import { Container } from '../container/Container'; @@ -32,9 +33,9 @@ const languages: LanguageOption[] = [ { label: 'English', value: 'en' }, ]; -export const Example = (args) => ; +export const Example = (args: BreadcrumbProps) => ; -export const ExampleInHeader = (args) => { +export const ExampleInHeader = (args: BreadcrumbProps) => { return ( <>
@@ -105,7 +106,7 @@ export const ExampleInHeader = (args) => { ExampleInHeader.storyName = 'Breadcrumb in header'; -export const LastItemIsLink = (args) => ( +export const LastItemIsLink = (args: BreadcrumbProps) => ( ( LastItemIsLink.storyName = 'Last item a link'; -export const WithCustomTheme = (args) => ( +export const WithCustomTheme = (args: BreadcrumbProps) => ( spec', () => { const defaultProps: BreadcrumbProps = { @@ -25,6 +26,18 @@ describe(' spec', () => { const results = await axe(container); expect(results).toHaveNoViolations(); }); + it('native html props are passed to the element', async () => { + const navProps = getCommonElementTestProps<'nav'>('nav'); + // BreadCrumb has prop "ariaLabel". It will override "aria-label". + navProps['aria-label'] = defaultProps.ariaLabel; + const expectedProps = { + ...navProps, + ...defaultProps, + }; + const { getByTestId } = render(); + const element = getByTestId(navProps['data-testid']); + expect(getElementAttributesMisMatches(element, navProps)).toHaveLength(0); + }); it('Mobile view renders the last item with a path. That item is rendered twice: in the desktop and mobile views.', async () => { const { getAllByText, getByText, container } = render(); const defaultList = defaultProps.list; diff --git a/packages/react/src/components/breadcrumb/Breadcrumb.tsx b/packages/react/src/components/breadcrumb/Breadcrumb.tsx index 7dd44affbc..a5272a9bc2 100644 --- a/packages/react/src/components/breadcrumb/Breadcrumb.tsx +++ b/packages/react/src/components/breadcrumb/Breadcrumb.tsx @@ -6,6 +6,7 @@ import { Link } from '../link'; import { IconAngleLeft, IconAngleRight } from '../../icons'; import classNames from '../../utils/classNames'; import { useTheme } from '../../hooks/useTheme'; +import { AllElementPropsWithoutRef } from '../../utils/elementTypings'; export interface BreadcrumbCustomTheme { /** @@ -32,10 +33,12 @@ export interface BreadcrumbCustomTheme { } export type BreadcrumbListItem = { title: string; path: string | null }; -export type BreadcrumbProps = { +export type BreadcrumbProps = AllElementPropsWithoutRef<'nav'> & { /** * Aria-label for the created