@byyuurin/ui 0.0.0

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.
Files changed (101) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +32 -0
  3. package/dist/components/Accordion.vue +104 -0
  4. package/dist/components/App.vue +57 -0
  5. package/dist/components/Button.vue +94 -0
  6. package/dist/components/Card.vue +76 -0
  7. package/dist/components/Checkbox.vue +104 -0
  8. package/dist/components/Drawer.vue +133 -0
  9. package/dist/components/Input.vue +169 -0
  10. package/dist/components/Link.vue +117 -0
  11. package/dist/components/Modal.vue +145 -0
  12. package/dist/components/ModalProvider.vue +10 -0
  13. package/dist/components/Popover.vue +97 -0
  14. package/dist/components/RadioGroup.vue +180 -0
  15. package/dist/components/Select.vue +258 -0
  16. package/dist/components/Switch.vue +99 -0
  17. package/dist/components/Tabs.vue +117 -0
  18. package/dist/components/Toast.vue +126 -0
  19. package/dist/components/Toaster.vue +143 -0
  20. package/dist/components/Tooltip.vue +71 -0
  21. package/dist/components/index.d.ts +18 -0
  22. package/dist/components/index.mjs +18 -0
  23. package/dist/composables/index.d.ts +4 -0
  24. package/dist/composables/index.mjs +4 -0
  25. package/dist/composables/useComponentIcons.d.ts +26 -0
  26. package/dist/composables/useComponentIcons.mjs +24 -0
  27. package/dist/composables/useModal.d.ts +15 -0
  28. package/dist/composables/useModal.mjs +51 -0
  29. package/dist/composables/useTheme.d.ts +8 -0
  30. package/dist/composables/useTheme.mjs +18 -0
  31. package/dist/composables/useToast.d.ts +24 -0
  32. package/dist/composables/useToast.mjs +48 -0
  33. package/dist/index.d.ts +3 -0
  34. package/dist/index.mjs +3 -0
  35. package/dist/internal/constants.d.ts +3 -0
  36. package/dist/internal/constants.mjs +21 -0
  37. package/dist/internal/extend-theme.d.ts +9 -0
  38. package/dist/internal/extend-theme.mjs +16 -0
  39. package/dist/internal/extend-theme.test.d.ts +1 -0
  40. package/dist/internal/extend-theme.test.mjs +45 -0
  41. package/dist/internal/index.d.ts +4 -0
  42. package/dist/internal/index.mjs +4 -0
  43. package/dist/internal/link.d.ts +15 -0
  44. package/dist/internal/link.mjs +4 -0
  45. package/dist/internal/styler.d.ts +5 -0
  46. package/dist/internal/styler.mjs +236 -0
  47. package/dist/internal/styler.test.d.ts +1 -0
  48. package/dist/internal/styler.test.mjs +10 -0
  49. package/dist/nuxt.d.ts +10 -0
  50. package/dist/nuxt.mjs +28 -0
  51. package/dist/resolver.d.ts +10 -0
  52. package/dist/resolver.mjs +18 -0
  53. package/dist/theme/accordion.d.ts +39 -0
  54. package/dist/theme/accordion.mjs +25 -0
  55. package/dist/theme/app.d.ts +10 -0
  56. package/dist/theme/app.mjs +9 -0
  57. package/dist/theme/button.d.ts +184 -0
  58. package/dist/theme/button.mjs +140 -0
  59. package/dist/theme/card.d.ts +43 -0
  60. package/dist/theme/card.mjs +11 -0
  61. package/dist/theme/checkbox.d.ts +97 -0
  62. package/dist/theme/checkbox.mjs +53 -0
  63. package/dist/theme/drawer.d.ts +72 -0
  64. package/dist/theme/drawer.mjs +72 -0
  65. package/dist/theme/index.d.ts +17 -0
  66. package/dist/theme/index.mjs +17 -0
  67. package/dist/theme/input.d.ts +159 -0
  68. package/dist/theme/input.mjs +133 -0
  69. package/dist/theme/link.d.ts +31 -0
  70. package/dist/theme/link.mjs +23 -0
  71. package/dist/theme/modal.d.ts +50 -0
  72. package/dist/theme/modal.mjs +54 -0
  73. package/dist/theme/popover.d.ts +27 -0
  74. package/dist/theme/popover.mjs +10 -0
  75. package/dist/theme/radioGroup.d.ts +131 -0
  76. package/dist/theme/radioGroup.mjs +67 -0
  77. package/dist/theme/select.d.ts +177 -0
  78. package/dist/theme/select.mjs +154 -0
  79. package/dist/theme/switch.d.ts +131 -0
  80. package/dist/theme/switch.mjs +78 -0
  81. package/dist/theme/tabs.d.ts +101 -0
  82. package/dist/theme/tabs.mjs +117 -0
  83. package/dist/theme/toast.d.ts +51 -0
  84. package/dist/theme/toast.mjs +27 -0
  85. package/dist/theme/toaster.d.ts +73 -0
  86. package/dist/theme/toaster.mjs +89 -0
  87. package/dist/theme/tooltip.d.ts +31 -0
  88. package/dist/theme/tooltip.mjs +8 -0
  89. package/dist/types/components.d.ts +18 -0
  90. package/dist/types/components.mjs +0 -0
  91. package/dist/types/index.d.ts +7 -0
  92. package/dist/types/index.mjs +2 -0
  93. package/dist/types/utils.d.ts +29 -0
  94. package/dist/types/utils.mjs +0 -0
  95. package/dist/unocss-preset.d.ts +37 -0
  96. package/dist/unocss-preset.mjs +164 -0
  97. package/dist/utils/index.d.ts +18 -0
  98. package/dist/utils/index.mjs +70 -0
  99. package/dist/utils/unocss.d.ts +3 -0
  100. package/dist/utils/unocss.mjs +50 -0
  101. package/package.json +103 -0
@@ -0,0 +1,126 @@
1
+ <script lang="ts">
2
+ import type { PrimitiveProps, ToastRootEmits, ToastRootProps } from 'reka-ui'
3
+ import type { toast } from '../theme'
4
+ import type { ButtonProps, ComponentAttrs } from '../types'
5
+
6
+ export interface ToastProps extends ComponentAttrs<typeof toast>, Pick<ToastRootProps, 'defaultOpen' | 'open' | 'type' | 'duration'> {
7
+ /** @default "li" */
8
+ as?: PrimitiveProps['as']
9
+ title?: string
10
+ description?: string
11
+ icon?: string
12
+ actions?: ButtonProps[]
13
+ /**
14
+ * Display a close button to dismiss the toast.
15
+ * @default true
16
+ */
17
+ close?: ButtonProps | boolean
18
+ /** @default `app.icons.close` */
19
+ closeIcon?: string
20
+ }
21
+
22
+ export interface ToastEmits extends ToastRootEmits {}
23
+
24
+ export interface ToastSlots {
25
+ icon?: (props?: {}) => any
26
+ title?: (props?: {}) => any
27
+ description?: (props?: {}) => any
28
+ actions?: (props?: {}) => any
29
+ close?: (props: { ui: any }) => any
30
+
31
+ }
32
+ </script>
33
+
34
+ <script setup lang="ts">
35
+ import { reactivePick, useElementBounding } from '@vueuse/core'
36
+ import { ToastAction, ToastClose, ToastDescription, ToastRoot, ToastTitle, useForwardPropsEmits } from 'reka-ui'
37
+ import { computed, ref } from 'vue'
38
+ import { useTheme } from '../composables'
39
+ import Button from './Button.vue'
40
+
41
+ const props = withDefaults(defineProps<ToastProps>(), {
42
+ close: true,
43
+ })
44
+
45
+ const emit = defineEmits<ToastEmits>()
46
+ const slots = defineSlots<ToastSlots>()
47
+
48
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultOpen', 'open', 'duration', 'type'), emit)
49
+
50
+ const el = ref<InstanceType<typeof ToastRoot>>()
51
+ const { height } = useElementBounding(() => el.value?.$el.getBoundingClientRect ? el.value.$el : undefined)
52
+
53
+ const multiline = computed(() => !!props.title && !!props.description)
54
+
55
+ const { theme, createStyler } = useTheme()
56
+ const style = computed(() => {
57
+ const styler = createStyler(theme.value.toast)
58
+ return styler({ ...props, multiline: multiline.value })
59
+ })
60
+
61
+ defineExpose({
62
+ height,
63
+ })
64
+ </script>
65
+
66
+ <template>
67
+ <ToastRoot
68
+ ref="el"
69
+ v-slot="{ remaining, duration }"
70
+ v-bind="rootProps"
71
+ :class="style.root({ class: [props.class, props.ui?.root], multiline })"
72
+ :style="{ '--height': height }"
73
+ >
74
+ <slot name="icon">
75
+ <i v-if="props.icon" :class="style.icon({ class: [props.icon, props.ui?.icon] })"></i>
76
+ </slot>
77
+
78
+ <div :class="style.wrapper({ class: props.ui?.wrapper })">
79
+ <ToastTitle v-if="props.title || !!slots.title" :class="style.title({ class: props.ui?.title })">
80
+ <slot name="title">
81
+ {{ props.title }}
82
+ </slot>
83
+ </ToastTitle>
84
+ <ToastDescription v-if="props.description || !!slots.description" :class="style.description({ class: props.ui?.description })">
85
+ <slot name="description">
86
+ {{ props.description }}
87
+ </slot>
88
+ </ToastDescription>
89
+
90
+ <div v-if="multiline && actions?.length" :class="style.actions({ class: props.ui?.actions, multiline: true })">
91
+ <slot name="actions">
92
+ <ToastAction v-for="(action, index) in props.actions" :key="index" :alt-text="action.label || 'Action'" as-child @click.stop>
93
+ <Button size="xs" v-bind="action" />
94
+ </ToastAction>
95
+ </slot>
96
+ </div>
97
+ </div>
98
+
99
+ <div v-if="(!multiline && actions?.length) || props.close !== null" :class="style.actions({ class: props.ui?.actions, multiline: false })">
100
+ <template v-if="!multiline">
101
+ <slot name="actions">
102
+ <ToastAction v-for="(action, index) in props.actions" :key="index" :alt-text="action.label || 'Action'" as-child @click.stop>
103
+ <Button size="xs" v-bind="action" />
104
+ </ToastAction>
105
+ </slot>
106
+ </template>
107
+
108
+ <ToastClose as-child>
109
+ <slot name="close" :ui="ui">
110
+ <UButton
111
+ v-if="props.close"
112
+ :icon="props.closeIcon || theme.app.icons.close"
113
+ size="md"
114
+ variant="link"
115
+ aria-label="close"
116
+ v-bind="typeof close === 'object' ? close : undefined"
117
+ :class="style.close({ class: props.ui?.close })"
118
+ @click.stop
119
+ />
120
+ </slot>
121
+ </ToastClose>
122
+ </div>
123
+
124
+ <div v-if="remaining > 0 && duration" :class="style.progress({ class: props.ui?.progress })" :style="{ width: `${remaining / duration * 100}%` }"></div>
125
+ </ToastRoot>
126
+ </template>
@@ -0,0 +1,143 @@
1
+ <script lang="ts">
2
+ import type { VariantProps } from '@byyuurin/ui-kit'
3
+ import type { ToastProviderProps } from 'reka-ui'
4
+ import type { toaster } from '../theme'
5
+ import type { ComponentAttrs } from '../types'
6
+
7
+ type ToasterVariants = VariantProps<typeof toaster>
8
+
9
+ export interface ToasterProps extends ComponentAttrs<typeof toaster>, Omit<ToastProviderProps, 'swipeDirection'> {
10
+ /** @default "bottom-right" */
11
+ position?: ToasterVariants['position']
12
+ /**
13
+ * Expand the toasts to show multiple toasts at once.
14
+ * @default true
15
+ */
16
+ expand?: boolean
17
+ /**
18
+ * Render the toaster in a portal.
19
+ * @default true
20
+ */
21
+ portal?: boolean
22
+ }
23
+
24
+ export interface ToasterSlots {
25
+ default?: (props?: {}) => any
26
+ }
27
+ </script>
28
+
29
+ <script setup lang="ts">
30
+ import { reactivePick } from '@vueuse/core'
31
+ import { ToastPortal, ToastProvider, ToastViewport, useForwardProps } from 'reka-ui'
32
+ import { computed, ref } from 'vue'
33
+ import { useTheme, useToast } from '../composables'
34
+ import { omit } from '../utils'
35
+ import Toast from './Toast.vue'
36
+
37
+ const props = withDefaults(defineProps<ToasterProps>(), {
38
+ position: 'bottom-right',
39
+ expand: true,
40
+ portal: true,
41
+ duration: 5000,
42
+ })
43
+ defineSlots<ToasterSlots>()
44
+
45
+ const providerProps = useForwardProps(reactivePick(props, 'duration', 'label', 'swipeThreshold'))
46
+
47
+ const { toasts, remove } = useToast()
48
+
49
+ const swipeDirection = computed(() => {
50
+ switch (props.position) {
51
+ case 'top-center':
52
+ return 'up'
53
+ case 'top-right':
54
+ case 'bottom-right':
55
+ return 'right'
56
+ case 'bottom-center':
57
+ return 'down'
58
+ case 'top-left':
59
+ case 'bottom-left':
60
+ return 'left'
61
+ }
62
+
63
+ console.warn(`[Toaster] Unknown position "${props.position}"`)
64
+
65
+ return 'right'
66
+ })
67
+
68
+ const { theme, createStyler } = useTheme()
69
+ const style = computed(() => {
70
+ const styler = createStyler(theme.value.toaster)
71
+ return styler({
72
+ ...props,
73
+ swipeDirection: swipeDirection.value,
74
+ })
75
+ })
76
+
77
+ function onUpdateOpen(value: boolean, id: string | number) {
78
+ if (value)
79
+ return
80
+
81
+ remove(id)
82
+ }
83
+
84
+ const hovered = ref(false)
85
+ const expanded = computed(() => props.expand || hovered.value)
86
+
87
+ const refs = ref<{ height: number }[]>([])
88
+
89
+ const height = computed(() => refs.value.reduce((sum, { height }) => sum + height + 16, 0))
90
+ const frontHeight = computed(() => refs.value[refs.value.length - 1]?.height || 0)
91
+
92
+ function getOffset(index: number) {
93
+ return refs.value.slice(index + 1).reduce((acc, { height }) => acc + height + 16, 0)
94
+ }
95
+ </script>
96
+
97
+ <template>
98
+ <ToastProvider :swipe-direction="swipeDirection" v-bind="providerProps">
99
+ <slot></slot>
100
+
101
+ <Toast
102
+ v-for="(toast, index) of toasts"
103
+ :key="toast.id"
104
+ ref="refs"
105
+ v-bind="omit(toast, ['id'])"
106
+ :data-expanded="expanded"
107
+ :data-front="!expanded && index === toasts.length - 1"
108
+ :style="{
109
+ '--index': (index - toasts.length) + toasts.length,
110
+ '--before': toasts.length - 1 - index,
111
+ '--offset': getOffset(index),
112
+ '--scale': expanded ? '1' : 'calc(1 - var(--before) * var(--scale-factor))',
113
+ '--translate': expanded ? 'calc(var(--offset) * var(--translate-factor))' : 'calc(var(--before) * var(--gap))',
114
+ '--transform': 'translateY(var(--translate)) scale(var(--scale))',
115
+ }"
116
+ :class="[style.base(), {
117
+ 'cursor-pointer': !!toast.click,
118
+ }]"
119
+ @update:open="onUpdateOpen($event, toast.id)"
120
+ @click="toast.click && toast.click(toast)"
121
+ />
122
+
123
+ <ToastPortal :disabled="!portal">
124
+ <ToastViewport
125
+ :data-expanded="expanded"
126
+ :class="style.viewport({ class: [props.class, props.ui?.viewport] })"
127
+ :style="{
128
+ '--scale-factor': '0.05',
129
+ '--translate-factor': position?.startsWith('top') ? '1px' : '-1px',
130
+ '--gap': position?.startsWith('top') ? '16px' : '-16px',
131
+ '--front-height': `${frontHeight}px`,
132
+ '--height': `${height}px`,
133
+ }"
134
+ @mouseenter="hovered = true"
135
+ @mouseleave="hovered = false"
136
+ />
137
+ </ToastPortal>
138
+ </ToastProvider>
139
+ </template>
140
+
141
+ <style>
142
+ @keyframes toast-collapsed-closed{0%{transform:var(--transform)}to{transform:translateY(calc((var(--before) - var(--height))*var(--gap))) scale(var(--scale))}}@keyframes toast-closed{0%{transform:var(--transform)}to{transform:translateY(calc((var(--offset) - var(--height))*var(--translate-factor)))}}@keyframes toast-slide-left{0%{transform:translateX(0) translateY(var(--translate))}to{transform:translateX(-100%) translateY(var(--translate))}}@keyframes toast-slide-right{0%{transform:translateX(0) translateY(var(--translate))}to{transform:translateX(100%) translateY(var(--translate))}}
143
+ </style>
@@ -0,0 +1,71 @@
1
+ <script lang="ts">
2
+ import type { TooltipArrowProps, TooltipContentProps, TooltipRootEmits, TooltipRootProps } from 'reka-ui'
3
+ import type { tooltip } from '../theme'
4
+ import type { ComponentAttrs } from '../types'
5
+
6
+ export interface TooltipProps extends ComponentAttrs<typeof tooltip>, TooltipRootProps {
7
+ text?: string
8
+ content?: Omit<TooltipContentProps, 'as' | 'asChild'>
9
+ arrow?: boolean | Omit<TooltipArrowProps, 'as' | 'asChild'>
10
+ /** @default true */
11
+ portal?: boolean
12
+ }
13
+
14
+ export interface TooltipEmits extends TooltipRootEmits {}
15
+
16
+ export interface TooltipSlots {
17
+ default?: (props: { open: boolean }) => any
18
+ content?: (props: {}) => any
19
+ }
20
+ </script>
21
+
22
+ <script lang="ts" setup>
23
+ import { reactivePick } from '@vueuse/core'
24
+ import { defu } from 'defu'
25
+ import { TooltipArrow, TooltipContent, TooltipPortal, TooltipRoot, TooltipTrigger, useForwardPropsEmits } from 'reka-ui'
26
+ import { computed, toRef } from 'vue'
27
+ import { useTheme } from '../composables'
28
+
29
+ const props = withDefaults(defineProps<TooltipProps>(), {
30
+ portal: true,
31
+ })
32
+ const emit = defineEmits<TooltipEmits>()
33
+ const slots = defineSlots<TooltipSlots>()
34
+
35
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'defaultOpen', 'open', 'delayDuration', 'disableHoverableContent', 'disableClosingTrigger', 'disabled', 'ignoreNonKeyboardFocus'), emit)
36
+
37
+ const contentDefaults: TooltipContentProps = {
38
+ side: 'bottom',
39
+ sideOffset: 8,
40
+ collisionPadding: 8,
41
+ }
42
+
43
+ const contentProps = toRef(() => defu(props.content, contentDefaults) as TooltipContentProps)
44
+
45
+ const arrowProps = toRef(() => props.arrow as TooltipArrowProps)
46
+
47
+ const { theme, createStyler } = useTheme()
48
+ const style = computed(() => {
49
+ const styler = createStyler(theme.value.tooltip)
50
+ return styler(props)
51
+ })
52
+ </script>
53
+
54
+ <template>
55
+ <TooltipRoot v-slot="{ open }" v-bind="rootProps">
56
+ <TooltipTrigger v-if="slots.default" as-child :class="props.class">
57
+ <slot :open="open">
58
+ </slot>
59
+ </TooltipTrigger>
60
+
61
+ <TooltipPortal :disabled="!props.portal">
62
+ <TooltipContent v-bind="contentProps" :class="style.content({ class: [!slots.default && props.class, props.ui?.content] })">
63
+ <slot name="content">
64
+ <span v-if="props.text" :class="style.text({ class: props.ui?.text })">{{ props.text }}</span>
65
+ </slot>
66
+
67
+ <TooltipArrow v-if="props.arrow" v-bind="arrowProps" :class="style.arrow({ class: props.ui?.arrow })" />
68
+ </TooltipContent>
69
+ </TooltipPortal>
70
+ </TooltipRoot>
71
+ </template>
@@ -0,0 +1,18 @@
1
+ export { default as Accordion } from './Accordion.vue';
2
+ export { default as App } from './App.vue';
3
+ export { default as Button } from './Button.vue';
4
+ export { default as Card } from './Card.vue';
5
+ export { default as Checkbox } from './Checkbox.vue';
6
+ export { default as Drawer } from './Drawer.vue';
7
+ export { default as Input } from './Input.vue';
8
+ export { default as Link } from './Link.vue';
9
+ export { default as Modal } from './Modal.vue';
10
+ export { default as ModalProvider } from './ModalProvider.vue';
11
+ export { default as Popover } from './Popover.vue';
12
+ export { default as RadioGroup } from './RadioGroup.vue';
13
+ export { default as Select } from './Select.vue';
14
+ export { default as Switch } from './Switch.vue';
15
+ export { default as Tabs } from './Tabs.vue';
16
+ export { default as Toast } from './Toast.vue';
17
+ export { default as Toaster } from './Toaster.vue';
18
+ export { default as Tooltip } from './Tooltip.vue';
@@ -0,0 +1,18 @@
1
+ export { default as Accordion } from "./Accordion.vue";
2
+ export { default as App } from "./App.vue";
3
+ export { default as Button } from "./Button.vue";
4
+ export { default as Card } from "./Card.vue";
5
+ export { default as Checkbox } from "./Checkbox.vue";
6
+ export { default as Drawer } from "./Drawer.vue";
7
+ export { default as Input } from "./Input.vue";
8
+ export { default as Link } from "./Link.vue";
9
+ export { default as Modal } from "./Modal.vue";
10
+ export { default as ModalProvider } from "./ModalProvider.vue";
11
+ export { default as Popover } from "./Popover.vue";
12
+ export { default as RadioGroup } from "./RadioGroup.vue";
13
+ export { default as Select } from "./Select.vue";
14
+ export { default as Switch } from "./Switch.vue";
15
+ export { default as Tabs } from "./Tabs.vue";
16
+ export { default as Toast } from "./Toast.vue";
17
+ export { default as Toaster } from "./Toaster.vue";
18
+ export { default as Tooltip } from "./Tooltip.vue";
@@ -0,0 +1,4 @@
1
+ export { useComponentIcons } from './useComponentIcons';
2
+ export { useModal } from './useModal';
3
+ export { useTheme } from './useTheme';
4
+ export { useToast } from './useToast';
@@ -0,0 +1,4 @@
1
+ export { useComponentIcons } from "./useComponentIcons.mjs";
2
+ export { useModal } from "./useModal.mjs";
3
+ export { useTheme } from "./useTheme.mjs";
4
+ export { useToast } from "./useToast.mjs";
@@ -0,0 +1,26 @@
1
+ import { type MaybeRefOrGetter } from 'vue';
2
+ export interface UseComponentIconsProps {
3
+ /** Display an icon based on the `prefix` and `suffix` props. */
4
+ icon?: string;
5
+ /** When `true`, the icon will be displayed on the left side. */
6
+ prefix?: boolean;
7
+ /** Display an icon on the left side. */
8
+ prefixIcon?: string;
9
+ /** When `true`, the icon will be displayed on the right side. */
10
+ suffix?: boolean;
11
+ /** Display an icon on the right side. */
12
+ suffixIcon?: string;
13
+ /** When `true`, the loading icon will be displayed. */
14
+ loading?: boolean;
15
+ /**
16
+ * The icon when the `loading` prop is `true`.
17
+ * @default app.icons.loading
18
+ */
19
+ loadingIcon?: string;
20
+ }
21
+ export declare function useComponentIcons(componentProps: MaybeRefOrGetter<UseComponentIconsProps>): {
22
+ isPrefix: import("vue").ComputedRef<boolean>;
23
+ isSuffix: import("vue").ComputedRef<boolean>;
24
+ prefixIconName: import("vue").ComputedRef<string | undefined>;
25
+ suffixIconName: import("vue").ComputedRef<string | undefined>;
26
+ };
@@ -0,0 +1,24 @@
1
+ import { computed, toValue } from "vue";
2
+ import { useTheme } from "./useTheme.mjs";
3
+ export function useComponentIcons(componentProps) {
4
+ const { theme } = useTheme();
5
+ const props = computed(() => toValue(componentProps));
6
+ const isPrefix = computed(() => props.value.icon && props.value.prefix || props.value.icon && !props.value.suffix || props.value.loading && !props.value.suffix || !!props.value.prefixIcon);
7
+ const isSuffix = computed(() => props.value.icon && props.value.suffix || props.value.loading && props.value.suffix || !!props.value.suffixIcon);
8
+ const prefixIconName = computed(() => {
9
+ if (props.value.loading)
10
+ return props.value.loadingIcon || theme.value.app.icons.loading;
11
+ return props.value.prefixIcon || props.value.icon;
12
+ });
13
+ const suffixIconName = computed(() => {
14
+ if (props.value.loading && !isPrefix.value)
15
+ return props.value.loadingIcon || theme.value.app.icons.loading;
16
+ return props.value.suffixIcon || props.value.icon;
17
+ });
18
+ return {
19
+ isPrefix,
20
+ isSuffix,
21
+ prefixIconName,
22
+ suffixIconName
23
+ };
24
+ }
@@ -0,0 +1,15 @@
1
+ import type { Component, ShallowRef } from 'vue';
2
+ import type { ComponentProps } from 'vue-component-type-helpers';
3
+ import type { ModalProps } from '../types';
4
+ export interface ModalState {
5
+ component: Component | string;
6
+ props: ModalProps;
7
+ }
8
+ export declare const injectModalState: () => ShallowRef<ModalState> | undefined, provideModalState: (value: ShallowRef<ModalState>) => void;
9
+ export declare const useModal: () => {
10
+ open: <T extends Component>(component: T, props?: ModalProps & ComponentProps<T>) => void;
11
+ close: () => void;
12
+ reset: () => void;
13
+ patch: <T extends Component = Record<string, never>>(props: Partial<ModalProps & ComponentProps<T>>) => void;
14
+ isOpen: import("vue").Ref<boolean, boolean>;
15
+ };
@@ -0,0 +1,51 @@
1
+ import { createSharedComposable } from "@vueuse/core";
2
+ import { ref } from "vue";
3
+ import { createInjection } from "../utils/index.mjs";
4
+ export const {
5
+ inject: injectModalState,
6
+ provide: provideModalState
7
+ } = createInjection("ui.modal");
8
+ export const useModal = createSharedComposable(() => {
9
+ const modalState = injectModalState();
10
+ const isOpen = ref(false);
11
+ function open(component, props) {
12
+ if (!modalState)
13
+ throw new Error("useModal() is called without provider");
14
+ modalState.value = {
15
+ component,
16
+ props: props ?? {}
17
+ };
18
+ isOpen.value = true;
19
+ }
20
+ function close() {
21
+ if (!modalState)
22
+ return;
23
+ isOpen.value = false;
24
+ }
25
+ function reset() {
26
+ if (!modalState)
27
+ return;
28
+ modalState.value = {
29
+ component: "div",
30
+ props: {}
31
+ };
32
+ }
33
+ function patch(props) {
34
+ if (!modalState)
35
+ return;
36
+ modalState.value = {
37
+ ...modalState.value,
38
+ props: {
39
+ ...modalState.value.props,
40
+ ...props
41
+ }
42
+ };
43
+ }
44
+ return {
45
+ open,
46
+ close,
47
+ reset,
48
+ patch,
49
+ isOpen
50
+ };
51
+ });
@@ -0,0 +1,8 @@
1
+ import type { MaybeRefOrGetter } from 'vue';
2
+ import * as theme from '../theme';
3
+ export declare const provideThemeExtension: (value: MaybeRefOrGetter<import("../types").PartialTheme<typeof theme>>) => void, injectThemeExtension: () => MaybeRefOrGetter<import("../types").PartialTheme<typeof theme>>;
4
+ export declare const mergeRules: import("@byyuurin/ui-kit/index").CRRule[];
5
+ export declare const useTheme: () => {
6
+ theme: import("vue").ComputedRef<typeof theme>;
7
+ createStyler: <V extends import("@byyuurin/ui-kit/index").CVVariants<S, B>, CV extends import("@byyuurin/ui-kit/index").CVCompoundVariants<V, S, B>, B extends import("@byyuurin/ui-kit/index").ClassValue = undefined, S extends import("@byyuurin/ui-kit/index").CVSlots = undefined>(theme: import("@byyuurin/ui-kit/index").CVMeta<V, CV, never, B, S>) => [keyof V] extends string[] ? (props: Required<import("@byyuurin/ui-kit/index").VariantProps<import("@byyuurin/ui-kit/index").CVReturnType<V, S, B>>> & import("../types").StylerBaseProps) => S extends undefined ? string : { [K in keyof S | (B extends undefined ? never : "base")]: import("@byyuurin/ui-kit/index").CVHandler<V, S, string>; } : (props?: import("../types").StylerBaseProps) => S extends undefined ? string : { [K in keyof S | (B extends undefined ? never : "base")]: import("@byyuurin/ui-kit/index").CVHandler<V, S, string>; };
8
+ };
@@ -0,0 +1,18 @@
1
+ import { createSharedComposable } from "@vueuse/core";
2
+ import { computed, toValue } from "vue";
3
+ import { createMergeRules, extendTheme, prepareStyler } from "../internal/index.mjs";
4
+ import * as theme from "../theme/index.mjs";
5
+ import { createInjection } from "../utils/index.mjs";
6
+ export const {
7
+ provide: provideThemeExtension,
8
+ inject: injectThemeExtension
9
+ } = createInjection("ui.themeExtension", {});
10
+ export const mergeRules = createMergeRules();
11
+ export const useTheme = createSharedComposable(() => {
12
+ const _theme = injectThemeExtension();
13
+ const { createStyler } = prepareStyler(mergeRules);
14
+ return {
15
+ theme: computed(() => extendTheme(toValue(_theme), theme)),
16
+ createStyler
17
+ };
18
+ });
@@ -0,0 +1,24 @@
1
+ import type { ToastProps } from '../types';
2
+ export interface Toast extends Omit<ToastProps, 'defaultOpen'> {
3
+ id: string | number;
4
+ click?: (toast: Toast) => void;
5
+ }
6
+ export declare const useToast: () => {
7
+ toasts: import("vue").Ref<{
8
+ [x: string]: any;
9
+ [x: number]: any;
10
+ [x: symbol]: ToastProps;
11
+ id: string | number;
12
+ click?: ((toast: Toast) => void) | undefined;
13
+ }[], Toast[] | {
14
+ [x: string]: any;
15
+ [x: number]: any;
16
+ [x: symbol]: ToastProps;
17
+ id: string | number;
18
+ click?: ((toast: Toast) => void) | undefined;
19
+ }[]>;
20
+ add: (toast: Partial<Toast>) => Toast;
21
+ update: (id: string | number, toast: Partial<Omit<Toast, "id">>) => void;
22
+ remove: (id: string | number) => void;
23
+ clear: () => void;
24
+ };
@@ -0,0 +1,48 @@
1
+ import { createSharedComposable } from "@vueuse/core";
2
+ import { ref } from "vue";
3
+ export const useToast = createSharedComposable(() => {
4
+ const toasts = ref([]);
5
+ function add(toast) {
6
+ const body = {
7
+ id: Date.now().toString(),
8
+ open: true,
9
+ ...toast
10
+ };
11
+ const index = toasts.value.findIndex((t) => t.id === body.id);
12
+ if (index === -1)
13
+ toasts.value.push(body);
14
+ toasts.value = toasts.value.slice(-5);
15
+ return body;
16
+ }
17
+ function update(id, toast) {
18
+ const index = toasts.value.findIndex((t) => t.id === id);
19
+ if (index === -1)
20
+ return;
21
+ toasts.value[index] = {
22
+ ...toasts.value[index],
23
+ ...toast
24
+ };
25
+ }
26
+ function remove(id) {
27
+ const index = toasts.value.findIndex((t) => t.id === id);
28
+ if (index === -1)
29
+ return;
30
+ toasts.value[index] = {
31
+ ...toasts.value[index],
32
+ open: false
33
+ };
34
+ setTimeout(() => {
35
+ toasts.value = toasts.value.filter((t) => t.id !== id);
36
+ }, 200);
37
+ }
38
+ function clear() {
39
+ toasts.value = [];
40
+ }
41
+ return {
42
+ toasts,
43
+ add,
44
+ update,
45
+ remove,
46
+ clear
47
+ };
48
+ });
@@ -0,0 +1,3 @@
1
+ export * from './components';
2
+ export * from './composables';
3
+ export * from './types';
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./components/index.mjs";
2
+ export * from "./composables/index.mjs";
3
+ export * from "./types/index.mjs";
@@ -0,0 +1,3 @@
1
+ import type { ComponentName } from '../types';
2
+ export declare const packageName = "@byyuurin/ui";
3
+ export declare const componentNames: ComponentName[];
@@ -0,0 +1,21 @@
1
+ export const packageName = "@byyuurin/ui";
2
+ export const componentNames = [
3
+ "Accordion",
4
+ "App",
5
+ "Button",
6
+ "Card",
7
+ "Checkbox",
8
+ "Drawer",
9
+ "Input",
10
+ "Link",
11
+ "Modal",
12
+ "ModalProvider",
13
+ "Popover",
14
+ "RadioGroup",
15
+ "Select",
16
+ "Switch",
17
+ "Tabs",
18
+ "Toast",
19
+ "Toaster",
20
+ "Tooltip"
21
+ ];
@@ -0,0 +1,9 @@
1
+ export declare const extendTheme: <Source extends {
2
+ [x: string]: any;
3
+ [x: number]: any;
4
+ [x: symbol]: any;
5
+ }, Defaults extends Array<{
6
+ [x: string]: any;
7
+ [x: number]: any;
8
+ [x: symbol]: any;
9
+ } | (number | boolean | any[] | Record<never, any> | null | undefined)>>(source: Source, ...defaults: Defaults) => import("defu").Defu<Source, Defaults>;