From f75c9f3cf6ead4b7f9d8ca91c2a20e41854b6628 Mon Sep 17 00:00:00 2001 From: Francesco Mussoni Date: Mon, 13 Jul 2026 21:18:20 +0200 Subject: [PATCH 01/16] feat(Checkbox/RadioGroup): add leading icon support for items - Introduced `leadingIcon` prop in Checkbox and RadioGroup components to display an icon next to the label. - Updated CheckboxGroup and RadioGroup to handle the new `icon` property in items. - Enhanced styles in themes to accommodate leading icons. - Added tests to verify rendering of leading icons in CheckboxGroup and RadioGroup. --- src/runtime/components/Checkbox.vue | 6 + src/runtime/components/CheckboxGroup.vue | 8 +- src/runtime/components/RadioGroup.vue | 9 +- src/theme/checkbox.ts | 16 +- src/theme/radio-group.ts | 16 +- .../CheckboxGroupIcon.a4cec7.spec.ts | 71 +++ test/components/RadioGroupIcon.781254.spec.ts | 62 +++ .../__snapshots__/Checkbox-vue.spec.ts.snap | 20 +- .../CheckboxGroup-vue.spec.ts.snap | 468 +++++++++++++----- .../__snapshots__/RadioGroup-vue.spec.ts.snap | 468 +++++++++++++----- .../__snapshots__/Table-vue.spec.ts.snap | 20 +- 11 files changed, 908 insertions(+), 256 deletions(-) create mode 100644 test/components/CheckboxGroupIcon.a4cec7.spec.ts create mode 100644 test/components/RadioGroupIcon.781254.spec.ts diff --git a/src/runtime/components/Checkbox.vue b/src/runtime/components/Checkbox.vue index f14d3f2f7e..05cace429a 100644 --- a/src/runtime/components/Checkbox.vue +++ b/src/runtime/components/Checkbox.vue @@ -48,6 +48,11 @@ export interface CheckboxProps extends Pick, ' * @IconifyIcon */ indeterminateIcon?: IconProps['name'] + /** + * The icon displayed next to the label. + * @IconifyIcon + */ + leadingIcon?: IconProps['name'] class?: any ui?: Checkbox['slots'] } @@ -139,6 +144,7 @@ function onUpdate(value: any) {
+ {{ props.label }} diff --git a/src/runtime/components/CheckboxGroup.vue b/src/runtime/components/CheckboxGroup.vue index 07c5c523f4..71a650b495 100644 --- a/src/runtime/components/CheckboxGroup.vue +++ b/src/runtime/components/CheckboxGroup.vue @@ -16,6 +16,11 @@ export type CheckboxGroupItem = CheckboxGroupValue | { description?: string disabled?: boolean value?: string + /** + * The icon displayed next to the label. + * @IconifyIcon + */ + icon?: string class?: any ui?: Pick & Omit['ui'], 'root'> [key: string]: any @@ -187,7 +192,8 @@ function onUpdate(value: any) { + ui?: Pick [key: string]: any } @@ -100,6 +105,7 @@ import { useForwardProps } from '../composables/useForwardProps' import { useFormField } from '../composables/useFormField' import { get } from '../utils' import { tv } from '../utils/tv' +import UIcon from './Icon.vue' const _props = withDefaults(defineProps>(), { valueKey: 'value' as never, @@ -213,6 +219,7 @@ function onUpdate(value: any) {
+ {{ item.label }} diff --git a/src/theme/checkbox.ts b/src/theme/checkbox.ts index 8a977897d6..1d73424164 100644 --- a/src/theme/checkbox.ts +++ b/src/theme/checkbox.ts @@ -9,6 +9,7 @@ export default (options: Required) => ({ icon: 'shrink-0 size-full', wrapper: 'w-full', label: 'block font-medium text-default', + leadingIcon: 'inline-block align-middle shrink-0 me-1.5', description: 'text-muted' }, variants: { @@ -48,27 +49,32 @@ export default (options: Required) => ({ xs: { base: 'size-3', container: 'h-4', - wrapper: 'text-xs' + wrapper: 'text-xs', + leadingIcon: 'size-3' }, sm: { base: 'size-3.5', container: 'h-4', - wrapper: 'text-xs' + wrapper: 'text-xs', + leadingIcon: 'size-3.5' }, md: { base: 'size-4', container: 'h-5', - wrapper: 'text-sm' + wrapper: 'text-sm', + leadingIcon: 'size-4' }, lg: { base: 'size-4.5', container: 'h-5', - wrapper: 'text-sm' + wrapper: 'text-sm', + leadingIcon: 'size-4.5' }, xl: { base: 'size-5', container: 'h-6', - wrapper: 'text-base' + wrapper: 'text-base', + leadingIcon: 'size-5' } }, required: { diff --git a/src/theme/radio-group.ts b/src/theme/radio-group.ts index 640199c1b4..7a18c0df7e 100644 --- a/src/theme/radio-group.ts +++ b/src/theme/radio-group.ts @@ -11,6 +11,7 @@ export default (options: Required) => ({ indicator: 'flex items-center justify-center size-full after:bg-default after:rounded-full', wrapper: 'w-full', label: 'block font-medium text-default', + leadingIcon: 'inline-block align-middle shrink-0 me-1.5', description: 'text-muted' }, variants: { @@ -64,7 +65,8 @@ export default (options: Required) => ({ base: 'size-3', item: 'text-xs', container: 'h-4', - indicator: 'after:size-1' + indicator: 'after:size-1', + leadingIcon: 'size-3' }, sm: { fieldset: 'gap-y-0.5', @@ -72,7 +74,8 @@ export default (options: Required) => ({ base: 'size-3.5', item: 'text-xs', container: 'h-4', - indicator: 'after:size-1' + indicator: 'after:size-1', + leadingIcon: 'size-3.5' }, md: { fieldset: 'gap-y-1', @@ -80,7 +83,8 @@ export default (options: Required) => ({ base: 'size-4', item: 'text-sm', container: 'h-5', - indicator: 'after:size-1.5' + indicator: 'after:size-1.5', + leadingIcon: 'size-4' }, lg: { fieldset: 'gap-y-1', @@ -88,7 +92,8 @@ export default (options: Required) => ({ base: 'size-4.5', item: 'text-sm', container: 'h-5', - indicator: 'after:size-1.5' + indicator: 'after:size-1.5', + leadingIcon: 'size-4.5' }, xl: { fieldset: 'gap-y-1.5', @@ -96,7 +101,8 @@ export default (options: Required) => ({ base: 'size-5', item: 'text-base', container: 'h-6', - indicator: 'after:size-2' + indicator: 'after:size-2', + leadingIcon: 'size-5' } }, highlight: { diff --git a/test/components/CheckboxGroupIcon.a4cec7.spec.ts b/test/components/CheckboxGroupIcon.a4cec7.spec.ts new file mode 100644 index 0000000000..effae60901 --- /dev/null +++ b/test/components/CheckboxGroupIcon.a4cec7.spec.ts @@ -0,0 +1,71 @@ +import { describe, it, expect } from 'vitest' +import { mountSuspended } from '@nuxt/test-utils/runtime' +import CheckboxGroup from '../../src/runtime/components/CheckboxGroup.vue' +import theme from '#build/ui/checkbox-group' +import themeCheckbox from '#build/ui/checkbox' + +describe('CheckboxGroup with icon', () => { + const items = [ + { value: 'table', label: 'Table', icon: 'i-lucide-table' }, + { value: 'board', label: 'Board', icon: 'i-lucide-layout-grid' }, + { value: 'list', label: 'List' } + ] + + const sizes = Object.keys(theme.variants.size) as any + const variants = Object.keys(theme.variants.variant) as any + const indicators = Object.keys(themeCheckbox.variants.indicator) as any + + it('renders a leading icon only for items that define one', async () => { + const wrapper = await mountSuspended(CheckboxGroup, { props: { items } }) + expect(wrapper.findAll('[data-slot="leadingIcon"]')).toHaveLength(2) + }) + + it('keeps the label text alongside the icon', async () => { + const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [items[0]] } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(true) + expect(wrapper.text()).toContain('Table') + }) + + it('does not render a leading icon when the item has none', async () => { + const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [{ value: 'list', label: 'List' }] } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(false) + }) + + it('keeps the item description alongside the icon', async () => { + const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [{ ...items[0], description: 'Spreadsheet view' }] } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(true) + expect(wrapper.text()).toContain('Spreadsheet view') + }) + + it('adds a label icon without replacing the existing checkbox indicator icon', async () => { + const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [items[0]], modelValue: ['table'] } }) + // The item icon renders as a leading label icon... + expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(true) + // ...and the checkbox check indicator icon remains its own, separate element. + expect(wrapper.find('[data-slot="icon"]').exists()).toBe(true) + }) + + it('renders the icon across every size', async () => { + for (const size of sizes) { + const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [items[0]], size } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `size=${size}`).toBe(true) + } + }) + + it('renders the icon across every variant', async () => { + for (const variant of variants) { + const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [items[0]], variant } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `variant=${variant}`).toBe(true) + } + }) + + it('renders the icon in horizontal orientation and for every indicator position', async () => { + const horizontal = await mountSuspended(CheckboxGroup, { props: { items: [items[0]], orientation: 'horizontal' } }) + expect(horizontal.find('[data-slot="leadingIcon"]').exists()).toBe(true) + + for (const indicator of indicators) { + const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [items[0]], indicator } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `indicator=${indicator}`).toBe(true) + } + }) +}) diff --git a/test/components/RadioGroupIcon.781254.spec.ts b/test/components/RadioGroupIcon.781254.spec.ts new file mode 100644 index 0000000000..1350e3af0e --- /dev/null +++ b/test/components/RadioGroupIcon.781254.spec.ts @@ -0,0 +1,62 @@ +import { describe, it, expect } from 'vitest' +import { mountSuspended } from '@nuxt/test-utils/runtime' +import RadioGroup from '../../src/runtime/components/RadioGroup.vue' +import theme from '#build/ui/radio-group' + +describe('RadioGroup with icon', () => { + const items = [ + { value: 'table', label: 'Table', icon: 'i-lucide-table' }, + { value: 'board', label: 'Board', icon: 'i-lucide-layout-grid' }, + { value: 'list', label: 'List' } + ] + + const sizes = Object.keys(theme.variants.size) as any + const variants = Object.keys(theme.variants.variant) as any + const indicators = Object.keys(theme.variants.indicator) as any + + it('renders a leading icon only for items that define one', async () => { + const wrapper = await mountSuspended(RadioGroup, { props: { items } }) + expect(wrapper.findAll('[data-slot="leadingIcon"]')).toHaveLength(2) + }) + + it('keeps the label text alongside the icon', async () => { + const wrapper = await mountSuspended(RadioGroup, { props: { items: [items[0]] } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(true) + expect(wrapper.text()).toContain('Table') + }) + + it('does not render a leading icon when the item has none', async () => { + const wrapper = await mountSuspended(RadioGroup, { props: { items: [{ value: 'list', label: 'List' }] } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(false) + }) + + it('keeps the item description alongside the icon', async () => { + const wrapper = await mountSuspended(RadioGroup, { props: { items: [{ ...items[0], description: 'Spreadsheet view' }] } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(true) + expect(wrapper.text()).toContain('Spreadsheet view') + }) + + it('renders the icon across every size', async () => { + for (const size of sizes) { + const wrapper = await mountSuspended(RadioGroup, { props: { items: [items[0]], size } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `size=${size}`).toBe(true) + } + }) + + it('renders the icon across every variant', async () => { + for (const variant of variants) { + const wrapper = await mountSuspended(RadioGroup, { props: { items: [items[0]], variant } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `variant=${variant}`).toBe(true) + } + }) + + it('renders the icon in horizontal orientation and for every indicator position', async () => { + const horizontal = await mountSuspended(RadioGroup, { props: { items: [items[0]], orientation: 'horizontal' } }) + expect(horizontal.find('[data-slot="leadingIcon"]').exists()).toBe(true) + + for (const indicator of indicators) { + const wrapper = await mountSuspended(RadioGroup, { props: { items: [items[0]], indicator } }) + expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `indicator=${indicator}`).toBe(true) + } + }) +}) diff --git a/test/components/__snapshots__/Checkbox-vue.spec.ts.snap b/test/components/__snapshots__/Checkbox-vue.spec.ts.snap index 38139da7f2..00ed900fd8 100644 --- a/test/components/__snapshots__/Checkbox-vue.spec.ts.snap +++ b/test/components/__snapshots__/Checkbox-vue.spec.ts.snap @@ -49,7 +49,9 @@ exports[`Checkbox > renders with description correctly 1`] = `
-
+

Description

" @@ -62,7 +64,9 @@ exports[`Checkbox > renders with description slot correctly 1`] = `
-
+
" @@ -153,7 +157,9 @@ exports[`Checkbox > renders with label correctly 1`] = ` -
+
" @@ -166,7 +172,9 @@ exports[`Checkbox > renders with label slot correctly 1`] = ` -
+
" @@ -271,7 +279,9 @@ exports[`Checkbox > renders with required correctly 1`] = ` -
+
" diff --git a/test/components/__snapshots__/CheckboxGroup-vue.spec.ts.snap b/test/components/__snapshots__/CheckboxGroup-vue.spec.ts.snap index 17c6235c7e..7835dd710c 100644 --- a/test/components/__snapshots__/CheckboxGroup-vue.spec.ts.snap +++ b/test/components/__snapshots__/CheckboxGroup-vue.spec.ts.snap @@ -10,7 +10,9 @@ exports[`CheckboxGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -20,7 +22,9 @@ exports[`CheckboxGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -30,7 +34,9 @@ exports[`CheckboxGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -49,7 +55,9 @@ exports[`CheckboxGroup > renders with as correctly 1`] = ` -
+
@@ -59,7 +67,9 @@ exports[`CheckboxGroup > renders with as correctly 1`] = ` -
+
@@ -69,7 +79,9 @@ exports[`CheckboxGroup > renders with as correctly 1`] = ` -
+
@@ -88,7 +100,9 @@ exports[`CheckboxGroup > renders with class correctly 1`] = ` -
+
@@ -98,7 +112,9 @@ exports[`CheckboxGroup > renders with class correctly 1`] = ` -
+
@@ -108,7 +124,9 @@ exports[`CheckboxGroup > renders with class correctly 1`] = ` -
+
@@ -125,7 +143,9 @@ exports[`CheckboxGroup > renders with defaultValue correctly 1`] = `
-
+
@@ -135,7 +155,9 @@ exports[`CheckboxGroup > renders with defaultValue correctly 1`] = ` -
+
@@ -145,7 +167,9 @@ exports[`CheckboxGroup > renders with defaultValue correctly 1`] = ` -
+
@@ -164,7 +188,9 @@ exports[`CheckboxGroup > renders with description correctly 1`] = ` -
+

Description 0

@@ -174,7 +200,9 @@ exports[`CheckboxGroup > renders with description correctly 1`] = ` -
+

Description 1

@@ -184,7 +212,9 @@ exports[`CheckboxGroup > renders with description correctly 1`] = ` -
+

Description 2

@@ -203,7 +233,9 @@ exports[`CheckboxGroup > renders with description slot correctly 1`] = ` -
+

Description slot

@@ -213,7 +245,9 @@ exports[`CheckboxGroup > renders with description slot correctly 1`] = ` -
+

Description slot

@@ -223,7 +257,9 @@ exports[`CheckboxGroup > renders with description slot correctly 1`] = ` -
+

Description slot

@@ -242,7 +278,9 @@ exports[`CheckboxGroup > renders with descriptionKey correctly 1`] = ` -
+

1

@@ -252,7 +290,9 @@ exports[`CheckboxGroup > renders with descriptionKey correctly 1`] = ` -
+

2

@@ -262,7 +302,9 @@ exports[`CheckboxGroup > renders with descriptionKey correctly 1`] = ` -
+

3

@@ -281,7 +323,9 @@ exports[`CheckboxGroup > renders with disabled correctly 1`] = ` -
+
@@ -291,7 +335,9 @@ exports[`CheckboxGroup > renders with disabled correctly 1`] = ` -
+
@@ -301,7 +347,9 @@ exports[`CheckboxGroup > renders with disabled correctly 1`] = ` -
+
@@ -318,7 +366,9 @@ exports[`CheckboxGroup > renders with horizontal variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -355,7 +409,9 @@ exports[`CheckboxGroup > renders with horizontal variant list correctly 1`] = `
-
+
@@ -365,7 +421,9 @@ exports[`CheckboxGroup > renders with horizontal variant list correctly 1`] = ` -
+
@@ -375,7 +433,9 @@ exports[`CheckboxGroup > renders with horizontal variant list correctly 1`] = ` -
+
@@ -392,7 +452,9 @@ exports[`CheckboxGroup > renders with horizontal variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -429,7 +495,9 @@ exports[`CheckboxGroup > renders with indicator end correctly 1`] = `
-
+
@@ -439,7 +507,9 @@ exports[`CheckboxGroup > renders with indicator end correctly 1`] = ` -
+
@@ -449,7 +519,9 @@ exports[`CheckboxGroup > renders with indicator end correctly 1`] = ` -
+
@@ -466,7 +538,9 @@ exports[`CheckboxGroup > renders with indicator hidden correctly 1`] = `
-
+
@@ -476,7 +550,9 @@ exports[`CheckboxGroup > renders with indicator hidden correctly 1`] = ` -
+
@@ -486,7 +562,9 @@ exports[`CheckboxGroup > renders with indicator hidden correctly 1`] = ` -
+
@@ -503,7 +581,9 @@ exports[`CheckboxGroup > renders with indicator start correctly 1`] = `
-
+
@@ -513,7 +593,9 @@ exports[`CheckboxGroup > renders with indicator start correctly 1`] = ` -
+
@@ -523,7 +605,9 @@ exports[`CheckboxGroup > renders with indicator start correctly 1`] = ` -
+
@@ -542,7 +626,9 @@ exports[`CheckboxGroup > renders with items correctly 1`] = ` -
+
@@ -552,7 +638,9 @@ exports[`CheckboxGroup > renders with items correctly 1`] = ` -
+
@@ -562,7 +650,9 @@ exports[`CheckboxGroup > renders with items correctly 1`] = ` -
+
@@ -581,7 +671,9 @@ exports[`CheckboxGroup > renders with label slot correctly 1`] = ` -
+
@@ -591,7 +683,9 @@ exports[`CheckboxGroup > renders with label slot correctly 1`] = ` -
+
@@ -601,7 +695,9 @@ exports[`CheckboxGroup > renders with label slot correctly 1`] = ` -
+
@@ -620,7 +716,9 @@ exports[`CheckboxGroup > renders with labelKey correctly 1`] = ` -
+
@@ -630,7 +728,9 @@ exports[`CheckboxGroup > renders with labelKey correctly 1`] = ` -
+
@@ -640,7 +740,9 @@ exports[`CheckboxGroup > renders with labelKey correctly 1`] = ` -
+
@@ -659,7 +761,9 @@ exports[`CheckboxGroup > renders with legend slot correctly 1`] = ` -
+
@@ -669,7 +773,9 @@ exports[`CheckboxGroup > renders with legend slot correctly 1`] = ` -
+
@@ -679,7 +785,9 @@ exports[`CheckboxGroup > renders with legend slot correctly 1`] = ` -
+
@@ -696,7 +804,9 @@ exports[`CheckboxGroup > renders with modelValue correctly 1`] = `
-
+
@@ -706,7 +816,9 @@ exports[`CheckboxGroup > renders with modelValue correctly 1`] = ` -
+
@@ -716,7 +828,9 @@ exports[`CheckboxGroup > renders with modelValue correctly 1`] = ` -
+
@@ -733,7 +847,9 @@ exports[`CheckboxGroup > renders with neutral variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -770,7 +890,9 @@ exports[`CheckboxGroup > renders with neutral variant card highlight correctly 1
-

Option 1

+

+ Option 1 +

@@ -807,7 +933,9 @@ exports[`CheckboxGroup > renders with neutral variant list correctly 1`] = `
-
+
@@ -817,7 +945,9 @@ exports[`CheckboxGroup > renders with neutral variant list correctly 1`] = ` -
+
@@ -827,7 +957,9 @@ exports[`CheckboxGroup > renders with neutral variant list correctly 1`] = ` -
+
@@ -844,7 +976,9 @@ exports[`CheckboxGroup > renders with neutral variant list highlight correctly 1
-
+
@@ -854,7 +988,9 @@ exports[`CheckboxGroup > renders with neutral variant list highlight correctly 1 -
+
@@ -864,7 +1000,9 @@ exports[`CheckboxGroup > renders with neutral variant list highlight correctly 1 -
+
@@ -881,7 +1019,9 @@ exports[`CheckboxGroup > renders with neutral variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -918,7 +1062,9 @@ exports[`CheckboxGroup > renders with neutral variant table highlight correctly
-

Option 1

+

+ Option 1 +

@@ -955,7 +1105,9 @@ exports[`CheckboxGroup > renders with primary variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -992,7 +1148,9 @@ exports[`CheckboxGroup > renders with primary variant card highlight correctly 1
-

Option 1

+

+ Option 1 +

@@ -1029,7 +1191,9 @@ exports[`CheckboxGroup > renders with primary variant list correctly 1`] = `
-
+
@@ -1039,7 +1203,9 @@ exports[`CheckboxGroup > renders with primary variant list correctly 1`] = ` -
+
@@ -1049,7 +1215,9 @@ exports[`CheckboxGroup > renders with primary variant list correctly 1`] = ` -
+
@@ -1066,7 +1234,9 @@ exports[`CheckboxGroup > renders with primary variant list highlight correctly 1
-
+
@@ -1076,7 +1246,9 @@ exports[`CheckboxGroup > renders with primary variant list highlight correctly 1 -
+
@@ -1086,7 +1258,9 @@ exports[`CheckboxGroup > renders with primary variant list highlight correctly 1 -
+
@@ -1103,7 +1277,9 @@ exports[`CheckboxGroup > renders with primary variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -1140,7 +1320,9 @@ exports[`CheckboxGroup > renders with primary variant table highlight correctly
-

Option 1

+

+ Option 1 +

@@ -1179,7 +1365,9 @@ exports[`CheckboxGroup > renders with required correctly 1`] = ` -
+
@@ -1189,7 +1377,9 @@ exports[`CheckboxGroup > renders with required correctly 1`] = ` -
+
@@ -1199,7 +1389,9 @@ exports[`CheckboxGroup > renders with required correctly 1`] = ` -
+
@@ -1216,7 +1408,9 @@ exports[`CheckboxGroup > renders with size lg correctly 1`] = `
-
+
@@ -1226,7 +1420,9 @@ exports[`CheckboxGroup > renders with size lg correctly 1`] = ` -
+
@@ -1236,7 +1432,9 @@ exports[`CheckboxGroup > renders with size lg correctly 1`] = ` -
+
@@ -1253,7 +1451,9 @@ exports[`CheckboxGroup > renders with size md correctly 1`] = `
-
+
@@ -1263,7 +1463,9 @@ exports[`CheckboxGroup > renders with size md correctly 1`] = ` -
+
@@ -1273,7 +1475,9 @@ exports[`CheckboxGroup > renders with size md correctly 1`] = ` -
+
@@ -1290,7 +1494,9 @@ exports[`CheckboxGroup > renders with size sm correctly 1`] = `
-
+
@@ -1300,7 +1506,9 @@ exports[`CheckboxGroup > renders with size sm correctly 1`] = ` -
+
@@ -1310,7 +1518,9 @@ exports[`CheckboxGroup > renders with size sm correctly 1`] = ` -
+
@@ -1327,7 +1537,9 @@ exports[`CheckboxGroup > renders with size xl correctly 1`] = `
-
+
@@ -1337,7 +1549,9 @@ exports[`CheckboxGroup > renders with size xl correctly 1`] = ` -
+
@@ -1347,7 +1561,9 @@ exports[`CheckboxGroup > renders with size xl correctly 1`] = ` -
+
@@ -1364,7 +1580,9 @@ exports[`CheckboxGroup > renders with size xs correctly 1`] = `
-
+
@@ -1374,7 +1592,9 @@ exports[`CheckboxGroup > renders with size xs correctly 1`] = ` -
+
@@ -1384,7 +1604,9 @@ exports[`CheckboxGroup > renders with size xs correctly 1`] = ` -
+
@@ -1403,7 +1625,9 @@ exports[`CheckboxGroup > renders with ui correctly 1`] = ` -
+
@@ -1413,7 +1637,9 @@ exports[`CheckboxGroup > renders with ui correctly 1`] = ` -
+
@@ -1423,7 +1649,9 @@ exports[`CheckboxGroup > renders with ui correctly 1`] = ` -
+
@@ -1440,7 +1668,9 @@ exports[`CheckboxGroup > renders with valueKey correctly 1`] = `
-
+
@@ -1450,7 +1680,9 @@ exports[`CheckboxGroup > renders with valueKey correctly 1`] = ` -
+
@@ -1460,7 +1692,9 @@ exports[`CheckboxGroup > renders with valueKey correctly 1`] = ` -
+
diff --git a/test/components/__snapshots__/RadioGroup-vue.spec.ts.snap b/test/components/__snapshots__/RadioGroup-vue.spec.ts.snap index 266edf59b7..77d339964a 100644 --- a/test/components/__snapshots__/RadioGroup-vue.spec.ts.snap +++ b/test/components/__snapshots__/RadioGroup-vue.spec.ts.snap @@ -10,7 +10,9 @@ exports[`RadioGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -20,7 +22,9 @@ exports[`RadioGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -30,7 +34,9 @@ exports[`RadioGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -49,7 +55,9 @@ exports[`RadioGroup > renders with as correctly 1`] = ` -
+
@@ -59,7 +67,9 @@ exports[`RadioGroup > renders with as correctly 1`] = ` -
+
@@ -69,7 +79,9 @@ exports[`RadioGroup > renders with as correctly 1`] = ` -
+
@@ -88,7 +100,9 @@ exports[`RadioGroup > renders with class correctly 1`] = ` -
+
@@ -98,7 +112,9 @@ exports[`RadioGroup > renders with class correctly 1`] = ` -
+
@@ -108,7 +124,9 @@ exports[`RadioGroup > renders with class correctly 1`] = ` -
+
@@ -125,7 +143,9 @@ exports[`RadioGroup > renders with defaultValue correctly 1`] = `
-
+
@@ -135,7 +155,9 @@ exports[`RadioGroup > renders with defaultValue correctly 1`] = ` -
+
@@ -145,7 +167,9 @@ exports[`RadioGroup > renders with defaultValue correctly 1`] = ` -
+
@@ -164,7 +188,9 @@ exports[`RadioGroup > renders with description correctly 1`] = ` -
+

Description 0

@@ -174,7 +200,9 @@ exports[`RadioGroup > renders with description correctly 1`] = ` -
+

Description 1

@@ -184,7 +212,9 @@ exports[`RadioGroup > renders with description correctly 1`] = ` -
+

Description 2

@@ -203,7 +233,9 @@ exports[`RadioGroup > renders with description slot correctly 1`] = ` -
+
@@ -213,7 +245,9 @@ exports[`RadioGroup > renders with description slot correctly 1`] = ` -
+
@@ -223,7 +257,9 @@ exports[`RadioGroup > renders with description slot correctly 1`] = ` -
+
@@ -242,7 +278,9 @@ exports[`RadioGroup > renders with descriptionKey correctly 1`] = ` -
+

1

@@ -252,7 +290,9 @@ exports[`RadioGroup > renders with descriptionKey correctly 1`] = ` -
+

2

@@ -262,7 +302,9 @@ exports[`RadioGroup > renders with descriptionKey correctly 1`] = ` -
+

3

@@ -281,7 +323,9 @@ exports[`RadioGroup > renders with disabled correctly 1`] = ` -
+
@@ -291,7 +335,9 @@ exports[`RadioGroup > renders with disabled correctly 1`] = ` -
+
@@ -301,7 +347,9 @@ exports[`RadioGroup > renders with disabled correctly 1`] = ` -
+
@@ -318,7 +366,9 @@ exports[`RadioGroup > renders with horizontal variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -355,7 +409,9 @@ exports[`RadioGroup > renders with horizontal variant list correctly 1`] = `
-
+
@@ -365,7 +421,9 @@ exports[`RadioGroup > renders with horizontal variant list correctly 1`] = ` -
+
@@ -375,7 +433,9 @@ exports[`RadioGroup > renders with horizontal variant list correctly 1`] = ` -
+
@@ -392,7 +452,9 @@ exports[`RadioGroup > renders with horizontal variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -429,7 +495,9 @@ exports[`RadioGroup > renders with indicator end correctly 1`] = `
-
+
@@ -439,7 +507,9 @@ exports[`RadioGroup > renders with indicator end correctly 1`] = ` -
+
@@ -449,7 +519,9 @@ exports[`RadioGroup > renders with indicator end correctly 1`] = ` -
+
@@ -466,7 +538,9 @@ exports[`RadioGroup > renders with indicator hidden correctly 1`] = `
-
+
@@ -476,7 +550,9 @@ exports[`RadioGroup > renders with indicator hidden correctly 1`] = ` -
+
@@ -486,7 +562,9 @@ exports[`RadioGroup > renders with indicator hidden correctly 1`] = ` -
+
@@ -503,7 +581,9 @@ exports[`RadioGroup > renders with indicator start correctly 1`] = `
-
+
@@ -513,7 +593,9 @@ exports[`RadioGroup > renders with indicator start correctly 1`] = ` -
+
@@ -523,7 +605,9 @@ exports[`RadioGroup > renders with indicator start correctly 1`] = ` -
+
@@ -542,7 +626,9 @@ exports[`RadioGroup > renders with items correctly 1`] = ` -
+
@@ -552,7 +638,9 @@ exports[`RadioGroup > renders with items correctly 1`] = ` -
+
@@ -562,7 +650,9 @@ exports[`RadioGroup > renders with items correctly 1`] = ` -
+
@@ -581,7 +671,9 @@ exports[`RadioGroup > renders with label slot correctly 1`] = ` -
+
@@ -591,7 +683,9 @@ exports[`RadioGroup > renders with label slot correctly 1`] = ` -
+
@@ -601,7 +695,9 @@ exports[`RadioGroup > renders with label slot correctly 1`] = ` -
+
@@ -620,7 +716,9 @@ exports[`RadioGroup > renders with labelKey correctly 1`] = ` -
+
@@ -630,7 +728,9 @@ exports[`RadioGroup > renders with labelKey correctly 1`] = ` -
+
@@ -640,7 +740,9 @@ exports[`RadioGroup > renders with labelKey correctly 1`] = ` -
+
@@ -659,7 +761,9 @@ exports[`RadioGroup > renders with legend slot correctly 1`] = ` -
+
@@ -669,7 +773,9 @@ exports[`RadioGroup > renders with legend slot correctly 1`] = ` -
+
@@ -679,7 +785,9 @@ exports[`RadioGroup > renders with legend slot correctly 1`] = ` -
+
@@ -696,7 +804,9 @@ exports[`RadioGroup > renders with modelValue correctly 1`] = `
-
+
@@ -706,7 +816,9 @@ exports[`RadioGroup > renders with modelValue correctly 1`] = ` -
+
@@ -716,7 +828,9 @@ exports[`RadioGroup > renders with modelValue correctly 1`] = ` -
+
@@ -733,7 +847,9 @@ exports[`RadioGroup > renders with neutral variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -770,7 +890,9 @@ exports[`RadioGroup > renders with neutral variant card highlight correctly 1`]
-

Option 1

+

+ Option 1 +

@@ -807,7 +933,9 @@ exports[`RadioGroup > renders with neutral variant list correctly 1`] = `
-
+
@@ -817,7 +945,9 @@ exports[`RadioGroup > renders with neutral variant list correctly 1`] = ` -
+
@@ -827,7 +957,9 @@ exports[`RadioGroup > renders with neutral variant list correctly 1`] = ` -
+
@@ -844,7 +976,9 @@ exports[`RadioGroup > renders with neutral variant list highlight correctly 1`]
-
+
@@ -854,7 +988,9 @@ exports[`RadioGroup > renders with neutral variant list highlight correctly 1`] -
+
@@ -864,7 +1000,9 @@ exports[`RadioGroup > renders with neutral variant list highlight correctly 1`] -
+
@@ -881,7 +1019,9 @@ exports[`RadioGroup > renders with neutral variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -918,7 +1062,9 @@ exports[`RadioGroup > renders with neutral variant table highlight correctly 1`]
-

Option 1

+

+ Option 1 +

@@ -955,7 +1105,9 @@ exports[`RadioGroup > renders with primary variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -992,7 +1148,9 @@ exports[`RadioGroup > renders with primary variant card highlight correctly 1`]
-

Option 1

+

+ Option 1 +

@@ -1029,7 +1191,9 @@ exports[`RadioGroup > renders with primary variant list correctly 1`] = `
-
+
@@ -1039,7 +1203,9 @@ exports[`RadioGroup > renders with primary variant list correctly 1`] = ` -
+
@@ -1049,7 +1215,9 @@ exports[`RadioGroup > renders with primary variant list correctly 1`] = ` -
+
@@ -1066,7 +1234,9 @@ exports[`RadioGroup > renders with primary variant list highlight correctly 1`]
-
+
@@ -1076,7 +1246,9 @@ exports[`RadioGroup > renders with primary variant list highlight correctly 1`] -
+
@@ -1086,7 +1258,9 @@ exports[`RadioGroup > renders with primary variant list highlight correctly 1`] -
+
@@ -1103,7 +1277,9 @@ exports[`RadioGroup > renders with primary variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -1140,7 +1320,9 @@ exports[`RadioGroup > renders with primary variant table highlight correctly 1`]
-

Option 1

+

+ Option 1 +

@@ -1179,7 +1365,9 @@ exports[`RadioGroup > renders with required correctly 1`] = ` -
+
@@ -1189,7 +1377,9 @@ exports[`RadioGroup > renders with required correctly 1`] = ` -
+
@@ -1199,7 +1389,9 @@ exports[`RadioGroup > renders with required correctly 1`] = ` -
+
@@ -1216,7 +1408,9 @@ exports[`RadioGroup > renders with size lg correctly 1`] = `
-
+
@@ -1226,7 +1420,9 @@ exports[`RadioGroup > renders with size lg correctly 1`] = ` -
+
@@ -1236,7 +1432,9 @@ exports[`RadioGroup > renders with size lg correctly 1`] = ` -
+
@@ -1253,7 +1451,9 @@ exports[`RadioGroup > renders with size md correctly 1`] = `
-
+
@@ -1263,7 +1463,9 @@ exports[`RadioGroup > renders with size md correctly 1`] = ` -
+
@@ -1273,7 +1475,9 @@ exports[`RadioGroup > renders with size md correctly 1`] = ` -
+
@@ -1290,7 +1494,9 @@ exports[`RadioGroup > renders with size sm correctly 1`] = `
-
+
@@ -1300,7 +1506,9 @@ exports[`RadioGroup > renders with size sm correctly 1`] = ` -
+
@@ -1310,7 +1518,9 @@ exports[`RadioGroup > renders with size sm correctly 1`] = ` -
+
@@ -1327,7 +1537,9 @@ exports[`RadioGroup > renders with size xl correctly 1`] = `
-
+
@@ -1337,7 +1549,9 @@ exports[`RadioGroup > renders with size xl correctly 1`] = ` -
+
@@ -1347,7 +1561,9 @@ exports[`RadioGroup > renders with size xl correctly 1`] = ` -
+
@@ -1364,7 +1580,9 @@ exports[`RadioGroup > renders with size xs correctly 1`] = `
-
+
@@ -1374,7 +1592,9 @@ exports[`RadioGroup > renders with size xs correctly 1`] = ` -
+
@@ -1384,7 +1604,9 @@ exports[`RadioGroup > renders with size xs correctly 1`] = ` -
+
@@ -1403,7 +1625,9 @@ exports[`RadioGroup > renders with ui correctly 1`] = ` -
+
@@ -1413,7 +1637,9 @@ exports[`RadioGroup > renders with ui correctly 1`] = ` -
+
@@ -1423,7 +1649,9 @@ exports[`RadioGroup > renders with ui correctly 1`] = ` -
+
@@ -1440,7 +1668,9 @@ exports[`RadioGroup > renders with valueKey correctly 1`] = `
-
+
@@ -1450,7 +1680,9 @@ exports[`RadioGroup > renders with valueKey correctly 1`] = ` -
+
@@ -1460,7 +1692,9 @@ exports[`RadioGroup > renders with valueKey correctly 1`] = ` -
+
diff --git a/test/components/__snapshots__/Table-vue.spec.ts.snap b/test/components/__snapshots__/Table-vue.spec.ts.snap index c75f5e1f75..d1a5149208 100644 --- a/test/components/__snapshots__/Table-vue.spec.ts.snap +++ b/test/components/__snapshots__/Table-vue.spec.ts.snap @@ -397,7 +397,9 @@ exports[`Table > renders with columns correctly 1`] = ` -
+
@@ -661,7 +663,9 @@ exports[`Table > renders with empty slot correctly 1`] = ` -
+
@@ -1495,7 +1499,9 @@ exports[`Table > renders with loading slot correctly 1`] = ` -
+
@@ -1559,7 +1565,9 @@ exports[`Table > renders with meta field on columns correctly 1`] = ` -
+
@@ -1992,7 +2000,9 @@ exports[`Table > renders with virtualize and sticky correctly 1`] = ` -
+
From 49468cbffcfd7232fe50917185bbe10fad13beb1 Mon Sep 17 00:00:00 2001 From: Francesco Mussoni Date: Mon, 13 Jul 2026 21:42:13 +0200 Subject: [PATCH 02/16] feat(Checkbox/RadioGroup): enhance item properties with icon support - Updated documentation to reflect the new `icon` property and its usage in examples. - Modified playground examples to demonstrate the new icon functionality in Checkbox and RadioGroup components. --- .../docs/2.components/checkbox-group.md | 33 ++++++++++++++++++- docs/content/docs/2.components/checkbox.md | 14 ++++++++ docs/content/docs/2.components/radio-group.md | 32 +++++++++++++++++- .../app/pages/components/checkbox-group.vue | 29 ++++++++++++++++ .../nuxt/app/pages/components/checkbox.vue | 1 + .../nuxt/app/pages/components/radio-group.vue | 29 ++++++++++++++++ 6 files changed, 136 insertions(+), 2 deletions(-) diff --git a/docs/content/docs/2.components/checkbox-group.md b/docs/content/docs/2.components/checkbox-group.md index 3d79f203b0..a24175533e 100644 --- a/docs/content/docs/2.components/checkbox-group.md +++ b/docs/content/docs/2.components/checkbox-group.md @@ -64,8 +64,9 @@ You can also pass an array of objects with the following properties: - `description?: string`{lang="ts-type"} - [`value?: string`{lang="ts-type"}](#value-key) - `disabled?: boolean`{lang="ts-type"} +- `icon?: string`{lang="ts-type"} - `class?: any`{lang="ts-type"} -- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, icon?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, icon?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, leadingIcon?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} ::component-code --- @@ -129,6 +130,36 @@ props: --- :: +### Icon + +Use the `icon` property in the items to display an icon next to the label. + +::component-code +--- +ignore: + - modelValue + - items +external: + - items + - modelValue +externalTypes: + - CheckboxGroupItem[] +props: + modelValue: + - 'system' + items: + - label: 'System' + icon: 'i-lucide-monitor' + value: 'system' + - label: 'Light' + icon: 'i-lucide-sun' + value: 'light' + - label: 'Dark' + icon: 'i-lucide-moon' + value: 'dark' +--- +:: + ### Legend Use the `legend` prop to set the legend of the CheckboxGroup. diff --git a/docs/content/docs/2.components/checkbox.md b/docs/content/docs/2.components/checkbox.md index 5704e5125c..4970116a55 100644 --- a/docs/content/docs/2.components/checkbox.md +++ b/docs/content/docs/2.components/checkbox.md @@ -140,6 +140,20 @@ You can customize this icon globally in your `vite.config.ts` under `ui.icons.ch ::: :: +### Leading Icon + +Use the `leading-icon` prop to display an icon next to the label of the Checkbox. + +::component-code +--- +ignore: + - label +props: + leadingIcon: 'i-lucide-tag' + label: Check me +--- +:: + ### Color Use the `color` prop to change the color of the Checkbox. diff --git a/docs/content/docs/2.components/radio-group.md b/docs/content/docs/2.components/radio-group.md index 40fc431639..f49cbdeb52 100644 --- a/docs/content/docs/2.components/radio-group.md +++ b/docs/content/docs/2.components/radio-group.md @@ -61,8 +61,9 @@ You can also pass an array of objects with the following properties: - `description?: string`{lang="ts-type"} - [`value?: string`{lang="ts-type"}](#value-key) - `disabled?: boolean`{lang="ts-type"} +- `icon?: string`{lang="ts-type"} - `class?: any`{lang="ts-type"} -- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, leadingIcon?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} ::component-code --- @@ -124,6 +125,35 @@ props: --- :: +### Icon + +Use the `icon` property in the items to display an icon next to the label. + +::component-code +--- +ignore: + - modelValue + - items +external: + - items + - modelValue +externalTypes: + - RadioGroupItem[] +props: + modelValue: 'system' + items: + - label: 'System' + icon: 'i-lucide-monitor' + value: 'system' + - label: 'Light' + icon: 'i-lucide-sun' + value: 'light' + - label: 'Dark' + icon: 'i-lucide-moon' + value: 'dark' +--- +:: + ### Legend Use the `legend` prop to set the legend of the RadioGroup. diff --git a/playgrounds/nuxt/app/pages/components/checkbox-group.vue b/playgrounds/nuxt/app/pages/components/checkbox-group.vue index 14033d2b3d..63ab872e94 100644 --- a/playgrounds/nuxt/app/pages/components/checkbox-group.vue +++ b/playgrounds/nuxt/app/pages/components/checkbox-group.vue @@ -32,6 +32,19 @@ const itemsWithDescription = [ { value: '2', label: 'Option 2', description: 'Description 2' }, { value: '3', label: 'Option 3', description: 'Description 3' } ] +const itemsWithIcon = [ + { value: '1', label: 'System', icon: 'i-lucide-monitor' }, + { value: '2', label: 'Light', icon: 'i-lucide-sun' }, + { value: '3', label: 'Dark', icon: 'i-lucide-moon' } +] +const viewItems = [ + { value: 'table', label: 'Table', icon: 'i-lucide-table' }, + { value: 'board', label: 'Board', icon: 'i-lucide-kanban' }, + { value: 'calendar', label: 'Calendar', icon: 'i-lucide-calendar' }, + { value: 'list', label: 'List', icon: 'i-lucide-list' }, + { value: 'gallery', label: 'Gallery', icon: 'i-lucide-images' }, + { value: 'map', label: 'Map', icon: 'i-lucide-map' } +] + + +
+ +
diff --git a/playgrounds/nuxt/app/pages/components/checkbox.vue b/playgrounds/nuxt/app/pages/components/checkbox.vue index 08ed72e0c4..ae6c0f8a5e 100644 --- a/playgrounds/nuxt/app/pages/components/checkbox.vue +++ b/playgrounds/nuxt/app/pages/components/checkbox.vue @@ -29,6 +29,7 @@ const value = ref(true) + diff --git a/playgrounds/nuxt/app/pages/components/radio-group.vue b/playgrounds/nuxt/app/pages/components/radio-group.vue index 447367f1fe..c29abceffb 100644 --- a/playgrounds/nuxt/app/pages/components/radio-group.vue +++ b/playgrounds/nuxt/app/pages/components/radio-group.vue @@ -31,6 +31,19 @@ const itemsWithDescription = [ { value: '2', label: 'Option 2', description: 'Description 2' }, { value: '3', label: 'Option 3', description: 'Description 3' } ] +const itemsWithIcon = [ + { value: '1', label: 'System', icon: 'i-lucide-monitor' }, + { value: '2', label: 'Light', icon: 'i-lucide-sun' }, + { value: '3', label: 'Dark', icon: 'i-lucide-moon' } +] +const viewItems = [ + { value: 'table', label: 'Table', icon: 'i-lucide-table' }, + { value: 'board', label: 'Board', icon: 'i-lucide-kanban' }, + { value: 'calendar', label: 'Calendar', icon: 'i-lucide-calendar' }, + { value: 'list', label: 'List', icon: 'i-lucide-list' }, + { value: 'gallery', label: 'Gallery', icon: 'i-lucide-images' }, + { value: 'map', label: 'Map', icon: 'i-lucide-map' } +] + + +
+ +
From 87af34436d9aec73189a0a2f834ed0513b940354 Mon Sep 17 00:00:00 2001 From: Francesco Mussoni Date: Mon, 13 Jul 2026 22:09:48 +0200 Subject: [PATCH 03/16] refactor(tests): remove CheckboxGroup and RadioGroup icon tests - Deleted test files for CheckboxGroup and RadioGroup components that were previously verifying leading icon functionality. - This cleanup is part of a broader effort to streamline test coverage and focus on essential components. --- .../CheckboxGroupIcon.a4cec7.spec.ts | 71 ------------------- test/components/RadioGroupIcon.781254.spec.ts | 62 ---------------- 2 files changed, 133 deletions(-) delete mode 100644 test/components/CheckboxGroupIcon.a4cec7.spec.ts delete mode 100644 test/components/RadioGroupIcon.781254.spec.ts diff --git a/test/components/CheckboxGroupIcon.a4cec7.spec.ts b/test/components/CheckboxGroupIcon.a4cec7.spec.ts deleted file mode 100644 index effae60901..0000000000 --- a/test/components/CheckboxGroupIcon.a4cec7.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { describe, it, expect } from 'vitest' -import { mountSuspended } from '@nuxt/test-utils/runtime' -import CheckboxGroup from '../../src/runtime/components/CheckboxGroup.vue' -import theme from '#build/ui/checkbox-group' -import themeCheckbox from '#build/ui/checkbox' - -describe('CheckboxGroup with icon', () => { - const items = [ - { value: 'table', label: 'Table', icon: 'i-lucide-table' }, - { value: 'board', label: 'Board', icon: 'i-lucide-layout-grid' }, - { value: 'list', label: 'List' } - ] - - const sizes = Object.keys(theme.variants.size) as any - const variants = Object.keys(theme.variants.variant) as any - const indicators = Object.keys(themeCheckbox.variants.indicator) as any - - it('renders a leading icon only for items that define one', async () => { - const wrapper = await mountSuspended(CheckboxGroup, { props: { items } }) - expect(wrapper.findAll('[data-slot="leadingIcon"]')).toHaveLength(2) - }) - - it('keeps the label text alongside the icon', async () => { - const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [items[0]] } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(true) - expect(wrapper.text()).toContain('Table') - }) - - it('does not render a leading icon when the item has none', async () => { - const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [{ value: 'list', label: 'List' }] } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(false) - }) - - it('keeps the item description alongside the icon', async () => { - const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [{ ...items[0], description: 'Spreadsheet view' }] } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(true) - expect(wrapper.text()).toContain('Spreadsheet view') - }) - - it('adds a label icon without replacing the existing checkbox indicator icon', async () => { - const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [items[0]], modelValue: ['table'] } }) - // The item icon renders as a leading label icon... - expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(true) - // ...and the checkbox check indicator icon remains its own, separate element. - expect(wrapper.find('[data-slot="icon"]').exists()).toBe(true) - }) - - it('renders the icon across every size', async () => { - for (const size of sizes) { - const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [items[0]], size } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `size=${size}`).toBe(true) - } - }) - - it('renders the icon across every variant', async () => { - for (const variant of variants) { - const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [items[0]], variant } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `variant=${variant}`).toBe(true) - } - }) - - it('renders the icon in horizontal orientation and for every indicator position', async () => { - const horizontal = await mountSuspended(CheckboxGroup, { props: { items: [items[0]], orientation: 'horizontal' } }) - expect(horizontal.find('[data-slot="leadingIcon"]').exists()).toBe(true) - - for (const indicator of indicators) { - const wrapper = await mountSuspended(CheckboxGroup, { props: { items: [items[0]], indicator } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `indicator=${indicator}`).toBe(true) - } - }) -}) diff --git a/test/components/RadioGroupIcon.781254.spec.ts b/test/components/RadioGroupIcon.781254.spec.ts deleted file mode 100644 index 1350e3af0e..0000000000 --- a/test/components/RadioGroupIcon.781254.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { describe, it, expect } from 'vitest' -import { mountSuspended } from '@nuxt/test-utils/runtime' -import RadioGroup from '../../src/runtime/components/RadioGroup.vue' -import theme from '#build/ui/radio-group' - -describe('RadioGroup with icon', () => { - const items = [ - { value: 'table', label: 'Table', icon: 'i-lucide-table' }, - { value: 'board', label: 'Board', icon: 'i-lucide-layout-grid' }, - { value: 'list', label: 'List' } - ] - - const sizes = Object.keys(theme.variants.size) as any - const variants = Object.keys(theme.variants.variant) as any - const indicators = Object.keys(theme.variants.indicator) as any - - it('renders a leading icon only for items that define one', async () => { - const wrapper = await mountSuspended(RadioGroup, { props: { items } }) - expect(wrapper.findAll('[data-slot="leadingIcon"]')).toHaveLength(2) - }) - - it('keeps the label text alongside the icon', async () => { - const wrapper = await mountSuspended(RadioGroup, { props: { items: [items[0]] } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(true) - expect(wrapper.text()).toContain('Table') - }) - - it('does not render a leading icon when the item has none', async () => { - const wrapper = await mountSuspended(RadioGroup, { props: { items: [{ value: 'list', label: 'List' }] } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(false) - }) - - it('keeps the item description alongside the icon', async () => { - const wrapper = await mountSuspended(RadioGroup, { props: { items: [{ ...items[0], description: 'Spreadsheet view' }] } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists()).toBe(true) - expect(wrapper.text()).toContain('Spreadsheet view') - }) - - it('renders the icon across every size', async () => { - for (const size of sizes) { - const wrapper = await mountSuspended(RadioGroup, { props: { items: [items[0]], size } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `size=${size}`).toBe(true) - } - }) - - it('renders the icon across every variant', async () => { - for (const variant of variants) { - const wrapper = await mountSuspended(RadioGroup, { props: { items: [items[0]], variant } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `variant=${variant}`).toBe(true) - } - }) - - it('renders the icon in horizontal orientation and for every indicator position', async () => { - const horizontal = await mountSuspended(RadioGroup, { props: { items: [items[0]], orientation: 'horizontal' } }) - expect(horizontal.find('[data-slot="leadingIcon"]').exists()).toBe(true) - - for (const indicator of indicators) { - const wrapper = await mountSuspended(RadioGroup, { props: { items: [items[0]], indicator } }) - expect(wrapper.find('[data-slot="leadingIcon"]').exists(), `indicator=${indicator}`).toBe(true) - } - }) -}) From 19f5af532f0d11357fb60970d49c3e2128e57c9d Mon Sep 17 00:00:00 2001 From: Francesco Mussoni Date: Mon, 13 Jul 2026 22:11:23 +0200 Subject: [PATCH 04/16] feat(Checkbox/RadioGroup): update icon property type and enhance tests - Changed the type of the `icon` property in CheckboxGroup and RadioGroup components from `string` to `IconProps['name']` for better type safety. - Updated tests to include scenarios for rendering items with icons in both CheckboxGroup and RadioGroup components. - Added snapshot tests to verify correct rendering of icons in the respective components. --- src/runtime/components/CheckboxGroup.vue | 5 ++- src/runtime/components/RadioGroup.vue | 3 +- test/components/CheckboxGroup.spec.ts | 1 + test/components/RadioGroup.spec.ts | 1 + .../CheckboxGroup-vue.spec.ts.snap | 39 +++++++++++++++++++ .../__snapshots__/RadioGroup-vue.spec.ts.snap | 39 +++++++++++++++++++ 6 files changed, 85 insertions(+), 3 deletions(-) diff --git a/src/runtime/components/CheckboxGroup.vue b/src/runtime/components/CheckboxGroup.vue index 71a650b495..17ff21c51f 100644 --- a/src/runtime/components/CheckboxGroup.vue +++ b/src/runtime/components/CheckboxGroup.vue @@ -20,7 +20,7 @@ export type CheckboxGroupItem = CheckboxGroupValue | { * The icon displayed next to the label. * @IconifyIcon */ - icon?: string + icon?: IconProps['name'] class?: any ui?: Pick & Omit['ui'], 'root'> [key: string]: any @@ -94,6 +94,7 @@ import { useFormField } from '../composables/useFormField' import { get, omit } from '../utils' import { tv } from '../utils/tv' import UCheckbox from './Checkbox.vue' +import type { IconProps } from './Icon.vue' const _props = withDefaults(defineProps>(), { labelKey: 'label', @@ -192,7 +193,7 @@ function onUpdate(value: any) { [key: string]: any @@ -105,6 +105,7 @@ import { useForwardProps } from '../composables/useForwardProps' import { useFormField } from '../composables/useFormField' import { get } from '../utils' import { tv } from '../utils/tv' +import type { IconProps } from './Icon.vue' import UIcon from './Icon.vue' const _props = withDefaults(defineProps>(), { diff --git a/test/components/CheckboxGroup.spec.ts b/test/components/CheckboxGroup.spec.ts index d13f5ac115..c4cd729087 100644 --- a/test/components/CheckboxGroup.spec.ts +++ b/test/components/CheckboxGroup.spec.ts @@ -31,6 +31,7 @@ describe('CheckboxGroup', () => { ['with descriptionKey', { props: { ...props, descriptionKey: 'value' } }], ['with disabled', { props: { ...props, disabled: true } }], ['with description', { props: { items: items.map((opt, count) => ({ ...opt, description: `Description ${count}` })) } }], + ['with icon', { props: { items: items.map(opt => ({ ...opt, icon: 'i-lucide-rocket' })) } }], ['with required', { props: { ...props, legend: 'Legend', required: true } }], ...sizes.map((size: string) => [`with size ${size}`, { props: { ...props, size, defaultValue: ['1'] } }]), ...variants.map((variant: string) => [`with primary variant ${variant}`, { props: { ...props, variant, defaultValue: ['1'] } }]), diff --git a/test/components/RadioGroup.spec.ts b/test/components/RadioGroup.spec.ts index 5c849709a9..f02a50827a 100644 --- a/test/components/RadioGroup.spec.ts +++ b/test/components/RadioGroup.spec.ts @@ -30,6 +30,7 @@ describe('RadioGroup', () => { ['with descriptionKey', { props: { ...props, descriptionKey: 'value' } }], ['with disabled', { props: { ...props, disabled: true } }], ['with description', { props: { items: items.map((opt, count) => ({ ...opt, description: `Description ${count}` })) } }], + ['with icon', { props: { items: items.map(opt => ({ ...opt, icon: 'i-lucide-rocket' })) } }], ['with required', { props: { ...props, legend: 'Legend', required: true } }], ...sizes.map((size: string) => [`with size ${size}`, { props: { ...props, size, defaultValue: '1' } }]), ...variants.map((variant: string) => [`with primary variant ${variant}`, { props: { ...props, variant, defaultValue: '1' } }]), diff --git a/test/components/__snapshots__/CheckboxGroup-vue.spec.ts.snap b/test/components/__snapshots__/CheckboxGroup-vue.spec.ts.snap index 7835dd710c..1d6943e446 100644 --- a/test/components/__snapshots__/CheckboxGroup-vue.spec.ts.snap +++ b/test/components/__snapshots__/CheckboxGroup-vue.spec.ts.snap @@ -487,6 +487,45 @@ exports[`CheckboxGroup > renders with horizontal variant table correctly 1`] = ` " `; +exports[`CheckboxGroup > renders with icon correctly 1`] = ` +"
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
" +`; + exports[`CheckboxGroup > renders with indicator end correctly 1`] = ` "
diff --git a/test/components/__snapshots__/RadioGroup-vue.spec.ts.snap b/test/components/__snapshots__/RadioGroup-vue.spec.ts.snap index 77d339964a..a5941fd6c7 100644 --- a/test/components/__snapshots__/RadioGroup-vue.spec.ts.snap +++ b/test/components/__snapshots__/RadioGroup-vue.spec.ts.snap @@ -487,6 +487,45 @@ exports[`RadioGroup > renders with horizontal variant table correctly 1`] = `
" `; +exports[`RadioGroup > renders with icon correctly 1`] = ` +"
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
" +`; + exports[`RadioGroup > renders with indicator end correctly 1`] = ` "
From 9b15a9719f4647a954f96e17583659d268d8274f Mon Sep 17 00:00:00 2001 From: Francesco Mussoni Date: Mon, 13 Jul 2026 22:28:26 +0200 Subject: [PATCH 05/16] fix(tests): update snapshots for Checkbox, CheckboxGroup, RadioGroup, and Table components - Adjusted snapshots to reflect changes in label rendering, ensuring labels now include conditional rendering comments. - Updated multiple test files to maintain consistency across Checkbox, CheckboxGroup, RadioGroup, and Table components. --- .../__snapshots__/Checkbox.spec.ts.snap | 20 +- .../__snapshots__/CheckboxGroup.spec.ts.snap | 507 ++++++++++++++---- .../__snapshots__/RadioGroup.spec.ts.snap | 507 ++++++++++++++---- .../__snapshots__/Table.spec.ts.snap | 20 +- 4 files changed, 810 insertions(+), 244 deletions(-) diff --git a/test/components/__snapshots__/Checkbox.spec.ts.snap b/test/components/__snapshots__/Checkbox.spec.ts.snap index 8db481e6aa..216d0adf46 100644 --- a/test/components/__snapshots__/Checkbox.spec.ts.snap +++ b/test/components/__snapshots__/Checkbox.spec.ts.snap @@ -49,7 +49,9 @@ exports[`Checkbox > renders with description correctly 1`] = `
-
+

Description

" @@ -62,7 +64,9 @@ exports[`Checkbox > renders with description slot correctly 1`] = ` -
+
" @@ -153,7 +157,9 @@ exports[`Checkbox > renders with label correctly 1`] = ` -
+
" @@ -166,7 +172,9 @@ exports[`Checkbox > renders with label slot correctly 1`] = ` -
+
" @@ -271,7 +279,9 @@ exports[`Checkbox > renders with required correctly 1`] = ` -
+
" diff --git a/test/components/__snapshots__/CheckboxGroup.spec.ts.snap b/test/components/__snapshots__/CheckboxGroup.spec.ts.snap index 34765fe1e9..960b2dcd08 100644 --- a/test/components/__snapshots__/CheckboxGroup.spec.ts.snap +++ b/test/components/__snapshots__/CheckboxGroup.spec.ts.snap @@ -10,7 +10,9 @@ exports[`CheckboxGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -20,7 +22,9 @@ exports[`CheckboxGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -30,7 +34,9 @@ exports[`CheckboxGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -49,7 +55,9 @@ exports[`CheckboxGroup > renders with as correctly 1`] = ` -
+
@@ -59,7 +67,9 @@ exports[`CheckboxGroup > renders with as correctly 1`] = ` -
+
@@ -69,7 +79,9 @@ exports[`CheckboxGroup > renders with as correctly 1`] = ` -
+
@@ -88,7 +100,9 @@ exports[`CheckboxGroup > renders with class correctly 1`] = ` -
+
@@ -98,7 +112,9 @@ exports[`CheckboxGroup > renders with class correctly 1`] = ` -
+
@@ -108,7 +124,9 @@ exports[`CheckboxGroup > renders with class correctly 1`] = ` -
+
@@ -125,7 +143,9 @@ exports[`CheckboxGroup > renders with defaultValue correctly 1`] = `
-
+
@@ -135,7 +155,9 @@ exports[`CheckboxGroup > renders with defaultValue correctly 1`] = ` -
+
@@ -145,7 +167,9 @@ exports[`CheckboxGroup > renders with defaultValue correctly 1`] = ` -
+
@@ -164,7 +188,9 @@ exports[`CheckboxGroup > renders with description correctly 1`] = ` -
+

Description 0

@@ -174,7 +200,9 @@ exports[`CheckboxGroup > renders with description correctly 1`] = ` -
+

Description 1

@@ -184,7 +212,9 @@ exports[`CheckboxGroup > renders with description correctly 1`] = ` -
+

Description 2

@@ -203,7 +233,9 @@ exports[`CheckboxGroup > renders with description slot correctly 1`] = ` -
+

Description slot

@@ -213,7 +245,9 @@ exports[`CheckboxGroup > renders with description slot correctly 1`] = ` -
+

Description slot

@@ -223,7 +257,9 @@ exports[`CheckboxGroup > renders with description slot correctly 1`] = ` -
+

Description slot

@@ -242,7 +278,9 @@ exports[`CheckboxGroup > renders with descriptionKey correctly 1`] = ` -
+

1

@@ -252,7 +290,9 @@ exports[`CheckboxGroup > renders with descriptionKey correctly 1`] = ` -
+

2

@@ -262,7 +302,9 @@ exports[`CheckboxGroup > renders with descriptionKey correctly 1`] = ` -
+

3

@@ -281,7 +323,9 @@ exports[`CheckboxGroup > renders with disabled correctly 1`] = ` -
+
@@ -291,7 +335,9 @@ exports[`CheckboxGroup > renders with disabled correctly 1`] = ` -
+
@@ -301,7 +347,9 @@ exports[`CheckboxGroup > renders with disabled correctly 1`] = ` -
+
@@ -318,7 +366,9 @@ exports[`CheckboxGroup > renders with horizontal variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -355,7 +409,9 @@ exports[`CheckboxGroup > renders with horizontal variant list correctly 1`] = `
-
+
@@ -365,7 +421,9 @@ exports[`CheckboxGroup > renders with horizontal variant list correctly 1`] = ` -
+
@@ -375,7 +433,9 @@ exports[`CheckboxGroup > renders with horizontal variant list correctly 1`] = ` -
+
@@ -392,7 +452,9 @@ exports[`CheckboxGroup > renders with horizontal variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -421,6 +487,45 @@ exports[`CheckboxGroup > renders with horizontal variant table correctly 1`] = ` " `; +exports[`CheckboxGroup > renders with icon correctly 1`] = ` +"
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
" +`; + exports[`CheckboxGroup > renders with indicator end correctly 1`] = ` "
@@ -429,7 +534,9 @@ exports[`CheckboxGroup > renders with indicator end correctly 1`] = `
-
+
@@ -439,7 +546,9 @@ exports[`CheckboxGroup > renders with indicator end correctly 1`] = `
-
+
@@ -449,7 +558,9 @@ exports[`CheckboxGroup > renders with indicator end correctly 1`] = ` -
+
@@ -466,7 +577,9 @@ exports[`CheckboxGroup > renders with indicator hidden correctly 1`] = `
-
+
@@ -476,7 +589,9 @@ exports[`CheckboxGroup > renders with indicator hidden correctly 1`] = ` -
+
@@ -486,7 +601,9 @@ exports[`CheckboxGroup > renders with indicator hidden correctly 1`] = ` -
+
@@ -503,7 +620,9 @@ exports[`CheckboxGroup > renders with indicator start correctly 1`] = `
-
+
@@ -513,7 +632,9 @@ exports[`CheckboxGroup > renders with indicator start correctly 1`] = ` -
+
@@ -523,7 +644,9 @@ exports[`CheckboxGroup > renders with indicator start correctly 1`] = ` -
+
@@ -542,7 +665,9 @@ exports[`CheckboxGroup > renders with items correctly 1`] = ` -
+
@@ -552,7 +677,9 @@ exports[`CheckboxGroup > renders with items correctly 1`] = ` -
+
@@ -562,7 +689,9 @@ exports[`CheckboxGroup > renders with items correctly 1`] = ` -
+
@@ -581,7 +710,9 @@ exports[`CheckboxGroup > renders with label slot correctly 1`] = ` -
+
@@ -591,7 +722,9 @@ exports[`CheckboxGroup > renders with label slot correctly 1`] = ` -
+
@@ -601,7 +734,9 @@ exports[`CheckboxGroup > renders with label slot correctly 1`] = ` -
+
@@ -620,7 +755,9 @@ exports[`CheckboxGroup > renders with labelKey correctly 1`] = ` -
+
@@ -630,7 +767,9 @@ exports[`CheckboxGroup > renders with labelKey correctly 1`] = ` -
+
@@ -640,7 +779,9 @@ exports[`CheckboxGroup > renders with labelKey correctly 1`] = ` -
+
@@ -659,7 +800,9 @@ exports[`CheckboxGroup > renders with legend slot correctly 1`] = ` -
+
@@ -669,7 +812,9 @@ exports[`CheckboxGroup > renders with legend slot correctly 1`] = ` -
+
@@ -679,7 +824,9 @@ exports[`CheckboxGroup > renders with legend slot correctly 1`] = ` -
+
@@ -696,7 +843,9 @@ exports[`CheckboxGroup > renders with modelValue correctly 1`] = `
-
+
@@ -706,7 +855,9 @@ exports[`CheckboxGroup > renders with modelValue correctly 1`] = ` -
+
@@ -716,7 +867,9 @@ exports[`CheckboxGroup > renders with modelValue correctly 1`] = ` -
+
@@ -733,7 +886,9 @@ exports[`CheckboxGroup > renders with neutral variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -770,7 +929,9 @@ exports[`CheckboxGroup > renders with neutral variant card highlight correctly 1
-

Option 1

+

+ Option 1 +

@@ -807,7 +972,9 @@ exports[`CheckboxGroup > renders with neutral variant list correctly 1`] = `
-
+
@@ -817,7 +984,9 @@ exports[`CheckboxGroup > renders with neutral variant list correctly 1`] = ` -
+
@@ -827,7 +996,9 @@ exports[`CheckboxGroup > renders with neutral variant list correctly 1`] = ` -
+
@@ -844,7 +1015,9 @@ exports[`CheckboxGroup > renders with neutral variant list highlight correctly 1
-
+
@@ -854,7 +1027,9 @@ exports[`CheckboxGroup > renders with neutral variant list highlight correctly 1 -
+
@@ -864,7 +1039,9 @@ exports[`CheckboxGroup > renders with neutral variant list highlight correctly 1 -
+
@@ -881,7 +1058,9 @@ exports[`CheckboxGroup > renders with neutral variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -918,7 +1101,9 @@ exports[`CheckboxGroup > renders with neutral variant table highlight correctly
-

Option 1

+

+ Option 1 +

@@ -955,7 +1144,9 @@ exports[`CheckboxGroup > renders with primary variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -992,7 +1187,9 @@ exports[`CheckboxGroup > renders with primary variant card highlight correctly 1
-

Option 1

+

+ Option 1 +

@@ -1029,7 +1230,9 @@ exports[`CheckboxGroup > renders with primary variant list correctly 1`] = `
-
+
@@ -1039,7 +1242,9 @@ exports[`CheckboxGroup > renders with primary variant list correctly 1`] = ` -
+
@@ -1049,7 +1254,9 @@ exports[`CheckboxGroup > renders with primary variant list correctly 1`] = ` -
+
@@ -1066,7 +1273,9 @@ exports[`CheckboxGroup > renders with primary variant list highlight correctly 1
-
+
@@ -1076,7 +1285,9 @@ exports[`CheckboxGroup > renders with primary variant list highlight correctly 1 -
+
@@ -1086,7 +1297,9 @@ exports[`CheckboxGroup > renders with primary variant list highlight correctly 1 -
+
@@ -1103,7 +1316,9 @@ exports[`CheckboxGroup > renders with primary variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -1140,7 +1359,9 @@ exports[`CheckboxGroup > renders with primary variant table highlight correctly
-

Option 1

+

+ Option 1 +

@@ -1179,7 +1404,9 @@ exports[`CheckboxGroup > renders with required correctly 1`] = ` -
+
@@ -1189,7 +1416,9 @@ exports[`CheckboxGroup > renders with required correctly 1`] = ` -
+
@@ -1199,7 +1428,9 @@ exports[`CheckboxGroup > renders with required correctly 1`] = ` -
+
@@ -1216,7 +1447,9 @@ exports[`CheckboxGroup > renders with size lg correctly 1`] = `
-
+
@@ -1226,7 +1459,9 @@ exports[`CheckboxGroup > renders with size lg correctly 1`] = ` -
+
@@ -1236,7 +1471,9 @@ exports[`CheckboxGroup > renders with size lg correctly 1`] = ` -
+
@@ -1253,7 +1490,9 @@ exports[`CheckboxGroup > renders with size md correctly 1`] = `
-
+
@@ -1263,7 +1502,9 @@ exports[`CheckboxGroup > renders with size md correctly 1`] = ` -
+
@@ -1273,7 +1514,9 @@ exports[`CheckboxGroup > renders with size md correctly 1`] = ` -
+
@@ -1290,7 +1533,9 @@ exports[`CheckboxGroup > renders with size sm correctly 1`] = `
-
+
@@ -1300,7 +1545,9 @@ exports[`CheckboxGroup > renders with size sm correctly 1`] = ` -
+
@@ -1310,7 +1557,9 @@ exports[`CheckboxGroup > renders with size sm correctly 1`] = ` -
+
@@ -1327,7 +1576,9 @@ exports[`CheckboxGroup > renders with size xl correctly 1`] = `
-
+
@@ -1337,7 +1588,9 @@ exports[`CheckboxGroup > renders with size xl correctly 1`] = ` -
+
@@ -1347,7 +1600,9 @@ exports[`CheckboxGroup > renders with size xl correctly 1`] = ` -
+
@@ -1364,7 +1619,9 @@ exports[`CheckboxGroup > renders with size xs correctly 1`] = `
-
+
@@ -1374,7 +1631,9 @@ exports[`CheckboxGroup > renders with size xs correctly 1`] = ` -
+
@@ -1384,7 +1643,9 @@ exports[`CheckboxGroup > renders with size xs correctly 1`] = ` -
+
@@ -1403,7 +1664,9 @@ exports[`CheckboxGroup > renders with ui correctly 1`] = ` -
+
@@ -1413,7 +1676,9 @@ exports[`CheckboxGroup > renders with ui correctly 1`] = ` -
+
@@ -1423,7 +1688,9 @@ exports[`CheckboxGroup > renders with ui correctly 1`] = ` -
+
@@ -1440,7 +1707,9 @@ exports[`CheckboxGroup > renders with valueKey correctly 1`] = `
-
+
@@ -1450,7 +1719,9 @@ exports[`CheckboxGroup > renders with valueKey correctly 1`] = ` -
+
@@ -1460,7 +1731,9 @@ exports[`CheckboxGroup > renders with valueKey correctly 1`] = ` -
+
diff --git a/test/components/__snapshots__/RadioGroup.spec.ts.snap b/test/components/__snapshots__/RadioGroup.spec.ts.snap index 4405aae944..6856412314 100644 --- a/test/components/__snapshots__/RadioGroup.spec.ts.snap +++ b/test/components/__snapshots__/RadioGroup.spec.ts.snap @@ -10,7 +10,9 @@ exports[`RadioGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -20,7 +22,9 @@ exports[`RadioGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -30,7 +34,9 @@ exports[`RadioGroup > renders with ariaLabel correctly 1`] = ` -
+
@@ -49,7 +55,9 @@ exports[`RadioGroup > renders with as correctly 1`] = ` -
+
@@ -59,7 +67,9 @@ exports[`RadioGroup > renders with as correctly 1`] = ` -
+
@@ -69,7 +79,9 @@ exports[`RadioGroup > renders with as correctly 1`] = ` -
+
@@ -88,7 +100,9 @@ exports[`RadioGroup > renders with class correctly 1`] = ` -
+
@@ -98,7 +112,9 @@ exports[`RadioGroup > renders with class correctly 1`] = ` -
+
@@ -108,7 +124,9 @@ exports[`RadioGroup > renders with class correctly 1`] = ` -
+
@@ -125,7 +143,9 @@ exports[`RadioGroup > renders with defaultValue correctly 1`] = `
-
+
@@ -135,7 +155,9 @@ exports[`RadioGroup > renders with defaultValue correctly 1`] = ` -
+
@@ -145,7 +167,9 @@ exports[`RadioGroup > renders with defaultValue correctly 1`] = ` -
+
@@ -164,7 +188,9 @@ exports[`RadioGroup > renders with description correctly 1`] = ` -
+

Description 0

@@ -174,7 +200,9 @@ exports[`RadioGroup > renders with description correctly 1`] = ` -
+

Description 1

@@ -184,7 +212,9 @@ exports[`RadioGroup > renders with description correctly 1`] = ` -
+

Description 2

@@ -203,7 +233,9 @@ exports[`RadioGroup > renders with description slot correctly 1`] = ` -
+
@@ -213,7 +245,9 @@ exports[`RadioGroup > renders with description slot correctly 1`] = ` -
+
@@ -223,7 +257,9 @@ exports[`RadioGroup > renders with description slot correctly 1`] = ` -
+
@@ -242,7 +278,9 @@ exports[`RadioGroup > renders with descriptionKey correctly 1`] = ` -
+

1

@@ -252,7 +290,9 @@ exports[`RadioGroup > renders with descriptionKey correctly 1`] = ` -
+

2

@@ -262,7 +302,9 @@ exports[`RadioGroup > renders with descriptionKey correctly 1`] = ` -
+

3

@@ -281,7 +323,9 @@ exports[`RadioGroup > renders with disabled correctly 1`] = ` -
+
@@ -291,7 +335,9 @@ exports[`RadioGroup > renders with disabled correctly 1`] = ` -
+
@@ -301,7 +347,9 @@ exports[`RadioGroup > renders with disabled correctly 1`] = ` -
+
@@ -318,7 +366,9 @@ exports[`RadioGroup > renders with horizontal variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -355,7 +409,9 @@ exports[`RadioGroup > renders with horizontal variant list correctly 1`] = `
-
+
@@ -365,7 +421,9 @@ exports[`RadioGroup > renders with horizontal variant list correctly 1`] = ` -
+
@@ -375,7 +433,9 @@ exports[`RadioGroup > renders with horizontal variant list correctly 1`] = ` -
+
@@ -392,7 +452,9 @@ exports[`RadioGroup > renders with horizontal variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -421,6 +487,45 @@ exports[`RadioGroup > renders with horizontal variant table correctly 1`] = ` " `; +exports[`RadioGroup > renders with icon correctly 1`] = ` +"
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
" +`; + exports[`RadioGroup > renders with indicator end correctly 1`] = ` "
@@ -429,7 +534,9 @@ exports[`RadioGroup > renders with indicator end correctly 1`] = `
-
+
@@ -439,7 +546,9 @@ exports[`RadioGroup > renders with indicator end correctly 1`] = `
-
+
@@ -449,7 +558,9 @@ exports[`RadioGroup > renders with indicator end correctly 1`] = ` -
+
@@ -466,7 +577,9 @@ exports[`RadioGroup > renders with indicator hidden correctly 1`] = `
-
+
@@ -476,7 +589,9 @@ exports[`RadioGroup > renders with indicator hidden correctly 1`] = ` -
+
@@ -486,7 +601,9 @@ exports[`RadioGroup > renders with indicator hidden correctly 1`] = ` -
+
@@ -503,7 +620,9 @@ exports[`RadioGroup > renders with indicator start correctly 1`] = `
-
+
@@ -513,7 +632,9 @@ exports[`RadioGroup > renders with indicator start correctly 1`] = ` -
+
@@ -523,7 +644,9 @@ exports[`RadioGroup > renders with indicator start correctly 1`] = ` -
+
@@ -542,7 +665,9 @@ exports[`RadioGroup > renders with items correctly 1`] = ` -
+
@@ -552,7 +677,9 @@ exports[`RadioGroup > renders with items correctly 1`] = ` -
+
@@ -562,7 +689,9 @@ exports[`RadioGroup > renders with items correctly 1`] = ` -
+
@@ -581,7 +710,9 @@ exports[`RadioGroup > renders with label slot correctly 1`] = ` -
+
@@ -591,7 +722,9 @@ exports[`RadioGroup > renders with label slot correctly 1`] = ` -
+
@@ -601,7 +734,9 @@ exports[`RadioGroup > renders with label slot correctly 1`] = ` -
+
@@ -620,7 +755,9 @@ exports[`RadioGroup > renders with labelKey correctly 1`] = ` -
+
@@ -630,7 +767,9 @@ exports[`RadioGroup > renders with labelKey correctly 1`] = ` -
+
@@ -640,7 +779,9 @@ exports[`RadioGroup > renders with labelKey correctly 1`] = ` -
+
@@ -659,7 +800,9 @@ exports[`RadioGroup > renders with legend slot correctly 1`] = ` -
+
@@ -669,7 +812,9 @@ exports[`RadioGroup > renders with legend slot correctly 1`] = ` -
+
@@ -679,7 +824,9 @@ exports[`RadioGroup > renders with legend slot correctly 1`] = ` -
+
@@ -696,7 +843,9 @@ exports[`RadioGroup > renders with modelValue correctly 1`] = `
-
+
@@ -706,7 +855,9 @@ exports[`RadioGroup > renders with modelValue correctly 1`] = ` -
+
@@ -716,7 +867,9 @@ exports[`RadioGroup > renders with modelValue correctly 1`] = ` -
+
@@ -733,7 +886,9 @@ exports[`RadioGroup > renders with neutral variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -770,7 +929,9 @@ exports[`RadioGroup > renders with neutral variant card highlight correctly 1`]
-

Option 1

+

+ Option 1 +

@@ -807,7 +972,9 @@ exports[`RadioGroup > renders with neutral variant list correctly 1`] = `
-
+
@@ -817,7 +984,9 @@ exports[`RadioGroup > renders with neutral variant list correctly 1`] = ` -
+
@@ -827,7 +996,9 @@ exports[`RadioGroup > renders with neutral variant list correctly 1`] = ` -
+
@@ -844,7 +1015,9 @@ exports[`RadioGroup > renders with neutral variant list highlight correctly 1`]
-
+
@@ -854,7 +1027,9 @@ exports[`RadioGroup > renders with neutral variant list highlight correctly 1`] -
+
@@ -864,7 +1039,9 @@ exports[`RadioGroup > renders with neutral variant list highlight correctly 1`] -
+
@@ -881,7 +1058,9 @@ exports[`RadioGroup > renders with neutral variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -918,7 +1101,9 @@ exports[`RadioGroup > renders with neutral variant table highlight correctly 1`]
-

Option 1

+

+ Option 1 +

@@ -955,7 +1144,9 @@ exports[`RadioGroup > renders with primary variant card correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -992,7 +1187,9 @@ exports[`RadioGroup > renders with primary variant card highlight correctly 1`]
-

Option 1

+

+ Option 1 +

@@ -1029,7 +1230,9 @@ exports[`RadioGroup > renders with primary variant list correctly 1`] = `
-
+
@@ -1039,7 +1242,9 @@ exports[`RadioGroup > renders with primary variant list correctly 1`] = ` -
+
@@ -1049,7 +1254,9 @@ exports[`RadioGroup > renders with primary variant list correctly 1`] = ` -
+
@@ -1066,7 +1273,9 @@ exports[`RadioGroup > renders with primary variant list highlight correctly 1`]
-
+
@@ -1076,7 +1285,9 @@ exports[`RadioGroup > renders with primary variant list highlight correctly 1`] -
+
@@ -1086,7 +1297,9 @@ exports[`RadioGroup > renders with primary variant list highlight correctly 1`] -
+
@@ -1103,7 +1316,9 @@ exports[`RadioGroup > renders with primary variant table correctly 1`] = `
-

Option 1

+

+ Option 1 +

@@ -1140,7 +1359,9 @@ exports[`RadioGroup > renders with primary variant table highlight correctly 1`]
-

Option 1

+

+ Option 1 +

@@ -1179,7 +1404,9 @@ exports[`RadioGroup > renders with required correctly 1`] = ` -
+
@@ -1189,7 +1416,9 @@ exports[`RadioGroup > renders with required correctly 1`] = ` -
+
@@ -1199,7 +1428,9 @@ exports[`RadioGroup > renders with required correctly 1`] = ` -
+
@@ -1216,7 +1447,9 @@ exports[`RadioGroup > renders with size lg correctly 1`] = `
-
+
@@ -1226,7 +1459,9 @@ exports[`RadioGroup > renders with size lg correctly 1`] = ` -
+
@@ -1236,7 +1471,9 @@ exports[`RadioGroup > renders with size lg correctly 1`] = ` -
+
@@ -1253,7 +1490,9 @@ exports[`RadioGroup > renders with size md correctly 1`] = `
-
+
@@ -1263,7 +1502,9 @@ exports[`RadioGroup > renders with size md correctly 1`] = ` -
+
@@ -1273,7 +1514,9 @@ exports[`RadioGroup > renders with size md correctly 1`] = ` -
+
@@ -1290,7 +1533,9 @@ exports[`RadioGroup > renders with size sm correctly 1`] = `
-
+
@@ -1300,7 +1545,9 @@ exports[`RadioGroup > renders with size sm correctly 1`] = ` -
+
@@ -1310,7 +1557,9 @@ exports[`RadioGroup > renders with size sm correctly 1`] = ` -
+
@@ -1327,7 +1576,9 @@ exports[`RadioGroup > renders with size xl correctly 1`] = `
-
+
@@ -1337,7 +1588,9 @@ exports[`RadioGroup > renders with size xl correctly 1`] = ` -
+
@@ -1347,7 +1600,9 @@ exports[`RadioGroup > renders with size xl correctly 1`] = ` -
+
@@ -1364,7 +1619,9 @@ exports[`RadioGroup > renders with size xs correctly 1`] = `
-
+
@@ -1374,7 +1631,9 @@ exports[`RadioGroup > renders with size xs correctly 1`] = ` -
+
@@ -1384,7 +1643,9 @@ exports[`RadioGroup > renders with size xs correctly 1`] = ` -
+
@@ -1403,7 +1664,9 @@ exports[`RadioGroup > renders with ui correctly 1`] = ` -
+
@@ -1413,7 +1676,9 @@ exports[`RadioGroup > renders with ui correctly 1`] = ` -
+
@@ -1423,7 +1688,9 @@ exports[`RadioGroup > renders with ui correctly 1`] = ` -
+
@@ -1440,7 +1707,9 @@ exports[`RadioGroup > renders with valueKey correctly 1`] = `
-
+
@@ -1450,7 +1719,9 @@ exports[`RadioGroup > renders with valueKey correctly 1`] = ` -
+
@@ -1460,7 +1731,9 @@ exports[`RadioGroup > renders with valueKey correctly 1`] = ` -
+
diff --git a/test/components/__snapshots__/Table.spec.ts.snap b/test/components/__snapshots__/Table.spec.ts.snap index 5a1dff536c..5c444f0380 100644 --- a/test/components/__snapshots__/Table.spec.ts.snap +++ b/test/components/__snapshots__/Table.spec.ts.snap @@ -397,7 +397,9 @@ exports[`Table > renders with columns correctly 1`] = ` -
+
@@ -661,7 +663,9 @@ exports[`Table > renders with empty slot correctly 1`] = ` -
+
@@ -1495,7 +1499,9 @@ exports[`Table > renders with loading slot correctly 1`] = ` -
+
@@ -1559,7 +1565,9 @@ exports[`Table > renders with meta field on columns correctly 1`] = ` -
+
@@ -1992,7 +2000,9 @@ exports[`Table > renders with virtualize and sticky correctly 1`] = ` -
+
From 9d8deaed0d697e077ec0984591c43df8e1319fcd Mon Sep 17 00:00:00 2001 From: Francesco Mussoni Date: Mon, 13 Jul 2026 23:01:39 +0200 Subject: [PATCH 06/16] fix(CheckboxGroup): map item icon to leading icon, not the indicator The per-item `icon` was spread onto the underlying `UCheckbox`, so a checked item rendered the item icon in place of its check indicator. `useForwardProps` strips `undefined`, so the group-level `icon` did not shadow it. Omit `icon` from the forwarded props and bind it only to `leading-icon`. - Type item `icon` as `IconProps['name']` - Add a regression test asserting an item `icon` maps to `leadingIcon` and leaves the checkbox `icon` untouched --- src/runtime/components/CheckboxGroup.vue | 2 +- test/components/CheckboxGroup.spec.ts | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/runtime/components/CheckboxGroup.vue b/src/runtime/components/CheckboxGroup.vue index 17ff21c51f..80e40a7cca 100644 --- a/src/runtime/components/CheckboxGroup.vue +++ b/src/runtime/components/CheckboxGroup.vue @@ -193,7 +193,7 @@ function onUpdate(value: any) { { expect(await axe(wrapper.element)).toHaveNoViolations() }) + it('maps an item icon to the leading icon, not the checkbox indicator icon', async () => { + const wrapper = await mountSuspended(CheckboxGroup, { + props: { items: [{ value: '1', label: 'Option 1', icon: 'i-lucide-rocket' }] } + }) + const checkbox = wrapper.findComponent(Checkbox) as unknown as VueWrapper + expect(checkbox.props('leadingIcon')).toBe('i-lucide-rocket') + expect(checkbox.props('icon')).toBeUndefined() + }) + describe('emits', () => { test('update:modelValue event', async () => { const wrapper = mount(CheckboxGroup, { props: { items: ['Option 1', 'Option 2'] } }) From 2caffb33c8ecc29f46dfc9b65f8044b9d90c00fc Mon Sep 17 00:00:00 2001 From: Francesco Mussoni Date: Mon, 13 Jul 2026 23:15:10 +0200 Subject: [PATCH 07/16] fix(tests): update CheckboxGroup.spec.ts to use type imports for VueWrapper --- test/components/CheckboxGroup.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/components/CheckboxGroup.spec.ts b/test/components/CheckboxGroup.spec.ts index f5bad0d258..0145fe6e5c 100644 --- a/test/components/CheckboxGroup.spec.ts +++ b/test/components/CheckboxGroup.spec.ts @@ -1,6 +1,6 @@ import { describe, it, expect, test } from 'vitest' import { axe } from 'vitest-axe' -import { flushPromises, mount, VueWrapper } from '@vue/test-utils' +import { flushPromises, mount, type VueWrapper } from '@vue/test-utils' import CheckboxGroup from '../../src/runtime/components/CheckboxGroup.vue' import Checkbox from '../../src/runtime/components/Checkbox.vue' import type { FormInputEvents } from '../../src/module' From 0c4e289d5fd3757d4a7ff77be71d41c13e4fef36 Mon Sep 17 00:00:00 2001 From: Benjamin Canac Date: Thu, 20 Aug 2026 14:21:53 +0200 Subject: [PATCH 08/16] refactor(CheckboxGroup/RadioGroup): render item `icon` next to the label when `indicator` is hidden Replaces the `leadingIcon` prop with the existing `icon` one, which is dead weight when the indicator is hidden since `base` is `sr-only` there. --- .../docs/2.components/checkbox-group.md | 11 +- docs/content/docs/2.components/checkbox.md | 16 +- docs/content/docs/2.components/radio-group.md | 9 +- .../app/pages/components/checkbox-group.vue | 23 - .../nuxt/app/pages/components/checkbox.vue | 1 - .../nuxt/app/pages/components/radio-group.vue | 23 - src/runtime/components/Checkbox.vue | 17 +- src/runtime/components/CheckboxGroup.vue | 10 +- src/runtime/components/RadioGroup.vue | 10 +- src/theme/checkbox.ts | 21 +- src/theme/radio-group.ts | 22 +- test/components/CheckboxGroup.spec.ts | 29 +- test/components/RadioGroup.spec.ts | 19 +- .../__snapshots__/Checkbox-vue.spec.ts.snap | 27 +- .../__snapshots__/Checkbox.spec.ts.snap | 27 +- .../CheckboxGroup-vue.spec.ts.snap | 619 +++++++----------- .../__snapshots__/CheckboxGroup.spec.ts.snap | 619 +++++++----------- .../__snapshots__/RadioGroup-vue.spec.ts.snap | 603 +++++++---------- .../__snapshots__/RadioGroup.spec.ts.snap | 603 +++++++---------- .../__snapshots__/Table-vue.spec.ts.snap | 25 +- .../__snapshots__/Table.spec.ts.snap | 25 +- 21 files changed, 1118 insertions(+), 1641 deletions(-) diff --git a/docs/content/docs/2.components/checkbox-group.md b/docs/content/docs/2.components/checkbox-group.md index a24175533e..5dea9ba35b 100644 --- a/docs/content/docs/2.components/checkbox-group.md +++ b/docs/content/docs/2.components/checkbox-group.md @@ -66,7 +66,7 @@ You can also pass an array of objects with the following properties: - `disabled?: boolean`{lang="ts-type"} - `icon?: string`{lang="ts-type"} - `class?: any`{lang="ts-type"} -- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, icon?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, leadingIcon?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, icon?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} ::component-code --- @@ -130,15 +130,18 @@ props: --- :: -### Icon +### Icon :badge{label="Soon" class="align-text-top"} -Use the `icon` property in the items to display an icon next to the label. +Use the `icon` property in the items to display an icon when the checkbox is checked. + +When `indicator` is `hidden`, the icon is displayed next to the label instead, which is how you build a visual picker. ::component-code --- ignore: - modelValue - items + - variant external: - items - modelValue @@ -147,6 +150,8 @@ externalTypes: props: modelValue: - 'system' + variant: 'card' + indicator: 'hidden' items: - label: 'System' icon: 'i-lucide-monitor' diff --git a/docs/content/docs/2.components/checkbox.md b/docs/content/docs/2.components/checkbox.md index 4970116a55..a4493548a7 100644 --- a/docs/content/docs/2.components/checkbox.md +++ b/docs/content/docs/2.components/checkbox.md @@ -116,6 +116,8 @@ props: Use the `icon` prop to set the icon of the Checkbox when it is checked. Defaults to `i-lucide-check`. +When [`indicator`](#indicator) is `hidden`, the icon is displayed next to the label instead. :badge{label="Soon" class="align-text-top"} + ::component-code --- ignore: @@ -140,20 +142,6 @@ You can customize this icon globally in your `vite.config.ts` under `ui.icons.ch ::: :: -### Leading Icon - -Use the `leading-icon` prop to display an icon next to the label of the Checkbox. - -::component-code ---- -ignore: - - label -props: - leadingIcon: 'i-lucide-tag' - label: Check me ---- -:: - ### Color Use the `color` prop to change the color of the Checkbox. diff --git a/docs/content/docs/2.components/radio-group.md b/docs/content/docs/2.components/radio-group.md index f49cbdeb52..6f71f44ee5 100644 --- a/docs/content/docs/2.components/radio-group.md +++ b/docs/content/docs/2.components/radio-group.md @@ -63,7 +63,7 @@ You can also pass an array of objects with the following properties: - `disabled?: boolean`{lang="ts-type"} - `icon?: string`{lang="ts-type"} - `class?: any`{lang="ts-type"} -- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, leadingIcon?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, icon?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} ::component-code --- @@ -125,15 +125,16 @@ props: --- :: -### Icon +### Icon :badge{label="Soon" class="align-text-top"} -Use the `icon` property in the items to display an icon next to the label. +Use the `icon` property in the items to display an icon next to the label when `indicator` is `hidden`, which is how you build a visual picker. ::component-code --- ignore: - modelValue - items + - variant external: - items - modelValue @@ -141,6 +142,8 @@ externalTypes: - RadioGroupItem[] props: modelValue: 'system' + variant: 'card' + indicator: 'hidden' items: - label: 'System' icon: 'i-lucide-monitor' diff --git a/playgrounds/nuxt/app/pages/components/checkbox-group.vue b/playgrounds/nuxt/app/pages/components/checkbox-group.vue index 63ab872e94..f7387bf142 100644 --- a/playgrounds/nuxt/app/pages/components/checkbox-group.vue +++ b/playgrounds/nuxt/app/pages/components/checkbox-group.vue @@ -37,14 +37,6 @@ const itemsWithIcon = [ { value: '2', label: 'Light', icon: 'i-lucide-sun' }, { value: '3', label: 'Dark', icon: 'i-lucide-moon' } ] -const viewItems = [ - { value: 'table', label: 'Table', icon: 'i-lucide-table' }, - { value: 'board', label: 'Board', icon: 'i-lucide-kanban' }, - { value: 'calendar', label: 'Calendar', icon: 'i-lucide-calendar' }, - { value: 'list', label: 'List', icon: 'i-lucide-list' }, - { value: 'gallery', label: 'Gallery', icon: 'i-lucide-images' }, - { value: 'map', label: 'Map', icon: 'i-lucide-map' } -] - - -
- -
diff --git a/playgrounds/nuxt/app/pages/components/checkbox.vue b/playgrounds/nuxt/app/pages/components/checkbox.vue index ae6c0f8a5e..08ed72e0c4 100644 --- a/playgrounds/nuxt/app/pages/components/checkbox.vue +++ b/playgrounds/nuxt/app/pages/components/checkbox.vue @@ -29,7 +29,6 @@ const value = ref(true) - diff --git a/playgrounds/nuxt/app/pages/components/radio-group.vue b/playgrounds/nuxt/app/pages/components/radio-group.vue index c29abceffb..cb53eabbba 100644 --- a/playgrounds/nuxt/app/pages/components/radio-group.vue +++ b/playgrounds/nuxt/app/pages/components/radio-group.vue @@ -36,14 +36,6 @@ const itemsWithIcon = [ { value: '2', label: 'Light', icon: 'i-lucide-sun' }, { value: '3', label: 'Dark', icon: 'i-lucide-moon' } ] -const viewItems = [ - { value: 'table', label: 'Table', icon: 'i-lucide-table' }, - { value: 'board', label: 'Board', icon: 'i-lucide-kanban' }, - { value: 'calendar', label: 'Calendar', icon: 'i-lucide-calendar' }, - { value: 'list', label: 'List', icon: 'i-lucide-list' }, - { value: 'gallery', label: 'Gallery', icon: 'i-lucide-images' }, - { value: 'map', label: 'Map', icon: 'i-lucide-map' } -] - - -
- -
diff --git a/src/runtime/components/Checkbox.vue b/src/runtime/components/Checkbox.vue index 54b9cfcc24..e560646589 100644 --- a/src/runtime/components/Checkbox.vue +++ b/src/runtime/components/Checkbox.vue @@ -37,7 +37,7 @@ export interface CheckboxProps extends Pick, ' /** Highlight the ring color like a focus state. */ highlight?: boolean /** - * The icon displayed when checked. + * The icon displayed when checked, or next to the label when `indicator` is `hidden`. * @defaultValue appConfig.ui.icons.check * @IconifyIcon */ @@ -48,11 +48,6 @@ export interface CheckboxProps extends Pick, ' * @IconifyIcon */ indeterminateIcon?: IconProps['name'] - /** - * The icon displayed next to the label. - * @IconifyIcon - */ - leadingIcon?: IconProps['name'] class?: any ui?: Checkbox['slots'] } @@ -102,6 +97,10 @@ const size = computed(() => formFieldSize.value ?? props.size) const disabled = computed(() => formFieldDisabled.value ?? props.disabled) +// When the indicator is hidden the checked icon is never visible, so `icon` renders next to the +// label instead. No `appConfig` fallback here, an unset `icon` must render nothing. +const labelIcon = computed(() => props.indicator === 'hidden' ? props.icon : undefined) + const attrs = useAttrs() // Omit `data-state` to prevent conflicts with parent components (e.g. TooltipTrigger) const forwardedAttrs = computed(() => { @@ -143,7 +142,7 @@ function onUpdate(value: any) { @update:model-value="onUpdate" >