Skip to content

Commit 6a27953

Browse files
committed
chore: up
1 parent b391350 commit 6a27953

File tree

5 files changed

+709
-735
lines changed

5 files changed

+709
-735
lines changed

playground/app/pages/components/radio-group.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import theme from '#build/ui/radio-group'
33
44
const sizes = Object.keys(theme.variants.size) as Array<keyof typeof theme.variants.size>
55
const variants = Object.keys(theme.variants.variant)
6-
const variant = ref('table' as const)
6+
const variant = ref('list' as const)
77
88
const literalOptions = [
99
'Option 1',
@@ -34,7 +34,10 @@ const itemsWithDescription = [
3434
<URadioGroup :variant="variant" :items="items" color="neutral" default-value="1" />
3535
<URadioGroup :variant="variant" :items="items" color="error" default-value="2" />
3636
<URadioGroup :variant="variant" :items="literalOptions" />
37-
<URadioGroup :variant="variant" :items="items" label="Disabled" disabled />
37+
<URadioGroup :variant="variant" :items="items" disabled />
38+
<URadioGroup :variant="variant" :items="items" indicator="left" />
39+
<URadioGroup :variant="variant" :items="items" indicator="right" />
40+
<URadioGroup :variant="variant" :items="items" indicator="hidden" />
3841
</div>
3942

4043
<URadioGroup :variant="variant" :items="items" orientation="horizontal" class="ms-[95px]" />

src/runtime/components/RadioGroup.vue

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,12 @@ export type RadioGroupItem = {
2323
} | RadioGroupValue
2424
2525
export interface RadioGroupProps<T extends RadioGroupItem = RadioGroupItem> extends Pick<RadioGroupRootProps, 'defaultValue' | 'disabled' | 'loop' | 'modelValue' | 'name' | 'required'> {
26-
legend?: string
27-
/**
28-
* @defaultValue 'primary'
29-
*/
30-
color?: RadioGroupVariants['color']
3126
/**
32-
* @defaultValue 'radio'
33-
*/
34-
variant?: RadioGroupVariants['variant']
35-
/**
36-
* @defaultValue 'md'
37-
*/
38-
size?: RadioGroupVariants['size']
39-
/**
40-
* The orientation the radio buttons are laid out.
41-
* @defaultValue 'vertical'
27+
* The element or component this component should render as.
28+
* @defaultValue 'div'
4229
*/
43-
orientation?: RadioGroupRootProps['orientation']
44-
items?: T[]
30+
as?: any
31+
legend?: string
4532
/**
4633
* When `items` is an array of objects, select the field to use as the value.
4734
* @defaultValue 'value'
@@ -57,11 +44,29 @@ export interface RadioGroupProps<T extends RadioGroupItem = RadioGroupItem> exte
5744
* @defaultValue 'description'
5845
*/
5946
descriptionKey?: string
47+
items?: T[]
6048
/**
61-
* The element or component this component should render as.
62-
* @defaultValue 'div'
49+
* @defaultValue 'md'
6350
*/
64-
as?: any
51+
size?: RadioGroupVariants['size']
52+
/**
53+
* @defaultValue 'list'
54+
*/
55+
variant?: RadioGroupVariants['variant']
56+
/**
57+
* @defaultValue 'primary'
58+
*/
59+
color?: RadioGroupVariants['color']
60+
/**
61+
* The orientation the radio buttons are laid out.
62+
* @defaultValue 'vertical'
63+
*/
64+
orientation?: RadioGroupRootProps['orientation']
65+
/**
66+
* Position of the indicator.
67+
* @defaultValue 'left'
68+
*/
69+
indicator?: RadioGroupVariants['indicator']
6570
class?: any
6671
ui?: Partial<typeof radioGroup.slots>
6772
}
@@ -95,9 +100,7 @@ const props = withDefaults(defineProps<RadioGroupProps<T>>(), {
95100
const emits = defineEmits<RadioGroupEmits>()
96101
const slots = defineSlots<RadioGroupSlots<T>>()
97102
98-
const modelValue = defineModel<AcceptableValue>()
99-
100-
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultValue', 'orientation', 'loop', 'required'), emits)
103+
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'loop', 'required'), emits)
101104
102105
const { emitFormChange, emitFormInput, color, name, size, id: _id, disabled, ariaAttrs } = useFormField<RadioGroupProps<T>>(props, { bind: false })
103106
const id = _id.value ?? useId()
@@ -108,7 +111,8 @@ const ui = computed(() => radioGroup({
108111
disabled: disabled.value,
109112
required: props.required,
110113
orientation: props.orientation,
111-
variant: props.variant
114+
variant: props.variant,
115+
indicator: props.indicator
112116
}))
113117
114118
function normalizeItem(item: any) {
@@ -161,8 +165,8 @@ function onUpdate(value: any) {
161165
<template>
162166
<RadioGroupRoot
163167
:id="id"
168+
v-slot="{ modelValue }"
164169
v-bind="rootProps"
165-
:model-value="modelValue"
166170
:name="name"
167171
:disabled="disabled"
168172
:class="ui.root({ class: [props.class, props.ui?.root] })"
@@ -174,36 +178,32 @@ function onUpdate(value: any) {
174178
{{ legend }}
175179
</slot>
176180
</legend>
177-
<div :class="ui.itemWrapper({ class: props.ui?.item })">
178-
<div
179-
v-for="item in normalizedItems"
180-
:key="item.value"
181-
:class="ui.item({ class: props.ui?.item })"
182-
:data-checked="item.value === modelValue || !modelValue && item.value === defaultValue"
183-
@click.prevent="modelValue = disabled ? modelValue : item.value"
184-
>
181+
<div :class="ui.itemWrapper({ class: props.ui?.itemWrapper })">
182+
<component :is="variant === 'list' ? 'div' : Label" v-for="item in normalizedItems" :key="item.value" :class="ui.item({ class: props.ui?.item })">
185183
<div :class="ui.container({ class: props.ui?.container })">
186184
<RadioGroupItem
187185
:id="item.id"
188186
:value="item.value"
189-
:disabled="disabled"
190-
:class="ui.base({ class: props.ui?.base })"
187+
:disabled="item.disabled"
188+
:class="ui.base({ class: props.ui?.base, disabled: item.disabled })"
191189
>
192190
<RadioGroupIndicator :class="ui.indicator({ class: props.ui?.indicator })" />
193191
</RadioGroupItem>
194192
</div>
195193

196194
<div :class="ui.wrapper({ class: props.ui?.wrapper })">
197-
<Label :class="ui.label({ class: props.ui?.label })" :for="item.id">
198-
<slot name="label" :item="item" :model-value="modelValue as RadioGroupValue">{{ item.label }}</slot>
199-
</Label>
195+
<component :is="variant === 'list' ? Label : 'p'" :class="ui.label({ class: props.ui?.label })" :for="item.id">
196+
<slot name="label" :item="item" :model-value="(modelValue as RadioGroupValue)">
197+
{{ item.label }}
198+
</slot>
199+
</component>
200200
<p v-if="item.description || !!slots.description" :class="ui.description({ class: props.ui?.description })">
201-
<slot name="description" :item="item" :model-value="modelValue as RadioGroupValue">
201+
<slot name="description" :item="item" :model-value="(modelValue as RadioGroupValue)">
202202
{{ item.description }}
203203
</slot>
204204
</p>
205205
</div>
206-
</div>
206+
</component>
207207
</div>
208208
</fieldset>
209209
</RadioGroupRoot>

src/theme/radio-group.ts

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ export default (options: Required<ModuleOptions>) => ({
88
item: 'flex items-start',
99
base: 'rounded-full ring ring-inset ring-(--ui-border-accented) focus-visible:outline-2 focus-visible:outline-offset-2',
1010
indicator: 'flex items-center justify-center size-full rounded-full after:bg-(--ui-bg) after:rounded-full',
11-
itemWrapper: 'flex',
1211
container: 'flex items-center',
13-
wrapper: 'ms-2',
12+
itemWrapper: 'flex',
13+
wrapper: '',
1414
label: 'block font-medium text-(--ui-text)',
1515
description: 'text-(--ui-text-muted)'
1616
},
@@ -26,24 +26,40 @@ export default (options: Required<ModuleOptions>) => ({
2626
}
2727
},
2828
variant: {
29-
radio: {},
29+
list: {
30+
},
3031
card: {
31-
base: 'ml-4',
32-
item: 'flex-row-reverse items-center justify-between border-1 border-[var(--ui-border-muted)] rounded-lg'
32+
itemWrapper: 'gap-2',
33+
item: 'items-center justify-between border-1 border-[var(--ui-border-muted)] rounded-lg'
3334
},
3435
table: {
3536
item: 'border-[var(--ui-border-muted)]'
3637
}
3738
},
3839
orientation: {
3940
horizontal: {
40-
itemWrapper: 'flex-row',
41-
wrapper: 'me-2'
41+
itemWrapper: 'flex-row'
4242
},
4343
vertical: {
4444
itemWrapper: 'flex-col'
4545
}
4646
},
47+
48+
indicator: {
49+
left: {
50+
item: 'flex-row',
51+
base: 'me-2'
52+
},
53+
right: {
54+
item: 'flex-row-reverse',
55+
base: 'ms-2'
56+
},
57+
58+
hidden: {
59+
base: 'hidden'
60+
}
61+
},
62+
4763
size: {
4864
xs: {
4965
fieldset: 'gap-0.5',
@@ -99,47 +115,50 @@ export default (options: Required<ModuleOptions>) => ({
99115
}
100116
},
101117
compoundVariants: [
102-
{ size: 'xs', variant: 'card', class: { item: 'p-2.5', itemWrapper: 'gap-2' } },
103-
{ size: 'sm', variant: 'card', class: { item: 'p-3', itemWrapper: 'gap-2.5' } },
104-
{ size: 'md', variant: 'card', class: { item: 'p-3.5', itemWrapper: 'gap-2.5' } },
105-
{ size: 'lg', variant: 'card', class: { item: 'p-4', itemWrapper: 'gap-3.5' } },
106-
{ size: 'xl', variant: 'card', class: { item: 'p-4.5', itemWrapper: 'gap-3.5' } },
118+
{ size: 'xs', variant: 'card', class: { item: 'p-2.5' } },
119+
{ size: 'sm', variant: 'card', class: { item: 'p-3' } },
120+
{ size: 'md', variant: 'card', class: { item: 'p-3.5' } },
121+
{ size: 'lg', variant: 'card', class: { item: 'p-4' } },
122+
{ size: 'xl', variant: 'card', class: { item: 'p-4.5' } },
107123

108-
{ size: 'xs', variant: 'table', class: { item: 'p-2.5', itemWrapper: 'gap-0' } },
109-
{ size: 'sm', variant: 'table', class: { item: 'p-3', itemWrapper: 'gap-0' } },
110-
{ size: 'md', variant: 'table', class: { item: 'p-3.5', itemWrapper: 'gap-0' } },
111-
{ size: 'lg', variant: 'table', class: { item: 'p-4', itemWrapper: 'gap-0' } },
112-
{ size: 'xl', variant: 'table', class: { item: 'p-4.5', itemWrapper: 'gap-0' } },
124+
{ size: 'xs', variant: 'table', class: { item: 'p-2.5' } },
125+
{ size: 'sm', variant: 'table', class: { item: 'p-3' } },
126+
{ size: 'md', variant: 'table', class: { item: 'p-3.5' } },
127+
{ size: 'lg', variant: 'table', class: { item: 'p-4' } },
128+
{ size: 'xl', variant: 'table', class: { item: 'p-4.5' } },
113129

130+
{ orientation: 'horizontal', variant: 'list', class: { item: 'me-2' } },
114131
{ orientation: 'horizontal', variant: 'table', class: { item: 'first:rounded-l-lg last:rounded-r-lg not-last:-ml-0.25 border-1' } },
115132
{ orientation: 'vertical', variant: 'table', class: { item: 'first:rounded-t-lg last:rounded-b-lg not-last:-mb-0.25 border-1' } },
116133
...(options.theme.colors || []).map((color: string) => ({
117134
color,
118135
variant: 'card',
119136
class: {
120-
item: `data-[checked=true]:border-[var(--ui-${color})]`
137+
item: `has-data-[state=checked]:border-[var(--ui-${color})]`
121138
}
122139
})),
123140

124141
{
125142
color: 'neutral',
126143
variant: 'card',
127144
class: {
128-
item: 'data-[checked=true]:border-[var(--ui-border-elevated)]'
145+
item: 'has-data-[state=checked]:border-[var(--ui-border-elevated)]'
129146
}
130147
},
131148

132149
...(options.theme.colors || []).map((color: string) => ({
133150
color,
134151
variant: 'table',
135152
class: {
136-
item: `data-[checked=true]:relative data-[checked=true]:bg-[var(--ui-${color})]/20 data-[checked=true]:border-[var(--ui-${color})]/20`
153+
item: `has-data-[state=checked]:relative has-data-[state=checked]:bg-[var(--ui-${color})]/20 has-data-[state=checked]:border-[var(--ui-${color})]/20`
137154
}
138155
}))
139156
],
140157
defaultVariants: {
141158
size: 'md',
142159
color: 'primary',
143-
variant: 'radio'
160+
variant: 'list',
161+
orientation: 'vertical',
162+
indicator: 'left'
144163
}
145164
})

0 commit comments

Comments
 (0)