@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,99 +1,98 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
-
import type { PrimitiveProps, SwitchRootProps } from 'reka-ui'
|
|
4
|
-
import type { switch as _switch } from '../theme'
|
|
5
|
-
import type { ComponentAttrs } from '../types'
|
|
6
|
-
|
|
7
|
-
type SwitchVariants = VariantProps<typeof _switch>
|
|
8
|
-
|
|
9
|
-
export interface SwitchProps extends ComponentAttrs<typeof _switch>, Pick<SwitchRootProps, 'disabled' | 'id' | 'name' | 'required' | 'value' | 'defaultValue'> {
|
|
10
|
-
as?: PrimitiveProps['as']
|
|
11
|
-
size?: SwitchVariants['size']
|
|
12
|
-
/** When `true`, the loading icon will be displayed. */
|
|
13
|
-
loading?: boolean
|
|
14
|
-
/**
|
|
15
|
-
* The icon when the `loading` prop is `true`.
|
|
16
|
-
* @default app.icons.loading
|
|
17
|
-
*/
|
|
18
|
-
loadingIcon?: string
|
|
19
|
-
/** Display an icon when the switch is checked. */
|
|
20
|
-
checkedIcon?: string
|
|
21
|
-
/** Display an icon when the switch is unchecked. */
|
|
22
|
-
uncheckedIcon?: string
|
|
23
|
-
label?: string
|
|
24
|
-
description?: string
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
v-
|
|
73
|
-
|
|
74
|
-
:
|
|
75
|
-
:
|
|
76
|
-
:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<
|
|
81
|
-
|
|
82
|
-
<i v-if="props.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
</template>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
+
import type { PrimitiveProps, SwitchRootProps } from 'reka-ui'
|
|
4
|
+
import type { switch as _switch } from '../theme'
|
|
5
|
+
import type { ComponentAttrs } from '../types'
|
|
6
|
+
|
|
7
|
+
type SwitchVariants = VariantProps<typeof _switch>
|
|
8
|
+
|
|
9
|
+
export interface SwitchProps extends ComponentAttrs<typeof _switch>, Pick<SwitchRootProps, 'disabled' | 'id' | 'name' | 'required' | 'value' | 'defaultValue'> {
|
|
10
|
+
as?: PrimitiveProps['as']
|
|
11
|
+
size?: SwitchVariants['size']
|
|
12
|
+
/** When `true`, the loading icon will be displayed. */
|
|
13
|
+
loading?: boolean
|
|
14
|
+
/**
|
|
15
|
+
* The icon when the `loading` prop is `true`.
|
|
16
|
+
* @default app.icons.loading
|
|
17
|
+
*/
|
|
18
|
+
loadingIcon?: string
|
|
19
|
+
/** Display an icon when the switch is checked. */
|
|
20
|
+
checkedIcon?: string
|
|
21
|
+
/** Display an icon when the switch is unchecked. */
|
|
22
|
+
uncheckedIcon?: string
|
|
23
|
+
label?: string
|
|
24
|
+
description?: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SwitchEmits {
|
|
28
|
+
(event: 'change', payload: Event): void
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface SwitchSlots {
|
|
32
|
+
label?: (props: { label?: string }) => any
|
|
33
|
+
description?: (props: { description?: string }) => any
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<script lang="ts" setup>
|
|
38
|
+
import { reactivePick } from '@vueuse/core'
|
|
39
|
+
import { Label, Primitive, SwitchRoot, SwitchThumb, useForwardProps } from 'reka-ui'
|
|
40
|
+
import { computed, useId } from 'vue'
|
|
41
|
+
import { useTheme } from '../composables'
|
|
42
|
+
|
|
43
|
+
const props = withDefaults(defineProps<SwitchProps>(), {
|
|
44
|
+
size: 'md',
|
|
45
|
+
})
|
|
46
|
+
const emit = defineEmits<SwitchEmits>()
|
|
47
|
+
const slots = defineSlots<SwitchSlots>()
|
|
48
|
+
const modelValue = defineModel<boolean>({ default: undefined })
|
|
49
|
+
|
|
50
|
+
const rootProps = useForwardProps(reactivePick(props, 'required', 'value', 'defaultValue'))
|
|
51
|
+
const id = useId()
|
|
52
|
+
|
|
53
|
+
const { theme, createStyler } = useTheme()
|
|
54
|
+
const style = computed(() => {
|
|
55
|
+
const styler = createStyler(theme.value.switch)
|
|
56
|
+
return styler({ ...props, checked: false, unchecked: false })
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
function onUpdate(value: any) {
|
|
60
|
+
// @ts-expect-error - 'target' does not exist in type 'EventInit'
|
|
61
|
+
const event = new Event('change', { target: { value } })
|
|
62
|
+
emit('change', event)
|
|
63
|
+
}
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<template>
|
|
67
|
+
<Primitive :as="props.as" :class="style.root({ class: [props.class, props.ui?.root] })">
|
|
68
|
+
<div :class="style.container({ class: props.ui?.container })">
|
|
69
|
+
<SwitchRoot
|
|
70
|
+
:id="id"
|
|
71
|
+
v-bind="rootProps"
|
|
72
|
+
v-model="modelValue"
|
|
73
|
+
:name="props.name"
|
|
74
|
+
:disabled="props.disabled || props.loading"
|
|
75
|
+
:class="style.base({ class: props.ui?.base })"
|
|
76
|
+
@update:model-value="onUpdate"
|
|
77
|
+
>
|
|
78
|
+
<SwitchThumb :class="style.thumb({ class: props.ui?.thumb })">
|
|
79
|
+
<i v-if="props.loading" :class="style.icon({ class: [theme.app.icons.loading, props.ui?.icon], checked: true, unchecked: true })"></i>
|
|
80
|
+
<template v-else>
|
|
81
|
+
<i v-if="props.checkedIcon" :class="style.icon({ class: [props.checkedIcon, props.ui?.icon], checked: true })"></i>
|
|
82
|
+
<i v-if="props.uncheckedIcon" :class="style.icon({ class: [props.uncheckedIcon, props.ui?.icon], unchecked: true })"></i>
|
|
83
|
+
</template>
|
|
84
|
+
</SwitchThumb>
|
|
85
|
+
</SwitchRoot>
|
|
86
|
+
</div>
|
|
87
|
+
<div v-if="props.label || slots.label || props.description || slots.description" :class="style.wrapper({ class: props.ui?.wrapper })">
|
|
88
|
+
<Label v-if="props.label || slots.label" :for="id" :class="style.label({ class: props.ui?.label })">
|
|
89
|
+
<slot name="label" :label="props.label">{{ props.label }}</slot>
|
|
90
|
+
</Label>
|
|
91
|
+
<p v-if="props.description || slots.description" :class="style.description({ class: props.ui?.description })">
|
|
92
|
+
<slot name="description" :description="props.description">
|
|
93
|
+
{{ props.description }}
|
|
94
|
+
</slot>
|
|
95
|
+
</p>
|
|
96
|
+
</div>
|
|
97
|
+
</Primitive>
|
|
98
|
+
</template>
|
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
-
import type { PrimitiveProps, TabsRootEmits, TabsRootProps } from 'reka-ui'
|
|
4
|
-
import type { tabs } from '../theme'
|
|
5
|
-
import type { ComponentAttrs, DynamicSlots } from '../types'
|
|
6
|
-
|
|
7
|
-
export interface TabsItem {
|
|
8
|
-
label?: string
|
|
9
|
-
icon?: string
|
|
10
|
-
slot?: string
|
|
11
|
-
content?: string
|
|
12
|
-
/** A unique value for the tab item. Defaults to the index. */
|
|
13
|
-
value?: string | number
|
|
14
|
-
disabled?: boolean
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
type TabsVariants = VariantProps<typeof tabs>
|
|
18
|
-
|
|
19
|
-
export interface TabsProps<T> extends ComponentAttrs<typeof tabs>, Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
|
|
20
|
-
as?: PrimitiveProps['as']
|
|
21
|
-
items?: T[]
|
|
22
|
-
variant?: TabsVariants['variant']
|
|
23
|
-
orientation?: TabsVariants['orientation']
|
|
24
|
-
size?: TabsVariants['size']
|
|
25
|
-
/** @default true */
|
|
26
|
-
full?: boolean
|
|
27
|
-
/**
|
|
28
|
-
* The content of the tabs, can be disabled to prevent rendering the content.
|
|
29
|
-
* @default true
|
|
30
|
-
*/
|
|
31
|
-
content?: boolean
|
|
32
|
-
/**
|
|
33
|
-
* The key used to get the label from the item.
|
|
34
|
-
* @default 'label'
|
|
35
|
-
*/
|
|
36
|
-
labelKey?: string
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface TabsEmits extends TabsRootEmits<string | number> {}
|
|
40
|
-
|
|
41
|
-
type SlotProps<T> = (props: { item: T, index: number }) => any
|
|
42
|
-
|
|
43
|
-
export type TabsSlots<T extends { slot?: string }> = {
|
|
44
|
-
|
|
45
|
-
default?: SlotProps<T>
|
|
46
|
-
|
|
47
|
-
content?: SlotProps<T>
|
|
48
|
-
} & DynamicSlots<T, SlotProps<T>>
|
|
49
|
-
</script>
|
|
50
|
-
|
|
51
|
-
<script lang="ts" setup generic="T extends TabsItem">
|
|
52
|
-
import { reactivePick } from '@vueuse/core'
|
|
53
|
-
import { TabsContent, TabsIndicator, TabsList, TabsRoot, TabsTrigger, useForwardPropsEmits } from 'reka-ui'
|
|
54
|
-
import { computed } from 'vue'
|
|
55
|
-
import { useTheme } from '../composables'
|
|
56
|
-
import { get } from '../utils'
|
|
57
|
-
|
|
58
|
-
const props = withDefaults(defineProps<TabsProps<T>>(), {
|
|
59
|
-
defaultValue: '0',
|
|
60
|
-
variant: 'solid',
|
|
61
|
-
orientation: 'horizontal',
|
|
62
|
-
size: 'md',
|
|
63
|
-
full: true,
|
|
64
|
-
content: true,
|
|
65
|
-
labelKey: 'label',
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
const emits = defineEmits<TabsEmits>()
|
|
69
|
-
const slots = defineSlots<TabsSlots<T>>()
|
|
70
|
-
|
|
71
|
-
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'activationMode', 'unmountOnHide'), emits)
|
|
72
|
-
|
|
73
|
-
const { theme, createStyler } = useTheme()
|
|
74
|
-
const style = computed(() => {
|
|
75
|
-
const styler = createStyler(theme.value.tabs)
|
|
76
|
-
return styler(props)
|
|
77
|
-
})
|
|
78
|
-
</script>
|
|
79
|
-
|
|
80
|
-
<template>
|
|
81
|
-
<TabsRoot v-bind="rootProps" :class="style.root({ class: [props.class, props.ui?.root] })">
|
|
82
|
-
<TabsList :class="style.list({ class: props.ui?.list })">
|
|
83
|
-
<TabsIndicator :class="style.indicator({ class: props.ui?.indicator })" />
|
|
84
|
-
|
|
85
|
-
<TabsTrigger
|
|
86
|
-
v-for="(item, index) of items"
|
|
87
|
-
:key="index"
|
|
88
|
-
:value="item.value || String(index)"
|
|
89
|
-
:disabled="item.disabled"
|
|
90
|
-
:class="style.trigger({ class: props.ui?.trigger })"
|
|
91
|
-
>
|
|
92
|
-
<slot name="
|
|
93
|
-
<i v-if="item.icon" :class="style.
|
|
94
|
-
</slot>
|
|
95
|
-
|
|
96
|
-
<span v-if="get(item, props.labelKey) || slots.default" :class="style.label({ class: props.ui?.label })">
|
|
97
|
-
<slot :item="item" :index="index">{{ get(item, props.labelKey) }}</slot>
|
|
98
|
-
</span>
|
|
99
|
-
|
|
100
|
-
<slot name="
|
|
101
|
-
</TabsTrigger>
|
|
102
|
-
</TabsList>
|
|
103
|
-
|
|
104
|
-
<template v-if="props.content">
|
|
105
|
-
<TabsContent
|
|
106
|
-
v-for="(item, index) of items"
|
|
107
|
-
:key="index"
|
|
108
|
-
:value="item.value || String(index)"
|
|
109
|
-
:class="style.content({ class: props.ui?.content })"
|
|
110
|
-
>
|
|
111
|
-
<slot :name="item.slot || 'content'" :item="item" :index="index">
|
|
112
|
-
{{ item.content }}
|
|
113
|
-
</slot>
|
|
114
|
-
</TabsContent>
|
|
115
|
-
</template>
|
|
116
|
-
</TabsRoot>
|
|
117
|
-
</template>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
+
import type { PrimitiveProps, TabsRootEmits, TabsRootProps } from 'reka-ui'
|
|
4
|
+
import type { tabs } from '../theme'
|
|
5
|
+
import type { ComponentAttrs, DynamicSlots } from '../types'
|
|
6
|
+
|
|
7
|
+
export interface TabsItem {
|
|
8
|
+
label?: string
|
|
9
|
+
icon?: string
|
|
10
|
+
slot?: string
|
|
11
|
+
content?: string
|
|
12
|
+
/** A unique value for the tab item. Defaults to the index. */
|
|
13
|
+
value?: string | number
|
|
14
|
+
disabled?: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type TabsVariants = VariantProps<typeof tabs>
|
|
18
|
+
|
|
19
|
+
export interface TabsProps<T> extends ComponentAttrs<typeof tabs>, Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
|
|
20
|
+
as?: PrimitiveProps['as']
|
|
21
|
+
items?: T[]
|
|
22
|
+
variant?: TabsVariants['variant']
|
|
23
|
+
orientation?: TabsVariants['orientation']
|
|
24
|
+
size?: TabsVariants['size']
|
|
25
|
+
/** @default true */
|
|
26
|
+
full?: boolean
|
|
27
|
+
/**
|
|
28
|
+
* The content of the tabs, can be disabled to prevent rendering the content.
|
|
29
|
+
* @default true
|
|
30
|
+
*/
|
|
31
|
+
content?: boolean
|
|
32
|
+
/**
|
|
33
|
+
* The key used to get the label from the item.
|
|
34
|
+
* @default 'label'
|
|
35
|
+
*/
|
|
36
|
+
labelKey?: string
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface TabsEmits extends TabsRootEmits<string | number> {}
|
|
40
|
+
|
|
41
|
+
type SlotProps<T> = (props: { item: T, index: number }) => any
|
|
42
|
+
|
|
43
|
+
export type TabsSlots<T extends { slot?: string }> = {
|
|
44
|
+
prefix?: SlotProps<T>
|
|
45
|
+
default?: SlotProps<T>
|
|
46
|
+
suffix?: SlotProps<T>
|
|
47
|
+
content?: SlotProps<T>
|
|
48
|
+
} & DynamicSlots<T, SlotProps<T>>
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<script lang="ts" setup generic="T extends TabsItem">
|
|
52
|
+
import { reactivePick } from '@vueuse/core'
|
|
53
|
+
import { TabsContent, TabsIndicator, TabsList, TabsRoot, TabsTrigger, useForwardPropsEmits } from 'reka-ui'
|
|
54
|
+
import { computed } from 'vue'
|
|
55
|
+
import { useTheme } from '../composables'
|
|
56
|
+
import { get } from '../utils'
|
|
57
|
+
|
|
58
|
+
const props = withDefaults(defineProps<TabsProps<T>>(), {
|
|
59
|
+
defaultValue: '0',
|
|
60
|
+
variant: 'solid',
|
|
61
|
+
orientation: 'horizontal',
|
|
62
|
+
size: 'md',
|
|
63
|
+
full: true,
|
|
64
|
+
content: true,
|
|
65
|
+
labelKey: 'label',
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const emits = defineEmits<TabsEmits>()
|
|
69
|
+
const slots = defineSlots<TabsSlots<T>>()
|
|
70
|
+
|
|
71
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'activationMode', 'unmountOnHide'), emits)
|
|
72
|
+
|
|
73
|
+
const { theme, createStyler } = useTheme()
|
|
74
|
+
const style = computed(() => {
|
|
75
|
+
const styler = createStyler(theme.value.tabs)
|
|
76
|
+
return styler(props)
|
|
77
|
+
})
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<template>
|
|
81
|
+
<TabsRoot v-bind="rootProps" :class="style.root({ class: [props.class, props.ui?.root] })">
|
|
82
|
+
<TabsList :class="style.list({ class: props.ui?.list })">
|
|
83
|
+
<TabsIndicator :class="style.indicator({ class: props.ui?.indicator })" />
|
|
84
|
+
|
|
85
|
+
<TabsTrigger
|
|
86
|
+
v-for="(item, index) of items"
|
|
87
|
+
:key="index"
|
|
88
|
+
:value="item.value || String(index)"
|
|
89
|
+
:disabled="item.disabled"
|
|
90
|
+
:class="style.trigger({ class: props.ui?.trigger })"
|
|
91
|
+
>
|
|
92
|
+
<slot name="prefix" :item="item" :index="index">
|
|
93
|
+
<i v-if="item.icon" :class="style.prefixIcon({ class: [item.icon, props.ui?.prefixIcon] })"></i>
|
|
94
|
+
</slot>
|
|
95
|
+
|
|
96
|
+
<span v-if="get(item, props.labelKey) || slots.default" :class="style.label({ class: props.ui?.label })">
|
|
97
|
+
<slot :item="item" :index="index">{{ get(item, props.labelKey) }}</slot>
|
|
98
|
+
</span>
|
|
99
|
+
|
|
100
|
+
<slot name="suffix" :item="item" :index="index"></slot>
|
|
101
|
+
</TabsTrigger>
|
|
102
|
+
</TabsList>
|
|
103
|
+
|
|
104
|
+
<template v-if="props.content">
|
|
105
|
+
<TabsContent
|
|
106
|
+
v-for="(item, index) of items"
|
|
107
|
+
:key="index"
|
|
108
|
+
:value="item.value || String(index)"
|
|
109
|
+
:class="style.content({ class: props.ui?.content })"
|
|
110
|
+
>
|
|
111
|
+
<slot :name="item.slot || 'content'" :item="item" :index="index">
|
|
112
|
+
{{ item.content }}
|
|
113
|
+
</slot>
|
|
114
|
+
</TabsContent>
|
|
115
|
+
</template>
|
|
116
|
+
</TabsRoot>
|
|
117
|
+
</template>
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
+
import type { PrimitiveProps } from 'reka-ui'
|
|
4
|
+
import type { textarea } from '../theme'
|
|
5
|
+
import type { ComponentAttrs } from '../types'
|
|
6
|
+
|
|
7
|
+
type TextareaVariants = VariantProps<typeof textarea>
|
|
8
|
+
|
|
9
|
+
export interface TextareaProps extends ComponentAttrs<typeof textarea> {
|
|
10
|
+
/**
|
|
11
|
+
* The element or component this component should render as.
|
|
12
|
+
* @defaultValue 'div'
|
|
13
|
+
*/
|
|
14
|
+
as?: PrimitiveProps['as']
|
|
15
|
+
id?: string
|
|
16
|
+
name?: string
|
|
17
|
+
placeholder?: string
|
|
18
|
+
size?: TextareaVariants['size']
|
|
19
|
+
variant?: TextareaVariants['variant']
|
|
20
|
+
highlight?: boolean
|
|
21
|
+
underline?: boolean
|
|
22
|
+
required?: boolean
|
|
23
|
+
autofocus?: boolean
|
|
24
|
+
autofocusDelay?: number
|
|
25
|
+
disabled?: boolean
|
|
26
|
+
rows?: number
|
|
27
|
+
maxRows?: number
|
|
28
|
+
autoResize?: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface TextareaEmits {
|
|
32
|
+
(e: 'update:modelValue', payload: string): void
|
|
33
|
+
(e: 'blur', event: FocusEvent): void
|
|
34
|
+
(e: 'change', event: Event): void
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface TextareaSlots {
|
|
38
|
+
default?: (props?: {}) => any
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<script setup lang="ts">
|
|
43
|
+
import { Primitive } from 'reka-ui'
|
|
44
|
+
import { computed, nextTick, onMounted, ref, watch } from 'vue'
|
|
45
|
+
import { useTheme } from '../composables'
|
|
46
|
+
|
|
47
|
+
defineOptions({
|
|
48
|
+
inheritAttrs: false,
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const props = withDefaults(defineProps<TextareaProps>(), {
|
|
52
|
+
size: 'md',
|
|
53
|
+
variant: 'outline',
|
|
54
|
+
rows: 3,
|
|
55
|
+
maxRows: 0,
|
|
56
|
+
autofocusDelay: 0,
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
const emit = defineEmits<TextareaEmits>()
|
|
60
|
+
defineSlots<TextareaSlots>()
|
|
61
|
+
const [modelValue, modelModifiers] = defineModel<string | number>()
|
|
62
|
+
|
|
63
|
+
const textareaRef = ref<HTMLTextAreaElement | null>(null)
|
|
64
|
+
|
|
65
|
+
const { theme, createStyler } = useTheme()
|
|
66
|
+
const style = computed(() => {
|
|
67
|
+
const styler = createStyler(theme.value.textarea)
|
|
68
|
+
return styler(props)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
function autoFocus() {
|
|
72
|
+
if (props.autofocus)
|
|
73
|
+
textareaRef.value?.focus()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function updateInput(value: string) {
|
|
77
|
+
if (modelModifiers.trim)
|
|
78
|
+
value = value.trim()
|
|
79
|
+
|
|
80
|
+
modelValue.value = value
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function onInput(event: Event) {
|
|
84
|
+
autoResize()
|
|
85
|
+
|
|
86
|
+
if (!modelModifiers.lazy)
|
|
87
|
+
updateInput((event.target as HTMLInputElement).value)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function onChange(event: Event) {
|
|
91
|
+
const value = (event.target as HTMLInputElement).value
|
|
92
|
+
|
|
93
|
+
if (modelModifiers.lazy)
|
|
94
|
+
updateInput(value)
|
|
95
|
+
|
|
96
|
+
if (modelModifiers.trim)
|
|
97
|
+
(event.target as HTMLInputElement).value = value.trim()
|
|
98
|
+
|
|
99
|
+
emit('change', event)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function onBlur(event: FocusEvent) {
|
|
103
|
+
emit('blur', event)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function autoResize() {
|
|
107
|
+
if (!props.autoResize)
|
|
108
|
+
return
|
|
109
|
+
|
|
110
|
+
if (!textareaRef.value)
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
textareaRef.value.rows = props.rows
|
|
114
|
+
|
|
115
|
+
const overflow = textareaRef.value.style.overflow
|
|
116
|
+
textareaRef.value.style.overflow = 'hidden'
|
|
117
|
+
|
|
118
|
+
const styles = window.getComputedStyle(textareaRef.value)
|
|
119
|
+
const paddingTop = Number.parseInt(styles.paddingTop)
|
|
120
|
+
const paddingBottom = Number.parseInt(styles.paddingBottom)
|
|
121
|
+
const padding = paddingTop + paddingBottom
|
|
122
|
+
const lineHeight = Number.parseInt(styles.lineHeight)
|
|
123
|
+
const { scrollHeight } = textareaRef.value
|
|
124
|
+
const newRows = Math.ceil((scrollHeight - padding) / lineHeight)
|
|
125
|
+
|
|
126
|
+
if (newRows > props.rows)
|
|
127
|
+
textareaRef.value.rows = props.maxRows ? Math.min(newRows, props.maxRows) : newRows
|
|
128
|
+
|
|
129
|
+
textareaRef.value.style.overflow = overflow
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
watch(modelValue, () => {
|
|
133
|
+
nextTick(autoResize)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
defineExpose({
|
|
137
|
+
textareaRef,
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
onMounted(() => {
|
|
141
|
+
setTimeout(() => {
|
|
142
|
+
autoFocus()
|
|
143
|
+
}, props.autofocusDelay)
|
|
144
|
+
})
|
|
145
|
+
</script>
|
|
146
|
+
|
|
147
|
+
<template>
|
|
148
|
+
<Primitive
|
|
149
|
+
:as="props.as"
|
|
150
|
+
:class="style.root({ class: [props.class, props.ui?.root] })"
|
|
151
|
+
:aria-disabled="props.disabled ? true : undefined"
|
|
152
|
+
>
|
|
153
|
+
<textarea
|
|
154
|
+
:id="props.id"
|
|
155
|
+
ref="textareaRef"
|
|
156
|
+
:value="modelValue"
|
|
157
|
+
:name="props.name"
|
|
158
|
+
:rows="props.rows"
|
|
159
|
+
:placeholder="props.placeholder"
|
|
160
|
+
:class="style.base({ class: props.ui?.base })"
|
|
161
|
+
:disabled="props.disabled"
|
|
162
|
+
:required="props.required"
|
|
163
|
+
v-bind="$attrs"
|
|
164
|
+
@input="onInput"
|
|
165
|
+
@blur="onBlur"
|
|
166
|
+
@change="onChange"
|
|
167
|
+
@focus="autoResize"
|
|
168
|
+
>
|
|
169
|
+
</textarea>
|
|
170
|
+
|
|
171
|
+
<slot></slot>
|
|
172
|
+
</Primitive>
|
|
173
|
+
</template>
|
|
@@ -121,6 +121,6 @@ defineExpose({
|
|
|
121
121
|
</ToastClose>
|
|
122
122
|
</div>
|
|
123
123
|
|
|
124
|
-
<div v-if="remaining
|
|
124
|
+
<div v-if="remaining >= 0 && duration" :class="style.progress({ class: props.ui?.progress })" :style="{ width: `${remaining / duration * 100}%` }"></div>
|
|
125
125
|
</ToastRoot>
|
|
126
126
|
</template>
|
|
@@ -139,5 +139,39 @@ function getOffset(index: number) {
|
|
|
139
139
|
</template>
|
|
140
140
|
|
|
141
141
|
<style>
|
|
142
|
-
@keyframes toast-collapsed-closed
|
|
142
|
+
@keyframes toast-collapsed-closed {
|
|
143
|
+
from {
|
|
144
|
+
transform: var(--transform);
|
|
145
|
+
}
|
|
146
|
+
to {
|
|
147
|
+
transform: translateY(calc((var(--before) - var(--height)) * var(--gap)))
|
|
148
|
+
scale(var(--scale));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
@keyframes toast-closed {
|
|
152
|
+
from {
|
|
153
|
+
transform: var(--transform);
|
|
154
|
+
}
|
|
155
|
+
to {
|
|
156
|
+
transform: translateY(
|
|
157
|
+
calc((var(--offset) - var(--height)) * var(--translate-factor))
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
@keyframes toast-slide-left {
|
|
162
|
+
from {
|
|
163
|
+
transform: translateX(0) translateY(var(--translate));
|
|
164
|
+
}
|
|
165
|
+
to {
|
|
166
|
+
transform: translateX(-100%) translateY(var(--translate));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
@keyframes toast-slide-right {
|
|
170
|
+
from {
|
|
171
|
+
transform: translateX(0) translateY(var(--translate));
|
|
172
|
+
}
|
|
173
|
+
to {
|
|
174
|
+
transform: translateX(100%) translateY(var(--translate));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
143
177
|
</style>
|