@byyuurin/ui 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -4
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/nuxt.d.mts +13 -0
- package/dist/nuxt.d.ts +6 -3
- package/dist/nuxt.mjs +6 -3
- package/dist/resolver.d.mts +13 -0
- package/dist/resolver.d.ts +6 -3
- package/dist/resolver.mjs +5 -2
- package/dist/{components → runtime/components}/Accordion.vue +19 -3
- package/dist/{components → runtime/components}/App.vue +5 -1
- package/dist/{components → runtime/components}/Button.vue +92 -94
- package/dist/{components → runtime/components}/Checkbox.vue +101 -104
- package/dist/{components → runtime/components}/Input.vue +5 -1
- package/dist/{components → runtime/components}/ModalProvider.vue +1 -1
- package/dist/{components → runtime/components}/RadioGroup.vue +174 -180
- package/dist/runtime/components/ScrollArea.vue +72 -0
- package/dist/{components → runtime/components}/Select.vue +262 -258
- package/dist/{components → runtime/components}/Switch.vue +98 -99
- package/dist/{components → runtime/components}/Tabs.vue +117 -117
- package/dist/runtime/components/Textarea.vue +173 -0
- package/dist/{components → runtime/components}/Toast.vue +1 -1
- package/dist/{components → runtime/components}/Toaster.vue +35 -1
- package/dist/{components → runtime/components}/index.d.ts +2 -0
- package/dist/{components → runtime/components}/index.mjs +2 -0
- package/dist/runtime/composables/defineInjection.d.ts +11 -0
- package/dist/runtime/composables/defineInjection.mjs +9 -0
- package/dist/{composables → runtime/composables}/index.d.ts +1 -0
- package/dist/{composables → runtime/composables}/index.mjs +1 -0
- package/dist/{composables → runtime/composables}/useModal.d.ts +1 -1
- package/dist/{composables → runtime/composables}/useModal.mjs +3 -2
- package/dist/{composables → runtime/composables}/useTheme.d.ts +3 -2
- package/dist/runtime/composables/useTheme.mjs +26 -0
- package/dist/{composables → runtime/composables}/useToast.d.ts +1 -1
- package/dist/{theme → runtime/theme}/button.d.ts +0 -8
- package/dist/{theme → runtime/theme}/button.mjs +1 -9
- package/dist/{theme → runtime/theme}/checkbox.d.ts +0 -12
- package/dist/{theme → runtime/theme}/checkbox.mjs +4 -9
- package/dist/{theme → runtime/theme}/index.d.ts +2 -0
- package/dist/{theme → runtime/theme}/index.mjs +2 -0
- package/dist/{theme → runtime/theme}/radioGroup.d.ts +0 -24
- package/dist/{theme → runtime/theme}/radioGroup.mjs +8 -20
- package/dist/runtime/theme/scrollArea.d.ts +51 -0
- package/dist/runtime/theme/scrollArea.mjs +30 -0
- package/dist/{theme → runtime/theme}/switch.d.ts +0 -12
- package/dist/{theme → runtime/theme}/switch.mjs +2 -8
- package/dist/{theme → runtime/theme}/tabs.d.ts +32 -11
- package/dist/{theme → runtime/theme}/tabs.mjs +19 -12
- package/dist/runtime/theme/textarea.d.ts +90 -0
- package/dist/runtime/theme/textarea.mjs +100 -0
- package/dist/{theme → runtime/theme}/toast.mjs +1 -1
- package/dist/{types → runtime/types}/components.d.ts +2 -0
- package/dist/{types → runtime/types}/index.d.ts +1 -1
- package/dist/{utils → runtime/utils}/index.d.ts +3 -12
- package/dist/{utils → runtime/utils}/index.mjs +3 -12
- package/dist/{internal → runtime/utils}/styler.d.ts +0 -1
- package/dist/runtime/utils/styler.mjs +10 -0
- package/dist/{internal/constants.mjs → shared/ui.Cmq14xN9.mjs} +6 -2
- package/dist/unocss-preset.d.mts +57 -0
- package/dist/unocss-preset.d.ts +29 -9
- package/dist/unocss-preset.mjs +164 -110
- package/package.json +18 -12
- package/dist/composables/useTheme.mjs +0 -18
- package/dist/internal/constants.d.ts +0 -3
- package/dist/internal/index.d.ts +0 -4
- package/dist/internal/index.mjs +0 -4
- package/dist/internal/styler.mjs +0 -236
- package/dist/utils/unocss.d.ts +0 -3
- package/dist/utils/unocss.mjs +0 -50
- /package/dist/{components → runtime/components}/Card.vue +0 -0
- /package/dist/{components → runtime/components}/Drawer.vue +0 -0
- /package/dist/{components → runtime/components}/Link.vue +0 -0
- /package/dist/{components → runtime/components}/Modal.vue +0 -0
- /package/dist/{components → runtime/components}/Popover.vue +0 -0
- /package/dist/{components → runtime/components}/Tooltip.vue +0 -0
- /package/dist/{composables → runtime/composables}/useComponentIcons.d.ts +0 -0
- /package/dist/{composables → runtime/composables}/useComponentIcons.mjs +0 -0
- /package/dist/{composables → runtime/composables}/useToast.mjs +0 -0
- /package/dist/{theme → runtime/theme}/accordion.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/accordion.mjs +0 -0
- /package/dist/{theme → runtime/theme}/app.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/app.mjs +0 -0
- /package/dist/{theme → runtime/theme}/card.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/card.mjs +0 -0
- /package/dist/{theme → runtime/theme}/drawer.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/drawer.mjs +0 -0
- /package/dist/{theme → runtime/theme}/input.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/input.mjs +0 -0
- /package/dist/{theme → runtime/theme}/link.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/link.mjs +0 -0
- /package/dist/{theme → runtime/theme}/modal.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/modal.mjs +0 -0
- /package/dist/{theme → runtime/theme}/popover.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/popover.mjs +0 -0
- /package/dist/{theme → runtime/theme}/select.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/select.mjs +0 -0
- /package/dist/{theme → runtime/theme}/toast.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/toaster.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/toaster.mjs +0 -0
- /package/dist/{theme → runtime/theme}/tooltip.d.ts +0 -0
- /package/dist/{theme → runtime/theme}/tooltip.mjs +0 -0
- /package/dist/{types → runtime/types}/components.mjs +0 -0
- /package/dist/{types → runtime/types}/index.mjs +0 -0
- /package/dist/{types → runtime/types}/utils.d.ts +0 -0
- /package/dist/{types → runtime/types}/utils.mjs +0 -0
- /package/dist/{internal → runtime/utils}/extend-theme.d.ts +0 -0
- /package/dist/{internal → runtime/utils}/extend-theme.mjs +0 -0
- /package/dist/{internal → runtime/utils}/link.d.ts +0 -0
- /package/dist/{internal → runtime/utils}/link.mjs +0 -0
|
@@ -1,104 +1,101 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
-
import type { CheckboxRootProps, PrimitiveProps } from 'reka-ui'
|
|
4
|
-
import type { checkbox } from '../theme'
|
|
5
|
-
import type { ComponentAttrs } from '../types'
|
|
6
|
-
|
|
7
|
-
type CheckboxVariants = VariantProps<typeof checkbox>
|
|
8
|
-
|
|
9
|
-
export interface CheckboxProps extends ComponentAttrs<typeof checkbox>, Pick<CheckboxRootProps, 'disabled' | 'required' | 'name' | 'value' | 'id' | 'defaultValue'> {
|
|
10
|
-
as?: PrimitiveProps['as']
|
|
11
|
-
label?: string
|
|
12
|
-
description?: string
|
|
13
|
-
size?: CheckboxVariants['size']
|
|
14
|
-
/**
|
|
15
|
-
* The icon displayed when checked.
|
|
16
|
-
* @default app.icons.check
|
|
17
|
-
*/
|
|
18
|
-
icon?: string
|
|
19
|
-
/**
|
|
20
|
-
* The icon displayed when the checkbox is indeterminate.
|
|
21
|
-
* @default app.icons.indeterminate
|
|
22
|
-
*/
|
|
23
|
-
indeterminateIcon?: string
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface CheckboxEmits {
|
|
27
|
-
(event: 'change', payload: Event): void
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface CheckboxSlots {
|
|
31
|
-
label?: (props: { label?: string }) => any
|
|
32
|
-
description?: (props: { description?: string }) => any
|
|
33
|
-
}
|
|
34
|
-
</script>
|
|
35
|
-
|
|
36
|
-
<script lang="ts" setup>
|
|
37
|
-
import { reactivePick } from '@vueuse/core'
|
|
38
|
-
import { CheckboxIndicator, CheckboxRoot, Label, Primitive, useForwardProps } from 'reka-ui'
|
|
39
|
-
import { computed, useId } from 'vue'
|
|
40
|
-
import { useTheme } from '../composables'
|
|
41
|
-
|
|
42
|
-
const props = withDefaults(defineProps<CheckboxProps>(), {
|
|
43
|
-
size: 'md',
|
|
44
|
-
required: false,
|
|
45
|
-
disabled: false,
|
|
46
|
-
})
|
|
47
|
-
const emit = defineEmits<CheckboxEmits>()
|
|
48
|
-
const slots = defineSlots<CheckboxSlots>()
|
|
49
|
-
|
|
50
|
-
const innerValue = defineModel<boolean | 'indeterminate'>({ default: undefined })
|
|
51
|
-
const rootProps = useForwardProps(reactivePick(props, 'required', 'value', 'defaultValue'))
|
|
52
|
-
|
|
53
|
-
const id = props.id ?? useId()
|
|
54
|
-
|
|
55
|
-
const { theme, createStyler } = useTheme()
|
|
56
|
-
const style = computed(() => {
|
|
57
|
-
const styler = createStyler(theme.value.checkbox)
|
|
58
|
-
return styler(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<
|
|
95
|
-
<slot name="
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
</div>
|
|
103
|
-
</Primitive>
|
|
104
|
-
</template>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
+
import type { CheckboxRootProps, PrimitiveProps } from 'reka-ui'
|
|
4
|
+
import type { checkbox } from '../theme'
|
|
5
|
+
import type { ComponentAttrs } from '../types'
|
|
6
|
+
|
|
7
|
+
type CheckboxVariants = VariantProps<typeof checkbox>
|
|
8
|
+
|
|
9
|
+
export interface CheckboxProps extends ComponentAttrs<typeof checkbox>, Pick<CheckboxRootProps, 'disabled' | 'required' | 'name' | 'value' | 'id' | 'defaultValue'> {
|
|
10
|
+
as?: PrimitiveProps['as']
|
|
11
|
+
label?: string
|
|
12
|
+
description?: string
|
|
13
|
+
size?: CheckboxVariants['size']
|
|
14
|
+
/**
|
|
15
|
+
* The icon displayed when checked.
|
|
16
|
+
* @default app.icons.check
|
|
17
|
+
*/
|
|
18
|
+
icon?: string
|
|
19
|
+
/**
|
|
20
|
+
* The icon displayed when the checkbox is indeterminate.
|
|
21
|
+
* @default app.icons.indeterminate
|
|
22
|
+
*/
|
|
23
|
+
indeterminateIcon?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CheckboxEmits {
|
|
27
|
+
(event: 'change', payload: Event): void
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CheckboxSlots {
|
|
31
|
+
label?: (props: { label?: string }) => any
|
|
32
|
+
description?: (props: { description?: string }) => any
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<script lang="ts" setup>
|
|
37
|
+
import { reactivePick } from '@vueuse/core'
|
|
38
|
+
import { CheckboxIndicator, CheckboxRoot, Label, Primitive, useForwardProps } from 'reka-ui'
|
|
39
|
+
import { computed, useId } from 'vue'
|
|
40
|
+
import { useTheme } from '../composables'
|
|
41
|
+
|
|
42
|
+
const props = withDefaults(defineProps<CheckboxProps>(), {
|
|
43
|
+
size: 'md',
|
|
44
|
+
required: false,
|
|
45
|
+
disabled: false,
|
|
46
|
+
})
|
|
47
|
+
const emit = defineEmits<CheckboxEmits>()
|
|
48
|
+
const slots = defineSlots<CheckboxSlots>()
|
|
49
|
+
|
|
50
|
+
const innerValue = defineModel<boolean | 'indeterminate'>({ default: undefined })
|
|
51
|
+
const rootProps = useForwardProps(reactivePick(props, 'required', 'value', 'defaultValue'))
|
|
52
|
+
|
|
53
|
+
const id = props.id ?? useId()
|
|
54
|
+
|
|
55
|
+
const { theme, createStyler } = useTheme()
|
|
56
|
+
const style = computed(() => {
|
|
57
|
+
const styler = createStyler(theme.value.checkbox)
|
|
58
|
+
return styler(props)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
function onUpdate(value: any) {
|
|
62
|
+
// @ts-expect-error - 'target' does not exist in type 'EventInit'
|
|
63
|
+
const event = new Event('change', { target: value })
|
|
64
|
+
emit('change', event)
|
|
65
|
+
}
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<template>
|
|
69
|
+
<Primitive :as="props.as" :class="style.root({ class: [props.class, props.ui?.root] })">
|
|
70
|
+
<div :class="style.container({ class: props.ui?.container })">
|
|
71
|
+
<CheckboxRoot
|
|
72
|
+
:id="id"
|
|
73
|
+
v-bind="rootProps"
|
|
74
|
+
v-slot="{ modelValue }"
|
|
75
|
+
v-model="innerValue"
|
|
76
|
+
:name="props.name"
|
|
77
|
+
:disabled="props.disabled"
|
|
78
|
+
:class="style.base({ class: props.ui?.base })"
|
|
79
|
+
@update:model-value="onUpdate"
|
|
80
|
+
>
|
|
81
|
+
<CheckboxIndicator as-child force-mount>
|
|
82
|
+
<i
|
|
83
|
+
v-if="modelValue === 'indeterminate'"
|
|
84
|
+
:class="style.icon({ class: [props.indeterminateIcon || theme.app.icons.indeterminate, props.ui?.icon] })"
|
|
85
|
+
></i>
|
|
86
|
+
<i v-else :class="style.icon({ class: [props.icon, theme.app.icons.check, props.ui?.icon] })"></i>
|
|
87
|
+
</CheckboxIndicator>
|
|
88
|
+
</CheckboxRoot>
|
|
89
|
+
</div>
|
|
90
|
+
<div v-if="props.label || slots.label || props.description || slots.description" :class="style.wrapper({ class: props.ui?.wrapper })">
|
|
91
|
+
<Label v-if="props.label || slots.label" :for="id" :class="style.label({ class: props.ui?.label })">
|
|
92
|
+
<slot name="label" :label="props.label">{{ props.label }}</slot>
|
|
93
|
+
</Label>
|
|
94
|
+
<p v-if="props.description || slots.description" :class="style.description({ class: props.ui?.description })">
|
|
95
|
+
<slot name="description" :description="props.description">
|
|
96
|
+
{{ props.description }}
|
|
97
|
+
</slot>
|
|
98
|
+
</p>
|
|
99
|
+
</div>
|
|
100
|
+
</Primitive>
|
|
101
|
+
</template>
|
|
@@ -128,7 +128,11 @@ onMounted(() => {
|
|
|
128
128
|
</script>
|
|
129
129
|
|
|
130
130
|
<template>
|
|
131
|
-
<Primitive
|
|
131
|
+
<Primitive
|
|
132
|
+
:as="as"
|
|
133
|
+
:class="style.root({ class: [props.class, props.ui?.root] })"
|
|
134
|
+
:aria-disabled="props.disabled ? true : undefined"
|
|
135
|
+
>
|
|
132
136
|
<span v-if="isPrefix || slots.prefix" :class="style.prefix({ class: props.ui?.prefix })">
|
|
133
137
|
<slot name="prefix">
|
|
134
138
|
<i
|
|
@@ -6,5 +6,5 @@ const { isOpen } = useModal()
|
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
8
|
<template>
|
|
9
|
-
<component :is="modalState.component" v-if="modalState
|
|
9
|
+
<component :is="modalState.component" v-if="modalState" v-bind="modalState.props" v-model:open="isOpen" />
|
|
10
10
|
</template>
|
|
@@ -1,180 +1,174 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
-
import type { AcceptableValue, PrimitiveProps, RadioGroupRootProps } from 'reka-ui'
|
|
4
|
-
import type { radioGroup } from '../theme'
|
|
5
|
-
import type { ComponentAttrs } from '../types'
|
|
6
|
-
|
|
7
|
-
type RadioGroupVariants = VariantProps<typeof radioGroup>
|
|
8
|
-
|
|
9
|
-
export interface RadioOption {
|
|
10
|
-
label?: string
|
|
11
|
-
description?: string
|
|
12
|
-
disabled?: boolean
|
|
13
|
-
value?: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface RadioGroupProps<T> extends ComponentAttrs<typeof radioGroup>, Pick<RadioGroupRootProps, 'defaultValue' | 'disabled' | 'loop' | 'modelValue' | 'name' | 'required'> {
|
|
17
|
-
as?: PrimitiveProps['as']
|
|
18
|
-
legend?: string
|
|
19
|
-
/**
|
|
20
|
-
* When `options` is an array of objects, select the field to use as the value.
|
|
21
|
-
* @default 'value'
|
|
22
|
-
*/
|
|
23
|
-
valueKey?: string
|
|
24
|
-
/**
|
|
25
|
-
* When `options` is an array of objects, select the field to use as the label.
|
|
26
|
-
* @default 'label'
|
|
27
|
-
*/
|
|
28
|
-
labelKey?: string
|
|
29
|
-
/**
|
|
30
|
-
* When `options` is an array of objects, select the field to use as the description.
|
|
31
|
-
* @default 'description'
|
|
32
|
-
*/
|
|
33
|
-
descriptionKey?: string
|
|
34
|
-
options?: T[]
|
|
35
|
-
size?: RadioGroupVariants['size']
|
|
36
|
-
/**
|
|
37
|
-
* The orientation the radio buttons are laid out.
|
|
38
|
-
* @default 'vertical'
|
|
39
|
-
*/
|
|
40
|
-
orientation?: RadioGroupRootProps['orientation']
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
import {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
>
|
|
163
|
-
<
|
|
164
|
-
</
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
</p>
|
|
176
|
-
</div>
|
|
177
|
-
</div>
|
|
178
|
-
</fieldset>
|
|
179
|
-
</RadioGroupRoot>
|
|
180
|
-
</template>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
+
import type { AcceptableValue, PrimitiveProps, RadioGroupRootProps } from 'reka-ui'
|
|
4
|
+
import type { radioGroup } from '../theme'
|
|
5
|
+
import type { ComponentAttrs } from '../types'
|
|
6
|
+
|
|
7
|
+
type RadioGroupVariants = VariantProps<typeof radioGroup>
|
|
8
|
+
|
|
9
|
+
export interface RadioOption {
|
|
10
|
+
label?: string
|
|
11
|
+
description?: string
|
|
12
|
+
disabled?: boolean
|
|
13
|
+
value?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface RadioGroupProps<T> extends ComponentAttrs<typeof radioGroup>, Pick<RadioGroupRootProps, 'defaultValue' | 'disabled' | 'loop' | 'modelValue' | 'name' | 'required'> {
|
|
17
|
+
as?: PrimitiveProps['as']
|
|
18
|
+
legend?: string
|
|
19
|
+
/**
|
|
20
|
+
* When `options` is an array of objects, select the field to use as the value.
|
|
21
|
+
* @default 'value'
|
|
22
|
+
*/
|
|
23
|
+
valueKey?: string
|
|
24
|
+
/**
|
|
25
|
+
* When `options` is an array of objects, select the field to use as the label.
|
|
26
|
+
* @default 'label'
|
|
27
|
+
*/
|
|
28
|
+
labelKey?: string
|
|
29
|
+
/**
|
|
30
|
+
* When `options` is an array of objects, select the field to use as the description.
|
|
31
|
+
* @default 'description'
|
|
32
|
+
*/
|
|
33
|
+
descriptionKey?: string
|
|
34
|
+
options?: T[]
|
|
35
|
+
size?: RadioGroupVariants['size']
|
|
36
|
+
/**
|
|
37
|
+
* The orientation the radio buttons are laid out.
|
|
38
|
+
* @default 'vertical'
|
|
39
|
+
*/
|
|
40
|
+
orientation?: RadioGroupRootProps['orientation']
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface RadioGroupEmits {
|
|
44
|
+
(event: 'update:modelValue', payload: string): void
|
|
45
|
+
(event: 'change', payload: Event): void
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type SlotProps<T> = (props: { item: NormalizeItem<T>, modelValue?: AcceptableValue }) => any
|
|
49
|
+
|
|
50
|
+
export interface RadioGroupSlots<T> {
|
|
51
|
+
legend?: (props?: {}) => any
|
|
52
|
+
label?: SlotProps<T>
|
|
53
|
+
description?: SlotProps<T>
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
type NormalizeItem<T> = { id: string } & (
|
|
57
|
+
T extends RadioOption
|
|
58
|
+
? T
|
|
59
|
+
: {
|
|
60
|
+
id: string
|
|
61
|
+
label: string
|
|
62
|
+
value: any
|
|
63
|
+
description: string
|
|
64
|
+
disabled: false
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<script lang="ts" setup generic="T extends RadioOption | AcceptableValue">
|
|
70
|
+
import { reactivePick } from '@vueuse/core'
|
|
71
|
+
import { Label, RadioGroupIndicator, RadioGroupItem, RadioGroupRoot, useForwardPropsEmits } from 'reka-ui'
|
|
72
|
+
import { computed, useId } from 'vue'
|
|
73
|
+
import { useTheme } from '../composables'
|
|
74
|
+
import { get } from '../utils'
|
|
75
|
+
|
|
76
|
+
const props = withDefaults(defineProps<RadioGroupProps<T>>(), {
|
|
77
|
+
size: 'md',
|
|
78
|
+
valueKey: 'value',
|
|
79
|
+
labelKey: 'label',
|
|
80
|
+
descriptionKey: 'description',
|
|
81
|
+
orientation: 'vertical',
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const emit = defineEmits<RadioGroupEmits>()
|
|
85
|
+
const slots = defineSlots<RadioGroupSlots<T>>()
|
|
86
|
+
|
|
87
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'loop', 'required'), emit)
|
|
88
|
+
const id = useId()
|
|
89
|
+
|
|
90
|
+
const { theme, createStyler } = useTheme()
|
|
91
|
+
const style = computed(() => {
|
|
92
|
+
const styler = createStyler(theme.value.radioGroup)
|
|
93
|
+
return styler(props)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
function normalizeItem(item: any): NormalizeItem<T> {
|
|
97
|
+
if (['string', 'number', 'boolean'].includes(typeof item)) {
|
|
98
|
+
return {
|
|
99
|
+
id: `${id}:${item}`,
|
|
100
|
+
value: item,
|
|
101
|
+
label: item,
|
|
102
|
+
description: '',
|
|
103
|
+
} as any
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const value = get(item, props.valueKey)
|
|
107
|
+
const label = get(item, props.labelKey)
|
|
108
|
+
const description = get(item, props.descriptionKey)
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
...item,
|
|
112
|
+
value,
|
|
113
|
+
label,
|
|
114
|
+
description,
|
|
115
|
+
id: `${id}:${value}`,
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const normalizedItems = computed(() => {
|
|
120
|
+
if (!props.options)
|
|
121
|
+
return []
|
|
122
|
+
|
|
123
|
+
return props.options.map(normalizeItem)
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
function onUpdate(value: any) {
|
|
127
|
+
// @ts-expect-error - 'target' does not exist in type 'EventInit'
|
|
128
|
+
const event = new Event('change', { target: { value } })
|
|
129
|
+
emit('change', event)
|
|
130
|
+
}
|
|
131
|
+
</script>
|
|
132
|
+
|
|
133
|
+
<template>
|
|
134
|
+
<RadioGroupRoot
|
|
135
|
+
:id="id"
|
|
136
|
+
v-slot="{ modelValue }"
|
|
137
|
+
v-bind="rootProps"
|
|
138
|
+
:name="props.name"
|
|
139
|
+
:disabled="props.disabled"
|
|
140
|
+
:class="style.root({ class: [props.class, props.ui?.root] })"
|
|
141
|
+
@update:model-value="onUpdate"
|
|
142
|
+
>
|
|
143
|
+
<fieldset :class="style.fieldset({ class: props.ui?.fieldset })">
|
|
144
|
+
<legend v-if="props.legend || slots.legend" :class="style.legend({ class: props.ui?.legend })">
|
|
145
|
+
<slot name="legend">
|
|
146
|
+
{{ props.legend }}
|
|
147
|
+
</slot>
|
|
148
|
+
</legend>
|
|
149
|
+
<div v-for="item in normalizedItems" :key="item.value" :class="style.item({ class: props.ui?.item })">
|
|
150
|
+
<div :class="style.container({ class: props.ui?.container })">
|
|
151
|
+
<RadioGroupItem
|
|
152
|
+
:id="item.id"
|
|
153
|
+
:value="item.value"
|
|
154
|
+
:disabled="item.disabled"
|
|
155
|
+
:class="style.base({ class: props.ui?.base })"
|
|
156
|
+
>
|
|
157
|
+
<RadioGroupIndicator :class="style.indicator({ class: props.ui?.indicator })" force-mount />
|
|
158
|
+
</RadioGroupItem>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<div :class="style.wrapper({ class: props.ui?.wrapper })">
|
|
162
|
+
<Label :for="item.id" :class="style.label({ class: props.ui?.label })">
|
|
163
|
+
<slot name="label" :item="item" :model-value="modelValue">{{ item.label }}</slot>
|
|
164
|
+
</Label>
|
|
165
|
+
<p v-if="item.description || slots.description" :class="style.description({ class: props.ui?.description })">
|
|
166
|
+
<slot name="description" :item="item" :model-value="modelValue">
|
|
167
|
+
{{ item.description }}
|
|
168
|
+
</slot>
|
|
169
|
+
</p>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
</fieldset>
|
|
173
|
+
</RadioGroupRoot>
|
|
174
|
+
</template>
|