From f041c1fe10981ea554da91aa06548ed1d9a043a4 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Thu, 9 Oct 2025 15:50:53 +0200 Subject: [PATCH 1/3] ui: extract data-* attributes Signed-off-by: Vincenzo Scamporlino --- packages/ui/src/utils/extractProps.ts | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/ui/src/utils/extractProps.ts b/packages/ui/src/utils/extractProps.ts index 1668117909..3914072ff4 100644 --- a/packages/ui/src/utils/extractProps.ts +++ b/packages/ui/src/utils/extractProps.ts @@ -86,16 +86,25 @@ export function extractProps( } // Ensure keys from props that are defined in propDefs are removed - const cleanedProps = Object.keys(props).reduce((acc, key) => { - if (!propDefs.hasOwnProperty(key)) { - acc[key] = props[key]; - } - return acc; - }, {} as { [key: string]: any }); + const { cleanedProps, dataProps } = Object.keys(props).reduce( + (acc, key) => { + if (key.startsWith('data-')) { + acc.dataProps[key] = props[key]; + } + if (!propDefs.hasOwnProperty(key)) { + acc.cleanedProps[key] = props[key]; + } + return acc; + }, + { dataProps: {}, cleanedProps: {} } as { + dataProps: { [key: string]: any }; + cleanedProps: { [key: string]: any }; + }, + ); const newClassNames = className .filter(name => name && name.trim() !== '') .join(' '); - return { ...cleanedProps, className: newClassNames, style }; + return { ...cleanedProps, className: newClassNames, style, dataProps }; } From 03050a6ad426e6ed6893ca179a3deb2cf899f194 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Thu, 9 Oct 2025 15:51:33 +0200 Subject: [PATCH 2/3] ui: make sure data attributes are passed down to the DOM Signed-off-by: Vincenzo Scamporlino --- packages/ui/src/components/Box/Box.tsx | 3 ++- packages/ui/src/components/Container/Container.tsx | 3 ++- packages/ui/src/components/Flex/Flex.tsx | 3 ++- packages/ui/src/components/Grid/Grid.tsx | 6 ++++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/ui/src/components/Box/Box.tsx b/packages/ui/src/components/Box/Box.tsx index 4273ee86f9..06d7d1d434 100644 --- a/packages/ui/src/components/Box/Box.tsx +++ b/packages/ui/src/components/Box/Box.tsx @@ -40,11 +40,12 @@ export const Box = forwardRef((props, ref) => { }; const { classNames } = useStyles('Box'); - const { className, style } = extractProps(props, propDefs); + const { className, style, dataProps } = extractProps(props, propDefs); return createElement(props.as || 'div', { ref, className: clsx(classNames.root, className), + ...dataProps, style, children, }); diff --git a/packages/ui/src/components/Container/Container.tsx b/packages/ui/src/components/Container/Container.tsx index 7be4e5fdce..eef1e187c4 100644 --- a/packages/ui/src/components/Container/Container.tsx +++ b/packages/ui/src/components/Container/Container.tsx @@ -43,11 +43,12 @@ export const Container = forwardRef( ...displayPropDefs, ...containerSpacingProps, }; - const { className, style } = extractProps(props, propDefs); + const { className, style, dataProps } = extractProps(props, propDefs); return createElement('div', { ref, className: clsx(classNames.root, className), + ...dataProps, style, children, }); diff --git a/packages/ui/src/components/Flex/Flex.tsx b/packages/ui/src/components/Flex/Flex.tsx index ded4fffffa..021fe87820 100644 --- a/packages/ui/src/components/Flex/Flex.tsx +++ b/packages/ui/src/components/Flex/Flex.tsx @@ -32,11 +32,12 @@ export const Flex = forwardRef((props, ref) => { }; const { classNames } = useStyles('Flex'); - const { className, style } = extractProps(props, propDefs); + const { className, style, dataProps } = extractProps(props, propDefs); return createElement('div', { ref, className: clsx(classNames.root, className), + ...dataProps, style, children: props.children, }); diff --git a/packages/ui/src/components/Grid/Grid.tsx b/packages/ui/src/components/Grid/Grid.tsx index 27257c8972..18ed40b87b 100644 --- a/packages/ui/src/components/Grid/Grid.tsx +++ b/packages/ui/src/components/Grid/Grid.tsx @@ -32,11 +32,12 @@ const GridRoot = forwardRef((props, ref) => { const { classNames } = useStyles('Grid'); - const { className, style } = extractProps(props, propDefs); + const { className, style, dataProps } = extractProps(props, propDefs); return createElement('div', { ref, className: clsx(classNames.root, className), + ...dataProps, style, children: props.children, }); @@ -48,11 +49,12 @@ const GridItem = forwardRef((props, ref) => { }; const { classNames } = useStyles('Grid'); - const { className, style } = extractProps(props, propDefs); + const { className, style, dataProps } = extractProps(props, propDefs); return createElement('div', { ref, className: clsx(classNames.item, className), + ...dataProps, style, children: props.children, }); From b94006200dbd4eb0aa363249d31b3b3f5775343a Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Thu, 9 Oct 2025 15:53:57 +0200 Subject: [PATCH 3/3] ui: data attributes changesets Signed-off-by: Vincenzo Scamporlino --- .changeset/open-symbols-find.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/open-symbols-find.md diff --git a/.changeset/open-symbols-find.md b/.changeset/open-symbols-find.md new file mode 100644 index 0000000000..a7d4908980 --- /dev/null +++ b/.changeset/open-symbols-find.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Added support for data attributes in ``, ``, ``, and `` components, ensuring they are correctly applied to the rendered elements.