From c9a500ca9441a0f675db5e87f29301e5d29c8cf6 Mon Sep 17 00:00:00 2001 From: Muhammad Date: Tue, 2 Jun 2026 23:24:19 +0700 Subject: [PATCH 01/14] Refactor choice icons and update SVG assets - Remove custom `iconStyle` for now. - Updated svg icons. - Adjusted ChoiceGroup component styles for better icon alignment and spacing. - Updated icon sources for JavaScript, TypeScript, npm, pnpm, Bun, and Yarn to use devicon CDN. --- demo/+docpress.tsx | 10 +-- demo/assets/choices-icons/express-icon.svg | 2 +- demo/assets/choices-icons/fastify-icon.svg | 2 +- demo/assets/choices-icons/index.ts | 4 +- demo/assets/choices-icons/react-icon.svg | 2 +- demo/assets/choices-icons/solid-icon.svg | 83 ------------------- demo/assets/choices-icons/solidjs-icon.svg | 1 + demo/assets/choices-icons/vue-icon.svg | 4 - demo/assets/choices-icons/vuejs-icon.svg | 1 + src/code-blocks/components/ChoiceGroup.css | 17 +++- src/code-blocks/components/ChoiceGroup.tsx | 6 +- .../utils/generateChoiceGroupCode.ts | 22 ++--- 12 files changed, 37 insertions(+), 117 deletions(-) delete mode 100644 demo/assets/choices-icons/solid-icon.svg create mode 100644 demo/assets/choices-icons/solidjs-icon.svg delete mode 100644 demo/assets/choices-icons/vue-icon.svg create mode 100644 demo/assets/choices-icons/vuejs-icon.svg diff --git a/demo/+docpress.tsx b/demo/+docpress.tsx index 4e5aff8c..d11fd774 100644 --- a/demo/+docpress.tsx +++ b/demo/+docpress.tsx @@ -51,18 +51,18 @@ const config: Config = { choices: { server: { choices: [ - { name: 'Hono', icon: iconHono, iconStyle: { width: 13, height: 13 } }, + { name: 'Hono', icon: iconHono }, { name: 'Express', icon: iconExpress }, - { name: 'Fastify', icon: iconFastify, iconStyle: { position: 'relative', top: 1 } }, + { name: 'Fastify', icon: iconFastify }, { name: 'H3', icon: iconH3 }, ], default: 'Hono', }, uiFramework: { choices: [ - { name: 'React', icon: iconReact, iconStyle: { position: 'relative', top: -0.5, opacity: 1 } }, - { name: 'Vue', icon: iconVue, iconStyle: { position: 'relative', top: -0.5 } }, - { name: 'Solid', icon: iconSolid, iconStyle: { position: 'relative', top: -0.5 } }, + { name: 'React', icon: iconReact }, + { name: 'Vue', icon: iconVue }, + { name: 'Solid', icon: iconSolid }, ], default: 'React', }, diff --git a/demo/assets/choices-icons/express-icon.svg b/demo/assets/choices-icons/express-icon.svg index 087ca19a..0dc200a9 100644 --- a/demo/assets/choices-icons/express-icon.svg +++ b/demo/assets/choices-icons/express-icon.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/demo/assets/choices-icons/fastify-icon.svg b/demo/assets/choices-icons/fastify-icon.svg index bf09e402..19ade42f 100644 --- a/demo/assets/choices-icons/fastify-icon.svg +++ b/demo/assets/choices-icons/fastify-icon.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/demo/assets/choices-icons/index.ts b/demo/assets/choices-icons/index.ts index f990fb9e..04635e3c 100644 --- a/demo/assets/choices-icons/index.ts +++ b/demo/assets/choices-icons/index.ts @@ -3,5 +3,5 @@ export { default as iconExpress } from './express-icon.svg' export { default as iconFastify } from './fastify-icon.svg' export { default as iconH3 } from './h3-icon.svg' export { default as iconReact } from './react-icon.svg' -export { default as iconVue } from './vue-icon.svg' -export { default as iconSolid } from './solid-icon.svg' +export { default as iconVue } from './vuejs-icon.svg' +export { default as iconSolid } from './solidjs-icon.svg' diff --git a/demo/assets/choices-icons/react-icon.svg b/demo/assets/choices-icons/react-icon.svg index 9fdd5ed0..9af92b9d 100644 --- a/demo/assets/choices-icons/react-icon.svg +++ b/demo/assets/choices-icons/react-icon.svg @@ -1 +1 @@ -logo \ No newline at end of file + \ No newline at end of file diff --git a/demo/assets/choices-icons/solid-icon.svg b/demo/assets/choices-icons/solid-icon.svg deleted file mode 100644 index d973379a..00000000 --- a/demo/assets/choices-icons/solid-icon.svg +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/assets/choices-icons/solidjs-icon.svg b/demo/assets/choices-icons/solidjs-icon.svg new file mode 100644 index 00000000..c51b886f --- /dev/null +++ b/demo/assets/choices-icons/solidjs-icon.svg @@ -0,0 +1 @@ + diff --git a/demo/assets/choices-icons/vue-icon.svg b/demo/assets/choices-icons/vue-icon.svg deleted file mode 100644 index 71c1cfb9..00000000 --- a/demo/assets/choices-icons/vue-icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/demo/assets/choices-icons/vuejs-icon.svg b/demo/assets/choices-icons/vuejs-icon.svg new file mode 100644 index 00000000..27afad0c --- /dev/null +++ b/demo/assets/choices-icons/vuejs-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/code-blocks/components/ChoiceGroup.css b/src/code-blocks/components/ChoiceGroup.css index 9b7303b5..c96b5567 100644 --- a/src/code-blocks/components/ChoiceGroup.css +++ b/src/code-blocks/components/ChoiceGroup.css @@ -16,7 +16,6 @@ .choice-select { background: #eee; - font-size: 13.3333px; -webkit-user-select: none; /* Safari */ -moz-user-select: none; /* Firefox */ @@ -53,9 +52,19 @@ display: inline-flex; align-items: center; gap: 2px; + line-height: normal; } - .choice-select__option img { + .choice-select__option-icon { + width: 16px; + flex-shrink: 0; + + display: flex; + align-items: center; + } + + .choice-select__option-icon img { + object-fit: contain; width: 14px; height: 14px; @@ -65,6 +74,10 @@ transition: filter var(--transition), opacity var(--transition); } + .choice-select__option-label { + font-size: 13.3333px; + } + .choice-select:hover .choice-select__option img, .choice-select[aria-expanded='true'] .choice-select__option img { filter: grayscale(0%); diff --git a/src/code-blocks/components/ChoiceGroup.tsx b/src/code-blocks/components/ChoiceGroup.tsx index 09a0025e..7986b6c6 100644 --- a/src/code-blocks/components/ChoiceGroup.tsx +++ b/src/code-blocks/components/ChoiceGroup.tsx @@ -96,8 +96,10 @@ function CustomSelect({ choiceGroup }: { choiceGroup: ChoiceGroupWithParent }) { onClick={(e) => handleOnClick(e, choice)} > - - {choice} + + + + {choice} ))} diff --git a/src/code-blocks/utils/generateChoiceGroupCode.ts b/src/code-blocks/utils/generateChoiceGroupCode.ts index 8fd68b6f..652880fd 100644 --- a/src/code-blocks/utils/generateChoiceGroupCode.ts +++ b/src/code-blocks/utils/generateChoiceGroupCode.ts @@ -21,31 +21,21 @@ const CHOICES_BUILT_IN: NonNullable = { choices: [ { name: 'JavaScript', - icon: 'https://www.svgrepo.com/show/452045/js.svg', - iconStyle: { position: 'relative', top: -0.5 }, + icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/javascript/javascript-original.svg', }, { name: 'TypeScript', - icon: 'https://www.svgrepo.com/show/349540/typescript.svg', - iconStyle: { position: 'relative', top: -0.5 }, + icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/typescript/typescript-original.svg', }, ], default: 'JavaScript', }, pkgManager: { choices: [ - { - name: 'npm', - icon: 'https://www.svgrepo.com/show/452077/npm.svg', - iconStyle: { position: 'relative', top: 1.5 }, - }, - { name: 'pnpm', icon: 'https://www.svgrepo.com/show/373778/light-pnpm.svg' }, - { name: 'Bun', icon: 'https://bun.com/logo.svg' }, - { - name: 'Yarn', - icon: 'https://www.svgrepo.com/show/354588/yarn.svg', - iconStyle: { position: 'relative', top: -0.5 }, - }, + { name: 'npm', icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/npm/npm-original.svg' }, + { name: 'pnpm', icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/pnpm/pnpm-original.svg' }, + { name: 'Bun', icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/bun/bun-original.svg' }, + { name: 'Yarn', icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/yarn/yarn-original.svg' }, ], default: 'npm', }, From 3fcee611485ca3daf1bd7452cce76f58b0172507 Mon Sep 17 00:00:00 2001 From: Muhammad Date: Thu, 4 Jun 2026 20:49:37 +0700 Subject: [PATCH 02/14] Update SVG icons and adjust CSS styles for ChoiceGroup component - Modified viewBox and aspect ratio for h3-icon.svg, react-icon.svg, solidjs-icon.svg, and vuejs-icon.svg - Adjusted the gap and line-height in ChoiceGroup.css. - Changed image dimensions in ChoiceGroup.css to enhance icon display consistency. --- demo/+docpress.tsx | 2 +- demo/assets/choices-icons/express-icon.svg | 2 +- demo/assets/choices-icons/fastify-icon.svg | 2 +- demo/assets/choices-icons/h3-icon.svg | 4 ++-- demo/assets/choices-icons/react-icon.svg | 2 +- demo/assets/choices-icons/solidjs-icon.svg | 2 +- demo/assets/choices-icons/vuejs-icon.svg | 2 +- src/code-blocks/components/ChoiceGroup.css | 9 ++++----- 8 files changed, 12 insertions(+), 13 deletions(-) diff --git a/demo/+docpress.tsx b/demo/+docpress.tsx index d11fd774..44139bed 100644 --- a/demo/+docpress.tsx +++ b/demo/+docpress.tsx @@ -52,7 +52,7 @@ const config: Config = { server: { choices: [ { name: 'Hono', icon: iconHono }, - { name: 'Express', icon: iconExpress }, + { name: 'Express', icon: iconExpress, iconStyle: { objectFit: 'contain' } }, { name: 'Fastify', icon: iconFastify }, { name: 'H3', icon: iconH3 }, ], diff --git a/demo/assets/choices-icons/express-icon.svg b/demo/assets/choices-icons/express-icon.svg index 0dc200a9..6736a0f2 100644 --- a/demo/assets/choices-icons/express-icon.svg +++ b/demo/assets/choices-icons/express-icon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/demo/assets/choices-icons/fastify-icon.svg b/demo/assets/choices-icons/fastify-icon.svg index 19ade42f..5040a4f5 100644 --- a/demo/assets/choices-icons/fastify-icon.svg +++ b/demo/assets/choices-icons/fastify-icon.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/demo/assets/choices-icons/h3-icon.svg b/demo/assets/choices-icons/h3-icon.svg index 736df9c1..4667be12 100644 --- a/demo/assets/choices-icons/h3-icon.svg +++ b/demo/assets/choices-icons/h3-icon.svg @@ -1,5 +1,5 @@ - + - + \ No newline at end of file diff --git a/demo/assets/choices-icons/react-icon.svg b/demo/assets/choices-icons/react-icon.svg index 9af92b9d..794ffbf3 100644 --- a/demo/assets/choices-icons/react-icon.svg +++ b/demo/assets/choices-icons/react-icon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/demo/assets/choices-icons/solidjs-icon.svg b/demo/assets/choices-icons/solidjs-icon.svg index c51b886f..e63ff038 100644 --- a/demo/assets/choices-icons/solidjs-icon.svg +++ b/demo/assets/choices-icons/solidjs-icon.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/demo/assets/choices-icons/vuejs-icon.svg b/demo/assets/choices-icons/vuejs-icon.svg index 27afad0c..6eda6c53 100644 --- a/demo/assets/choices-icons/vuejs-icon.svg +++ b/demo/assets/choices-icons/vuejs-icon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/code-blocks/components/ChoiceGroup.css b/src/code-blocks/components/ChoiceGroup.css index c96b5567..4532d781 100644 --- a/src/code-blocks/components/ChoiceGroup.css +++ b/src/code-blocks/components/ChoiceGroup.css @@ -51,8 +51,8 @@ .choice-select__option-content { display: inline-flex; align-items: center; - gap: 2px; - line-height: normal; + gap: 3px; + line-height: 1; } .choice-select__option-icon { @@ -64,9 +64,8 @@ } .choice-select__option-icon img { - object-fit: contain; - width: 14px; - height: 14px; + height: 13px; + max-width: 16px; filter: grayscale(100%); opacity: 0.8; From e49c49f98ba8b1fd41c2dbdee2b82c6520a2625a Mon Sep 17 00:00:00 2001 From: Muhammad Date: Thu, 4 Jun 2026 21:22:46 +0700 Subject: [PATCH 03/14] refactor(code-blocks): normalize built-in choice SVGs and embed as data URIs Adjust SVG viewBox values for consistent rendering, then replace external devicon URLs with local data URI icons for Code Lang and Package Managers. --- src/code-blocks/utils/constant.ts | 17 +++++++++++++++++ .../utils/generateChoiceGroupCode.ts | 13 +++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 src/code-blocks/utils/constant.ts diff --git a/src/code-blocks/utils/constant.ts b/src/code-blocks/utils/constant.ts new file mode 100644 index 00000000..46a1339d --- /dev/null +++ b/src/code-blocks/utils/constant.ts @@ -0,0 +1,17 @@ +export { JAVASCRIPT_ICON, TYPESCRIPT_ICON, NPM_ICON, PNPM_ICON, BUN_ICON, YARN_ICON } + +// Code Lang +const JAVASCRIPT_ICON = + "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='1 1 126 126' preserveAspectRatio='xMidYMid meet'%3E%3Cpath fill='%23F0DB4F' d='M1.408 1.408h125.184v125.185H1.408z'/%3E%3Cpath fill='%23323330' d='M116.347 96.736c-.917-5.711-4.641-10.508-15.672-14.981-3.832-1.761-8.104-3.022-9.377-5.926-.452-1.69-.512-2.642-.226-3.665.821-3.32 4.784-4.355 7.925-3.403 2.023.678 3.938 2.237 5.093 4.724 5.402-3.498 5.391-3.475 9.163-5.879-1.381-2.141-2.118-3.129-3.022-4.045-3.249-3.629-7.676-5.498-14.756-5.355l-3.688.477c-3.534.893-6.902 2.748-8.877 5.235-5.926 6.724-4.236 18.492 2.975 23.335 7.104 5.332 17.54 6.545 18.873 11.531 1.297 6.104-4.486 8.08-10.234 7.378-4.236-.881-6.592-3.034-9.139-6.949-4.688 2.713-4.688 2.713-9.508 5.485 1.143 2.499 2.344 3.63 4.26 5.795 9.068 9.198 31.76 8.746 35.83-5.176.165-.478 1.261-3.666.38-8.581zM69.462 58.943H57.753l-.048 30.272c0 6.438.333 12.34-.714 14.149-1.713 3.558-6.152 3.117-8.175 2.427-2.059-1.012-3.106-2.451-4.319-4.485-.333-.584-.583-1.036-.667-1.071l-9.52 5.83c1.583 3.249 3.915 6.069 6.902 7.901 4.462 2.678 10.459 3.499 16.731 2.059 4.082-1.189 7.604-3.652 9.448-7.401 2.666-4.915 2.094-10.864 2.07-17.444.06-10.735.001-21.468.001-32.237z'/%3E%3C/svg%3E" +const TYPESCRIPT_ICON = + "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='1 1 126 126' preserveAspectRatio='xMidYMid meet'%3E%3Cpath fill='%23fff' d='M22.67 47h99.67v73.67H22.67z'/%3E%3Cpath data-name='original' fill='%23007acc' d='M1.5 63.91v62.5h125v-125H1.5zm100.73-5a15.56 15.56 0 017.82 4.5 20.58 20.58 0 013 4c0 .16-5.4 3.81-8.69 5.85-.12.08-.6-.44-1.13-1.23a7.09 7.09 0 00-5.87-3.53c-3.79-.26-6.23 1.73-6.21 5a4.58 4.58 0 00.54 2.34c.83 1.73 2.38 2.76 7.24 4.86 8.95 3.85 12.78 6.39 15.16 10 2.66 4 3.25 10.46 1.45 15.24-2 5.2-6.9 8.73-13.83 9.9a38.32 38.32 0 01-9.52-.1 23 23 0 01-12.72-6.63c-1.15-1.27-3.39-4.58-3.25-4.82a9.34 9.34 0 011.15-.73L82 101l3.59-2.08.75 1.11a16.78 16.78 0 004.74 4.54c4 2.1 9.46 1.81 12.16-.62a5.43 5.43 0 00.69-6.92c-1-1.39-3-2.56-8.59-5-6.45-2.78-9.23-4.5-11.77-7.24a16.48 16.48 0 01-3.43-6.25 25 25 0 01-.22-8c1.33-6.23 6-10.58 12.82-11.87a31.66 31.66 0 019.49.26zm-29.34 5.24v5.12H56.66v46.23H45.15V69.26H28.88v-5a49.19 49.19 0 01.12-5.17C29.08 59 39 59 51 59h21.83z'/%3E%3C/svg%3E" + +// Package Managers +const NPM_ICON = + "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 -1 130 130' preserveAspectRatio='xMidYMid meet'%3E%3Cpath fill='%23cb3837' d='m0 7.0624c0-3.8376 3.2248-7.0624 7.0624-7.0624h113.88c3.8376 0 7.0624 3.2248 7.0624 7.0624v113.88c0 3.8376-3.2248 7.0624-7.0624 7.0624h-113.88c-3.8376 0-7.0624-3.2248-7.0624-7.0624zm23.69 97.518h40.395l0.04975-58.532h19.494l-0.04975 58.581h19.543l0.0508-78.075-78.076-0.0995-0.0995 78.125z'/%3E%3Cpath fill='%23fff' d='m25.105 65.52v-39.008h15.855c8.7201 0 26.274 0.03373 39.008 0.07496l23.153 0.07496v77.866h-19.476v-58.54h-19.588v58.54h-38.952z'/%3E%3C/svg%3E" +const PNPM_ICON = + "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 -1 130 130' preserveAspectRatio='xMidYMid meet'%3E%3Cpath fill='%23f8ab00' d='M0 .004V40h39.996V.004Zm43.996 0V40h40V.004Zm44.008 0V40H128V.004Zm0 43.996v39.996H128V44Z'/%3E%3Cpath fill='%234c4c4c' d='M43.996 44v39.996h40V44ZM0 87.996v40h39.996v-40Zm43.996 0v40h40v-40Zm44.008 0v40H128v-40Z'/%3E%3C/svg%3E" +const BUN_ICON = + "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 10 128 108' preserveAspectRatio='xMidYMid meet'%3E%3Cpath d='M113.744 41.999a18.558 18.558 0 0 0-.8-.772c-.272-.246-.528-.524-.8-.771s-.528-.525-.8-.771c-.272-.247-.528-.525-.8-.772s-.528-.524-.8-.771-.528-.525-.8-.772-.528-.524-.8-.771c7.936 7.52 12.483 17.752 12.656 28.481 0 25.565-26.912 46.363-60 46.363-18.528 0-35.104-6.526-46.128-16.756l.8.772.8.771.8.772.8.771.8.772.8.771.8.771c11.008 10.662 27.952 17.527 46.928 17.527 33.088 0 60-20.797 60-46.285 0-10.893-4.864-21.215-13.456-29.33z'/%3E%3Cpath fill='%23fbf0df' d='M116.8 65.08c0 23.467-25.072 42.49-56 42.49s-56-19.023-56-42.49c0-14.55 9.6-27.401 24.352-35.023C43.904 22.435 53.088 14.628 60.8 14.628S75.104 21 92.448 30.058C107.2 37.677 116.8 50.53 116.8 65.08Z'/%3E%3Cpath fill='%23f6dece' d='M116.8 65.08a32.314 32.314 0 0 0-1.28-8.918c-4.368 51.377-69.36 53.846-94.912 38.48 11.486 8.584 25.66 13.144 40.192 12.928 30.88 0 56-19.054 56-42.49z'/%3E%3Cpath fill='%23fffefc' d='M39.248 27.234c7.152-4.135 16.656-11.896 26-11.911a15.372 15.372 0 0 0-4.448-.695c-3.872 0-8 1.93-13.2 4.83-1.808 1.018-3.68 2.144-5.664 3.317-3.728 2.222-8 4.736-12.8 7.251C13.904 37.972 4.8 51.071 4.8 65.08v1.836c9.696-33.033 27.312-35.547 34.448-39.682z'/%3E%3Cpath fill='%23ccbea7' d='M56.192 18.532A24.553 24.553 0 0 1 53.867 29.1a25.407 25.407 0 0 1-6.683 8.671c-.448.386-.096 1.127.48.91 5.392-2.02 12.672-8.068 9.6-20.272-.128-.695-1.072-.51-1.072.123zm3.632 0a24.474 24.474 0 0 1 3.646 10.12c.445 3.587.08 7.224-1.07 10.662-.192.54.496 1.003.88.556 3.504-4.32 6.56-12.899-2.592-22.156-.464-.4-1.184.216-.864.756zm4.416-.262a25.702 25.702 0 0 1 7.521 7.925A24.71 24.71 0 0 1 75.2 36.414c-.016.13.02.26.101.365a.543.543 0 0 0 .718.117.509.509 0 0 0 .221-.313c1.472-5.384.64-14.564-11.472-19.332-.64-.246-1.056.587-.528.957zM34.704 34.315a27.418 27.418 0 0 0 9.91-5.222 26.262 26.262 0 0 0 6.842-8.663c.288-.556 1.2-.34 1.056.277-2.768 12.343-12.032 14.92-17.792 14.58-.608.016-.592-.802-.016-.972z'/%3E%3Cpath d='M60.8 111.443c-33.088 0-60-20.798-60-46.363 0-15.429 9.888-29.823 26.448-38.448 4.8-2.469 8.912-4.953 12.576-7.128 2.016-1.203 3.92-2.33 5.76-3.379C51.2 12.916 56 10.771 60.8 10.771c4.8 0 8.992 1.852 14.24 4.845 1.6.88 3.2 1.836 4.912 2.885 3.984 2.376 8.48 5.06 14.4 8.131 16.56 8.625 26.448 23.004 26.448 38.448 0 25.565-26.912 46.363-60 46.363zm0-96.814c-3.872 0-8 1.928-13.2 4.829-1.808 1.018-3.68 2.144-5.664 3.317-3.728 2.222-8 4.736-12.8 7.251C13.904 37.972 4.8 51.071 4.8 65.08c0 23.436 25.12 42.506 56 42.506s56-19.07 56-42.506c0-14.01-9.104-27.108-24.352-35.023-6.048-3.086-10.768-5.986-14.592-8.27-1.744-1.033-3.344-1.99-4.8-2.838-4.848-2.778-8.384-4.32-12.256-4.32z'/%3E%3Cpath fill='%23b71422' d='M72.08 76.343c-.719 2.839-2.355 5.383-4.672 7.267a11.07 11.07 0 0 1-6.4 2.9 11.13 11.13 0 0 1-6.608-2.9c-2.293-1.892-3.906-4.436-4.608-7.267a1.073 1.073 0 0 1 .05-.5 1.11 1.11 0 0 1 .272-.428 1.19 1.19 0 0 1 .958-.322h19.744a1.185 1.185 0 0 1 .947.33 1.073 1.073 0 0 1 .317.92z'/%3E%3Cpath fill='%23ff6164' d='M54.4 83.733a11.24 11.24 0 0 0 6.592 2.932 11.239 11.239 0 0 0 6.576-2.932 16.652 16.652 0 0 0 1.6-1.65 10.904 10.904 0 0 0-3.538-2.564 11.26 11.26 0 0 0-4.302-1 10.121 10.121 0 0 0-4.549 1.192 9.71 9.71 0 0 0-3.451 3.097c.368.323.688.632 1.072.925z'/%3E%3Cpath d='M54.656 82.514a8.518 8.518 0 0 1 2.97-2.347 8.836 8.836 0 0 1 3.734-.862 9.78 9.78 0 0 1 6.4 2.608c.368-.386.72-.787 1.056-1.188-2.035-1.87-4.726-2.933-7.536-2.978a10.487 10.487 0 0 0-4.335.975 10.125 10.125 0 0 0-3.489 2.666c.378.396.779.772 1.2 1.126z'/%3E%3Cpath d='M60.944 87.436a12.078 12.078 0 0 1-7.12-3.086c-2.477-2.02-4.22-4.75-4.976-7.791-.054-.27-.045-.55.027-.817a1.83 1.83 0 0 1 .389-.726 2.25 2.25 0 0 1 .81-.595 2.32 2.32 0 0 1 .998-.192h19.744c.343-.007.683.06.996.196a2.3 2.3 0 0 1 .812.591c.182.212.313.46.382.728.07.267.076.545.018.815-.756 3.042-2.5 5.771-4.976 7.791a12.078 12.078 0 0 1-7.104 3.086zm-9.872-11.417c-.256 0-.32.108-.336.139.676 2.638 2.206 4.999 4.368 6.742a10.122 10.122 0 0 0 5.84 2.7 10.207 10.207 0 0 0 5.84-2.67c2.155-1.745 3.679-4.106 4.352-6.741a.333.333 0 0 0-.14-.113.348.348 0 0 0-.18-.026z'/%3E%3Cpath fill='%23febbd0' d='M85.152 77.3c5.17 0 9.36-2.377 9.36-5.308s-4.19-5.307-9.36-5.307c-5.17 0-9.36 2.376-9.36 5.307 0 2.931 4.19 5.307 9.36 5.307zm-48.432 0c5.17 0 9.36-2.377 9.36-5.308s-4.19-5.307-9.36-5.307c-5.17 0-9.36 2.376-9.36 5.307 0 2.931 4.19 5.307 9.36 5.307z'/%3E%3Cpath d='M41.12 69.863a9.052 9.052 0 0 0 4.902-1.425 8.578 8.578 0 0 0 3.254-3.812 8.22 8.22 0 0 0 .508-4.913 8.41 8.41 0 0 0-2.408-4.357 8.92 8.92 0 0 0-4.514-2.33 9.12 9.12 0 0 0-5.096.48 8.755 8.755 0 0 0-3.96 3.131 8.287 8.287 0 0 0-1.486 4.725c0 2.252.927 4.412 2.577 6.005 1.65 1.594 3.888 2.492 6.223 2.496zm39.632 0a9.054 9.054 0 0 0 4.915-1.403 8.582 8.582 0 0 0 3.275-3.802 8.22 8.22 0 0 0 .528-4.917 8.408 8.408 0 0 0-2.398-4.368 8.92 8.92 0 0 0-4.512-2.344 9.12 9.12 0 0 0-5.103.473 8.756 8.756 0 0 0-3.967 3.13 8.287 8.287 0 0 0-1.49 4.73c-.004 2.245.914 4.4 2.555 5.994 1.64 1.593 3.869 2.495 6.197 2.507z'/%3E%3Cpath fill='%23fff' d='M38.4 61.902a3.4 3.4 0 0 0 1.844-.531c.547-.35.974-.847 1.227-1.43a3.088 3.088 0 0 0 .195-1.847 3.16 3.16 0 0 0-.902-1.639 3.351 3.351 0 0 0-1.696-.878 3.426 3.426 0 0 0-1.916.179 3.29 3.29 0 0 0-1.489 1.176 3.113 3.113 0 0 0-.559 1.776c0 .844.347 1.654.964 2.253a3.374 3.374 0 0 0 2.332.94zm39.632 0a3.4 3.4 0 0 0 1.844-.531c.547-.35.974-.847 1.227-1.43a3.088 3.088 0 0 0 .195-1.847 3.16 3.16 0 0 0-.902-1.639 3.351 3.351 0 0 0-1.696-.878 3.426 3.426 0 0 0-1.916.179 3.29 3.29 0 0 0-1.489 1.176 3.113 3.113 0 0 0-.559 1.776c0 .84.342 1.644.953 2.242.61.598 1.44.94 2.311.952z'/%3E%3C/svg%3E" +const YARN_ICON = + "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 -1 130 130' preserveAspectRatio='xMidYMid meet'%3E%3Cpath fill='%232c8ebb' d='M64 0a64 64 0 1 0 64 64A64 64 0 0 0 64 0Zm4.685 21.948a5.037 5.037 0 0 1 2.21.802c.671.444 1.528 1.032 4.026 6.194a4.841 4.841 0 0 1 2.942-.103 3.933 3.933 0 0 1 2.468 2.004c2.55 4.893 2.889 13.614 1.774 19.22a34.89 34.89 0 0 1-6.028 13.74 26.56 26.56 0 0 1 5.957 9.733 26.24 26.24 0 0 1 1.456 10.746 29.626 29.626 0 0 0 3.22-1.796c3.158-1.951 7.927-4.894 13.615-4.966a6.834 6.834 0 0 1 7.225 5.885 6.555 6.555 0 0 1-5.046 7.256c-3.458.836-5.069 1.486-9.714 4.5a69.161 69.161 0 0 1-16.062 7.412 8.991 8.991 0 0 1-3.758 1.828c-3.933.96-17.425 1.682-18.488 1.682h-.248c-4.13 0-6.47-1.28-7.73-2.621-3.51 1.755-8.052 1.03-11.355-.714a5.729 5.729 0 0 1-3.097-4.024 6.194 6.194 0 0 1 0-2.127 6.875 6.875 0 0 1-.816-1.032 16.908 16.908 0 0 1-2.333-10.386c.3-3.85 2.964-7.287 4.698-9.114A29.481 29.481 0 0 1 35.726 64a27.685 27.685 0 0 1 7.04-9.29c-1.703-2.87-3.436-7.288-1.754-11.789 1.208-3.21 2.199-4.996 4.377-5.76a7.06 7.06 0 0 0 2.59-1.383 18.22 18.22 0 0 1 12.243-5.843c.196-.495.423-1.033.671-1.508 1.652-3.51 3.406-5.48 5.46-6.193a5.037 5.037 0 0 1 2.332-.286zm-.558 3.697c-2.703.089-5.355 8.099-5.355 8.099a14.452 14.452 0 0 0-12.089 4.645 9.951 9.951 0 0 1-3.973 2.345c-.424.144-.94.122-2.22 3.58-1.961 5.234 3.345 11.16 3.345 11.16s-6.328 4.47-8.672 10.034a25.58 25.58 0 0 0-1.806 12.057s-4.5 3.901-4.788 7.927a13.285 13.285 0 0 0 1.826 8.083 2.003 2.003 0 0 0 2.714.94s-2.993 3.487-.196 4.963c2.55 1.331 6.844 2.065 9.115-.196 1.652-1.651 1.982-5.335 2.591-6.842.144-.351.64.588 1.115 1.032a10.323 10.323 0 0 0 1.403 1.032s-4.024 1.734-2.373 5.688c.547 1.31 2.498 2.145 5.688 2.125 1.187 0 14.203-.743 17.671-1.58a4.47 4.47 0 0 0 2.696-1.505 65.032 65.032 0 0 0 15.99-7.226c4.892-3.19 6.895-4.059 10.848-4.998 3.262-.774 3.045-5.83-1.28-5.758-4.48.052-8.402 2.363-11.716 4.427-6.193 3.83-9.29 3.583-9.29 3.583l-.105-.175c-.423-.692 1.983-6.896-.712-14.287-2.91-8.082-7.534-10.033-7.163-10.653 1.58-2.673 5.534-6.917 7.113-14.824.94-4.79.691-12.676-1.435-16.805-.393-.764-3.902 1.28-3.902 1.28s-3.283-7.319-4.201-7.907a1.442 1.442 0 0 0-.839-.244z'/%3E%3C/svg%3E" diff --git a/src/code-blocks/utils/generateChoiceGroupCode.ts b/src/code-blocks/utils/generateChoiceGroupCode.ts index 652880fd..215c472c 100644 --- a/src/code-blocks/utils/generateChoiceGroupCode.ts +++ b/src/code-blocks/utils/generateChoiceGroupCode.ts @@ -8,6 +8,7 @@ import type { MdxJsxAttribute, MdxJsxFlowElement, MdxJsxFlowElementData } from ' import { getVikeConfig } from 'vike/plugin' import { assertUsage } from '../../utils/assert.js' import { valueToEstree } from 'estree-util-value-to-estree' +import { JAVASCRIPT_ICON, TYPESCRIPT_ICON, NPM_ICON, PNPM_ICON, BUN_ICON, YARN_ICON } from './constant.js' type ChoiceNode = { choiceValue: string @@ -21,21 +22,21 @@ const CHOICES_BUILT_IN: NonNullable = { choices: [ { name: 'JavaScript', - icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/javascript/javascript-original.svg', + icon: JAVASCRIPT_ICON, }, { name: 'TypeScript', - icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/typescript/typescript-original.svg', + icon: TYPESCRIPT_ICON, }, ], default: 'JavaScript', }, pkgManager: { choices: [ - { name: 'npm', icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/npm/npm-original.svg' }, - { name: 'pnpm', icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/pnpm/pnpm-original.svg' }, - { name: 'Bun', icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/bun/bun-original.svg' }, - { name: 'Yarn', icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/yarn/yarn-original.svg' }, + { name: 'npm', icon: NPM_ICON }, + { name: 'pnpm', icon: PNPM_ICON }, + { name: 'Bun', icon: BUN_ICON }, + { name: 'Yarn', icon: YARN_ICON }, ], default: 'npm', }, From 00f288c2eb12f1bfdb2d49f0cb9b7416796a4a30 Mon Sep 17 00:00:00 2001 From: Muhammad Date: Thu, 4 Jun 2026 21:46:20 +0700 Subject: [PATCH 04/14] Replace border separators with inset box-shadow for consistent rendering --- src/code-blocks/components/ChoiceGroup.css | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/code-blocks/components/ChoiceGroup.css b/src/code-blocks/components/ChoiceGroup.css index 4532d781..0d74e671 100644 --- a/src/code-blocks/components/ChoiceGroup.css +++ b/src/code-blocks/components/ChoiceGroup.css @@ -43,7 +43,7 @@ flex-wrap: nowrap; background: #fff; padding: 0 6px; - border-bottom: 1px solid rgba(0, 0, 0, 0.1); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.1); cursor: pointer; transition: background 120ms ease; } @@ -99,10 +99,6 @@ } } - .choice-select__option:last-child { - border-bottom: none; - } - .choice-select__option:hover { background: #f5f5f5; } From c69179a8b7f7aae7cb6d0f519c828e723b0db6b3 Mon Sep 17 00:00:00 2001 From: Muhammad Date: Thu, 4 Jun 2026 23:12:40 +0700 Subject: [PATCH 05/14] Remove `font-weight` from selected tab styles to fix layout shifts --- src/code-blocks/components/Tabs.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/code-blocks/components/Tabs.css b/src/code-blocks/components/Tabs.css index 6ace451a..2b5c7aea 100644 --- a/src/code-blocks/components/Tabs.css +++ b/src/code-blocks/components/Tabs.css @@ -11,7 +11,6 @@ select:has(option:nth-of-type(7):checked) ~ ul[role='tablist'] li:nth-of-type(7) { border-bottom: 2px solid #aaa; color: var(--color-text); - font-weight: 600; } } From d0eaad8e84115ca58f2b21b334b9a442776d8788 Mon Sep 17 00:00:00 2001 From: Muhammad Date: Thu, 4 Jun 2026 23:15:51 +0700 Subject: [PATCH 06/14] refactor(Tabs): adjust tab layout and improve icon styling --- src/code-blocks/components/Tabs.css | 15 +++++++++++++-- src/code-blocks/components/Tabs.tsx | 6 ++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/code-blocks/components/Tabs.css b/src/code-blocks/components/Tabs.css index 2b5c7aea..09755f7a 100644 --- a/src/code-blocks/components/Tabs.css +++ b/src/code-blocks/components/Tabs.css @@ -35,12 +35,23 @@ .choice-tabs__tab-content { display: inline-flex; align-items: center; - gap: 2px; + gap: 3px; + line-height: 1; +} + +.choice-tabs__tab-icon { + display: flex; + width: 16px; + flex-shrink: 0; } .choice-tabs__tab img { - width: 14px; height: 14px; + max-width: 16px; +} + +.choice-tabs__tab-label { + font-weight: 16px; } @media screen and (max-width: 400px) { diff --git a/src/code-blocks/components/Tabs.tsx b/src/code-blocks/components/Tabs.tsx index e9c23a7e..63207fc5 100644 --- a/src/code-blocks/components/Tabs.tsx +++ b/src/code-blocks/components/Tabs.tsx @@ -44,8 +44,10 @@ function Tabs({ choice, hide = [] }: { choice: string; hide: string[] }) { onKeyDown={handleOnKeyDown} > - - {choice} + + + + {choice} ))} From 587ded09cbee73cc1fd73e661e5a62810bea1a22 Mon Sep 17 00:00:00 2001 From: Muhammad Date: Thu, 4 Jun 2026 23:20:01 +0700 Subject: [PATCH 07/14] minor --- src/code-blocks/components/ChoiceGroup.css | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/code-blocks/components/ChoiceGroup.css b/src/code-blocks/components/ChoiceGroup.css index 0d74e671..fd9474c3 100644 --- a/src/code-blocks/components/ChoiceGroup.css +++ b/src/code-blocks/components/ChoiceGroup.css @@ -56,11 +56,9 @@ } .choice-select__option-icon { + display: flex; width: 16px; flex-shrink: 0; - - display: flex; - align-items: center; } .choice-select__option-icon img { From acbcb6aa7a8272e5246919f429c0139353ca8b81 Mon Sep 17 00:00:00 2001 From: Muhammad Date: Thu, 4 Jun 2026 23:28:40 +0700 Subject: [PATCH 08/14] remove `flex-shrink` --- src/code-blocks/components/ChoiceGroup.css | 1 - src/code-blocks/components/Tabs.css | 1 - 2 files changed, 2 deletions(-) diff --git a/src/code-blocks/components/ChoiceGroup.css b/src/code-blocks/components/ChoiceGroup.css index fd9474c3..c8d7619b 100644 --- a/src/code-blocks/components/ChoiceGroup.css +++ b/src/code-blocks/components/ChoiceGroup.css @@ -58,7 +58,6 @@ .choice-select__option-icon { display: flex; width: 16px; - flex-shrink: 0; } .choice-select__option-icon img { diff --git a/src/code-blocks/components/Tabs.css b/src/code-blocks/components/Tabs.css index 09755f7a..8d506477 100644 --- a/src/code-blocks/components/Tabs.css +++ b/src/code-blocks/components/Tabs.css @@ -42,7 +42,6 @@ .choice-tabs__tab-icon { display: flex; width: 16px; - flex-shrink: 0; } .choice-tabs__tab img { From 25cafbca2ee31883b138e546af7496fb5a93dc7a Mon Sep 17 00:00:00 2001 From: Muhammad Date: Sat, 27 Jun 2026 22:53:04 +0700 Subject: [PATCH 09/14] refactor(tabs): refine tab structure and styling --- src/code-blocks/components/Tabs.css | 56 +++++++++++++++++++---------- src/code-blocks/components/Tabs.tsx | 6 ++-- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/code-blocks/components/Tabs.css b/src/code-blocks/components/Tabs.css index ab67d085..81e0fe10 100644 --- a/src/code-blocks/components/Tabs.css +++ b/src/code-blocks/components/Tabs.css @@ -3,49 +3,67 @@ /* tablist style logic */ .choice-tabs__tab:has(.choice-tabs__radio:checked) { - border-bottom: 2px solid #aaa; + border-color: #aaa; color: var(--color-text); } } .choice-tabs__tab-list { border-bottom: 1px solid #eaeaea; + display: flex; + flex-wrap: wrap; + flex-direction: row; margin: 0 0 10px; - padding: 0; + gap: 6px; } .choice-tabs__tab { - display: inline-block; - bottom: -1px; position: relative; - list-style: none; - padding: 6px 12px; + bottom: -1px; cursor: pointer; + text-align: center; + vertical-align: middle; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + padding: 8px; font-weight: 500; - /* lighten --color-text by 20% */ + height: 36px; + + display: inline-flex; + flex-wrap: nowrap; + flex-shrink: 0; + justify-content: center; + align-items: center; + color: color-mix(in srgb, var(--color-text) 80%, white 20%); + border-bottom: 2px solid transparent; } .choice-tabs__tab-content { display: inline-flex; + flex-wrap: nowrap; + flex-shrink: 0; + justify-content: center; align-items: center; gap: 6px; line-height: 1; + font-size: 16px; + padding-inline: 4px; } -.choice-tabs__tab-icon { - display: flex; - justify-content: flex-end; - width: 16px; -} - -.choice-tabs__tab-icon img { - height: 14px; - max-width: 16px; +img { + display: block; + max-width: 100%; + height: auto; } -.choice-tabs__tab-label { - font-size: 16px; +.choice-tabs__tab-content img { + width: 16px; + height: 16px; } @media screen and (max-width: 400px) { @@ -66,4 +84,4 @@ .choice-tabs__tab:focus { outline: none; -} +} \ No newline at end of file diff --git a/src/code-blocks/components/Tabs.tsx b/src/code-blocks/components/Tabs.tsx index e19366d8..deb9f310 100644 --- a/src/code-blocks/components/Tabs.tsx +++ b/src/code-blocks/components/Tabs.tsx @@ -43,10 +43,8 @@ function Tabs({ choice, hide = [] }: { choice: string; hide: string[] }) { }} /> - - {icon && } - - {choice} + {icon && } + {choice} ))} From 52962a70042229308a2059e305a4fce25fc6e87c Mon Sep 17 00:00:00 2001 From: Muhammad Date: Sun, 28 Jun 2026 00:58:24 +0700 Subject: [PATCH 10/14] refactor(choice-select): refine dropdown structure and styling --- src/code-blocks/components/ChoiceGroup.css | 34 ++++++++++++---------- src/code-blocks/components/ChoiceGroup.tsx | 6 ++-- src/code-blocks/components/Tabs.css | 3 +- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/code-blocks/components/ChoiceGroup.css b/src/code-blocks/components/ChoiceGroup.css index 5d89eea6..c29587d0 100644 --- a/src/code-blocks/components/ChoiceGroup.css +++ b/src/code-blocks/components/ChoiceGroup.css @@ -22,6 +22,9 @@ .choice-select__list { position: relative; + display: flex; + flex-wrap: nowrap; + flex-direction: column; background: transparent; height: calc(var(--choice-count) * var(--option-height)); top: 0; @@ -32,7 +35,7 @@ user-select: none; /* Standard */ border-radius: var(--border-radius); - width: 100%; + min-width: max-content; transition: var(--transition-select-list); } @@ -54,42 +57,43 @@ } .choice-select__option { - display: flex; - height: var(--option-height); - white-space: nowrap; - align-items: center; + display: inline-flex; flex-wrap: nowrap; + flex-shrink: 0; + height: var(--option-height); + background: #fff; padding: 0 6px; cursor: pointer; + transition: var(--transition-select-option); } .choice-select__option-content { display: inline-flex; + flex-wrap: nowrap; + flex-shrink: 0; + justify-content: center; align-items: center; gap: 3px; line-height: 1; + font-size: 13.3333px; } - .choice-select__option-icon { - display: flex; - width: 16px; + img { + display: block; + max-width: 100%; } - .choice-select__option-icon img { - height: 13px; - max-width: 16px; + .choice-select__option-content img { + width: 14px; + height: 14px; filter: grayscale(100%); opacity: 0.8; transition: var(--transition-select-icon); } - .choice-select__option-label { - font-size: 13.3333px; - } - .choice-select__list:hover .choice-select__option img, .choice-select__list[aria-expanded='true'] .choice-select__option img { filter: grayscale(0%); diff --git a/src/code-blocks/components/ChoiceGroup.tsx b/src/code-blocks/components/ChoiceGroup.tsx index 8fae0faa..4509c331 100644 --- a/src/code-blocks/components/ChoiceGroup.tsx +++ b/src/code-blocks/components/ChoiceGroup.tsx @@ -113,10 +113,8 @@ function CustomSelect({ choiceGroup }: { choiceGroup: ChoiceGroupWithParent }) { readOnly /> - - {icon && } - - {choice} + {icon && } + {choice} ))} diff --git a/src/code-blocks/components/Tabs.css b/src/code-blocks/components/Tabs.css index 81e0fe10..24af48af 100644 --- a/src/code-blocks/components/Tabs.css +++ b/src/code-blocks/components/Tabs.css @@ -58,7 +58,6 @@ img { display: block; max-width: 100%; - height: auto; } .choice-tabs__tab-content img { @@ -84,4 +83,4 @@ img { .choice-tabs__tab:focus { outline: none; -} \ No newline at end of file +} From b520ac2ed847c20d7dc4b8e38fdb9d7ec1dcb77d Mon Sep 17 00:00:00 2001 From: Muhammad Date: Sun, 28 Jun 2026 23:59:56 +0700 Subject: [PATCH 11/14] refactor(choices): enhance icon styling and structure for dropdowns and tabs --- demo/+docpress.tsx | 10 ++++-- src/code-blocks/components/ChoiceGroup.css | 33 +++++++++++++++---- src/code-blocks/components/ChoiceGroup.tsx | 8 +++-- src/code-blocks/components/Tabs.css | 11 +++---- src/code-blocks/components/Tabs.tsx | 6 ++-- .../utils/generateChoiceGroupCode.ts | 4 ++- src/types/Config.ts | 9 ++++- 7 files changed, 56 insertions(+), 25 deletions(-) diff --git a/demo/+docpress.tsx b/demo/+docpress.tsx index 44139bed..78fe700f 100644 --- a/demo/+docpress.tsx +++ b/demo/+docpress.tsx @@ -51,9 +51,13 @@ const config: Config = { choices: { server: { choices: [ - { name: 'Hono', icon: iconHono }, - { name: 'Express', icon: iconExpress, iconStyle: { objectFit: 'contain' } }, - { name: 'Fastify', icon: iconFastify }, + { name: 'Hono', icon: iconHono, iconStyle: { dropdown: { height: '13px' } } }, + { + name: 'Express', + icon: iconExpress, + iconStyle: { dropdown: { objectFit: 'contain', width: '14px', marginTop: '1px' } }, + }, + { name: 'Fastify', icon: iconFastify, iconStyle: { dropdown: { width: '14px', marginTop: '1px' } } }, { name: 'H3', icon: iconH3 }, ], default: 'Hono', diff --git a/src/code-blocks/components/ChoiceGroup.css b/src/code-blocks/components/ChoiceGroup.css index c29587d0..69e00d1f 100644 --- a/src/code-blocks/components/ChoiceGroup.css +++ b/src/code-blocks/components/ChoiceGroup.css @@ -63,7 +63,7 @@ height: var(--option-height); background: #fff; - padding: 0 6px; + padding: 6px; cursor: pointer; transition: var(--transition-select-option); @@ -77,23 +77,26 @@ align-items: center; gap: 3px; line-height: 1; - font-size: 13.3333px; } - img { - display: block; - max-width: 100%; + .choice-select__option-icon { + display: inline-flex; + width: 16px; + justify-content: flex-start; } .choice-select__option-content img { - width: 14px; - height: 14px; + width: 13px; filter: grayscale(100%); opacity: 0.8; transition: var(--transition-select-icon); } + .choice-select__option-label { + font-size: 13.3333px; + } + .choice-select__list:hover .choice-select__option img, .choice-select__list[aria-expanded='true'] .choice-select__option img { filter: grayscale(0%); @@ -103,6 +106,7 @@ .choice-select__list[aria-expanded='true'] { z-index: 1; clip-path: inset(0px round var(--border-radius)) !important; + .choice-select__border { top: 0 !important; height: calc(var(--choice-count) * var(--option-height)); @@ -111,9 +115,11 @@ .choice-select__list:not(.hovered) { transition: none; + .choice-select__border { transition: none; } + .choice-select__option { transition: none; } @@ -141,66 +147,79 @@ calc(0 * var(--option-height)) 0 calc((var(--choice-count) - 0 - 1) * var(--option-height)) 0 round var(--border-radius) ); + .choice-select__border { top: 0; } } + .choice-select__list:has(.choice-select__option:nth-of-type(2) .choice-select__radio:checked) { top: calc(-1 * var(--option-height)); clip-path: inset( calc(1 * var(--option-height)) 0 calc((var(--choice-count) - 1 - 1) * var(--option-height)) 0 round var(--border-radius) ); + .choice-select__border { top: var(--option-height); } } + .choice-select__list:has(.choice-select__option:nth-of-type(3) .choice-select__radio:checked) { top: calc(-2 * var(--option-height)); clip-path: inset( calc(2 * var(--option-height)) 0 calc((var(--choice-count) - 2 - 1) * var(--option-height)) 0 round var(--border-radius) ); + .choice-select__border { top: calc(2 * var(--option-height)); } } + .choice-select__list:has(.choice-select__option:nth-of-type(4) .choice-select__radio:checked) { top: calc(-3 * var(--option-height)); clip-path: inset( calc(3 * var(--option-height)) 0 calc((var(--choice-count) - 3 - 1) * var(--option-height)) 0 round var(--border-radius) ); + .choice-select__border { top: calc(3 * var(--option-height)); } } + .choice-select__list:has(.choice-select__option:nth-of-type(5) .choice-select__radio:checked) { top: calc(-4 * var(--option-height)); clip-path: inset( calc(4 * var(--option-height)) 0 calc((var(--choice-count) - 4 - 1) * var(--option-height)) 0 round var(--border-radius) ); + .choice-select__border { top: calc(4 * var(--option-height)); } } + .choice-select__list:has(.choice-select__option:nth-of-type(6) .choice-select__radio:checked) { top: calc(-5 * var(--option-height)); clip-path: inset( calc(5 * var(--option-height)) 0 calc((var(--choice-count) - 5 - 1) * var(--option-height)) 0 round var(--border-radius) ); + .choice-select__border { top: calc(5 * var(--option-height)); } } + .choice-select__list:has(.choice-select__option:nth-of-type(7) .choice-select__radio:checked) { top: calc(-6 * var(--option-height)); clip-path: inset( calc(6 * var(--option-height)) 0 calc((var(--choice-count) - 6 - 1) * var(--option-height)) 0 round var(--border-radius) ); + .choice-select__border { top: calc(6 * var(--option-height)); } diff --git a/src/code-blocks/components/ChoiceGroup.tsx b/src/code-blocks/components/ChoiceGroup.tsx index 4509c331..2614b0b2 100644 --- a/src/code-blocks/components/ChoiceGroup.tsx +++ b/src/code-blocks/components/ChoiceGroup.tsx @@ -97,7 +97,7 @@ function CustomSelect({ choiceGroup }: { choiceGroup: ChoiceGroupWithParent }) { data-choice-group={groupName} >
- {filteredChoices.map(({ name: choice, icon, iconStyle }) => ( + {filteredChoices.map(({ name: choice, icon, iconStyle: { dropdown } = {} }) => ( ))} diff --git a/src/code-blocks/components/Tabs.css b/src/code-blocks/components/Tabs.css index 24af48af..29c3f464 100644 --- a/src/code-blocks/components/Tabs.css +++ b/src/code-blocks/components/Tabs.css @@ -51,18 +51,15 @@ align-items: center; gap: 6px; line-height: 1; - font-size: 16px; - padding-inline: 4px; + padding-inline: 2px; } -img { - display: block; - max-width: 100%; +.choice-tabs__tab-label { + font-size: 16px; } .choice-tabs__tab-content img { - width: 16px; - height: 16px; + height: 13px; } @media screen and (max-width: 400px) { diff --git a/src/code-blocks/components/Tabs.tsx b/src/code-blocks/components/Tabs.tsx index deb9f310..24d14e67 100644 --- a/src/code-blocks/components/Tabs.tsx +++ b/src/code-blocks/components/Tabs.tsx @@ -29,7 +29,7 @@ function Tabs({ choice, hide = [] }: { choice: string; hide: string[] }) { role="radiogroup" data-choice-group={groupName} > - {choices.map(({ name: choice, icon, iconStyle }) => ( + {choices.map(({ name: choice, icon, iconStyle: { tab } = {} }) => ( ))} diff --git a/src/code-blocks/utils/generateChoiceGroupCode.ts b/src/code-blocks/utils/generateChoiceGroupCode.ts index 2f9395da..fe08ed84 100644 --- a/src/code-blocks/utils/generateChoiceGroupCode.ts +++ b/src/code-blocks/utils/generateChoiceGroupCode.ts @@ -24,10 +24,12 @@ const CHOICES_BUILT_IN: NonNullable = { { name: 'JavaScript', icon: JAVASCRIPT_ICON, + iconStyle: { dropdown: { height: '13px' } }, }, { name: 'TypeScript', icon: TYPESCRIPT_ICON, + iconStyle: { dropdown: { height: '13px' } }, }, ], default: 'JavaScript', @@ -36,7 +38,7 @@ const CHOICES_BUILT_IN: NonNullable = { choices: [ { name: 'npm', icon: NPM_ICON }, { name: 'pnpm', icon: PNPM_ICON }, - { name: 'Bun', icon: BUN_ICON }, + { name: 'Bun', icon: BUN_ICON, iconStyle: { dropdown: { width: '14px', marginTop: '1px' } } }, { name: 'Yarn', icon: YARN_ICON }, ], default: 'npm', diff --git a/src/types/Config.ts b/src/types/Config.ts index d7a2d48c..dc864725 100644 --- a/src/types/Config.ts +++ b/src/types/Config.ts @@ -63,7 +63,14 @@ type Category = } /** A choice. A plain `string` is shorthand for `{ name: string }` (no icon). */ -type ChoiceItem = { name: string; icon?: string; iconStyle?: React.CSSProperties } +type ChoiceItem = { + name: string + icon?: string + iconStyle?: { + dropdown?: React.CSSProperties + tab?: React.CSSProperties + } +} type Choice = { choices: (string | ChoiceItem)[] default: string From fcf7436ede59c87e65fc1c0afcfd36724c6a0966 Mon Sep 17 00:00:00 2001 From: Muhammad Date: Mon, 29 Jun 2026 02:58:02 +0700 Subject: [PATCH 12/14] remove unnecessary format --- src/code-blocks/components/ChoiceGroup.css | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/code-blocks/components/ChoiceGroup.css b/src/code-blocks/components/ChoiceGroup.css index 69e00d1f..8d22f433 100644 --- a/src/code-blocks/components/ChoiceGroup.css +++ b/src/code-blocks/components/ChoiceGroup.css @@ -106,7 +106,6 @@ .choice-select__list[aria-expanded='true'] { z-index: 1; clip-path: inset(0px round var(--border-radius)) !important; - .choice-select__border { top: 0 !important; height: calc(var(--choice-count) * var(--option-height)); @@ -115,11 +114,9 @@ .choice-select__list:not(.hovered) { transition: none; - .choice-select__border { transition: none; } - .choice-select__option { transition: none; } @@ -147,79 +144,66 @@ calc(0 * var(--option-height)) 0 calc((var(--choice-count) - 0 - 1) * var(--option-height)) 0 round var(--border-radius) ); - .choice-select__border { top: 0; } } - .choice-select__list:has(.choice-select__option:nth-of-type(2) .choice-select__radio:checked) { top: calc(-1 * var(--option-height)); clip-path: inset( calc(1 * var(--option-height)) 0 calc((var(--choice-count) - 1 - 1) * var(--option-height)) 0 round var(--border-radius) ); - .choice-select__border { top: var(--option-height); } } - .choice-select__list:has(.choice-select__option:nth-of-type(3) .choice-select__radio:checked) { top: calc(-2 * var(--option-height)); clip-path: inset( calc(2 * var(--option-height)) 0 calc((var(--choice-count) - 2 - 1) * var(--option-height)) 0 round var(--border-radius) ); - .choice-select__border { top: calc(2 * var(--option-height)); } } - .choice-select__list:has(.choice-select__option:nth-of-type(4) .choice-select__radio:checked) { top: calc(-3 * var(--option-height)); clip-path: inset( calc(3 * var(--option-height)) 0 calc((var(--choice-count) - 3 - 1) * var(--option-height)) 0 round var(--border-radius) ); - .choice-select__border { top: calc(3 * var(--option-height)); } } - .choice-select__list:has(.choice-select__option:nth-of-type(5) .choice-select__radio:checked) { top: calc(-4 * var(--option-height)); clip-path: inset( calc(4 * var(--option-height)) 0 calc((var(--choice-count) - 4 - 1) * var(--option-height)) 0 round var(--border-radius) ); - .choice-select__border { top: calc(4 * var(--option-height)); } } - .choice-select__list:has(.choice-select__option:nth-of-type(6) .choice-select__radio:checked) { top: calc(-5 * var(--option-height)); clip-path: inset( calc(5 * var(--option-height)) 0 calc((var(--choice-count) - 5 - 1) * var(--option-height)) 0 round var(--border-radius) ); - .choice-select__border { top: calc(5 * var(--option-height)); } } - .choice-select__list:has(.choice-select__option:nth-of-type(7) .choice-select__radio:checked) { top: calc(-6 * var(--option-height)); clip-path: inset( calc(6 * var(--option-height)) 0 calc((var(--choice-count) - 6 - 1) * var(--option-height)) 0 round var(--border-radius) ); - .choice-select__border { top: calc(6 * var(--option-height)); } From 3b9d4f4dac9ea85ab7dabc24566b1236ec82f5e1 Mon Sep 17 00:00:00 2001 From: Muhammad Date: Mon, 29 Jun 2026 23:59:39 +0700 Subject: [PATCH 13/14] refactor: update iconStyle structure for choices and tabs --- demo/+docpress.tsx | 16 +++++++++++++--- src/code-blocks/components/ChoiceGroup.css | 1 + src/code-blocks/components/ChoiceGroup.tsx | 4 ++-- src/code-blocks/components/Tabs.tsx | 4 ++-- src/code-blocks/utils/generateChoiceGroupCode.ts | 13 +++++++++---- src/types/Config.ts | 7 +++---- 6 files changed, 30 insertions(+), 15 deletions(-) diff --git a/demo/+docpress.tsx b/demo/+docpress.tsx index 78fe700f..6bd57f5a 100644 --- a/demo/+docpress.tsx +++ b/demo/+docpress.tsx @@ -51,13 +51,23 @@ const config: Config = { choices: { server: { choices: [ - { name: 'Hono', icon: iconHono, iconStyle: { dropdown: { height: '13px' } } }, + { + name: 'Hono', + icon: iconHono, + iconStyle: { marginBottom: '1.5px' }, + }, { name: 'Express', icon: iconExpress, - iconStyle: { dropdown: { objectFit: 'contain', width: '14px', marginTop: '1px' } }, + iconStyle: { objectFit: 'contain' }, + iconStyleTab: { height: '11.5px' }, + }, + { + name: 'Fastify', + icon: iconFastify, + iconStyleDropdown: { width: '14px' }, + iconStyleTab: { width: '18px' }, }, - { name: 'Fastify', icon: iconFastify, iconStyle: { dropdown: { width: '14px', marginTop: '1px' } } }, { name: 'H3', icon: iconH3 }, ], default: 'Hono', diff --git a/src/code-blocks/components/ChoiceGroup.css b/src/code-blocks/components/ChoiceGroup.css index 8d22f433..f8003f03 100644 --- a/src/code-blocks/components/ChoiceGroup.css +++ b/src/code-blocks/components/ChoiceGroup.css @@ -87,6 +87,7 @@ .choice-select__option-content img { width: 13px; + height: 12px; filter: grayscale(100%); opacity: 0.8; diff --git a/src/code-blocks/components/ChoiceGroup.tsx b/src/code-blocks/components/ChoiceGroup.tsx index 2614b0b2..ff824ab4 100644 --- a/src/code-blocks/components/ChoiceGroup.tsx +++ b/src/code-blocks/components/ChoiceGroup.tsx @@ -97,7 +97,7 @@ function CustomSelect({ choiceGroup }: { choiceGroup: ChoiceGroupWithParent }) { data-choice-group={groupName} >
- {filteredChoices.map(({ name: choice, icon, iconStyle: { dropdown } = {} }) => ( + {filteredChoices.map(({ name: choice, icon, iconStyle, iconStyleDropdown }) => (