@byyuurin/ui 0.0.5 → 0.0.6
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 +13 -8
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +3 -0
- package/dist/nuxt.mjs +4 -3
- package/dist/nuxt.mjs.map +1 -1
- package/dist/runtime/components/App.vue +1 -1
- package/dist/runtime/components/Badge.vue +0 -1
- package/dist/runtime/components/Button.vue +4 -1
- package/dist/runtime/components/ButtonGroup.vue +47 -0
- package/dist/runtime/components/Carousel.vue +310 -0
- package/dist/runtime/components/Checkbox.vue +0 -1
- package/dist/runtime/components/Chip.vue +7 -2
- package/dist/runtime/components/Input.vue +8 -4
- package/dist/runtime/components/Modal.vue +2 -3
- package/dist/runtime/components/Pagination.vue +167 -0
- package/dist/runtime/components/PinInput.vue +0 -1
- package/dist/runtime/components/RadioGroup.vue +0 -1
- package/dist/runtime/components/ScrollArea.vue +1 -1
- package/dist/runtime/components/Select.vue +5 -1
- package/dist/runtime/components/Slider.vue +0 -1
- package/dist/runtime/components/Switch.vue +1 -3
- package/dist/runtime/components/Tabs.vue +0 -1
- package/dist/runtime/components/Textarea.vue +0 -1
- package/dist/runtime/components/Toast.vue +20 -9
- package/dist/runtime/components/Toaster.vue +3 -4
- package/dist/runtime/composables/useButtonGroup.d.ts +13 -0
- package/dist/runtime/composables/useButtonGroup.mjs +14 -0
- package/dist/runtime/composables/useTheme.d.ts +2 -2
- package/dist/runtime/composables/useTheme.mjs +1 -1
- package/dist/runtime/composables/useToast.d.ts +4 -4
- package/dist/runtime/composables/useToast.mjs +19 -6
- package/dist/runtime/theme/accordion.d.ts +17 -0
- package/dist/runtime/theme/alert.d.ts +40 -0
- package/dist/runtime/theme/alert.mjs +4 -4
- package/dist/runtime/theme/app.d.ts +5 -0
- package/dist/runtime/theme/app.mjs +6 -1
- package/dist/runtime/theme/badge.d.ts +3 -0
- package/dist/runtime/theme/badge.mjs +5 -2
- package/dist/runtime/theme/button-group.d.ts +66 -0
- package/dist/runtime/theme/button-group.mjs +42 -0
- package/dist/runtime/theme/button.d.ts +11 -0
- package/dist/runtime/theme/button.mjs +23 -18
- package/dist/runtime/theme/card.d.ts +19 -0
- package/dist/runtime/theme/card.mjs +1 -1
- package/dist/runtime/theme/carousel.d.ts +113 -0
- package/dist/runtime/theme/carousel.mjs +43 -0
- package/dist/runtime/theme/checkbox.d.ts +3 -0
- package/dist/runtime/theme/checkbox.mjs +6 -3
- package/dist/runtime/theme/chip.d.ts +11 -0
- package/dist/runtime/theme/chip.mjs +10 -5
- package/dist/runtime/theme/drawer.d.ts +38 -0
- package/dist/runtime/theme/drawer.mjs +2 -2
- package/dist/runtime/theme/index.d.ts +5 -2
- package/dist/runtime/theme/index.mjs +5 -2
- package/dist/runtime/theme/input.d.ts +33 -22
- package/dist/runtime/theme/input.mjs +36 -31
- package/dist/runtime/theme/link.d.ts +13 -0
- package/dist/runtime/theme/modal.d.ts +3 -0
- package/dist/runtime/theme/modal.mjs +5 -2
- package/dist/runtime/theme/pagination.d.ts +56 -0
- package/dist/runtime/theme/pagination.mjs +13 -0
- package/dist/runtime/theme/pinInput.d.ts +3 -0
- package/dist/runtime/theme/pinInput.mjs +14 -11
- package/dist/runtime/theme/popover.d.ts +11 -0
- package/dist/runtime/theme/popover.mjs +1 -1
- package/dist/runtime/theme/{radioGroup.d.ts → radio-group.d.ts} +3 -0
- package/dist/runtime/theme/{radioGroup.mjs → radio-group.mjs} +4 -1
- package/dist/runtime/theme/{scrollArea.d.ts → scroll-area.d.ts} +22 -0
- package/dist/runtime/theme/{scrollArea.mjs → scroll-area.mjs} +2 -2
- package/dist/runtime/theme/select.d.ts +11 -0
- package/dist/runtime/theme/select.mjs +20 -15
- package/dist/runtime/theme/slider.d.ts +3 -0
- package/dist/runtime/theme/slider.mjs +6 -3
- package/dist/runtime/theme/switch.d.ts +3 -0
- package/dist/runtime/theme/switch.mjs +5 -2
- package/dist/runtime/theme/tabs.d.ts +3 -0
- package/dist/runtime/theme/tabs.mjs +13 -10
- package/dist/runtime/theme/textarea.d.ts +3 -0
- package/dist/runtime/theme/textarea.mjs +14 -11
- package/dist/runtime/theme/toast.d.ts +44 -6
- package/dist/runtime/theme/toast.mjs +12 -7
- package/dist/runtime/theme/toaster.d.ts +49 -0
- package/dist/runtime/theme/toaster.mjs +5 -0
- package/dist/runtime/theme/tooltip.d.ts +13 -0
- package/dist/runtime/theme/tooltip.mjs +1 -1
- package/dist/runtime/types/components.d.ts +27 -25
- package/dist/runtime/types/components.mjs +27 -0
- package/dist/runtime/types/utils.d.ts +1 -1
- package/dist/runtime/utils/styler.d.ts +2 -2
- package/dist/shared/ui.D4zm1r0C.mjs +4 -0
- package/dist/shared/ui.D4zm1r0C.mjs.map +1 -0
- package/dist/{unocss-preset.d.mts → unocss.d.mts} +4 -4
- package/dist/{unocss-preset.d.ts → unocss.d.ts} +4 -4
- package/dist/{unocss-preset.mjs → unocss.mjs} +15 -2
- package/dist/unocss.mjs.map +1 -0
- package/dist/unplugin.d.mts +4 -3
- package/dist/unplugin.d.ts +4 -3
- package/dist/unplugin.mjs +13 -5
- package/dist/unplugin.mjs.map +1 -1
- package/dist/vite.d.mts +2 -1
- package/dist/vite.d.ts +2 -1
- package/dist/vite.mjs +5 -5
- package/dist/vite.mjs.map +1 -1
- package/package.json +35 -22
- package/dist/shared/ui.CzDyI29e.mjs +0 -8
- package/dist/shared/ui.CzDyI29e.mjs.map +0 -1
- package/dist/unocss-preset.mjs.map +0 -1
- /package/{LICENSE.md → LICENSE} +0 -0
package/README.md
CHANGED
|
@@ -5,7 +5,6 @@ A collection of Vue.js components for my projects.
|
|
|
5
5
|
[![npm version][npm-version-src]][npm-version-href]
|
|
6
6
|
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
7
7
|
[![bundle][bundle-src]][bundle-href]
|
|
8
|
-
[![JSDocs][jsdocs-src]][jsdocs-href]
|
|
9
8
|
[![License][license-src]][license-href]
|
|
10
9
|
|
|
11
10
|
## Preview
|
|
@@ -30,7 +29,7 @@ pnpm i -D @iconify-json/[the-collection-you-want]
|
|
|
30
29
|
|
|
31
30
|
```ts
|
|
32
31
|
// uno.config.ts
|
|
33
|
-
import ui from '@byyuurin/ui/unocss
|
|
32
|
+
import { preset as ui } from '@byyuurin/ui/unocss'
|
|
34
33
|
import { defineConfig, presetIcons, presetUno } from 'unocss'
|
|
35
34
|
|
|
36
35
|
export default defineConfig({
|
|
@@ -43,6 +42,9 @@ export default defineConfig({
|
|
|
43
42
|
radius: '0rem', // optional
|
|
44
43
|
radiusBox: '0rem', // optional
|
|
45
44
|
radiusButton: '0rem', // optional
|
|
45
|
+
radiusCheckbox: '0rem', // optional
|
|
46
|
+
radiusRadio: '0rem', // optional
|
|
47
|
+
radiusSwitch: '0rem', // optional
|
|
46
48
|
radiusTabs: '0rem', // optional
|
|
47
49
|
cb: '#1f2937', // optional
|
|
48
50
|
c1: '#ffffff', // optional
|
|
@@ -53,6 +55,12 @@ export default defineConfig({
|
|
|
53
55
|
})
|
|
54
56
|
```
|
|
55
57
|
|
|
58
|
+
New Rules
|
|
59
|
+
|
|
60
|
+
- `ui-[color]`
|
|
61
|
+
- `bg-solid-[color]`
|
|
62
|
+
- `bg-solid-[color]/[opacity]`
|
|
63
|
+
|
|
56
64
|
### Vite
|
|
57
65
|
|
|
58
66
|
```ts
|
|
@@ -62,7 +70,6 @@ import UI from '@byyuurin/ui/vite'
|
|
|
62
70
|
import Vue from '@vitejs/plugin-vue'
|
|
63
71
|
import UnoCSS from 'unocss/vite'
|
|
64
72
|
import { defineConfig } from 'vite'
|
|
65
|
-
import Inspect from 'vite-plugin-inspect'
|
|
66
73
|
|
|
67
74
|
export default defineConfig({
|
|
68
75
|
plugins: [
|
|
@@ -111,7 +118,7 @@ export default defineNuxtConfig({
|
|
|
111
118
|
|
|
112
119
|
## License
|
|
113
120
|
|
|
114
|
-
[MIT](./LICENSE) License © 2024-PRESENT [Yuurin](https://github.com/
|
|
121
|
+
[MIT](./LICENSE) License © 2024-PRESENT [Yuurin](https://github.com/byyuurin)
|
|
115
122
|
|
|
116
123
|
<!-- Badges -->
|
|
117
124
|
|
|
@@ -121,7 +128,5 @@ export default defineNuxtConfig({
|
|
|
121
128
|
[npm-downloads-href]: https://npmjs.com/package/@byyuurin/ui
|
|
122
129
|
[bundle-src]: https://img.shields.io/bundlephobia/minzip/@byyuurin/ui?style=flat&colorA=080f12&colorB=1fa669&label=minzip
|
|
123
130
|
[bundle-href]: https://bundlephobia.com/result?p=@byyuurin/ui
|
|
124
|
-
[license-src]: https://img.shields.io/github/license/byyuurin
|
|
125
|
-
[license-href]: https://github.com/byyuurin
|
|
126
|
-
[jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
|
|
127
|
-
[jsdocs-href]: https://www.jsdocs.io/package/@byyuurin/ui
|
|
131
|
+
[license-src]: https://img.shields.io/github/license/byyuurin/ui.svg?style=flat&colorA=080f12&colorB=1fa669
|
|
132
|
+
[license-href]: https://github.com/byyuurin/ui/blob/main/LICENSE
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ export { default as Alert } from './runtime/components/Alert.vue';
|
|
|
3
3
|
export { default as App } from './runtime/components/App.vue';
|
|
4
4
|
export { default as Badge } from './runtime/components/Badge.vue';
|
|
5
5
|
export { default as Button } from './runtime/components/Button.vue';
|
|
6
|
+
export { default as ButtonGroup } from './runtime/components/ButtonGroup.vue';
|
|
6
7
|
export { default as Card } from './runtime/components/Card.vue';
|
|
8
|
+
export { default as Carousel } from './runtime/components/Carousel.vue';
|
|
7
9
|
export { default as Checkbox } from './runtime/components/Checkbox.vue';
|
|
8
10
|
export { default as Chip } from './runtime/components/Chip.vue';
|
|
9
11
|
export { default as Drawer } from './runtime/components/Drawer.vue';
|
|
@@ -11,6 +13,7 @@ export { default as Input } from './runtime/components/Input.vue';
|
|
|
11
13
|
export { default as Link } from './runtime/components/Link.vue';
|
|
12
14
|
export { default as Modal } from './runtime/components/Modal.vue';
|
|
13
15
|
export { default as ModalProvider } from './runtime/components/ModalProvider.vue';
|
|
16
|
+
export { default as Pagination } from './runtime/components/Pagination.vue';
|
|
14
17
|
export { default as PinInput } from './runtime/components/PinInput.vue';
|
|
15
18
|
export { default as Popover } from './runtime/components/Popover.vue';
|
|
16
19
|
export { default as RadioGroup } from './runtime/components/RadioGroup.vue';
|
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,9 @@ export { default as Alert } from "./runtime/components/Alert.vue";
|
|
|
3
3
|
export { default as App } from "./runtime/components/App.vue";
|
|
4
4
|
export { default as Badge } from "./runtime/components/Badge.vue";
|
|
5
5
|
export { default as Button } from "./runtime/components/Button.vue";
|
|
6
|
+
export { default as ButtonGroup } from "./runtime/components/ButtonGroup.vue";
|
|
6
7
|
export { default as Card } from "./runtime/components/Card.vue";
|
|
8
|
+
export { default as Carousel } from "./runtime/components/Carousel.vue";
|
|
7
9
|
export { default as Checkbox } from "./runtime/components/Checkbox.vue";
|
|
8
10
|
export { default as Chip } from "./runtime/components/Chip.vue";
|
|
9
11
|
export { default as Drawer } from "./runtime/components/Drawer.vue";
|
|
@@ -11,6 +13,7 @@ export { default as Input } from "./runtime/components/Input.vue";
|
|
|
11
13
|
export { default as Link } from "./runtime/components/Link.vue";
|
|
12
14
|
export { default as Modal } from "./runtime/components/Modal.vue";
|
|
13
15
|
export { default as ModalProvider } from "./runtime/components/ModalProvider.vue";
|
|
16
|
+
export { default as Pagination } from "./runtime/components/Pagination.vue";
|
|
14
17
|
export { default as PinInput } from "./runtime/components/PinInput.vue";
|
|
15
18
|
export { default as Popover } from "./runtime/components/Popover.vue";
|
|
16
19
|
export { default as RadioGroup } from "./runtime/components/RadioGroup.vue";
|
package/dist/nuxt.mjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { defineNuxtModule, useLogger, createResolver, addComponentsDir, addImportsDir } from '@nuxt/kit';
|
|
2
|
-
import { p as packageName } from './shared/ui.
|
|
3
|
-
import 'node:url';
|
|
4
|
-
import 'pathe';
|
|
2
|
+
import { p as packageName } from './shared/ui.D4zm1r0C.mjs';
|
|
5
3
|
|
|
6
4
|
const nuxt = defineNuxtModule({
|
|
7
5
|
meta: {
|
|
@@ -21,6 +19,9 @@ const nuxt = defineNuxtModule({
|
|
|
21
19
|
logger.error(`\`${packageName}\` requires the \`@unocss/nuxt\` module to be installed.`);
|
|
22
20
|
return;
|
|
23
21
|
}
|
|
22
|
+
nuxt.options.vite.optimizeDeps ??= {};
|
|
23
|
+
nuxt.options.vite.optimizeDeps.include ??= [];
|
|
24
|
+
nuxt.options.vite.optimizeDeps.include.push(`${packageName}/unocss`);
|
|
24
25
|
nuxt.options.alias["#ui"] = resolve("./runtime");
|
|
25
26
|
addComponentsDir({
|
|
26
27
|
path: resolve("./runtime/components"),
|
package/dist/nuxt.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nuxt.mjs","sources":["../src/nuxt.ts"],"sourcesContent":["import { addComponentsDir, addImportsDir, createResolver, defineNuxtModule, useLogger } from '@nuxt/kit'\r\nimport type {} from '@nuxt/schema' // Mandatory to avoid a bug when building\r\nimport { packageName } from './
|
|
1
|
+
{"version":3,"file":"nuxt.mjs","sources":["../src/nuxt.ts"],"sourcesContent":["import { addComponentsDir, addImportsDir, createResolver, defineNuxtModule, useLogger } from '@nuxt/kit'\r\nimport type {} from '@nuxt/schema' // Mandatory to avoid a bug when building\r\nimport { packageName } from './shared'\r\n\r\nexport interface ModuleOptions {\r\n /**\r\n * prefix for components used in templates\r\n *\r\n * @default \"U\"\r\n */\r\n prefix?: string\r\n}\r\n\r\nexport default defineNuxtModule<ModuleOptions>({\r\n meta: {\r\n name: packageName,\r\n configKey: 'ui',\r\n compatibility: {\r\n nuxt: '>=3.13.1',\r\n },\r\n },\r\n defaults: {\r\n prefix: 'U',\r\n },\r\n setup(options, nuxt) {\r\n const logger = useLogger(packageName)\r\n const { resolve } = createResolver(import.meta.url)\r\n\r\n // Make sure the UnoCSS Nuxt module is installed\r\n if (!nuxt.options.modules.includes('@unocss/nuxt')) {\r\n logger.error(`\\`${packageName}\\` requires the \\`@unocss/nuxt\\` module to be installed.`)\r\n return\r\n }\r\n\r\n nuxt.options.vite.optimizeDeps ??= {}\r\n nuxt.options.vite.optimizeDeps.include ??= []\r\n nuxt.options.vite.optimizeDeps.include.push(`${packageName}/unocss`)\r\n\r\n nuxt.options.alias['#ui'] = resolve('./runtime')\r\n\r\n addComponentsDir({\r\n path: resolve('./runtime/components'),\r\n prefix: options.prefix,\r\n pathPrefix: false,\r\n })\r\n\r\n addImportsDir(resolve('./runtime/composables'))\r\n },\r\n})\r\n"],"names":[],"mappings":";;;AAaA,aAAe,gBAAgC,CAAA;AAAA,EAC7C,IAAM,EAAA;AAAA,IACJ,IAAM,EAAA,WAAA;AAAA,IACN,SAAW,EAAA,IAAA;AAAA,IACX,aAAe,EAAA;AAAA,MACb,IAAM,EAAA;AAAA;AACR,GACF;AAAA,EACA,QAAU,EAAA;AAAA,IACR,MAAQ,EAAA;AAAA,GACV;AAAA,EACA,KAAA,CAAM,SAAS,IAAM,EAAA;AACnB,IAAM,MAAA,MAAA,GAAS,UAAU,WAAW,CAAA;AACpC,IAAA,MAAM,EAAE,OAAA,EAAY,GAAA,cAAA,CAAe,YAAY,GAAG,CAAA;AAGlD,IAAA,IAAI,CAAC,IAAK,CAAA,OAAA,CAAQ,OAAQ,CAAA,QAAA,CAAS,cAAc,CAAG,EAAA;AAClD,MAAO,MAAA,CAAA,KAAA,CAAM,CAAK,EAAA,EAAA,WAAW,CAA0D,wDAAA,CAAA,CAAA;AACvF,MAAA;AAAA;AAGF,IAAK,IAAA,CAAA,OAAA,CAAQ,IAAK,CAAA,YAAA,KAAiB,EAAC;AACpC,IAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,CAAK,YAAa,CAAA,OAAA,KAAY,EAAC;AAC5C,IAAA,IAAA,CAAK,QAAQ,IAAK,CAAA,YAAA,CAAa,QAAQ,IAAK,CAAA,CAAA,EAAG,WAAW,CAAS,OAAA,CAAA,CAAA;AAEnE,IAAA,IAAA,CAAK,OAAQ,CAAA,KAAA,CAAM,KAAK,CAAA,GAAI,QAAQ,WAAW,CAAA;AAE/C,IAAiB,gBAAA,CAAA;AAAA,MACf,IAAA,EAAM,QAAQ,sBAAsB,CAAA;AAAA,MACpC,QAAQ,OAAQ,CAAA,MAAA;AAAA,MAChB,UAAY,EAAA;AAAA,KACb,CAAA;AAED,IAAc,aAAA,CAAA,OAAA,CAAQ,uBAAuB,CAAC,CAAA;AAAA;AAElD,CAAC,CAAA;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { UserConfig } from '@unocss/core'
|
|
2
3
|
import type { ConfigProviderProps, TooltipProviderProps } from 'reka-ui'
|
|
3
|
-
import type { UserConfig } from 'unocss'
|
|
4
4
|
import type { ThemeExtension, ToasterProps } from '../types'
|
|
5
5
|
|
|
6
6
|
export interface AppProps extends Omit<ConfigProviderProps, 'useId' | 'dir' | 'locale'> {
|
|
@@ -28,6 +28,7 @@ export interface ButtonProps extends Omit<ComponentAttrs<typeof button>, 'ui'>,
|
|
|
28
28
|
|
|
29
29
|
<script lang="ts" setup>
|
|
30
30
|
import { computed } from 'vue'
|
|
31
|
+
import { useButtonGroup } from '../composables/useButtonGroup'
|
|
31
32
|
import { useComponentIcons } from '../composables/useComponentIcons'
|
|
32
33
|
import { useTheme } from '../composables/useTheme'
|
|
33
34
|
import { omit, pickLinkProps } from '../utils'
|
|
@@ -35,11 +36,11 @@ import Link from './Link.vue'
|
|
|
35
36
|
|
|
36
37
|
const props = withDefaults(defineProps<ButtonProps>(), {
|
|
37
38
|
variant: 'solid',
|
|
38
|
-
size: 'md',
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
const slots = defineSlots<ButtonSlots>()
|
|
42
42
|
|
|
43
|
+
const { size, orientation } = useButtonGroup(props)
|
|
43
44
|
const { isPrefix, isSuffix, prefixIconName, suffixIconName } = useComponentIcons(
|
|
44
45
|
computed(() => ({ ...props, loading: props.loading })),
|
|
45
46
|
)
|
|
@@ -52,6 +53,8 @@ const style = computed(() => {
|
|
|
52
53
|
const styler = createStyler(theme.value.button)
|
|
53
54
|
return styler({
|
|
54
55
|
...props,
|
|
56
|
+
size: size.value,
|
|
57
|
+
groupOrientation: orientation.value,
|
|
55
58
|
prefix: isPrefix.value,
|
|
56
59
|
suffix: isSuffix.value,
|
|
57
60
|
class: [
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
+
import type { PrimitiveProps } from 'reka-ui'
|
|
4
|
+
import type { buttonGroup } from '../theme'
|
|
5
|
+
import type { ComponentAttrs } from '../types'
|
|
6
|
+
|
|
7
|
+
type ButtonGroupVariant = VariantProps<typeof buttonGroup>
|
|
8
|
+
|
|
9
|
+
export interface ButtonGroupProps extends Omit<ComponentAttrs<typeof buttonGroup>, 'ui'>, Pick<PrimitiveProps, 'as'> {
|
|
10
|
+
size?: ButtonGroupVariant['size']
|
|
11
|
+
orientation?: ButtonGroupVariant['orientation']
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ButtonGroupSlots {
|
|
15
|
+
default?: (props?: any) => any
|
|
16
|
+
}
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<script setup lang="ts">
|
|
20
|
+
import { Primitive } from 'reka-ui'
|
|
21
|
+
import { computed } from 'vue'
|
|
22
|
+
import { provideButtonGroup } from '../composables/useButtonGroup'
|
|
23
|
+
import { useTheme } from '../composables/useTheme'
|
|
24
|
+
|
|
25
|
+
const props = withDefaults(defineProps<ButtonGroupProps>(), {
|
|
26
|
+
orientation: 'horizontal',
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
defineSlots<ButtonGroupSlots>()
|
|
30
|
+
|
|
31
|
+
provideButtonGroup(computed(() => ({
|
|
32
|
+
size: props.size,
|
|
33
|
+
orientation: props.orientation,
|
|
34
|
+
})))
|
|
35
|
+
|
|
36
|
+
const { theme, createStyler } = useTheme()
|
|
37
|
+
const style = computed(() => {
|
|
38
|
+
const styler = createStyler(theme.value.buttonGroup)
|
|
39
|
+
return styler(props)
|
|
40
|
+
})
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<template>
|
|
44
|
+
<Primitive :as="props.as" :class="style">
|
|
45
|
+
<slot></slot>
|
|
46
|
+
</Primitive>
|
|
47
|
+
</template>
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
+
import type { EmblaCarouselType, EmblaOptionsType, EmblaPluginType } from 'embla-carousel'
|
|
4
|
+
import type { AutoHeightOptionsType } from 'embla-carousel-auto-height'
|
|
5
|
+
import type { AutoScrollOptionsType } from 'embla-carousel-auto-scroll'
|
|
6
|
+
import type { AutoplayOptionsType } from 'embla-carousel-autoplay'
|
|
7
|
+
import type { ClassNamesOptionsType } from 'embla-carousel-class-names'
|
|
8
|
+
import type { FadeOptionsType } from 'embla-carousel-fade'
|
|
9
|
+
import type { WheelGesturesPluginOptions } from 'embla-carousel-wheel-gestures'
|
|
10
|
+
import type { AcceptableValue, PrimitiveProps } from 'reka-ui'
|
|
11
|
+
import type { carousel } from '../theme'
|
|
12
|
+
import type { ButtonProps, ComponentAttrs } from '../types'
|
|
13
|
+
|
|
14
|
+
type CarouselVariants = VariantProps<typeof carousel>
|
|
15
|
+
|
|
16
|
+
export interface CarouselProps<T> extends ComponentAttrs<typeof carousel>, Pick<PrimitiveProps, 'as'>, Omit<EmblaOptionsType, 'axis' | 'container' | 'slides' | 'direction'> {
|
|
17
|
+
/**
|
|
18
|
+
* Configure the prev button when arrows are enabled.
|
|
19
|
+
* @default { size: 'md', variant: 'link' }
|
|
20
|
+
*/
|
|
21
|
+
prev?: ButtonProps
|
|
22
|
+
/**
|
|
23
|
+
* The icon displayed in the prev button.
|
|
24
|
+
* @default `app.icons.arrowLeft`
|
|
25
|
+
*/
|
|
26
|
+
prevIcon?: string
|
|
27
|
+
/**
|
|
28
|
+
* Configure the next button when arrows are enabled.
|
|
29
|
+
* @default { size: 'md', variant: 'link' }
|
|
30
|
+
*/
|
|
31
|
+
next?: ButtonProps
|
|
32
|
+
/**
|
|
33
|
+
* The icon displayed in the next button.
|
|
34
|
+
* @default `app.icons.arrowRight`
|
|
35
|
+
*/
|
|
36
|
+
nextIcon?: string
|
|
37
|
+
/**
|
|
38
|
+
* Display prev and next buttons to scroll the carousel.
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
arrows?: boolean
|
|
42
|
+
/**
|
|
43
|
+
* Display dots to scroll to a specific slide.
|
|
44
|
+
* @default false
|
|
45
|
+
*/
|
|
46
|
+
dots?: boolean
|
|
47
|
+
orientation?: CarouselVariants['orientation']
|
|
48
|
+
items?: T[]
|
|
49
|
+
dir?: 'rtl' | 'ltr'
|
|
50
|
+
/**
|
|
51
|
+
* Enable Autoplay plugin
|
|
52
|
+
* @link https://www.embla-carousel.com/plugins/autoplay/
|
|
53
|
+
*/
|
|
54
|
+
autoplay?: boolean | AutoplayOptionsType
|
|
55
|
+
/**
|
|
56
|
+
* Enable Auto Scroll plugin
|
|
57
|
+
* @link https://www.embla-carousel.com/plugins/auto-scroll/
|
|
58
|
+
*/
|
|
59
|
+
autoScroll?: boolean | AutoScrollOptionsType
|
|
60
|
+
/**
|
|
61
|
+
* Enable Auto Height plugin
|
|
62
|
+
* @link https://www.embla-carousel.com/plugins/auto-height/
|
|
63
|
+
*/
|
|
64
|
+
autoHeight?: boolean | AutoHeightOptionsType
|
|
65
|
+
/**
|
|
66
|
+
* Enable Class Names plugin
|
|
67
|
+
* @link https://www.embla-carousel.com/plugins/class-names/
|
|
68
|
+
*/
|
|
69
|
+
classNames?: boolean | ClassNamesOptionsType
|
|
70
|
+
/**
|
|
71
|
+
* Enable Fade plugin
|
|
72
|
+
* @link https://www.embla-carousel.com/plugins/fade/
|
|
73
|
+
*/
|
|
74
|
+
fade?: boolean | FadeOptionsType
|
|
75
|
+
/**
|
|
76
|
+
* Enable Wheel Gestures plugin
|
|
77
|
+
* @link https://www.embla-carousel.com/plugins/wheel-gestures/
|
|
78
|
+
*/
|
|
79
|
+
wheelGestures?: boolean | WheelGesturesPluginOptions
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface CarouselSlots<T> {
|
|
83
|
+
default?: (props: { item: T, index: number }) => any
|
|
84
|
+
}
|
|
85
|
+
</script>
|
|
86
|
+
|
|
87
|
+
<script setup lang="ts" generic="T extends AcceptableValue">
|
|
88
|
+
import { computedAsync, reactivePick } from '@vueuse/core'
|
|
89
|
+
import useEmblaCarousel from 'embla-carousel-vue'
|
|
90
|
+
import { Primitive, useForwardProps } from 'reka-ui'
|
|
91
|
+
import { computed, onMounted, ref, watch } from 'vue'
|
|
92
|
+
import { useTheme } from '../composables/useTheme'
|
|
93
|
+
import Button from './Button.vue'
|
|
94
|
+
|
|
95
|
+
const props = withDefaults(defineProps<CarouselProps<T>>(), {
|
|
96
|
+
orientation: 'horizontal',
|
|
97
|
+
arrows: false,
|
|
98
|
+
dots: false,
|
|
99
|
+
|
|
100
|
+
dir: 'ltr',
|
|
101
|
+
|
|
102
|
+
// Embla Options
|
|
103
|
+
active: true,
|
|
104
|
+
align: 'center',
|
|
105
|
+
breakpoints: () => ({}),
|
|
106
|
+
containScroll: 'trimSnaps',
|
|
107
|
+
dragFree: false,
|
|
108
|
+
dragThreshold: 10,
|
|
109
|
+
duration: 25,
|
|
110
|
+
inViewThreshold: 0,
|
|
111
|
+
loop: false,
|
|
112
|
+
skipSnaps: false,
|
|
113
|
+
slidesToScroll: 1,
|
|
114
|
+
startIndex: 0,
|
|
115
|
+
watchDrag: true,
|
|
116
|
+
watchResize: true,
|
|
117
|
+
watchSlides: true,
|
|
118
|
+
watchFocus: true,
|
|
119
|
+
|
|
120
|
+
// Embla Plugins
|
|
121
|
+
autoplay: false,
|
|
122
|
+
autoScroll: false,
|
|
123
|
+
autoHeight: false,
|
|
124
|
+
classNames: false,
|
|
125
|
+
fade: false,
|
|
126
|
+
wheelGestures: false,
|
|
127
|
+
})
|
|
128
|
+
defineSlots<CarouselSlots<T>>()
|
|
129
|
+
|
|
130
|
+
const rootProps = useForwardProps(reactivePick(props, 'active', 'align', 'breakpoints', 'containScroll', 'dragFree', 'dragThreshold', 'duration', 'inViewThreshold', 'loop', 'skipSnaps', 'slidesToScroll', 'startIndex', 'watchDrag', 'watchResize', 'watchSlides', 'watchFocus'))
|
|
131
|
+
|
|
132
|
+
const { theme, createStyler } = useTheme()
|
|
133
|
+
const style = computed(() => {
|
|
134
|
+
const styler = createStyler(theme.value.carousel)
|
|
135
|
+
return styler(props)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
const prevIcon = computed(() => props.prevIcon || (props.dir === 'rtl' ? theme.value.app.icons.arrowRight : theme.value.app.icons.arrowLeft))
|
|
139
|
+
const nextIcon = computed(() => props.nextIcon || (props.dir === 'rtl' ? theme.value.app.icons.arrowLeft : theme.value.app.icons.arrowRight))
|
|
140
|
+
|
|
141
|
+
const options = computed<EmblaOptionsType>(() => ({
|
|
142
|
+
...(props.fade ? { align: 'center', containScroll: false } : {}),
|
|
143
|
+
...rootProps.value,
|
|
144
|
+
axis: props.orientation === 'horizontal' ? 'x' : 'y',
|
|
145
|
+
direction: props.dir === 'rtl' ? 'rtl' : 'ltr',
|
|
146
|
+
}))
|
|
147
|
+
|
|
148
|
+
const plugins = computedAsync<EmblaPluginType[]>(async () => {
|
|
149
|
+
const plugins: EmblaPluginType[] = []
|
|
150
|
+
|
|
151
|
+
if (props.autoplay) {
|
|
152
|
+
const AutoplayPlugin = await import('embla-carousel-autoplay').then((r) => r.default)
|
|
153
|
+
plugins.push(AutoplayPlugin(typeof props.autoplay === 'boolean' ? {} : props.autoplay))
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (props.autoScroll) {
|
|
157
|
+
const AutoScrollPlugin = await import('embla-carousel-auto-scroll').then((r) => r.default)
|
|
158
|
+
plugins.push(AutoScrollPlugin(typeof props.autoScroll === 'boolean' ? {} : props.autoScroll))
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (props.autoHeight) {
|
|
162
|
+
const AutoHeightPlugin = await import('embla-carousel-auto-height').then((r) => r.default)
|
|
163
|
+
plugins.push(AutoHeightPlugin(typeof props.autoHeight === 'boolean' ? {} : props.autoHeight))
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (props.classNames) {
|
|
167
|
+
const ClassNamesPlugin = await import('embla-carousel-class-names').then((r) => r.default)
|
|
168
|
+
plugins.push(ClassNamesPlugin(typeof props.classNames === 'boolean' ? {} : props.classNames))
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (props.fade) {
|
|
172
|
+
const FadePlugin = await import('embla-carousel-fade').then((r) => r.default)
|
|
173
|
+
plugins.push(FadePlugin(typeof props.fade === 'boolean' ? {} : props.fade))
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (props.wheelGestures) {
|
|
177
|
+
const { WheelGesturesPlugin } = await import('embla-carousel-wheel-gestures')
|
|
178
|
+
plugins.push(WheelGesturesPlugin(typeof props.wheelGestures === 'boolean' ? {} : props.wheelGestures))
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return plugins
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
const [emblaRef, emblaApi] = useEmblaCarousel(options.value, plugins.value)
|
|
185
|
+
|
|
186
|
+
watch([options, plugins], () => {
|
|
187
|
+
emblaApi.value?.reInit(options.value, plugins.value)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
function scrollPrev() {
|
|
191
|
+
emblaApi.value?.scrollPrev()
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function scrollNext() {
|
|
195
|
+
emblaApi.value?.scrollNext()
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function scrollTo(index: number) {
|
|
199
|
+
emblaApi.value?.scrollTo(index)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
203
|
+
const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft'
|
|
204
|
+
const nextKey = props.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight'
|
|
205
|
+
|
|
206
|
+
if (event.key === prevKey) {
|
|
207
|
+
event.preventDefault()
|
|
208
|
+
scrollPrev()
|
|
209
|
+
|
|
210
|
+
return
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (event.key === nextKey) {
|
|
214
|
+
event.preventDefault()
|
|
215
|
+
scrollNext()
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const canScrollNext = ref(false)
|
|
220
|
+
const canScrollPrev = ref(false)
|
|
221
|
+
const selectedIndex = ref<number>(0)
|
|
222
|
+
const scrollSnaps = ref<number[]>([])
|
|
223
|
+
|
|
224
|
+
function onInit(api: EmblaCarouselType) {
|
|
225
|
+
scrollSnaps.value = api?.scrollSnapList() || []
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function onSelect(api: EmblaCarouselType) {
|
|
229
|
+
canScrollNext.value = api?.canScrollNext() || false
|
|
230
|
+
canScrollPrev.value = api?.canScrollPrev() || false
|
|
231
|
+
selectedIndex.value = api?.selectedScrollSnap() || 0
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
onMounted(() => {
|
|
235
|
+
if (!emblaApi.value)
|
|
236
|
+
return
|
|
237
|
+
|
|
238
|
+
emblaApi.value?.on('init', onInit)
|
|
239
|
+
emblaApi.value?.on('init', onSelect)
|
|
240
|
+
emblaApi.value?.on('reInit', onInit)
|
|
241
|
+
emblaApi.value?.on('reInit', onSelect)
|
|
242
|
+
emblaApi.value?.on('select', onSelect)
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
defineExpose({
|
|
246
|
+
emblaRef,
|
|
247
|
+
emblaApi,
|
|
248
|
+
})
|
|
249
|
+
</script>
|
|
250
|
+
|
|
251
|
+
<template>
|
|
252
|
+
<Primitive
|
|
253
|
+
:as="props.as"
|
|
254
|
+
role="region"
|
|
255
|
+
aria-roledescription="carousel"
|
|
256
|
+
tabindex="0"
|
|
257
|
+
:dir="props.dir"
|
|
258
|
+
:class="style.root({ class: [props.class, props.ui?.root] })"
|
|
259
|
+
@keydown="onKeyDown"
|
|
260
|
+
>
|
|
261
|
+
<div ref="emblaRef" :class="style.viewport({ class: props.ui?.viewport })">
|
|
262
|
+
<div :class="style.container({ class: props.ui?.container })">
|
|
263
|
+
<div
|
|
264
|
+
v-for="(item, index) in props.items"
|
|
265
|
+
:key="index"
|
|
266
|
+
role="group"
|
|
267
|
+
aria-roledescription="slide"
|
|
268
|
+
:class="style.item({ class: props.ui?.item })"
|
|
269
|
+
>
|
|
270
|
+
<slot :item="item" :index="index"></slot>
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
|
|
275
|
+
<div v-if="props.arrows || props.dots" :class="style.controls({ class: props.ui?.controls })">
|
|
276
|
+
<div v-if="props.arrows" :class="style.arrows({ class: props.ui?.arrows })">
|
|
277
|
+
<Button
|
|
278
|
+
:disabled="!canScrollPrev"
|
|
279
|
+
:icon="prevIcon"
|
|
280
|
+
size="md"
|
|
281
|
+
variant="outline"
|
|
282
|
+
aria-label="prev"
|
|
283
|
+
v-bind="typeof props.prev === 'object' ? props.prev : undefined"
|
|
284
|
+
:class="style.prev({ class: props.ui?.prev })"
|
|
285
|
+
@click="scrollPrev"
|
|
286
|
+
/>
|
|
287
|
+
<Button
|
|
288
|
+
:disabled="!canScrollNext"
|
|
289
|
+
:icon="nextIcon"
|
|
290
|
+
size="md"
|
|
291
|
+
variant="outline"
|
|
292
|
+
aria-label="next"
|
|
293
|
+
v-bind="typeof props.next === 'object' ? props.next : undefined"
|
|
294
|
+
:class="style.next({ class: props.ui?.next })"
|
|
295
|
+
@click="scrollNext"
|
|
296
|
+
/>
|
|
297
|
+
</div>
|
|
298
|
+
|
|
299
|
+
<div v-if="props.dots" :class="style.dots({ class: props.ui?.dots })">
|
|
300
|
+
<template v-for="(_, index) in scrollSnaps" :key="index">
|
|
301
|
+
<button
|
|
302
|
+
:aria-label="`Go to ${index + 1}`"
|
|
303
|
+
:class="style.dot({ class: props.ui?.dot, active: selectedIndex === index })"
|
|
304
|
+
@click="scrollTo(index)"
|
|
305
|
+
></button>
|
|
306
|
+
</template>
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
</Primitive>
|
|
310
|
+
</template>
|
|
@@ -23,22 +23,27 @@ export interface ChipSlots {
|
|
|
23
23
|
<script setup lang="ts">
|
|
24
24
|
import { Primitive } from 'reka-ui'
|
|
25
25
|
import { computed } from 'vue'
|
|
26
|
+
import { useButtonGroup } from '../composables/useButtonGroup'
|
|
26
27
|
import { useComponentIcons } from '../composables/useComponentIcons'
|
|
27
28
|
import { useTheme } from '../composables/useTheme'
|
|
28
29
|
|
|
29
30
|
const props = withDefaults(defineProps<ChipProps>(), {
|
|
30
31
|
variant: 'solid',
|
|
31
|
-
size: 'md',
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
const slots = defineSlots<ChipSlots>()
|
|
35
35
|
|
|
36
|
+
const { size, orientation } = useButtonGroup(props)
|
|
36
37
|
const { isPrefix, prefixIconName, isSuffix, suffixIconName } = useComponentIcons(props)
|
|
37
38
|
|
|
38
39
|
const { theme, createStyler } = useTheme()
|
|
39
40
|
const style = computed(() => {
|
|
40
41
|
const styler = createStyler(theme.value.chip)
|
|
41
|
-
return styler(
|
|
42
|
+
return styler({
|
|
43
|
+
...props,
|
|
44
|
+
size: size.value,
|
|
45
|
+
groupOrientation: orientation.value,
|
|
46
|
+
})
|
|
42
47
|
})
|
|
43
48
|
</script>
|
|
44
49
|
|
|
@@ -46,6 +46,7 @@ export interface InputSlots {
|
|
|
46
46
|
<script setup lang="ts">
|
|
47
47
|
import { Primitive } from 'reka-ui'
|
|
48
48
|
import { computed, onMounted, ref } from 'vue'
|
|
49
|
+
import { useButtonGroup } from '../composables/useButtonGroup'
|
|
49
50
|
import { useComponentIcons } from '../composables/useComponentIcons'
|
|
50
51
|
import { useTheme } from '../composables/useTheme'
|
|
51
52
|
import { looseToNumber } from '../utils'
|
|
@@ -56,7 +57,6 @@ defineOptions({
|
|
|
56
57
|
|
|
57
58
|
const props = withDefaults(defineProps<InputProps>(), {
|
|
58
59
|
type: 'text',
|
|
59
|
-
size: 'md',
|
|
60
60
|
variant: 'outline',
|
|
61
61
|
autocomplete: 'off',
|
|
62
62
|
autofocusDelay: 0,
|
|
@@ -68,14 +68,18 @@ const [modelValue, modelModifiers] = defineModel<string | number>()
|
|
|
68
68
|
|
|
69
69
|
const inputRef = ref<HTMLInputElement | null>(null)
|
|
70
70
|
|
|
71
|
+
const { size, orientation } = useButtonGroup(props)
|
|
71
72
|
const { isPrefix, prefixIconName, isSuffix, suffixIconName } = useComponentIcons(props)
|
|
72
73
|
|
|
73
74
|
const { theme, createStyler } = useTheme()
|
|
74
75
|
const style = computed(() => {
|
|
75
76
|
const styler = createStyler(theme.value.input)
|
|
76
|
-
// @ts-expect-error ignore type
|
|
77
77
|
return styler({
|
|
78
78
|
...props,
|
|
79
|
+
// @ts-expect-error ignore type
|
|
80
|
+
type: props.type,
|
|
81
|
+
size: size.value,
|
|
82
|
+
groupOrientation: orientation.value,
|
|
79
83
|
prefix: isPrefix.value || !!slots.prefix,
|
|
80
84
|
suffix: isSuffix.value || !!slots.suffix,
|
|
81
85
|
})
|
|
@@ -131,7 +135,7 @@ onMounted(() => {
|
|
|
131
135
|
<template>
|
|
132
136
|
<Primitive
|
|
133
137
|
:as="as"
|
|
134
|
-
:class="style.
|
|
138
|
+
:class="style.base({ class: [props.class, props.ui?.base] })"
|
|
135
139
|
:aria-disabled="props.disabled ? true : undefined"
|
|
136
140
|
>
|
|
137
141
|
<span v-if="isPrefix || slots.prefix" :class="style.prefix({ class: props.ui?.prefix })">
|
|
@@ -150,7 +154,7 @@ onMounted(() => {
|
|
|
150
154
|
:value="modelValue"
|
|
151
155
|
:name="props.name"
|
|
152
156
|
:placeholder="props.placeholder"
|
|
153
|
-
:class="style.
|
|
157
|
+
:class="style.input({ class: props.ui?.input })"
|
|
154
158
|
:disabled="props.disabled"
|
|
155
159
|
:required="props.required"
|
|
156
160
|
:autocomplete="props.autocomplete"
|
|
@@ -47,11 +47,10 @@ import { reactivePick } from '@vueuse/core'
|
|
|
47
47
|
import { DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogRoot, DialogTitle, DialogTrigger, useForwardPropsEmits } from 'reka-ui'
|
|
48
48
|
import { computed, toRef } from 'vue'
|
|
49
49
|
import { useTheme } from '../composables/useTheme'
|
|
50
|
-
import
|
|
50
|
+
import Button from './Button.vue'
|
|
51
51
|
|
|
52
52
|
const props = withDefaults(defineProps<ModalProps>(), {
|
|
53
53
|
modal: true,
|
|
54
|
-
size: 'md',
|
|
55
54
|
portal: true,
|
|
56
55
|
overlay: true,
|
|
57
56
|
transition: true,
|
|
@@ -110,7 +109,7 @@ const style = computed(() => {
|
|
|
110
109
|
|
|
111
110
|
<DialogClose as-child>
|
|
112
111
|
<slot name="close">
|
|
113
|
-
<
|
|
112
|
+
<Button
|
|
114
113
|
v-if="props.close"
|
|
115
114
|
variant="ghost"
|
|
116
115
|
:icon="props.closeIcon || theme.app.icons.close"
|