@una-ui/nuxt 0.15.1-beta.2 → 0.16.1-beta.1

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 (37) hide show
  1. package/dist/module.d.mts +2 -5
  2. package/dist/module.d.ts +2 -5
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +11 -2
  5. package/dist/runtime/components/data/table/Table.vue +4 -4
  6. package/dist/runtime/components/elements/Label.vue +28 -0
  7. package/dist/runtime/components/elements/popover/Popover.vue +16 -0
  8. package/dist/runtime/components/elements/popover/PopoverContent.vue +48 -0
  9. package/dist/runtime/components/forms/Checkbox.vue +49 -60
  10. package/dist/runtime/components/forms/FormGroup.vue +21 -21
  11. package/dist/runtime/components/misc/ThemeSwitcher.vue +159 -73
  12. package/dist/runtime/composables/useUnaSettings.d.ts +6 -1
  13. package/dist/runtime/composables/useUnaSettings.js +9 -1
  14. package/dist/runtime/constants.d.ts +1 -0
  15. package/dist/runtime/constants.js +1 -0
  16. package/dist/runtime/plugins/theme.client.js +11 -7
  17. package/dist/runtime/plugins/theme.server.js +7 -5
  18. package/dist/runtime/types/checkbox.d.ts +24 -20
  19. package/dist/runtime/types/form-group.d.ts +2 -12
  20. package/dist/runtime/types/index.d.ts +3 -0
  21. package/dist/runtime/types/index.js +2 -0
  22. package/dist/runtime/types/label.d.ts +8 -0
  23. package/dist/runtime/types/label.js +0 -0
  24. package/dist/runtime/types/popover.d.ts +10 -0
  25. package/dist/runtime/types/popover.js +0 -0
  26. package/package.json +3 -3
  27. package/playground/.nuxt/components.d.ts +116 -116
  28. package/playground/.nuxt/imports.d.ts +4 -5
  29. package/playground/.nuxt/nuxt.d.ts +1 -1
  30. package/playground/.nuxt/types/app.config.d.ts +3 -1
  31. package/playground/.nuxt/types/imports.d.ts +768 -764
  32. package/playground/.nuxt/types/nitro-imports.d.ts +22 -22
  33. package/playground/.nuxt/types/nitro-routes.d.ts +1 -1
  34. package/playground/.nuxt/types/plugins.d.ts +13 -13
  35. package/playground/.nuxt/types/schema.d.ts +132 -2
  36. package/dist/runtime/components/slots/FormGroupLabel.d.ts +0 -24
  37. package/dist/runtime/components/slots/FormGroupLabel.js +0 -29
package/dist/module.d.mts CHANGED
@@ -1,12 +1,9 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
+ import { UnaSettings } from '../dist/runtime/types/index.js';
2
3
 
3
- interface UnaOptions {
4
- primary?: string;
5
- gray?: string;
6
- }
7
4
  declare module '@nuxt/schema' {
8
5
  interface AppConfigInput {
9
- una?: UnaOptions;
6
+ una?: UnaSettings;
10
7
  }
11
8
  }
12
9
  interface ModuleOptions {
package/dist/module.d.ts CHANGED
@@ -1,12 +1,9 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
+ import { UnaSettings } from '../dist/runtime/types/index.js';
2
3
 
3
- interface UnaOptions {
4
- primary?: string;
5
- gray?: string;
6
- }
7
4
  declare module '@nuxt/schema' {
8
5
  interface AppConfigInput {
9
- una?: UnaOptions;
6
+ una?: UnaSettings;
10
7
  }
11
8
  }
12
9
  interface ModuleOptions {
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@una-ui/nuxt",
3
3
  "configKey": "una",
4
- "version": "0.15.1-beta.2",
4
+ "version": "0.16.1-beta.1",
5
5
  "compatibility": {
6
6
  "nuxt": ">=3.0.0"
7
7
  },
package/dist/module.mjs CHANGED
@@ -7,7 +7,7 @@ import '@una-ui/preset/prefixes';
7
7
  import '@una-ui/extractor-vue-script';
8
8
 
9
9
  const name = "@una-ui/nuxt";
10
- const version = "0.15.1-beta.2";
10
+ const version = "0.16.1-beta.1";
11
11
 
12
12
  const module = defineNuxtModule({
13
13
  meta: {
@@ -29,7 +29,9 @@ const module = defineNuxtModule({
29
29
  nuxt.options.css.unshift("@una-ui/preset/una.css");
30
30
  nuxt.options.appConfig.una = {
31
31
  primary: "yellow",
32
- gray: "stone"
32
+ gray: "stone",
33
+ radius: 0.5,
34
+ fontSize: 16
33
35
  };
34
36
  const runtimeDir = resolve("./runtime");
35
37
  nuxt.options.build.transpile.push(runtimeDir);
@@ -62,6 +64,13 @@ const module = defineNuxtModule({
62
64
  watch: nuxt.options.dev,
63
65
  priority: 10
64
66
  });
67
+ addComponentsDir({
68
+ path: resolve(runtimeDir, "components/elements", "popover"),
69
+ prefix: options.prefix,
70
+ global: options.global,
71
+ watch: nuxt.options.dev,
72
+ priority: 10
73
+ });
65
74
  addComponentsDir({
66
75
  path: resolve(runtimeDir, "components", "forms"),
67
76
  prefix: options.prefix,
@@ -73,8 +73,8 @@ const columnsWithMisc = computed(() => {
73
73
  accessorKey: 'selection',
74
74
  header: props.enableMultiRowSelection
75
75
  ? ({ table }: any) => h(Checkbox, {
76
- 'modelValue': table.getIsAllPageRowsSelected() ?? false,
77
- 'onUpdate:modelValue': (value: boolean) => {
76
+ 'checked': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
77
+ 'onUpdate:checked': (value: boolean) => {
78
78
  table.toggleAllPageRowsSelected(!!value)
79
79
  emit('selectAll', table.getRowModel().rows)
80
80
  },
@@ -82,8 +82,8 @@ const columnsWithMisc = computed(() => {
82
82
  })
83
83
  : '',
84
84
  cell: ({ row }: any) => h(Checkbox, {
85
- 'modelValue': row.getIsSelected() ?? false,
86
- 'onUpdate:modelValue': (value: boolean) => {
85
+ 'checked': row.getIsSelected() ?? false,
86
+ 'onUpdate:checked': (value: boolean) => {
87
87
  row.toggleSelected(!!value)
88
88
  emit('select', row)
89
89
  },
@@ -0,0 +1,28 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { Label } from 'radix-vue'
4
+ import { cn } from '../../utils'
5
+ import type { NLabelProps } from '../../types'
6
+
7
+ const props = defineProps<NLabelProps>()
8
+
9
+ const delegatedProps = computed(() => {
10
+ const { class: _, ...delegated } = props
11
+
12
+ return delegated
13
+ })
14
+ </script>
15
+
16
+ <template>
17
+ <Label
18
+ v-bind="delegatedProps"
19
+ :class="
20
+ cn(
21
+ 'label-base',
22
+ props.class,
23
+ )
24
+ "
25
+ >
26
+ <slot />
27
+ </Label>
28
+ </template>
@@ -0,0 +1,16 @@
1
+ <script setup lang="ts">
2
+ import { PopoverRoot, useForwardPropsEmits } from 'radix-vue'
3
+ import type { PopoverRootEmits } from 'radix-vue'
4
+ import type { NPopoverProps } from '../../../types'
5
+
6
+ const props = defineProps<NPopoverProps>()
7
+ const emits = defineEmits<PopoverRootEmits>()
8
+
9
+ const forwarded = useForwardPropsEmits(props, emits)
10
+ </script>
11
+
12
+ <template>
13
+ <PopoverRoot v-bind="forwarded">
14
+ <slot />
15
+ </PopoverRoot>
16
+ </template>
@@ -0,0 +1,48 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import {
4
+ PopoverContent,
5
+ type PopoverContentEmits,
6
+ PopoverPortal,
7
+ useForwardPropsEmits,
8
+ } from 'radix-vue'
9
+ import { cn } from '../../../utils'
10
+ import type { NPopoverContentProps } from '../../../types'
11
+
12
+ defineOptions({
13
+ inheritAttrs: false,
14
+ })
15
+
16
+ const props = withDefaults(
17
+ defineProps<NPopoverContentProps>(),
18
+ {
19
+ align: 'center',
20
+ sideOffset: 4,
21
+ },
22
+ )
23
+ const emits = defineEmits<PopoverContentEmits>()
24
+
25
+ const delegatedProps = computed(() => {
26
+ const { class: _, ...delegated } = props
27
+
28
+ return delegated
29
+ })
30
+
31
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
32
+ </script>
33
+
34
+ <template>
35
+ <PopoverPortal>
36
+ <PopoverContent
37
+ v-bind="{ ...forwarded, ...$attrs }"
38
+ :class="
39
+ cn(
40
+ 'popover',
41
+ props.class,
42
+ )
43
+ "
44
+ >
45
+ <slot />
46
+ </PopoverContent>
47
+ </PopoverPortal>
48
+ </template>
@@ -1,86 +1,75 @@
1
1
  <script setup lang="ts">
2
- import { computed, watch } from 'vue'
3
- import { useVModel } from '@vueuse/core'
4
- import NIcon from '../elements/Icon.vue'
5
- import { randomId } from '../../utils'
6
- import type { NCheckboxProps } from '../../types/checkbox'
2
+ import { computed } from 'vue'
3
+ import type { CheckboxRootEmits } from 'radix-vue'
4
+ import { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'radix-vue'
5
+ import { cn, randomId } from '../../utils'
6
+ import Icon from '../elements/Icon.vue'
7
+ import type { NCheckboxProps } from '../../types'
8
+ import Label from '../elements/Label.vue'
7
9
 
8
- defineOptions({
9
- inheritAttrs: false,
10
+ const props = withDefaults(defineProps<NCheckboxProps>(), {
11
+ forceMount: true,
10
12
  })
13
+ const emits = defineEmits<CheckboxRootEmits>()
11
14
 
12
- const props = withDefaults(
13
- defineProps<NCheckboxProps>(),
14
- {
15
- modelValue: false,
16
- disabled: false,
17
- },
18
- )
15
+ const delegatedProps = computed(() => {
16
+ const { class: _, ...delegated } = props
19
17
 
20
- const emit = defineEmits<{ (...args: any): void }>()
18
+ return delegated
19
+ })
21
20
 
22
- const slots = defineSlots<{
23
- default?: void
24
- icon?: any
25
- }>()
21
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
26
22
 
27
23
  const id = computed(() => props.id ?? randomId('checkbox'))
28
- const checked = useVModel(props, 'modelValue', emit, { passive: true })
29
-
30
- watch(checked, (value) => {
31
- emit('onUpdate', value)
32
- })
33
24
  </script>
34
25
 
35
26
  <template>
36
- <label
27
+ <div
37
28
  checkbox="wrapper"
38
- role="checkbox"
39
- :for="props.for ?? id"
40
29
  :class="[
41
30
  una?.checkboxWrapper,
42
31
  {
43
32
  'checkbox-reverse': reverse,
44
- 'checkbox-disabled': disabled,
45
33
  },
46
34
  ]"
47
- :checked="checked || null"
48
- :disabled="disabled || null"
49
35
  >
50
- <input
36
+ <CheckboxRoot
37
+ v-bind="forwarded"
51
38
  :id="id"
52
- :value="checked"
53
- :checked="!!checked"
54
- type="checkbox"
55
- class="peer"
56
- checkbox="input"
57
- :disabled="disabled"
58
- :name="name"
59
- @keypress.enter="checked = !checked"
60
- @click="checked = !checked"
39
+ :class="
40
+ cn(
41
+ 'peer checkbox',
42
+ props.class,
43
+ )"
61
44
  >
62
- <span
63
- :checkbox="checkbox"
64
- :size="size"
65
- class="checkbox checkbox-peer-focus"
66
- v-bind="$attrs"
67
- >
68
- <slot name="icon">
69
- <NIcon
70
- checkbox="icon-base icon-checked"
71
- :name="una?.checkboxIcon ?? 'checkbox-icon'"
72
- :class="una?.checkboxIconBase"
73
- />
74
- </slot>
75
- </span>
76
- <div
77
- v-if="slots.default || label"
78
- checkbox="label"
79
- :class="una?.checkboxLabel"
45
+ <CheckboxIndicator
46
+ :force-mount
47
+ :size
48
+ :class="cn('checkbox-indicator', una?.checkboxIndicator)"
49
+ v-bind="props._checkboxIndicator"
50
+ >
51
+ <slot name="icon">
52
+ <Icon
53
+ :name="props.checked === 'indeterminate'
54
+ ? props.una?.checkboxIndeterminateIcon ?? 'checkbox-indeterminate-icon'
55
+ : props.checked
56
+ ? props.una?.checkboxCheckedIcon ?? 'checkbox-checked-icon'
57
+ : props.una?.checkboxUncheckedIcon ?? 'checkbox-unchecked-icon'"
58
+ :class="cn('checkbox-icon-base', una?.checkboxIconBase)"
59
+ />
60
+ </slot>
61
+ </CheckboxIndicator>
62
+ </CheckboxRoot>
63
+
64
+ <Label
65
+ v-if="$slots.default || label"
66
+ :for="props.for || id"
67
+ :class="cn('checkbox-label', una?.checkboxLabel)"
68
+ v-bind="props._label"
80
69
  >
81
70
  <slot>
82
71
  {{ label }}
83
72
  </slot>
84
- </div>
85
- </label>
73
+ </Label>
74
+ </div>
86
75
  </template>
@@ -2,12 +2,10 @@
2
2
  import { computed } from 'vue'
3
3
  import type { NFormGroupProps } from '../../types'
4
4
  import NFormGroupDefaultSlot from '../slots/FormGroupDefault'
5
- import FormGroupLabel from '../slots/FormGroupLabel'
6
5
  import { randomId } from '../../utils'
6
+ import Label from '../elements/Label.vue'
7
7
 
8
- const props = withDefaults(defineProps<NFormGroupProps>(), {
9
- for: undefined,
10
- })
8
+ const props = defineProps<NFormGroupProps>()
11
9
 
12
10
  const id = computed(() => props.id ?? randomId('form-group'))
13
11
 
@@ -17,7 +15,7 @@ const statusClassVariants = computed(() => {
17
15
  success: 'text-success',
18
16
  warning: 'text-warning',
19
17
  error: 'text-error',
20
- default: 'text-$c-gray-500',
18
+ default: 'text-muted',
21
19
  }
22
20
 
23
21
  return text[props.status ?? 'default']
@@ -42,24 +40,26 @@ const statusClassVariants = computed(() => {
42
40
  :class="una?.formGroupTopWrapperInner"
43
41
  >
44
42
  <slot name="label">
45
- <FormGroupLabel
46
- :id="id"
47
- :for="props.for"
48
- form-group="label-wrapper"
49
- :class="una?.formGroupLabelWrapper"
43
+ <Label
44
+ :for="props.for ?? id"
50
45
  >
51
- <span
52
- form-group="label"
53
- :class="una?.formGroupLabel"
46
+ <div
47
+ form-group="label-wrapper"
48
+ :class="una?.formGroupLabelWrapper"
54
49
  >
55
- {{ label }}
56
- </span>
57
- <span
58
- v-if="required"
59
- form-group="label-required"
60
- :class="una?.formGroupLabelRequired"
61
- />
62
- </FormGroupLabel>
50
+ <span
51
+ form-group="label"
52
+ :class="una?.formGroupLabel"
53
+ >
54
+ {{ label }}
55
+ </span>
56
+ <span
57
+ v-if="required"
58
+ form-group="label-required"
59
+ :class="una?.formGroupLabelRequired"
60
+ />
61
+ </div>
62
+ </Label>
63
63
  </slot>
64
64
 
65
65
  <slot name="hint">
@@ -1,24 +1,31 @@
1
1
  <script setup lang="ts">
2
- import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
3
2
  import { useToggle } from '@vueuse/core'
4
3
  import { computed } from 'vue'
4
+ import { PopoverTrigger } from 'radix-vue'
5
5
  import { useUnaThemes } from '../../composables/useUnaThemes'
6
6
  import { useUnaSettings } from '../../composables/useUnaSettings'
7
- import NButton from '../elements/Button.vue'
7
+ import Popover from '../elements/popover/Popover.vue'
8
+ import PopoverContent from '../elements/popover/PopoverContent.vue'
9
+ import Button from '../elements/Button.vue'
10
+ import { RADIUS } from '../../constants'
11
+ import Label from '../elements/Label.vue'
12
+ import Separator from '../elements/Separator.vue'
8
13
 
9
- const { primaryThemes, grayThemes } = useUnaThemes()
14
+ // @ts-expect-error tsconfig
15
+ import { useColorMode } from '#imports'
16
+
17
+ const colorMode = useColorMode()
10
18
 
19
+ const [value, toggle] = useToggle()
20
+ const { primaryThemes, grayThemes } = useUnaThemes()
11
21
  const { settings, reset } = useUnaSettings()
12
22
 
13
23
  const currentPrimaryThemeHex = computed(() => settings.value.primaryColors?.['--una-primary-hex'])
14
-
15
24
  const currentPrimaryThemeName = computed(() => {
16
25
  const theme = primaryThemes.find(([, theme]) => theme['--una-primary-hex'] === currentPrimaryThemeHex.value)
17
26
  return theme ? theme[0] : ''
18
27
  })
19
-
20
28
  const currentGrayThemeHex = computed(() => settings.value.grayColors?.['--una-gray-hex'])
21
-
22
29
  const currentGrayThemeName = computed(() => {
23
30
  const theme = grayThemes.find(([, theme]) => theme['--una-gray-hex'] === currentGrayThemeHex.value)
24
31
  return theme ? theme[0] : ''
@@ -33,82 +40,161 @@ function updateGrayTheme(theme: string) {
33
40
  settings.value.gray = theme
34
41
  }
35
42
 
36
- const [value, toggle] = useToggle()
37
43
  function shuffleTheme() {
38
44
  const randomPrimaryTheme = primaryThemes[Math.floor(Math.random() * primaryThemes.length)][0]
39
45
  const randomGrayTheme = grayThemes[Math.floor(Math.random() * grayThemes.length)][0]
46
+ const randomRadius = RADIUS[Math.floor(Math.random() * RADIUS.length)]
40
47
  updatePrimaryTheme(randomPrimaryTheme)
41
48
  updateGrayTheme(randomGrayTheme)
49
+ settings.value.radius = randomRadius
42
50
  toggle()
43
51
  }
44
52
  </script>
45
53
 
46
54
  <template>
47
- <div>
48
- <Popover class="relative inline-block">
49
- <PopoverButton
50
- btn="~ square soft"
51
- class="rounded-lg"
52
- aria-label="Theme"
53
- >
54
- <span i-lucide-paintbrush text-md />
55
- </PopoverButton>
56
-
57
- <transition enter-active-class="transition ease-out duration-200" enter-from-class="opacity-0 translate-y-1" enter-to-class="opacity-100 translate-y-0" leave-active-class="transition ease-in duration-150" leave-from-class="opacity-100 translate-y-0" leave-to-class="opacity-0 translate-y-1">
58
- <PopoverPanel class="absolute right-0 z-100 mt-2 w-54 border-1 border-base rounded-xl bg-muted px-4 py-5 shadow-lg">
59
- <div class="flex flex-col space-y-5">
60
- <div class="grid grid-cols-5 gap-3">
61
- <button
62
- v-for="[key, theme] in primaryThemes"
63
- :key="key"
64
- :style="{ background: theme['--una-primary-hex'] }"
65
- class="h-6.5 w-6.5 rounded-full transition-all" :class="[currentPrimaryThemeName === key ? 'ring-2' : 'scale-93']"
66
- ring="primary offset-4 offset-base"
67
- aria-label="Primary Color"
68
- @click="updatePrimaryTheme(key)"
69
- />
70
- </div>
71
-
72
- <hr class="my-2 border-$c-divider">
73
-
74
- <div class="grid grid-cols-5 gap-3">
75
- <button
76
- v-for="[key, theme] in grayThemes"
77
- :key="key"
78
- :style="{ background: theme['--una-gray-hex'] }"
79
- :class="currentGrayThemeName === key ? 'ring-2' : 'scale-93'"
80
- class="h-6.5 w-6.5 rounded-full transition-all"
81
- aria-label="Gray Color"
82
- ring="gray offset-4 offset-base"
83
- @click="updateGrayTheme(key)"
84
- />
85
- </div>
86
-
87
- <hr class="my-2 border-$c-divider">
88
-
89
- <div class="flex space-x-3">
90
- <NButton
91
- btn="~ solid block"
92
- class="transition"
93
- label="Shuffle"
94
- leading="i-lucide-paintbrush-vertical"
95
- :una="{
96
- btnLeading: value ? 'rotate-180 transform' : 'rotate-0',
97
- }"
98
- @click="shuffleTheme"
99
- />
100
-
101
- <NButton
102
- btn="~ solid-gray"
103
- size="xs"
104
- icon
105
- label="i-lucide-delete"
106
- @click="reset"
107
- />
108
- </div>
55
+ <Popover>
56
+ <PopoverTrigger
57
+ as-child
58
+ >
59
+ <Button
60
+ btn="soft square"
61
+ icon
62
+ label="i-lucide-paintbrush"
63
+ />
64
+ </PopoverTrigger>
65
+
66
+ <PopoverContent
67
+ align="end"
68
+ class="z-100 w-73 bg-muted"
69
+ >
70
+ <div class="flex flex-col">
71
+ <div class="grid space-y-1">
72
+ <h1 class="text-md text-base font-semibold">
73
+ Customize
74
+ </h1>
75
+ <p class="text-xs text-muted">
76
+ Pick a style and color for your components.
77
+ </p>
78
+ </div>
79
+
80
+ <Separator />
81
+
82
+ <div class="space-y-3">
83
+ <Label for="color" class="text-xs"> Primary Color</Label>
84
+ <div class="grid grid-cols-7 gap-3">
85
+ <button
86
+ v-for="[key, theme] in primaryThemes"
87
+ :key="key"
88
+ :style="{ background: theme['--una-primary-hex'] }"
89
+ class="h-6.5 w-6.5 rounded-full transition-all"
90
+ :class="[currentPrimaryThemeName === key ? 'ring-2' : 'scale-93']"
91
+ ring="primary offset-4 offset-base"
92
+ aria-label="Primary Color"
93
+ @click="updatePrimaryTheme(key)"
94
+ />
95
+ </div>
96
+ </div>
97
+
98
+ <Separator />
99
+
100
+ <div class="space-y-3">
101
+ <Label for="color" class="text-xs"> Gray Color </Label>
102
+ <div class="grid grid-cols-7 gap-3">
103
+ <button
104
+ v-for="[key, theme] in grayThemes"
105
+ :key="key"
106
+ :style="{ background: theme['--una-gray-hex'] }"
107
+ :class="currentGrayThemeName === key ? 'ring-2' : 'scale-93'"
108
+ class="h-6.5 w-6.5 rounded-full transition-all"
109
+ aria-label="Gray Color"
110
+ ring="gray offset-4 offset-base"
111
+ @click="updateGrayTheme(key)"
112
+ />
113
+ </div>
114
+ </div>
115
+
116
+ <Separator />
117
+
118
+ <div class="space-y-3">
119
+ <Label for="radius" class="text-xs"> Radius </Label>
120
+ <div class="grid grid-cols-5 gap-2 py-1.5">
121
+ <Button
122
+ v-for="r in RADIUS"
123
+ :key="r"
124
+ btn="solid-gray"
125
+ size="xs"
126
+ :class="
127
+ r === settings.radius
128
+ ? 'ring-2 ring-primary'
129
+ : ''
130
+ "
131
+ @click="settings.radius = r"
132
+ >
133
+ {{ r }}
134
+ </Button>
135
+ </div>
136
+ </div>
137
+
138
+ <Separator />
139
+
140
+ <div class="space-y-3">
141
+ <Label for="theme" class="text-xs">Mode</Label>
142
+
143
+ <div class="flex justify-around py-1.5 space-x-2">
144
+ <Button
145
+ btn="solid-gray block"
146
+ :class="{ 'ring-2 ring-primary': colorMode.preference === 'system' }"
147
+ leading="i-radix-icons-desktop"
148
+ class="px-3"
149
+ size="xs"
150
+ label="System"
151
+ @click="colorMode.preference = 'system'"
152
+ />
153
+
154
+ <Button
155
+ btn="solid-gray block"
156
+ :class="{ 'ring-2 ring-primary': colorMode.preference === 'light' }"
157
+ leading="i-radix-icons-sun"
158
+ class="px-3"
159
+ size="xs"
160
+ label="Light"
161
+ @click="colorMode.preference = 'light'"
162
+ />
163
+
164
+ <Button
165
+ btn="solid-gray block"
166
+ :class="{ 'ring-2 ring-primary': colorMode.preference === 'dark' }"
167
+ leading="i-radix-icons-moon"
168
+ class="px-3"
169
+ size="xs"
170
+ label="Dark"
171
+ @click="colorMode.preference = 'dark'"
172
+ />
109
173
  </div>
110
- </PopoverPanel>
111
- </transition>
112
- </Popover>
113
- </div>
174
+ </div>
175
+
176
+ <Separator />
177
+
178
+ <div class="flex space-x-3">
179
+ <Button
180
+ btn="solid-gray block"
181
+ size="xs"
182
+ label="Reset"
183
+ leading="i-radix-icons-reload"
184
+ @click="reset"
185
+ />
186
+ <Button
187
+ btn="solid block"
188
+ class="transition"
189
+ label="Shuffle"
190
+ leading="i-lucide-paintbrush"
191
+ :una="{
192
+ btnLeading: value ? 'rotate-6 transform' : '-rotate-6',
193
+ }"
194
+ @click="shuffleTheme"
195
+ />
196
+ </div>
197
+ </div>
198
+ </PopoverContent>
199
+ </Popover>
114
200
  </template>