@una-ui/nuxt 0.2.0-beta.6 → 0.4.0-beta.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 (62) hide show
  1. package/README.md +10 -1
  2. package/dist/module.d.mts +35 -0
  3. package/dist/module.d.ts +11 -7
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +12 -40
  6. package/dist/runtime/components/elements/Link.vue +34 -3
  7. package/dist/runtime/components/elements/Link.vue.d.ts +8 -0
  8. package/dist/runtime/components/forms/Checkbox.vue +84 -0
  9. package/dist/runtime/components/forms/Input.vue +49 -9
  10. package/dist/runtime/components/forms/Radio.vue +12 -17
  11. package/dist/runtime/components/misc/ThemeSwitcher.vue +43 -40
  12. package/dist/runtime/components/navigation/NavLink.vue +36 -8
  13. package/dist/runtime/composables/useUnaSettings.d.ts +1 -0
  14. package/dist/runtime/composables/useUnaSettings.mjs +30 -0
  15. package/dist/runtime/composables/useUnaThemes.d.ts +7 -0
  16. package/dist/runtime/composables/{themes.mjs → useUnaThemes.mjs} +31 -17
  17. package/dist/runtime/plugins/theme.client.d.ts +0 -3
  18. package/dist/runtime/plugins/theme.client.mjs +4 -9
  19. package/dist/runtime/plugins/theme.server.mjs +6 -1
  20. package/dist/runtime/types/accordion.d.ts +15 -15
  21. package/dist/runtime/types/alert.d.ts +6 -6
  22. package/dist/runtime/types/avatar-group.d.ts +3 -3
  23. package/dist/runtime/types/avatar.d.ts +9 -9
  24. package/dist/runtime/types/badge.d.ts +4 -4
  25. package/dist/runtime/types/button.d.ts +10 -10
  26. package/dist/runtime/types/checkbox.d.ts +69 -0
  27. package/dist/runtime/types/checkbox.mjs +0 -0
  28. package/dist/runtime/types/form-group.d.ts +10 -10
  29. package/dist/runtime/types/icon.d.ts +1 -1
  30. package/dist/runtime/types/index.d.ts +24 -0
  31. package/dist/runtime/types/index.mjs +1 -0
  32. package/dist/runtime/types/indicator.d.ts +9 -9
  33. package/dist/runtime/types/input.d.ts +42 -13
  34. package/dist/runtime/types/kbd.d.ts +3 -3
  35. package/dist/runtime/types/link.d.ts +13 -4
  36. package/dist/runtime/types/nav-link.d.ts +10 -1
  37. package/dist/runtime/types/radio.d.ts +11 -12
  38. package/dist/runtime/types/switch.d.ts +8 -8
  39. package/dist/runtime/utils/index.d.ts +12 -12
  40. package/dist/types.d.mts +16 -0
  41. package/dist/types.d.ts +3 -2
  42. package/dist/una.config.d.mts +5 -0
  43. package/dist/una.config.d.ts +5 -0
  44. package/dist/una.config.mjs +35 -0
  45. package/package.json +24 -20
  46. package/playground/.nuxt/components.d.ts +208 -0
  47. package/playground/.nuxt/imports.d.ts +28 -0
  48. package/playground/.nuxt/nuxt.d.ts +18 -0
  49. package/playground/.nuxt/schema/nuxt.schema.d.ts +17 -0
  50. package/playground/.nuxt/types/app.config.d.ts +37 -0
  51. package/playground/.nuxt/types/imports.d.ts +1069 -0
  52. package/playground/.nuxt/types/nitro-config.d.ts +14 -0
  53. package/playground/.nuxt/types/nitro-imports.d.ts +121 -0
  54. package/playground/.nuxt/types/nitro-nuxt.d.ts +26 -0
  55. package/playground/.nuxt/types/nitro-routes.d.ts +11 -0
  56. package/playground/.nuxt/types/nitro.d.ts +3 -0
  57. package/playground/.nuxt/types/plugins.d.ts +30 -0
  58. package/playground/.nuxt/types/schema.d.ts +29 -0
  59. package/playground/.nuxt/types/vue-shim.d.ts +5 -0
  60. package/playground/.nuxt/vue-router-stub.d.ts +1 -0
  61. package/una.config.d.ts +1 -0
  62. package/dist/runtime/composables/themes.d.ts +0 -7
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # ✨ Una UI
2
2
 
3
- > **Warning**: This project is heavily working in progress.
3
+ > [!WARNING]
4
+ > This project is heavily working in progress.
4
5
 
5
6
  ## 🏗️ Release Status
6
7
 
@@ -13,6 +14,14 @@
13
14
 
14
15
  Visit https://www.unaui.com for full documentation.
15
16
 
17
+ ## 🌻 Sponsors
18
+
19
+ <p align="center">
20
+ <a href="https://cdn.jsdelivr.net/gh/phojie/static/sponsors.svg">
21
+ <img src='https://cdn.jsdelivr.net/gh/phojie/static/sponsors.svg'/>
22
+ </a>
23
+ </p>
24
+
16
25
  ## 🏛️ License
17
26
 
18
27
  [MIT](./LICENSE) License © 2023 [Phojie](https://github.com/phojie)
@@ -0,0 +1,35 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface UnaOptions {
4
+ primary?: string;
5
+ gray?: string;
6
+ }
7
+ declare module '@nuxt/schema' {
8
+ interface AppConfigInput {
9
+ una?: UnaOptions;
10
+ }
11
+ }
12
+ interface ModuleOptions {
13
+ /**
14
+ * @default 'N'
15
+ */
16
+ prefix?: string;
17
+ /**
18
+ * @default true
19
+ * @description Enable themeable ui
20
+ *
21
+ */
22
+ themeable?: boolean;
23
+ /**
24
+ * @default true
25
+ * @description Register components globally
26
+ */
27
+ global?: boolean;
28
+ /**
29
+ * @default false
30
+ */
31
+ dev: boolean;
32
+ }
33
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
34
+
35
+ export { type ModuleOptions, _default as default };
package/dist/module.d.ts CHANGED
@@ -1,5 +1,14 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
 
3
+ interface UnaOptions {
4
+ primary?: string;
5
+ gray?: string;
6
+ }
7
+ declare module '@nuxt/schema' {
8
+ interface AppConfigInput {
9
+ una?: UnaOptions;
10
+ }
11
+ }
3
12
  interface ModuleOptions {
4
13
  /**
5
14
  * @default 'N'
@@ -9,18 +18,13 @@ interface ModuleOptions {
9
18
  * @default true
10
19
  * @description Enable themeable ui
11
20
  *
12
- */
21
+ */
13
22
  themeable?: boolean;
14
23
  /**
15
24
  * @default true
16
25
  * @description Register components globally
17
26
  */
18
27
  global?: boolean;
19
- /**
20
- * @default '@una-ui/preset'
21
- * @description Path to preset
22
- */
23
- preset?: string;
24
28
  /**
25
29
  * @default false
26
30
  */
@@ -28,4 +32,4 @@ interface ModuleOptions {
28
32
  }
29
33
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
30
34
 
31
- export { ModuleOptions, _default as default };
35
+ export { type ModuleOptions, _default as default };
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@una-ui/nuxt",
3
3
  "configKey": "una",
4
- "version": "0.2.0-beta.6",
4
+ "version": "0.4.0-beta.0",
5
5
  "compatibility": {
6
6
  "nuxt": "^3.0.0-rc.8"
7
7
  }
package/dist/module.mjs CHANGED
@@ -1,45 +1,13 @@
1
- import { fileURLToPath } from 'node:url';
2
- import { defineNuxtModule, createResolver, addComponentsDir, addPlugin, installModule } from '@nuxt/kit';
3
- import { presetUno, presetAttributify, presetIcons, transformerDirectives, transformerVariantGroup } from 'unocss';
4
- import presetUna from '@una-ui/preset';
5
- import prefixes from '@una-ui/preset/prefixes';
6
- import extratorUna from '@una-ui/extractor-vue-script';
1
+ import { defineNuxtModule, createResolver, addComponentsDir, addPlugin, installModule, addImportsDir } from '@nuxt/kit';
2
+ import extendUnocssOptions from './una.config.mjs';
3
+ import 'unocss';
4
+ import '@una-ui/preset';
5
+ import '@una-ui/preset/prefixes';
6
+ import '@una-ui/extractor-vue-script';
7
7
 
8
8
  const name = "@una-ui/nuxt";
9
- const version = "0.2.0-beta.6";
9
+ const version = "0.4.0-beta.0";
10
10
 
11
- function extendUnocssOptions(user = {}) {
12
- return {
13
- ...user,
14
- preflight: false,
15
- presets: [
16
- presetUno(),
17
- presetAttributify(),
18
- presetIcons({
19
- scale: 1.2,
20
- extraProperties: {
21
- "display": "inline-block",
22
- "vertical-align": "middle"
23
- }
24
- }),
25
- presetUna(),
26
- ...user.presets || []
27
- ],
28
- extractors: [
29
- extratorUna({
30
- prefixes
31
- })
32
- ],
33
- transformers: [
34
- transformerDirectives(),
35
- transformerVariantGroup()
36
- ]
37
- };
38
- }
39
-
40
- function rPath(p) {
41
- return fileURLToPath(new URL(p, import.meta.url).toString());
42
- }
43
11
  const module = defineNuxtModule({
44
12
  meta: {
45
13
  name,
@@ -52,13 +20,16 @@ const module = defineNuxtModule({
52
20
  defaults: {
53
21
  prefix: "N",
54
22
  themeable: true,
55
- preset: rPath("./preset"),
56
23
  global: true,
57
24
  dev: false
58
25
  },
59
26
  async setup(options, nuxt) {
60
27
  const { resolve } = createResolver(import.meta.url);
61
28
  nuxt.options.css.unshift("@una-ui/preset/una.css");
29
+ nuxt.options.appConfig.una = {
30
+ primary: "yellow",
31
+ gray: "stone"
32
+ };
62
33
  const runtimeDir = resolve("./runtime");
63
34
  nuxt.options.build.transpile.push(runtimeDir);
64
35
  nuxt.options.build.transpile.push("@headlessui/vue");
@@ -97,6 +68,7 @@ const module = defineNuxtModule({
97
68
  classSuffix: ""
98
69
  });
99
70
  await installModule("@vueuse/nuxt");
71
+ addImportsDir(resolve(runtimeDir, "composables"));
100
72
  }
101
73
  });
102
74
 
@@ -23,6 +23,15 @@ export default defineComponent({
23
23
  inactiveClass: {
24
24
  type: String,
25
25
  default: void 0
26
+ },
27
+ // preset
28
+ navLinkActive: {
29
+ type: String,
30
+ default: void 0
31
+ },
32
+ navLinkInactive: {
33
+ type: String,
34
+ default: void 0
26
35
  }
27
36
  },
28
37
  setup(props) {
@@ -37,8 +46,30 @@ export default defineComponent({
37
46
  return props.activeClass;
38
47
  return props.inactiveClass;
39
48
  }
49
+ function resolveNavLinkActive(route, $route, { isActive, isExactActive }) {
50
+ if (props.exactQuery && !isEqual(route.query, $route.query))
51
+ return null;
52
+ if (props.exactHash && !isEqual(route.hash, $route.hash))
53
+ return null;
54
+ if (props.exact && isExactActive)
55
+ return props.navLinkActive;
56
+ if (!props.exact && isActive)
57
+ return props.navLinkActive;
58
+ return null;
59
+ }
60
+ function resolveNavLinkInactive(route, $route, { isActive, isExactActive }) {
61
+ if (props.exactQuery && !isEqual(route.query, $route.query))
62
+ return props.navLinkInactive;
63
+ if (props.exactHash && !isEqual(route.hash, $route.hash))
64
+ return props.navLinkInactive;
65
+ if (!props.exact && isActive || props.exact && isExactActive)
66
+ return null;
67
+ return props.navLinkInactive;
68
+ }
40
69
  return {
41
- resolveLinkClass
70
+ resolveLinkClass,
71
+ resolveNavLinkActive,
72
+ resolveNavLinkInactive
42
73
  };
43
74
  }
44
75
  });
@@ -48,16 +79,16 @@ export default defineComponent({
48
79
  <NuxtLink
49
80
  v-slot="{ route, href, target, rel, navigate, isActive, isExactActive, isExternal }"
50
81
  v-bind="$props"
51
- class="link"
52
82
  custom
53
83
  >
54
84
  <a
55
85
  v-bind="$attrs"
56
86
  :href="href"
57
87
  :rel="rel"
58
- class="link"
59
88
  :target="target"
60
89
  :class="resolveLinkClass(route, $route, { isActive, isExactActive })"
90
+ :nav-link-active="resolveNavLinkActive(route, $route, { isActive, isExactActive })"
91
+ :nav-link-inactive="resolveNavLinkInactive(route, $route, { isActive, isExactActive })"
61
92
  @click="(e) => !isExternal && navigate(e)"
62
93
  >
63
94
  <slot v-bind="{ isActive: exact ? isExactActive : isActive }" />
@@ -3,6 +3,14 @@ declare const _default: import("vue").DefineComponent<any, {
3
3
  isActive: boolean;
4
4
  isExactActive: boolean;
5
5
  }) => any;
6
+ resolveNavLinkActive: (route: any, $route: any, { isActive, isExactActive }: {
7
+ isActive: boolean;
8
+ isExactActive: boolean;
9
+ }) => any;
10
+ resolveNavLinkInactive: (route: any, $route: any, { isActive, isExactActive }: {
11
+ isActive: boolean;
12
+ isExactActive: boolean;
13
+ }) => any;
6
14
  }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<any>, {} | {
7
15
  [x: string]: any;
8
16
  }, {}>;
@@ -0,0 +1,84 @@
1
+ <script setup lang="ts">
2
+ import { useVModel } from '@vueuse/core'
3
+ import { computed } from 'vue'
4
+ import NIcon from '../elements/Icon.vue'
5
+ import { randomId } from '../../utils'
6
+ import type { NCheckboxProps } from '../../types/checkbox'
7
+
8
+ defineOptions({
9
+ inheritAttrs: false,
10
+ })
11
+
12
+ const props = withDefaults(
13
+ defineProps<NCheckboxProps>(),
14
+ {
15
+ modelValue: false,
16
+ disabled: false,
17
+ una: () => ({
18
+ checkboxIcon: 'checkbox-icon',
19
+ }),
20
+ },
21
+ )
22
+ const emit = defineEmits<{ (...args: any): void }>()
23
+
24
+ const slots = defineSlots<{
25
+ default?: void
26
+ icon?: any
27
+ }>()
28
+
29
+ const id = computed(() => props.id ?? randomId('checkbox'))
30
+
31
+ const checked = useVModel(props, 'modelValue', emit, { passive: true })
32
+ </script>
33
+
34
+ <template>
35
+ <label
36
+ checkbox="wrapper"
37
+ :for="props.for ?? id"
38
+ :class="[
39
+ una?.checkboxWrapper,
40
+ {
41
+ 'checkbox-reverse': reverse,
42
+ 'checkbox-disabled': disabled,
43
+ },
44
+ ]"
45
+ :checked="checked || null"
46
+ :disabled="disabled || null"
47
+ >
48
+ <input
49
+ :id="id"
50
+ v-model="checked"
51
+ type="checkbox"
52
+ class="peer"
53
+ checkbox="input"
54
+ :disabled="disabled"
55
+ :name="name"
56
+ @keypress.enter="checked = !checked"
57
+ >
58
+ <span
59
+ :checkbox="checkbox"
60
+ :size="size"
61
+ class="checkbox checkbox-peer-focus"
62
+ v-bind="$attrs"
63
+ >
64
+ <slot name="icon">
65
+ <NIcon
66
+ checkbox="icon-base icon-checked"
67
+ :name="una.checkboxIcon!"
68
+ :class="[
69
+ una.checkboxIconBase,
70
+ ]"
71
+ />
72
+ </slot>
73
+ </span>
74
+ <div
75
+ v-if="slots.default || label"
76
+ checkbox="label"
77
+ :class="una?.checkboxLabel"
78
+ >
79
+ <slot>
80
+ {{ label }}
81
+ </slot>
82
+ </div>
83
+ </label>
84
+ </template>
@@ -1,6 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { useVModel } from '@vueuse/core'
3
- import { computed } from 'vue'
2
+ import { computed, onMounted, ref } from 'vue'
4
3
  import NIcon from '../elements/Icon.vue'
5
4
  import type { NInputProps } from '../../types'
6
5
  import { randomId } from '../../utils'
@@ -11,6 +10,8 @@ defineOptions({
11
10
 
12
11
  const props = withDefaults(defineProps<NInputProps>(), {
13
12
  type: 'text',
13
+ resize: 'none',
14
+ rows: 3,
14
15
  })
15
16
 
16
17
  const emit = defineEmits<{ (...args: any): void }>()
@@ -20,8 +21,6 @@ const slots = defineSlots<{
20
21
  trailing?: any
21
22
  }>()
22
23
 
23
- const inputValue = useVModel(props, 'modelValue', emit, { passive: true })
24
-
25
24
  const id = computed(() => props.id ?? randomId('input'))
26
25
 
27
26
  const isLeading = computed(() => props.leading || slots.leading)
@@ -75,6 +74,41 @@ const reverseClassVariants = computed(() => {
75
74
  trailingWrapper: props.reverse ? 'input-leading-wrapper' : 'input-trailing-wrapper',
76
75
  }
77
76
  })
77
+
78
+ // html refs
79
+ const textarea = ref<HTMLTextAreaElement>()
80
+
81
+ function resizeTextarea() {
82
+ if (!(props.type === 'textarea' && props.autoresize) || !textarea.value)
83
+ return
84
+
85
+ textarea.value.rows = props.rows
86
+
87
+ const styles = window.getComputedStyle(textarea.value)
88
+ const paddingTop = Number.parseInt(styles.paddingTop)
89
+ const paddingBottom = Number.parseInt(styles.paddingBottom)
90
+ const padding = paddingTop + paddingBottom
91
+ const lineHeight = Number.parseInt(styles.lineHeight)
92
+ const { scrollHeight } = textarea.value
93
+ const newRows = (scrollHeight - padding) / lineHeight
94
+
95
+ if (newRows > props.rows)
96
+ textarea.value.rows = newRows
97
+
98
+ const maxAutoresizeRows = typeof props.autoresize === 'number' ? props.autoresize : Number.POSITIVE_INFINITY
99
+ if (textarea.value.rows > maxAutoresizeRows)
100
+ textarea.value.rows = maxAutoresizeRows
101
+ }
102
+
103
+ function onInput(event: Event) {
104
+ emit('update:modelValue', (event.target as HTMLInputElement).value)
105
+
106
+ resizeTextarea()
107
+ }
108
+
109
+ onMounted(() => {
110
+ resizeTextarea()
111
+ })
78
112
  </script>
79
113
 
80
114
  <template>
@@ -102,10 +136,12 @@ const reverseClassVariants = computed(() => {
102
136
  </slot>
103
137
  </div>
104
138
 
105
- <input
139
+ <Component
140
+ :is="props.type !== 'textarea' ? 'input' : 'textarea'"
106
141
  :id="id"
107
- v-model="inputValue"
108
- :type="type"
142
+ ref="textarea"
143
+ :value="modelValue"
144
+ :type="props.type !== 'textarea' ? props.type : undefined"
109
145
  class="input"
110
146
  :class="[
111
147
  statusClassVariants.input,
@@ -113,8 +149,12 @@ const reverseClassVariants = computed(() => {
113
149
  una?.input,
114
150
  ]"
115
151
  :input="input"
152
+ :resize="type === 'textarea' ? resize : undefined"
153
+ :rows="type === 'textarea' ? rows : undefined"
154
+ :cols="type === 'textarea' ? cols : undefined"
116
155
  v-bind="$attrs"
117
- >
156
+ @input="onInput"
157
+ />
118
158
 
119
159
  <div
120
160
  v-if="isTrailing"
@@ -132,7 +172,7 @@ const reverseClassVariants = computed(() => {
132
172
  />
133
173
 
134
174
  <NIcon
135
- v-if="status"
175
+ v-else-if="status"
136
176
  input="status-icon-base"
137
177
  :name="statusClassVariants.icon"
138
178
  />
@@ -57,27 +57,22 @@ const model = useVModel(props, 'modelValue', emit, { passive: true })
57
57
  :value="value"
58
58
  @keypress.enter="model = value!"
59
59
  >
60
- <div
60
+ <span
61
61
  :radio="radio"
62
62
  :size="size"
63
- class="radio radio-(peer-focus)"
64
- :class="[
65
- una?.radioPeerFocus,
66
- ]"
63
+ class="radio radio-peer-focus"
67
64
  v-bind="$attrs"
68
65
  >
69
- <div radio="icon-wrapper">
70
- <slot name="icon">
71
- <NIcon
72
- :class="[
73
- una.radioIconBase,
74
- ]"
75
- radio="icon-base icon-checked"
76
- :name="una.radioIcon!"
77
- />
78
- </slot>
79
- </div>
80
- </div>
66
+ <slot name="icon">
67
+ <NIcon
68
+ :class="[
69
+ una.radioIconBase,
70
+ ]"
71
+ radio="icon-base icon-checked"
72
+ :name="una.radioIcon!"
73
+ />
74
+ </slot>
75
+ </span>
81
76
  <div
82
77
  v-if="slots.default || label"
83
78
  radio="label"
@@ -1,51 +1,42 @@
1
1
  <script setup lang="ts">
2
2
  import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
3
- import { useStorage, useToggle } from '@vueuse/core'
3
+ import { useToggle } from '@vueuse/core'
4
4
  import { computed } from 'vue'
5
- import { grayThemes, primaryThemes } from '../../composables/themes'
5
+ import { useUnaThemes } from '../../composables/useUnaThemes'
6
+ import { useUnaSettings } from '../../composables/useUnaSettings'
7
+ import NButton from '../elements/Button.vue'
6
8
 
7
- // TODO: globalize
8
- export interface ThemeColors {
9
- [key: string]: string
10
- }
9
+ const { primaryThemes, grayThemes } = useUnaThemes()
11
10
 
12
- // TODO: confingurable in the app.config
13
- const defaultSettings = {
14
- primaryColors: primaryThemes.filter(([colorName, _]) => colorName === 'yellow')[0][1],
15
- grayColors: grayThemes.filter(([colorName, _]) => colorName === 'stone')[0][1],
16
- fontSize: 16,
17
- }
11
+ const { settings, reset } = useUnaSettings()
18
12
 
19
- const settings = useStorage('una-settings', defaultSettings)
13
+ const currentPrimaryThemeHex = computed(() => settings.value.primaryColors?.['--una-primary-hex'])
20
14
 
21
- // use yellow primary theme as default
22
- const currentPrimaryTheme = computed(() => settings.value.primaryColors?.['--una-primary-hex'])
23
- // get current theme name
24
15
  const currentPrimaryThemeName = computed(() => {
25
- const theme = primaryThemes.find(([, theme]) => theme['--una-primary-hex'] === currentPrimaryTheme.value)
16
+ const theme = primaryThemes.find(([, theme]) => theme['--una-primary-hex'] === currentPrimaryThemeHex.value)
26
17
  return theme ? theme[0] : ''
27
18
  })
28
19
 
29
- // use stone primary theme as default
30
- const currentGrayTheme = computed(() => settings.value.grayColors?.['--una-gray-hex'])
31
- // get current theme name
20
+ const currentGrayThemeHex = computed(() => settings.value.grayColors?.['--una-gray-hex'])
21
+
32
22
  const currentGrayThemeName = computed(() => {
33
- const theme = grayThemes.find(([, theme]) => theme['--una-gray-hex'] === currentGrayTheme.value)
23
+ const theme = grayThemes.find(([, theme]) => theme['--una-gray-hex'] === currentGrayThemeHex.value)
34
24
  return theme ? theme[0] : ''
35
25
  })
36
26
 
37
27
  // update theme in storage
38
- function updatePrimaryTheme(theme: ThemeColors) {
39
- settings.value.primaryColors = theme
28
+ function updatePrimaryTheme(theme: string) {
29
+ settings.value.primary = theme
40
30
  }
41
- function updateGrayTheme(theme: ThemeColors) {
42
- settings.value.grayColors = theme
31
+
32
+ function updateGrayTheme(theme: string) {
33
+ settings.value.gray = theme
43
34
  }
44
35
 
45
36
  const [value, toggle] = useToggle()
46
37
  function shuffleTheme() {
47
- const randomPrimaryTheme = primaryThemes[Math.floor(Math.random() * primaryThemes.length)][1]
48
- const randomGrayTheme = grayThemes[Math.floor(Math.random() * grayThemes.length)][1]
38
+ const randomPrimaryTheme = primaryThemes[Math.floor(Math.random() * primaryThemes.length)][0]
39
+ const randomGrayTheme = grayThemes[Math.floor(Math.random() * grayThemes.length)][0]
49
40
  updatePrimaryTheme(randomPrimaryTheme)
50
41
  updateGrayTheme(randomGrayTheme)
51
42
  toggle()
@@ -53,11 +44,12 @@ function shuffleTheme() {
53
44
  </script>
54
45
 
55
46
  <template>
56
- <div class="sm:ml-5">
47
+ <div>
57
48
  <Popover class="relative inline-block">
58
49
  <PopoverButton
59
50
  btn="~ square soft"
60
51
  class="rounded-lg"
52
+ aria-label="Theme"
61
53
  >
62
54
  <span i-heroicons-swatch-20-solid text-md />
63
55
  </PopoverButton>
@@ -72,7 +64,8 @@ function shuffleTheme() {
72
64
  :style="{ background: theme['--una-primary-hex'] }"
73
65
  class="h-6.5 w-6.5 rounded-full transition-all" :class="[currentPrimaryThemeName === key ? 'ring-2' : 'scale-93']"
74
66
  ring="primary offset-4 offset-base"
75
- @click="updatePrimaryTheme(theme)"
67
+ aria-label="Primary Color"
68
+ @click="updatePrimaryTheme(key)"
76
69
  />
77
70
  </div>
78
71
 
@@ -85,24 +78,34 @@ function shuffleTheme() {
85
78
  :style="{ background: theme['--una-gray-hex'] }"
86
79
  :class="currentGrayThemeName === key ? 'ring-2' : 'scale-93'"
87
80
  class="h-6.5 w-6.5 rounded-full transition-all"
81
+ aria-label="Gray Color"
88
82
  ring="gray offset-4 offset-base"
89
- @click="updateGrayTheme(theme)"
83
+ @click="updateGrayTheme(key)"
90
84
  />
91
85
  </div>
92
86
 
93
87
  <hr class="my-2 border-$c-divider">
94
88
 
95
- <button
96
- btn="~ solid block"
97
- class="rounded-lg transition"
98
- @click="shuffleTheme"
99
- >
100
- Shuffle
101
- <span
102
- i-heroicons-adjustments-horizontal-20-solid ml-2
103
- :class="value ? 'rotate-180 transform' : 'rotate-0'"
89
+ <div class="flex space-x-3">
90
+ <NButton
91
+ btn="~ solid block"
92
+ class="transition"
93
+ label="Shuffle"
94
+ leading="i-heroicons-adjustments-horizontal-solid"
95
+ :una="{
96
+ btnLeading: value ? 'rotate-180 transform' : 'rotate-0',
97
+ }"
98
+ @click="shuffleTheme"
104
99
  />
105
- </button>
100
+
101
+ <NButton
102
+ btn="~ solid-gray"
103
+ size="xs"
104
+ icon
105
+ label="i-heroicons-arrow-uturn-left"
106
+ @click="reset"
107
+ />
108
+ </div>
106
109
  </div>
107
110
  </PopoverPanel>
108
111
  </transition>