From b0611acb9e063c8efc4763ca3cfdb3a6fc6a7ab4 Mon Sep 17 00:00:00 2001 From: Dustin Healy <54083382+dustinhealy@users.noreply.github.com> Date: Mon, 13 Apr 2026 16:11:34 -0700 Subject: [PATCH 1/6] fix(CodeBlock): prevent action buttons from overlapping code content Add padding-left and background: inherit to the button container so buttons have a solid backdrop and don't overlap the code text. --- .changeset/fix-codeblock-button-overlap.md | 5 +++++ src/components/CodeBlock/CodeBlock.tsx | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .changeset/fix-codeblock-button-overlap.md diff --git a/.changeset/fix-codeblock-button-overlap.md b/.changeset/fix-codeblock-button-overlap.md new file mode 100644 index 000000000..20815e148 --- /dev/null +++ b/.changeset/fix-codeblock-button-overlap.md @@ -0,0 +1,5 @@ +--- +"@clickhouse/click-ui": patch +--- + +Prevent CodeBlock copy/wrap buttons from overlapping code content. Adds right padding to the highlighted code area proportional to the number of action buttons displayed. diff --git a/src/components/CodeBlock/CodeBlock.tsx b/src/components/CodeBlock/CodeBlock.tsx index d38edfa59..b20f7facd 100644 --- a/src/components/CodeBlock/CodeBlock.tsx +++ b/src/components/CodeBlock/CodeBlock.tsx @@ -87,8 +87,11 @@ const CodeContent = styled.code` const ButtonContainer = styled.div` position: absolute; display: flex; + z-index: 1; + padding-left: 1rem; + background: inherit; ${({ theme }) => ` - gap: 0.625rem; + gap: 0.625rem; top: ${theme.click.codeblock.space.y}; right: ${theme.click.codeblock.space.x}; `} From 33537f1c8230575e196ad9ed5b8d12dd5474e285 Mon Sep 17 00:00:00 2001 From: Dustin Healy <54083382+dustinhealy@users.noreply.github.com> Date: Mon, 13 Apr 2026 16:22:13 -0700 Subject: [PATCH 2/6] fix(CodeBlock): show action buttons on hover with subtle background Action buttons (copy, wrap) are now hidden by default and fade in on hover or focus-within. Buttons have a semi-opaque background matching the code block theme to prevent overlap with code content. --- src/components/CodeBlock/CodeBlock.tsx | 30 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/components/CodeBlock/CodeBlock.tsx b/src/components/CodeBlock/CodeBlock.tsx index b20f7facd..aa2497006 100644 --- a/src/components/CodeBlock/CodeBlock.tsx +++ b/src/components/CodeBlock/CodeBlock.tsx @@ -46,6 +46,10 @@ const CodeBlockContainer = styled.div<{ $theme?: CodeThemeType }>` width: fill-available; width: stretch; position: relative; + &:hover ${ButtonContainer}, + &:focus-within ${ButtonContainer} { + opacity: 1; + } ${({ theme, $theme }) => { const themeName = theme.name as CodeThemeType; @@ -84,17 +88,23 @@ const CodeContent = styled.code` color: inherit; `; -const ButtonContainer = styled.div` +const ButtonContainer = styled.div<{ $theme?: CodeThemeType }>` position: absolute; display: flex; - z-index: 1; - padding-left: 1rem; - background: inherit; - ${({ theme }) => ` - gap: 0.625rem; - top: ${theme.click.codeblock.space.y}; - right: ${theme.click.codeblock.space.x}; - `} + opacity: 0; + transition: opacity 0.15s ease; + border-radius: 0.25rem; + padding: 0.25rem; + ${({ theme, $theme }) => { + const themeName = ($theme ?? theme.name) as CodeThemeType; + const bg = theme.click.codeblock[`${themeName}Mode`].color.background.default; + return ` + gap: 0.625rem; + top: calc(${theme.click.codeblock.space.y} - 0.25rem); + right: calc(${theme.click.codeblock.space.x} - 0.25rem); + background: ${bg}e6; + `; + }} `; export const CodeBlock = ({ @@ -143,7 +153,7 @@ export const CodeBlock = ({ $theme={theme} {...props} > - + {showWrapButton && ( Date: Mon, 13 Apr 2026 16:25:23 -0700 Subject: [PATCH 3/6] fix: move ButtonContainer before CodeBlockContainer to fix TS2448 --- src/components/CodeBlock/CodeBlock.tsx | 37 +++++++++++++------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/components/CodeBlock/CodeBlock.tsx b/src/components/CodeBlock/CodeBlock.tsx index aa2497006..c10c29835 100644 --- a/src/components/CodeBlock/CodeBlock.tsx +++ b/src/components/CodeBlock/CodeBlock.tsx @@ -40,6 +40,25 @@ interface CustomRendererProps { useInlineStyles: boolean; } +const ButtonContainer = styled.div<{ $theme?: CodeThemeType }>` + position: absolute; + display: flex; + opacity: 0; + transition: opacity 0.15s ease; + border-radius: 0.25rem; + padding: 0.25rem; + ${({ theme, $theme }) => { + const themeName = ($theme ?? theme.name) as CodeThemeType; + const bg = theme.click.codeblock[`${themeName}Mode`].color.background.default; + return ` + gap: 0.625rem; + top: calc(${theme.click.codeblock.space.y} - 0.25rem); + right: calc(${theme.click.codeblock.space.x} - 0.25rem); + background: ${bg}e6; + `; + }} +`; + const CodeBlockContainer = styled.div<{ $theme?: CodeThemeType }>` width: 100%; width: -webkit-fill-available; @@ -88,24 +107,6 @@ const CodeContent = styled.code` color: inherit; `; -const ButtonContainer = styled.div<{ $theme?: CodeThemeType }>` - position: absolute; - display: flex; - opacity: 0; - transition: opacity 0.15s ease; - border-radius: 0.25rem; - padding: 0.25rem; - ${({ theme, $theme }) => { - const themeName = ($theme ?? theme.name) as CodeThemeType; - const bg = theme.click.codeblock[`${themeName}Mode`].color.background.default; - return ` - gap: 0.625rem; - top: calc(${theme.click.codeblock.space.y} - 0.25rem); - right: calc(${theme.click.codeblock.space.x} - 0.25rem); - background: ${bg}e6; - `; - }} -`; export const CodeBlock = ({ children, From 9b0a0a81818d510e923af10bcf74f28bfa0602aa Mon Sep 17 00:00:00 2001 From: Dustin Healy <54083382+dustinhealy@users.noreply.github.com> Date: Mon, 13 Apr 2026 16:31:13 -0700 Subject: [PATCH 4/6] style: format CodeBlock.tsx --- src/components/CodeBlock/CodeBlock.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/CodeBlock/CodeBlock.tsx b/src/components/CodeBlock/CodeBlock.tsx index c10c29835..90c1cad84 100644 --- a/src/components/CodeBlock/CodeBlock.tsx +++ b/src/components/CodeBlock/CodeBlock.tsx @@ -65,8 +65,7 @@ const CodeBlockContainer = styled.div<{ $theme?: CodeThemeType }>` width: fill-available; width: stretch; position: relative; - &:hover ${ButtonContainer}, - &:focus-within ${ButtonContainer} { + &:hover ${ButtonContainer}, &:focus-within ${ButtonContainer} { opacity: 1; } ${({ theme, $theme }) => { @@ -107,7 +106,6 @@ const CodeContent = styled.code` color: inherit; `; - export const CodeBlock = ({ children, language, From 5c35600b9f74cc5e65825f8c63849adbe9f7bf2e Mon Sep 17 00:00:00 2001 From: Dustin Healy <54083382+dustinhealy@users.noreply.github.com> Date: Mon, 13 Apr 2026 16:33:28 -0700 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20address=20code=20review=20=E2=80=94?= =?UTF-8?q?=20reduced-motion,=20theme=20tokens,=20color-mix,=20changeset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/fix-codeblock-button-overlap.md | 2 +- src/components/CodeBlock/CodeBlock.tsx | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.changeset/fix-codeblock-button-overlap.md b/.changeset/fix-codeblock-button-overlap.md index 20815e148..1bb3a1259 100644 --- a/.changeset/fix-codeblock-button-overlap.md +++ b/.changeset/fix-codeblock-button-overlap.md @@ -2,4 +2,4 @@ "@clickhouse/click-ui": patch --- -Prevent CodeBlock copy/wrap buttons from overlapping code content. Adds right padding to the highlighted code area proportional to the number of action buttons displayed. +CodeBlock action buttons (copy, wrap) are now hidden by default and revealed on hover or focus-within with a fade transition. Buttons display a semi-opaque background pill matching the code block theme to prevent overlap with code content. diff --git a/src/components/CodeBlock/CodeBlock.tsx b/src/components/CodeBlock/CodeBlock.tsx index 90c1cad84..21ae390ea 100644 --- a/src/components/CodeBlock/CodeBlock.tsx +++ b/src/components/CodeBlock/CodeBlock.tsx @@ -45,16 +45,19 @@ const ButtonContainer = styled.div<{ $theme?: CodeThemeType }>` display: flex; opacity: 0; transition: opacity 0.15s ease; - border-radius: 0.25rem; - padding: 0.25rem; + @media (prefers-reduced-motion: reduce) { + transition: none; + } ${({ theme, $theme }) => { const themeName = ($theme ?? theme.name) as CodeThemeType; const bg = theme.click.codeblock[`${themeName}Mode`].color.background.default; return ` gap: 0.625rem; - top: calc(${theme.click.codeblock.space.y} - 0.25rem); - right: calc(${theme.click.codeblock.space.x} - 0.25rem); - background: ${bg}e6; + border-radius: ${theme.click.codeblock.radii.all}; + padding: ${theme.sizes[1]}; + top: calc(${theme.click.codeblock.space.y} - ${theme.sizes[1]}); + right: calc(${theme.click.codeblock.space.x} - ${theme.sizes[1]}); + background: color-mix(in srgb, ${bg} 90%, transparent); `; }} `; From e615c4f3d494fe37a9343cac219bce1268488061 Mon Sep 17 00:00:00 2001 From: Dustin Healy <54083382+dustinhealy@users.noreply.github.com> Date: Mon, 13 Apr 2026 16:36:12 -0700 Subject: [PATCH 6/6] fix: remove calc offsets, use original top/right positioning --- src/components/CodeBlock/CodeBlock.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/CodeBlock/CodeBlock.tsx b/src/components/CodeBlock/CodeBlock.tsx index 21ae390ea..2e5df5afc 100644 --- a/src/components/CodeBlock/CodeBlock.tsx +++ b/src/components/CodeBlock/CodeBlock.tsx @@ -55,8 +55,8 @@ const ButtonContainer = styled.div<{ $theme?: CodeThemeType }>` gap: 0.625rem; border-radius: ${theme.click.codeblock.radii.all}; padding: ${theme.sizes[1]}; - top: calc(${theme.click.codeblock.space.y} - ${theme.sizes[1]}); - right: calc(${theme.click.codeblock.space.x} - ${theme.sizes[1]}); + top: ${theme.click.codeblock.space.y}; + right: ${theme.click.codeblock.space.x}; background: color-mix(in srgb, ${bg} 90%, transparent); `; }}