mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
feat(RadioGroup): add card and table variants (#3178)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
@@ -49,6 +49,10 @@ export interface RadioGroupProps<T extends RadioGroupItem = RadioGroupItem> exte
|
||||
* @defaultValue 'md'
|
||||
*/
|
||||
size?: RadioGroupVariants['size']
|
||||
/**
|
||||
* @defaultValue 'list'
|
||||
*/
|
||||
variant?: RadioGroupVariants['variant']
|
||||
/**
|
||||
* @defaultValue 'primary'
|
||||
*/
|
||||
@@ -58,6 +62,11 @@ export interface RadioGroupProps<T extends RadioGroupItem = RadioGroupItem> exte
|
||||
* @defaultValue 'vertical'
|
||||
*/
|
||||
orientation?: RadioGroupRootProps['orientation']
|
||||
/**
|
||||
* Position of the indicator.
|
||||
* @defaultValue 'start'
|
||||
*/
|
||||
indicator?: RadioGroupVariants['indicator']
|
||||
class?: any
|
||||
ui?: Partial<typeof radioGroup.slots>
|
||||
}
|
||||
@@ -101,7 +110,9 @@ const ui = computed(() => radioGroup({
|
||||
color: color.value,
|
||||
disabled: disabled.value,
|
||||
required: props.required,
|
||||
orientation: props.orientation
|
||||
orientation: props.orientation,
|
||||
variant: props.variant,
|
||||
indicator: props.indicator
|
||||
}))
|
||||
|
||||
function normalizeItem(item: any) {
|
||||
@@ -167,7 +178,7 @@ function onUpdate(value: any) {
|
||||
{{ legend }}
|
||||
</slot>
|
||||
</legend>
|
||||
<div v-for="item in normalizedItems" :key="item.value" :class="ui.item({ class: props.ui?.item })">
|
||||
<component :is="variant === 'list' ? 'div' : Label" v-for="item in normalizedItems" :key="item.value" :class="ui.item({ class: props.ui?.item })">
|
||||
<div :class="ui.container({ class: props.ui?.container })">
|
||||
<RadioGroupItem
|
||||
:id="item.id"
|
||||
@@ -180,16 +191,18 @@ function onUpdate(value: any) {
|
||||
</div>
|
||||
|
||||
<div :class="ui.wrapper({ class: props.ui?.wrapper })">
|
||||
<Label :class="ui.label({ class: props.ui?.label })" :for="item.id">
|
||||
<slot name="label" :item="item" :model-value="(modelValue as RadioGroupValue)">{{ item.label }}</slot>
|
||||
</Label>
|
||||
<component :is="variant === 'list' ? Label : 'p'" :class="ui.label({ class: props.ui?.label })" :for="item.id">
|
||||
<slot name="label" :item="item" :model-value="(modelValue as RadioGroupValue)">
|
||||
{{ item.label }}
|
||||
</slot>
|
||||
</component>
|
||||
<p v-if="item.description || !!slots.description" :class="ui.description({ class: props.ui?.description })">
|
||||
<slot name="description" :item="item" :model-value="(modelValue as RadioGroupValue)">
|
||||
{{ item.description }}
|
||||
</slot>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</component>
|
||||
</fieldset>
|
||||
</RadioGroupRoot>
|
||||
</template>
|
||||
|
||||
@@ -9,7 +9,7 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
base: 'rounded-full ring ring-inset ring-(--ui-border-accented) focus-visible:outline-2 focus-visible:outline-offset-2',
|
||||
indicator: 'flex items-center justify-center size-full rounded-full after:bg-(--ui-bg) after:rounded-full',
|
||||
container: 'flex items-center',
|
||||
wrapper: 'ms-2',
|
||||
wrapper: 'w-full',
|
||||
label: 'block font-medium text-(--ui-text)',
|
||||
description: 'text-(--ui-text-muted)'
|
||||
},
|
||||
@@ -24,6 +24,16 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
indicator: 'bg-(--ui-bg-inverted)'
|
||||
}
|
||||
},
|
||||
variant: {
|
||||
list: {
|
||||
},
|
||||
card: {
|
||||
item: 'items-center border border-(--ui-border-muted) rounded-lg'
|
||||
},
|
||||
table: {
|
||||
item: 'border border-(--ui-border-muted)'
|
||||
}
|
||||
},
|
||||
orientation: {
|
||||
horizontal: {
|
||||
fieldset: 'flex-row',
|
||||
@@ -33,6 +43,20 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
fieldset: 'flex-col'
|
||||
}
|
||||
},
|
||||
indicator: {
|
||||
start: {
|
||||
item: 'flex-row',
|
||||
base: 'me-2'
|
||||
},
|
||||
end: {
|
||||
item: 'flex-row-reverse',
|
||||
base: 'ms-2'
|
||||
},
|
||||
hidden: {
|
||||
base: 'sr-only',
|
||||
wrapper: 'text-center'
|
||||
}
|
||||
},
|
||||
size: {
|
||||
xs: {
|
||||
fieldset: 'gap-0.5',
|
||||
@@ -87,8 +111,62 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
}
|
||||
}
|
||||
},
|
||||
compoundVariants: [
|
||||
{ size: 'xs', variant: ['card', 'table'], class: { item: 'p-2.5' } },
|
||||
{ size: 'sm', variant: ['card', 'table'], class: { item: 'p-3' } },
|
||||
{ size: 'md', variant: ['card', 'table'], class: { item: 'p-3.5' } },
|
||||
{ size: 'lg', variant: ['card', 'table'], class: { item: 'p-4' } },
|
||||
{ size: 'xl', variant: ['card', 'table'], class: { item: 'p-4.5' } },
|
||||
{
|
||||
orientation: 'horizontal',
|
||||
variant: 'table',
|
||||
class: {
|
||||
item: 'first-of-type:rounded-l-lg last-of-type:rounded-r-lg',
|
||||
fieldset: 'gap-0 -space-x-px'
|
||||
}
|
||||
},
|
||||
{
|
||||
orientation: 'vertical',
|
||||
variant: 'table',
|
||||
class: {
|
||||
item: 'first-of-type:rounded-t-lg last-of-type:rounded-b-lg',
|
||||
fieldset: 'gap-0 -space-y-px'
|
||||
}
|
||||
},
|
||||
...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'card',
|
||||
class: {
|
||||
item: `has-data-[state=checked]:border-(--ui-${color})`
|
||||
}
|
||||
})),
|
||||
{
|
||||
color: 'neutral',
|
||||
variant: 'card',
|
||||
class: {
|
||||
item: 'has-data-[state=checked]:border-(--ui-border-elevated)'
|
||||
}
|
||||
},
|
||||
...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'table',
|
||||
class: {
|
||||
item: `has-data-[state=checked]:bg-(--ui-${color})/10 has-data-[state=checked]:border-(--ui-${color})/50 has-data-[state=checked]:z-[1]`
|
||||
}
|
||||
})),
|
||||
{
|
||||
color: 'neutral',
|
||||
variant: 'table',
|
||||
class: {
|
||||
item: 'has-data-[state=checked]:bg-(--ui-bg-elevated) has-data-[state=checked]:border-(--ui-border-inverted)/25 has-data-[state=checked]:z-[1]'
|
||||
}
|
||||
}
|
||||
],
|
||||
defaultVariants: {
|
||||
size: 'md',
|
||||
color: 'primary'
|
||||
color: 'primary',
|
||||
variant: 'list',
|
||||
orientation: 'vertical',
|
||||
indicator: 'start'
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user