From fe0f7dab85af2cdd3e99be36b1599758277b6f2d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Nov 2025 19:56:41 +0000 Subject: [PATCH 1/4] Initial plan From 2e2dc15c1fd54c492d586d3a4b39977670a2f208 Mon Sep 17 00:00:00 2001 From: GitHub Copilot Date: Fri, 14 Nov 2025 20:14:08 +0000 Subject: [PATCH 2/4] feat: add icon code snippet popover with copy-to-clipboard functionality Co-authored-by: mfranzke <787658+mfranzke@users.noreply.github.com> --- showcases/next-showcase/tsconfig.json | 2 +- .../components/icon-code-snippet/index.tsx | 113 ++++++++++++++++++ .../pages/foundations/icons/overview.tsx | 12 +- showcases/patternhub/styles/globals.scss | 62 ++++++++++ 4 files changed, 186 insertions(+), 3 deletions(-) create mode 100644 showcases/patternhub/components/icon-code-snippet/index.tsx diff --git a/showcases/next-showcase/tsconfig.json b/showcases/next-showcase/tsconfig.json index 2e8cd0fc7f52..017b20fd23cc 100644 --- a/showcases/next-showcase/tsconfig.json +++ b/showcases/next-showcase/tsconfig.json @@ -11,7 +11,7 @@ "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve", + "jsx": "react-jsx", "strictNullChecks": true, "downlevelIteration": true, "target": "ES2017" diff --git a/showcases/patternhub/components/icon-code-snippet/index.tsx b/showcases/patternhub/components/icon-code-snippet/index.tsx new file mode 100644 index 000000000000..a2de9558de81 --- /dev/null +++ b/showcases/patternhub/components/icon-code-snippet/index.tsx @@ -0,0 +1,113 @@ +import { + DBButton, + DBDivider, + DBPopover +} from '../../../../output/react/src/index'; +import CopyClipboardButton from '../copy-clipboard-button'; + +export type IconCodeSnippetProps = { + iconName: string; + weight: string; + family: string; +}; + +const IconCodeSnippet = ({ + iconName, + weight, + family +}: IconCodeSnippetProps) => { + // Generate code snippets for different configurations + const generateSnippet = ( + variant: 'before' | 'after', + withWeight: boolean, + withFamily: boolean + ) => { + const parts: string[] = []; + + if (variant === 'before') { + parts.push(`data-icon="${iconName}"`); + if (withWeight) { + parts.push(`data-icon-weight="${weight}"`); + } + + if (withFamily && family !== 'default') { + parts.push(`data-icon-variant="${family}"`); + } + } else { + parts.push(`data-icon-trailing="${iconName}"`); + if (withWeight) { + parts.push(`data-icon-weight-after="${weight}"`); + } + + if (withFamily && family !== 'default') { + parts.push(`data-icon-variant-after="${family}"`); + } + } + + return `Text`; + }; + + const snippets = [ + { + title: 'Icon Before (Basic)', + code: generateSnippet('before', false, false) + }, + { + title: `Icon Before (weight: ${weight}px)`, + code: generateSnippet('before', true, false) + }, + { + title: `Icon Before (weight: ${weight}px, family: ${family})`, + code: generateSnippet('before', true, true) + }, + { + title: 'Icon After (Basic)', + code: generateSnippet('after', false, false) + }, + { + title: `Icon After (weight: ${weight}px)`, + code: generateSnippet('after', true, false) + }, + { + title: `Icon After (weight: ${weight}px, family: ${family})`, + code: generateSnippet('after', true, true) + } + ]; + + return ( + + +
+
+ {iconName} +
+ +
+ {snippets.map((snippet, index) => ( +
+
{snippet.title}
+
+ + {snippet.code} + + + Copied to clipboard + +
+
+ ))} +
+
+
+ ); +}; + +export default IconCodeSnippet; diff --git a/showcases/patternhub/pages/foundations/icons/overview.tsx b/showcases/patternhub/pages/foundations/icons/overview.tsx index 7cc28012b1fe..3ad4dc0d60ba 100644 --- a/showcases/patternhub/pages/foundations/icons/overview.tsx +++ b/showcases/patternhub/pages/foundations/icons/overview.tsx @@ -8,6 +8,7 @@ import { DBSelect } from '../../../../../output/react/src'; import DefaultPage from '../../../components/default-page'; +import IconCodeSnippet from '../../../components/icon-code-snippet'; // Import root package.json for theme version import rootPackage from '../../../../../package.json'; @@ -91,12 +92,19 @@ const IconOverview = () => { }> {ALL_ICONS.filter((icon) => icon.includes(search)).map( (icon) => ( - - {/* TODO: Make this interactive to copy the icon name */} + {icon} {icon} + ) )} diff --git a/showcases/patternhub/styles/globals.scss b/showcases/patternhub/styles/globals.scss index 1e0a058e693f..272b31cfdec3 100644 --- a/showcases/patternhub/styles/globals.scss +++ b/showcases/patternhub/styles/globals.scss @@ -172,10 +172,72 @@ div[class^="ch-"] { > .db-card { justify-content: center; align-items: center; + position: relative; .db-infotext { word-break: break-word; } + + .db-button[aria-label^="Show code"] { + position: absolute; + inset-inline-end: variables.$db-spacing-fixed-xs; + inset-block-start: variables.$db-spacing-fixed-xs; + } + } +} + +// Icon code snippet popover styles +.icon-code-snippet-container { + @include display.display(flex); + flex-direction: column; + gap: variables.$db-spacing-fixed-sm; + min-inline-size: 300px; + max-inline-size: 500px; + + .icon-code-snippet-header { + @include display.display(flex); + justify-content: space-between; + align-items: center; + } + + .icon-code-snippet-content { + @include display.display(flex); + flex-direction: column; + gap: variables.$db-spacing-fixed-md; + max-block-size: 400px; + overflow-y: auto; + + .snippet-item { + @include display.display(flex); + flex-direction: column; + gap: variables.$db-spacing-fixed-xs; + + .snippet-title { + font-weight: bold; + @extend %db-overwrite-font-size-sm; + } + + .snippet-code-container { + @include display.display(flex); + align-items: flex-start; + gap: variables.$db-spacing-fixed-xs; + padding: variables.$db-spacing-fixed-sm; + background-color: colors.$db-adaptive-bg-basic-transparent-semi-default; + border-radius: variables.$db-border-radius-sm; + position: relative; + + .snippet-code { + flex: 1; + word-break: break-all; + white-space: pre-wrap; + @extend %db-overwrite-font-size-sm; + } + + .db-button { + flex-shrink: 0; + } + } + } } } From 2755844a17fb322394ddc77184d319e9afcca8cf Mon Sep 17 00:00:00 2001 From: Maximilian Franzke Date: Fri, 14 Nov 2025 23:39:52 +0100 Subject: [PATCH 3/4] refactor: added missing key --- showcases/patternhub/pages/foundations/icons/overview.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/showcases/patternhub/pages/foundations/icons/overview.tsx b/showcases/patternhub/pages/foundations/icons/overview.tsx index 3ad4dc0d60ba..a8bf7d2fef6c 100644 --- a/showcases/patternhub/pages/foundations/icons/overview.tsx +++ b/showcases/patternhub/pages/foundations/icons/overview.tsx @@ -66,7 +66,9 @@ const IconOverview = () => { setWeight(event.target.value); }}> {[16, 20, 24, 32].map((fw) => ( - + ))} { setFamily(event.target.value); }}> {['default', 'filled'].map((fam) => ( - + ))} From 52092821c2bb567b0528b531efae181acaf18ff4 Mon Sep 17 00:00:00 2001 From: Maximilian Franzke Date: Wed, 26 Nov 2025 20:40:44 +0100 Subject: [PATCH 4/4] refactor: optimizations --- .../components/icon-code-snippet/index.tsx | 20 +++++++++++++++++-- .../pages/foundations/icons/overview.tsx | 12 +---------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/showcases/patternhub/components/icon-code-snippet/index.tsx b/showcases/patternhub/components/icon-code-snippet/index.tsx index a2de9558de81..ba437e256218 100644 --- a/showcases/patternhub/components/icon-code-snippet/index.tsx +++ b/showcases/patternhub/components/icon-code-snippet/index.tsx @@ -1,6 +1,8 @@ import { DBButton, DBDivider, + DBIcon, + DBInfotext, DBPopover } from '../../../../output/react/src/index'; import CopyClipboardButton from '../copy-clipboard-button'; @@ -75,7 +77,18 @@ const IconCodeSnippet = ({ ]; return ( - + + {iconName} + + {iconName} + + + }> {snippets.map((snippet, index) => (
-
{snippet.title}
+
+ {iconName} + {snippet.title} +
{snippet.code} diff --git a/showcases/patternhub/pages/foundations/icons/overview.tsx b/showcases/patternhub/pages/foundations/icons/overview.tsx index a8bf7d2fef6c..2380021d60a7 100644 --- a/showcases/patternhub/pages/foundations/icons/overview.tsx +++ b/showcases/patternhub/pages/foundations/icons/overview.tsx @@ -1,12 +1,6 @@ import { ALL_ICONS } from '@db-ux/db-theme-icons'; import { useState } from 'react'; -import { - DBCard, - DBIcon, - DBInfotext, - DBInput, - DBSelect -} from '../../../../../output/react/src'; +import { DBCard, DBInput, DBSelect } from '../../../../../output/react/src'; import DefaultPage from '../../../components/default-page'; import IconCodeSnippet from '../../../components/icon-code-snippet'; @@ -100,10 +94,6 @@ const IconOverview = () => { key={icon} spacing="small" className="icon-card"> - {icon} - - {icon} -