@bitrix24/b24ui-nuxt 0.2.5 → 0.2.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/dist/module.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const defu = require('defu');
4
4
  const kit = require('@nuxt/kit');
5
- const templates = require('./shared/b24ui-nuxt.BfbMerCZ.cjs');
5
+ const templates = require('./shared/b24ui-nuxt.D-N3gDSr.cjs');
6
6
  require('node:url');
7
7
  require('scule');
8
8
 
package/dist/module.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "nuxt": ">=3.13.1"
6
6
  },
7
7
  "docs": "https://bitrix24.github.io/b24ui/guide/installation-nuxt-app.html",
8
- "version": "0.2.5",
8
+ "version": "0.2.6",
9
9
  "builder": {
10
10
  "@nuxt/module-builder": "0.8.4",
11
11
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defu } from 'defu';
2
2
  import { defineNuxtModule, createResolver, addVitePlugin, addPlugin, addComponentsDir, addImportsDir, hasNuxtModule, installModule } from '@nuxt/kit';
3
- import { d as defaultOptions, a as getDefaultUiConfig, b as addTemplates } from './shared/b24ui-nuxt.BYTVBEky.mjs';
3
+ import { d as defaultOptions, a as getDefaultUiConfig, b as addTemplates } from './shared/b24ui-nuxt.CAS1q3My.mjs';
4
4
  import 'node:url';
5
5
  import 'scule';
6
6
 
@@ -45,6 +45,12 @@ export interface DropdownMenuProps<T> extends Omit<DropdownMenuRootProps, 'dir'>
45
45
  * @defaultValue icons.check = `CheckIcon`
46
46
  */
47
47
  checkedIcon?: IconComponent
48
+ /**
49
+ * The icon displayed when the item is an external link.
50
+ * Set to `false` to hide the external icon.
51
+ * @defaultValue icons.external = `OpenIn50Icon`
52
+ */
53
+ externalIcon?: boolean | IconComponent
48
54
  /**
49
55
  * The content of the menu.
50
56
  * @defaultValue { side: 'bottom', sideOffset: 8, collisionPadding: 8 }
@@ -94,6 +100,7 @@ import B24DropdownMenuContent from './DropdownMenuContent.vue'
94
100
  const props = withDefaults(defineProps<DropdownMenuProps<T>>(), {
95
101
  portal: true,
96
102
  modal: true,
103
+ externalIcon: true,
97
104
  labelKey: 'label'
98
105
  })
99
106
  const emits = defineEmits<DropdownMenuEmits>()
@@ -124,6 +131,7 @@ const b24ui = computed(() => dropdownMenu({
124
131
  :portal="portal"
125
132
  :label-key="labelKey"
126
133
  :checked-icon="checkedIcon"
134
+ :external-icon="externalIcon"
127
135
  >
128
136
  <template v-for="(_, name) in proxySlots" #[name]="slotData: any">
129
137
  <slot :name="name" v-bind="slotData" />
@@ -13,6 +13,7 @@ interface DropdownMenuContentProps<T> extends Omit<RekaDropdownMenuContentProps,
13
13
  sub?: boolean
14
14
  labelKey: string
15
15
  checkedIcon?: IconComponent
16
+ externalIcon?: boolean | IconComponent
16
17
  class?: any
17
18
  b24ui: typeof _dropdownMenu
18
19
  b24uiOverride?: any
@@ -44,7 +45,7 @@ const props = defineProps<DropdownMenuContentProps<T>>()
44
45
  const emits = defineEmits<DropdownMenuContentEmits>()
45
46
  const slots = defineSlots<DropdownMenuContentSlots<T>>()
46
47
 
47
- const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'labelKey', 'checkedIcon', 'class', 'b24ui', 'b24uiOverride'), emits)
48
+ const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'labelKey', 'checkedIcon', 'externalIcon', 'class', 'b24ui', 'b24uiOverride'), emits)
48
49
  const proxySlots = omit(slots, ['default']) as Record<string, DropdownMenuContentSlots<T>[string]>
49
50
 
50
51
  const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: DropdownMenuItem, active?: boolean, index: number }>()
@@ -79,8 +80,8 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
79
80
  {{ get(item, props.labelKey as string) }}
80
81
  </slot>
81
82
  <Component
82
- :is="icons.external"
83
- v-if="item.target === '_blank'"
83
+ :is="typeof externalIcon !== 'boolean' ? externalIcon : icons.external"
84
+ v-if="item.target === '_blank' && externalIcon !== false"
84
85
  :class="b24ui.itemLabelExternalIcon({ class: b24uiOverride?.itemLabelExternalIcon, color: item?.color, active })"
85
86
  />
86
87
  </span>
@@ -139,6 +140,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
139
140
  :side-offset="3"
140
141
  :label-key="labelKey"
141
142
  :checked-icon="checkedIcon"
143
+ :external-icon="externalIcon"
142
144
  v-bind="item.content"
143
145
  >
144
146
  <template v-for="(_, name) in proxySlots" #[name]="slotData: any">
@@ -6,6 +6,7 @@ import _appConfig from '#build/app.config'
6
6
  import theme from '#build/b24ui/input-number'
7
7
  import { tv } from '../utils/tv'
8
8
  import type { ButtonProps, IconComponent } from '../types'
9
+ import type { PartialString } from '../types/utils'
9
10
 
10
11
  const appConfigInputNumber = _appConfig as AppConfig & { b24ui: { inputNumber: Partial<typeof theme> } }
11
12
 
@@ -35,8 +36,6 @@ export interface InputNumberProps extends Pick<NumberFieldRootProps, 'modelValue
35
36
  tagColor?: InputNumberVariants['tagColor']
36
37
  /** Highlight the ring color like a focus state. */
37
38
  highlight?: boolean
38
- class?: any
39
- b24ui?: Partial<typeof inputNumber.slots>
40
39
  /**
41
40
  * The orientation of the input menu.
42
41
  * @defaultValue 'horizontal'
@@ -69,6 +68,8 @@ export interface InputNumberProps extends Pick<NumberFieldRootProps, 'modelValue
69
68
  * @defaultValue B24App.locale.code
70
69
  */
71
70
  locale?: string
71
+ class?: any
72
+ b24ui?: PartialString<typeof inputNumber.slots>
72
73
  }
73
74
 
74
75
  export interface InputNumberEmits {
@@ -4,6 +4,7 @@ import type { AppConfig } from '@nuxt/schema'
4
4
  import _appConfig from '#build/app.config'
5
5
  import theme from '#build/b24ui/textarea'
6
6
  import { tv } from '../utils/tv'
7
+ import type { PartialString } from '../types/utils'
7
8
 
8
9
  const appConfigTextarea = _appConfig as AppConfig & { b24ui: { textarea: Partial<typeof theme> } }
9
10
 
@@ -42,7 +43,7 @@ export interface TextareaProps {
42
43
  /** Highlight the ring color like a focus state. */
43
44
  highlight?: boolean
44
45
  class?: any
45
- b24ui?: Partial<typeof textarea.slots>
46
+ b24ui?: PartialString<typeof textarea.slots>
46
47
  }
47
48
 
48
49
  export interface TextareaEmits {
@@ -73,7 +73,7 @@ export interface LinkProps extends NuxtLinkProps {
73
73
  /** Will only be active if the current route is an exact match. */
74
74
  exact?: boolean
75
75
  /** Will only be active if the current route query is an exact match. */
76
- exactQuery?: boolean
76
+ exactQuery?: boolean | 'partial'
77
77
  /** Will only be active if the current route hash is an exact match. */
78
78
  exactHash?: boolean
79
79
  /** The class to apply when the link is inactive. */
@@ -92,8 +92,8 @@ export interface LinkSlots {
92
92
  </script>
93
93
 
94
94
  <script setup lang="ts">
95
- import { computed } from 'vue'
96
- import { isEqual } from 'ohash'
95
+ import { computed, getCurrentInstance } from 'vue'
96
+ import { isEqual, diff } from 'ohash'
97
97
  import { useForwardProps } from 'reka-ui'
98
98
  import { reactiveOmit } from '@vueuse/core'
99
99
  import { hasProtocol } from 'ufo'
@@ -113,7 +113,22 @@ const props = withDefaults(defineProps<LinkProps>(), {
113
113
  })
114
114
  defineSlots<LinkSlots>()
115
115
 
116
- const route = useRoute()
116
+ // Check if vue-router is available by checking for the injection key
117
+ const hasRouter = computed(() => {
118
+ const app = getCurrentInstance()?.appContext.app
119
+ return !!(app?.config?.globalProperties?.$router)
120
+ })
121
+
122
+ // Only try to get route if router exists
123
+ const route = computed(() => {
124
+ if (!hasRouter.value) return null
125
+ try {
126
+ return useRoute()
127
+ } catch {
128
+ return null
129
+ }
130
+ })
131
+
117
132
  const routerLinkProps = useForwardProps(reactiveOmit(props, 'as', 'type', 'disabled', 'active', 'exact', 'exactQuery', 'exactHash', 'activeClass', 'inactiveClass', 'to', 'raw', 'class'))
118
133
 
119
134
  const ui = computed(() => tv({
@@ -126,21 +141,37 @@ const ui = computed(() => tv({
126
141
  }
127
142
  }))
128
143
 
129
- const isExternal = computed(() => typeof props.to === 'string' && hasProtocol(props.to, { acceptRelative: true }))
144
+ function isPartiallyEqual(item1: any, item2: any) {
145
+ const diffedKeys = diff(item1, item2).reduce((filtered, q) => {
146
+ if (q.type === 'added') {
147
+ filtered.push(q.key)
148
+ }
149
+ return filtered
150
+ }, [] as string[])
151
+ return isEqual(item1, item2, { excludeKeys: key => diffedKeys.includes(key) })
152
+ }
153
+
154
+ const isExternal = computed(() => {
155
+ if (!props.to) return false
156
+ return typeof props.to === 'string' && hasProtocol(props.to, { acceptRelative: true })
157
+ })
130
158
 
131
159
  function isLinkActive({ route: linkRoute, isActive, isExactActive }: any) {
132
160
  if (props.active !== undefined) {
133
161
  return props.active
134
162
  }
135
163
 
136
- if (!props.to) {
164
+ if (!props.to || !route.value) {
137
165
  return false
138
166
  }
139
167
 
140
- if (props.exactQuery && !isEqual(linkRoute.query, route.query)) {
141
- return false
168
+ if (props.exactQuery === 'partial') {
169
+ if (!isPartiallyEqual(linkRoute.query, route.value.query)) return false
170
+ } else if (props.exactQuery === true) {
171
+ if (!isEqual(linkRoute.query, route.value.query)) return false
142
172
  }
143
- if (props.exactHash && linkRoute.hash !== route.hash) {
173
+
174
+ if (props.exactHash && linkRoute.hash !== route.value.hash) {
144
175
  return false
145
176
  }
146
177
 
@@ -169,10 +200,52 @@ function resolveLinkClass({ route, isActive, isExactActive }: any) {
169
200
  isAction: Boolean(props.isAction)
170
201
  })
171
202
  }
203
+
204
+ // Handle navigation without vue-router
205
+ const handleNavigation = (href: string) => {
206
+ if (isExternal.value) {
207
+ window.location.href = href
208
+ } else {
209
+ window.location.pathname = href
210
+ }
211
+ }
172
212
  </script>
173
213
 
174
214
  <template>
175
- <RouterLink v-slot="{ href, navigate, route: linkRoute, isActive, isExactActive }" v-bind="routerLinkProps" :to="to || '#'" custom>
215
+ <template v-if="hasRouter">
216
+ <RouterLink v-slot="{ href, navigate, route: linkRoute, isActive, isExactActive }" v-bind="routerLinkProps" :to="to || '#'" custom>
217
+ <template v-if="custom">
218
+ <slot
219
+ v-bind="{
220
+ ...$attrs,
221
+ as,
222
+ type,
223
+ disabled,
224
+ target: props.target ? props.target : undefined,
225
+ href: to ? (isExternal ? to as string : href) : undefined,
226
+ navigate,
227
+ active: isLinkActive({ route: linkRoute, isActive, isExactActive })
228
+ }"
229
+ />
230
+ </template>
231
+ <B24LinkBase
232
+ v-else
233
+ v-bind="{
234
+ ...$attrs,
235
+ as,
236
+ type,
237
+ disabled,
238
+ href: to ? (isExternal ? to as string : href) : undefined,
239
+ navigate
240
+ }"
241
+ :class="resolveLinkClass({ route: linkRoute, isActive: isActive, isExactActive: isExactActive })"
242
+ >
243
+ <slot :active="isLinkActive({ route: linkRoute, isActive, isExactActive })" />
244
+ </B24LinkBase>
245
+ </RouterLink>
246
+ </template>
247
+
248
+ <template v-else>
176
249
  <template v-if="custom">
177
250
  <slot
178
251
  v-bind="{
@@ -180,10 +253,9 @@ function resolveLinkClass({ route, isActive, isExactActive }: any) {
180
253
  as,
181
254
  type,
182
255
  disabled,
183
- target: props.target ? props.target : undefined,
184
256
  href: to ? (isExternal ? to as string : href) : undefined,
185
- navigate,
186
- active: isLinkActive({ route: linkRoute, isActive, isExactActive })
257
+ navigate: () => to && handleNavigation(to as string),
258
+ active: false
187
259
  }"
188
260
  />
189
261
  </template>
@@ -194,12 +266,12 @@ function resolveLinkClass({ route, isActive, isExactActive }: any) {
194
266
  as,
195
267
  type,
196
268
  disabled,
197
- href: to ? (isExternal ? to as string : href) : undefined,
198
- navigate
269
+ href: to ? (isExternal ? to as string : href as string) : undefined
199
270
  }"
200
- :class="resolveLinkClass({ route: linkRoute, isActive: isActive, isExactActive: isExactActive })"
271
+ :class="ui({ class: props.class, disabled })"
272
+ @click="to && handleNavigation(to as string)"
201
273
  >
202
- <slot :active="isLinkActive({ route: linkRoute, isActive, isExactActive })" />
274
+ <slot :active="false" />
203
275
  </B24LinkBase>
204
- </RouterLink>
276
+ </template>
205
277
  </template>
@@ -3156,7 +3156,7 @@ const modal = {
3156
3156
  overlay: "fixed inset-0 bg-base-950/20 dark:bg-base-950/30",
3157
3157
  content: [
3158
3158
  "py-md2 px-5",
3159
- "fixed w-full h-dvh bg-white dark:bg-base-950",
3159
+ "fixed bg-white dark:bg-base-950",
3160
3160
  // 'divide-y divide-base-900/10 dark:divide-white/20',
3161
3161
  "flex flex-col focus:outline-none"
3162
3162
  ].join(" "),
@@ -3180,11 +3180,10 @@ const modal = {
3180
3180
  },
3181
3181
  false: {
3182
3182
  content: [
3183
- "top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]",
3184
- "sm:min-w-[400px]",
3185
- "sm:max-w-[420px] sm:h-auto sm:max-h-[calc(100vh-4rem)]",
3186
- "sm:rounded-md sm:shadow-lg",
3187
- "sm:ring ring-base-300 dark:ring-base-800"
3183
+ "top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2",
3184
+ "w-[calc(100vw-2rem)] max-w-lg max-h-[calc(100vh-2rem)] sm:max-h-[calc(100vh-4rem)]",
3185
+ "rounded-md shadow-lg",
3186
+ "ring ring-base-300 dark:ring-base-800"
3188
3187
  ].join(" ")
3189
3188
  }
3190
3189
  }
@@ -3158,7 +3158,7 @@ const modal = {
3158
3158
  overlay: "fixed inset-0 bg-base-950/20 dark:bg-base-950/30",
3159
3159
  content: [
3160
3160
  "py-md2 px-5",
3161
- "fixed w-full h-dvh bg-white dark:bg-base-950",
3161
+ "fixed bg-white dark:bg-base-950",
3162
3162
  // 'divide-y divide-base-900/10 dark:divide-white/20',
3163
3163
  "flex flex-col focus:outline-none"
3164
3164
  ].join(" "),
@@ -3182,11 +3182,10 @@ const modal = {
3182
3182
  },
3183
3183
  false: {
3184
3184
  content: [
3185
- "top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]",
3186
- "sm:min-w-[400px]",
3187
- "sm:max-w-[420px] sm:h-auto sm:max-h-[calc(100vh-4rem)]",
3188
- "sm:rounded-md sm:shadow-lg",
3189
- "sm:ring ring-base-300 dark:ring-base-800"
3185
+ "top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2",
3186
+ "w-[calc(100vw-2rem)] max-w-lg max-h-[calc(100vh-2rem)] sm:max-h-[calc(100vh-4rem)]",
3187
+ "rounded-md shadow-lg",
3188
+ "ring ring-base-300 dark:ring-base-800"
3190
3189
  ].join(" ")
3191
3190
  }
3192
3191
  }
package/dist/unplugin.cjs CHANGED
@@ -5,7 +5,7 @@ const pathe = require('pathe');
5
5
  const unplugin = require('unplugin');
6
6
  const defu = require('defu');
7
7
  const tailwind = require('@tailwindcss/vite');
8
- const templates = require('./shared/b24ui-nuxt.BfbMerCZ.cjs');
8
+ const templates = require('./shared/b24ui-nuxt.D-N3gDSr.cjs');
9
9
  const tinyglobby = require('tinyglobby');
10
10
  const knitwork = require('knitwork');
11
11
  const MagicString = require('magic-string');
package/dist/unplugin.mjs CHANGED
@@ -3,7 +3,7 @@ import { join, normalize } from 'pathe';
3
3
  import { createUnplugin } from 'unplugin';
4
4
  import { defu } from 'defu';
5
5
  import tailwind from '@tailwindcss/vite';
6
- import { g as getTemplates, d as defaultOptions, a as getDefaultUiConfig } from './shared/b24ui-nuxt.BYTVBEky.mjs';
6
+ import { g as getTemplates, d as defaultOptions, a as getDefaultUiConfig } from './shared/b24ui-nuxt.CAS1q3My.mjs';
7
7
  import { globSync } from 'tinyglobby';
8
8
  import { genSafeVariableName } from 'knitwork';
9
9
  import MagicString from 'magic-string';
package/dist/vite.cjs CHANGED
@@ -6,7 +6,7 @@ require('pathe');
6
6
  require('unplugin');
7
7
  require('defu');
8
8
  require('@tailwindcss/vite');
9
- require('./shared/b24ui-nuxt.BfbMerCZ.cjs');
9
+ require('./shared/b24ui-nuxt.D-N3gDSr.cjs');
10
10
  require('scule');
11
11
  require('@nuxt/kit');
12
12
  require('tinyglobby');
package/dist/vite.mjs CHANGED
@@ -4,7 +4,7 @@ import 'pathe';
4
4
  import 'unplugin';
5
5
  import 'defu';
6
6
  import '@tailwindcss/vite';
7
- import './shared/b24ui-nuxt.BYTVBEky.mjs';
7
+ import './shared/b24ui-nuxt.CAS1q3My.mjs';
8
8
  import 'scule';
9
9
  import '@nuxt/kit';
10
10
  import 'tinyglobby';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitrix24/b24ui-nuxt",
3
3
  "description": "Bitrix24 UI-Kit for developing web applications REST API for NUXT & VUE",
4
- "version": "0.2.5",
4
+ "version": "0.2.6",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/bitrix24/b24ui.git"
@@ -73,10 +73,10 @@
73
73
  "@nuxtjs/color-mode": "^3.5.2",
74
74
  "@tailwindcss/postcss": "^4.0.6",
75
75
  "@tailwindcss/vite": "^4.0.6",
76
- "@tanstack/vue-table": "^8.20.5",
77
- "@unhead/vue": "^1.11.18",
78
- "@vueuse/core": "^12.5.0",
79
- "@vueuse/integrations": "^12.5.0",
76
+ "@tanstack/vue-table": "^8.21.2",
77
+ "@unhead/vue": "^1.11.19",
78
+ "@vueuse/core": "^12.6.1",
79
+ "@vueuse/integrations": "^12.6.1",
80
80
  "colortranslator": "^4.1.0",
81
81
  "consola": "^3.4.0",
82
82
  "defu": "^6.1.4",
@@ -92,8 +92,8 @@
92
92
  "magic-string": "^0.30.17",
93
93
  "mlly": "^1.7.4",
94
94
  "ohash": "^1.1.4",
95
- "pathe": "^2.0.2",
96
- "reka-ui": "1.0.0-alpha.9",
95
+ "pathe": "^2.0.3",
96
+ "reka-ui": "1.0.0-alpha.10",
97
97
  "scule": "^1.3.0",
98
98
  "tailwind-variants": "^0.3.1",
99
99
  "tailwindcss": "^4.0.6",
@@ -111,7 +111,7 @@
111
111
  "@vue/test-utils": "^2.4.6",
112
112
  "embla-carousel": "^8.5.2",
113
113
  "eslint": "^9.20.1",
114
- "happy-dom": "15.7.4",
114
+ "happy-dom": "^17.1.0",
115
115
  "joi": "^17.13.3",
116
116
  "knitwork": "^1.2.0",
117
117
  "nuxt": "^3.15.4",
@@ -123,7 +123,7 @@
123
123
  "vitest-environment-nuxt": "^1.0.1",
124
124
  "vue-tsc": "^2.2.0",
125
125
  "yup": "^1.6.1",
126
- "zod": "^3.24.1"
126
+ "zod": "^3.24.2"
127
127
  },
128
128
  "peerDependencies": {
129
129
  "typescript": "^5.6.3"
@@ -132,13 +132,12 @@
132
132
  "@bitrix24/b24ui-nuxt": "workspace:*",
133
133
  "chokidar": "3.6.0",
134
134
  "debug": "4.3.7",
135
- "happy-dom": "14.12.3",
136
135
  "rollup": "^4.24.0",
137
136
  "typescript": "5.6.3",
138
137
  "unimport": "3.14.5",
139
- "vue-tsc": "^2.2.0",
140
138
  "unplugin": "^2.2.0",
141
- "vite": "^6.0.7"
139
+ "vite": "^6.0.11",
140
+ "vue-tsc": "2.2.0"
142
141
  },
143
142
  "keywords": [
144
143
  "bitrix24-ui",
@@ -158,16 +157,17 @@
158
157
  "ui-framework"
159
158
  ],
160
159
  "scripts": {
161
- "dev:prepare-short": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground && vite build playground-vue",
162
- "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground && vite build playground-vue && nuxt-component-meta playground --outputDir ../src/.component-meta/",
160
+ "dev:prepare-short": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground && vite build playground-vue && nuxi prepare demo",
161
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground && vite build playground-vue && nuxi prepare demo && nuxt-component-meta playground --outputDir ../src/.component-meta/",
163
162
  "build": "nuxt-module-build build",
164
163
  "dev": "DEV=true nuxi dev playground",
165
- "dev-window": "set DEV=true && nuxi dev playground",
166
164
  "dev:build": "nuxi build playground",
167
165
  "dev:generate": "nuxt generate playground",
168
166
  "dev:preview": "nuxt preview playground",
169
167
  "dev:vue": "DEV=true vite playground-vue",
170
- "dev:vue-window": "set DEV=true && vite playground-vue",
168
+ "demo:dev": "DEV=true nuxi dev demo",
169
+ "demo:generate": "nuxt generate demo",
170
+ "demo:preview": "nuxt preview demo",
171
171
  "docs:full:dev": "pnpm build && vitepress dev docs",
172
172
  "docs:full:build": "pnpm build && vitepress build docs",
173
173
  "docs:dev": "vitepress dev docs",