@falcondev-oss/nuxt-layers-base 0.34.0 → 0.35.2

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.
@@ -1,100 +1,89 @@
1
- import type { VNode } from 'vue'
2
- import { UCard, UDropdownMenu, UField, UForm, UInput } from '#components'
3
- import { Component } from 'vue'
4
- import { z } from 'zod'
5
-
6
- // https://github.com/vuejs/language-tools/blob/master/packages/component-type-helpers/index.ts
7
- type ComponentSlots<T> = T extends new (...args: any) => { $slots: infer S }
8
- ? NonNullable<S>
9
- : T extends (props: any, ctx: { slots: infer S; attrs: any; emit: any }, ...args: any) => any
10
- ? NonNullable<S>
11
- : {}
12
-
13
- type ComponentProps<T> = T extends new (...args: any) => { $props: infer P }
14
- ? NonNullable<P>
15
- : T extends (props: infer P, ...args: any) => any
16
- ? P
17
- : {}
1
+ // import type { VNode } from 'vue'
2
+ // import { UCard, UDropdownMenu, UField, UForm, UInput } from '#components'
3
+ // import { z } from 'zod'
18
4
 
19
5
  /* eslint-disable ts/no-empty-object-type */
20
- export default defineSetupComponent((_: { props: {}; emits: {}; slots: {} }) => ({
21
- props: [],
22
- emits: [],
23
- setup: () => {
24
- const form = useForm({
25
- schema: z.object({
26
- duration: z.number().meta({ title: 'Duration' }),
27
- dateIso: z.string().meta({ title: 'Datum' }),
28
- text: z
29
- .string()
30
- .length(8)
31
- // .max(8)
32
- .meta({
33
- title: 'Text',
34
- description: 'Beschreibung',
35
- default: 'Default Wert',
36
- examples: ['Hier könnte ein Beispieltext stehen', '123'],
37
- }),
38
- }),
39
- sourceValues: () => ({
40
- dateIso: null,
41
- duration: null,
42
- text: '',
43
- }),
44
- async submit({ values }) {
45
- await new Promise((resolve) => setTimeout(resolve, 2000))
46
- console.log(values)
47
- },
48
- })
6
+ // @ts-expect-error FIXME: empty emits causes type error
7
+ export default defineSetupComponent((_: { props: { name: string }; emits: {}; slots: {} }) => ({
8
+ props: props(_, ['name']),
9
+ emits: emits(_, []),
10
+ setup: (props) => {
11
+ console.log(props)
12
+ // const form = useForm({
13
+ // schema: z.object({
14
+ // duration: z.number().meta({ title: 'Duration' }),
15
+ // dateIso: z.string().meta({ title: 'Datum' }),
16
+ // text: z
17
+ // .string()
18
+ // .length(8)
19
+ // // .max(8)
20
+ // .meta({
21
+ // title: 'Text',
22
+ // description: 'Beschreibung',
23
+ // default: 'Default Wert',
24
+ // examples: ['Hier könnte ein Beispieltext stehen', '123'],
25
+ // }),
26
+ // }),
27
+ // sourceValues: () => ({
28
+ // dateIso: null,
29
+ // duration: null,
30
+ // text: '',
31
+ // }),
32
+ // async submit({ values }) {
33
+ // await new Promise((resolve) => setTimeout(resolve, 2000))
34
+ // console.log(values)
35
+ // },
36
+ // })
49
37
 
50
38
  return () => (
51
- <UCard
52
- class="max-w-sm"
53
- ui={{
54
- body: 'flex flex-col gap-4 items-start ',
55
- }}
56
- >
57
- <UForm form={form} successToast={{ title: 'Success' }} class="flex flex-col gap-4">
58
- {form.data}
39
+ // <UCard
40
+ // class="max-w-sm"
41
+ // ui={{
42
+ // body: 'flex flex-col gap-4 items-start ',
43
+ // }}
44
+ // >
45
+ // <UForm form={form} successToast={{ title: 'Success' }} class="flex flex-col gap-4">
46
+ // {form.data}
59
47
 
60
- {/* <UField
61
- field={form.fields.text.$use()}
62
- error-inline
63
- vSlots={vSlots(UField, {
64
- default({ bind }) {
65
- return <UInput class="w-full" {...bind} />
66
- },
67
- })}
68
- ></UField> */}
69
- </UForm>
70
- {/* <UForm
71
- :form
72
- :success-toast="{
73
- title: 'test',
74
- description: 'wow',
75
- }"
76
- class="flex flex-col gap-4"
77
- >
78
- {{ form.data }}
79
- <UField v-slot="{ bind, field }" :field="form.fields.text.$use()" error-inline>
80
- {{ field.schema }}
81
- <UInput class="w-full" v-bind="bind" />
82
- </UField>
83
- <UField
84
- v-slot="{ bind }"
85
- :field="
86
- form.fields.dateIso.$use({
87
- translate: dateValueIsoTranslator(),
88
- })
89
- "
90
- >
91
- <UInputDatePicker class="w-full" v-bind="bind" />
92
- </UField>
93
- <UField v-slot="{ bind }" :field="form.fields.duration.$use()">
94
- <UInputDurationMinutes class="w-full" v-bind="bind" />
95
- </UField>
96
- </UForm> */}
97
- </UCard>
48
+ // {/* <UField
49
+ // field={form.fields.text.$use()}
50
+ // error-inline
51
+ // vSlots={vSlots(UField, {
52
+ // default({ bind }) {
53
+ // return <UInput class="w-full" {...bind} />
54
+ // },
55
+ // })}
56
+ // ></UField> */}
57
+ // </UForm>
58
+ // {/* <UForm
59
+ // :form
60
+ // :success-toast="{
61
+ // title: 'test',
62
+ // description: 'wow',
63
+ // }"
64
+ // class="flex flex-col gap-4"
65
+ // >
66
+ // {{ form.data }}
67
+ // <UField v-slot="{ bind, field }" :field="form.fields.text.$use()" error-inline>
68
+ // {{ field.schema }}
69
+ // <UInput class="w-full" v-bind="bind" />
70
+ // </UField>
71
+ // <UField
72
+ // v-slot="{ bind }"
73
+ // :field="
74
+ // form.fields.dateIso.$use({
75
+ // translate: dateValueIsoTranslator(),
76
+ // })
77
+ // "
78
+ // >
79
+ // <UInputDatePicker class="w-full" v-bind="bind" />
80
+ // </UField>
81
+ // <UField v-slot="{ bind }" :field="form.fields.duration.$use()">
82
+ // <UInputDurationMinutes class="w-full" v-bind="bind" />
83
+ // </UField>
84
+ // </UForm> */}
85
+ // </UCard>
86
+ <></>
98
87
  )
99
88
  },
100
89
  }))
@@ -1,4 +1,5 @@
1
1
  import { UButton, UCard } from '#components'
2
+ import { setup } from '../../../app/utils/define-setup-component'
2
3
 
3
4
  export type ListItems = { label: string; value: string }[]
4
5
 
@@ -18,14 +19,14 @@ export default defineSetupComponent(
18
19
  // props: ['items'],
19
20
  emits: emits(_, ['choose']),
20
21
  // emits: ['choose'],
21
- setup: generic(_, (props, { emit, slots }) => {
22
+ setup: setup(_, (props, { emit, slots }) => {
22
23
  const selected = ref<T[number]>()
23
24
 
24
25
  return () => (
25
26
  <UCard
26
27
  class="w-fit"
27
28
  vSlots={vSlots(UCard, {
28
- header: () => <h1>Select an item</h1>,
29
+ header: () => [<h1>Select an item</h1>],
29
30
  })}
30
31
  >
31
32
  <div class="flex flex-col gap-2">
@@ -39,7 +40,7 @@ export default defineSetupComponent(
39
40
  emit('choose', item)
40
41
  }}
41
42
  vSlots={vSlots(UButton, {
42
- leading: () => `[${selected.value?.value === item.value ? 'x' : ' '}] `,
43
+ leading: () => [<>{`[${selected.value?.value === item.value ? 'x' : ' '}] `}</>],
43
44
  })}
44
45
  >
45
46
  {item.label}
@@ -7,6 +7,7 @@ import type {
7
7
  NavigationMenuItem,
8
8
  NavigationMenuProps,
9
9
  } from '@nuxt/ui'
10
+ import { mergeSlotClass } from '../../utils/ui'
10
11
 
11
12
  defineProps<{
12
13
  sidebar?: DashboardSidebarProps
@@ -43,8 +44,8 @@ const config = useRuntimeConfig()
43
44
  collapsible
44
45
  :ui="{
45
46
  ...sidebar?.ui,
46
- header: [sidebar?.ui?.header, 'border-b border-default'],
47
- footer: [sidebar?.ui?.footer, 'border-t border-default'],
47
+ header: mergeSlotClass(sidebar?.ui?.header, 'border-b border-default'),
48
+ footer: mergeSlotClass(sidebar?.ui?.footer, 'border-t border-default'),
48
49
  }"
49
50
  >
50
51
  <template
@@ -4,6 +4,7 @@ import type { FormFieldProps, FormFieldSlots } from '@nuxt/ui'
4
4
  import { createReusableTemplate } from '@vueuse/core'
5
5
  import { useForwardProps } from 'reka-ui'
6
6
  import * as R from 'remeda'
7
+ import { mergeSlotClass } from '../../utils/ui'
7
8
 
8
9
  type InputProps<T> = {
9
10
  'modelValue': T
@@ -99,8 +100,8 @@ const [DefineErrorTemplate, ErrorTemplate] = createReusableTemplate({
99
100
  v-bind="formFieldProps"
100
101
  :ui="{
101
102
  ...formFieldProps.ui,
102
- hint: [formFieldProps.ui?.hint, isOverMaxLength ? 'text-error' : ''],
103
- error: [formFieldProps.ui?.error, 'mt-1!'],
103
+ hint: mergeSlotClass(formFieldProps.ui?.hint, isOverMaxLength ? 'text-error' : ''),
104
+ error: mergeSlotClass(formFieldProps.ui?.error, 'mt-1!'),
104
105
  }"
105
106
  :error="!!field.errors"
106
107
  :class="props.class"
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable ts/no-empty-object-type */
2
- import type { AllUnionFields, Schema, UnionToTuple } from 'type-fest'
2
+ import type { AllUnionFields, UnionToTuple } from 'type-fest'
3
3
  import type {
4
4
  ComponentOptionsMixin,
5
5
  CreateComponentPublicInstanceWithMixins,
@@ -84,7 +84,7 @@ export function emits<
84
84
  return emits
85
85
  }
86
86
 
87
- export function generic<
87
+ export function setup<
88
88
  const Opts extends {
89
89
  props: Record<string, any>
90
90
  emits: ObjectEmitsOptions
@@ -96,6 +96,7 @@ export function generic<
96
96
  props: Props,
97
97
  ctx: SetupContext<Opts['emits'], Slots>,
98
98
  ) => RenderFunction | Promise<RenderFunction>,
99
+ // eslint-disable-next-line no-shadow
99
100
  >(_opts: Opts, setup: Setup): NoInfer<Setup> {
100
101
  return setup
101
102
  }
@@ -0,0 +1,13 @@
1
+ import type { SlotClass, SlotClassReplacer } from '@nuxt/ui'
2
+ import type { ClassValue } from 'tailwind-variants'
3
+ import { cnMerge } from 'tailwind-variants'
4
+
5
+ export function mergeSlotClass(ui: SlotClass, extend: ClassValue): SlotClassReplacer {
6
+ return (defaults) => {
7
+ const withBase = cnMerge(defaults, extend)() ?? ''
8
+ if (typeof ui === 'function') {
9
+ return ui(withBase)
10
+ }
11
+ return cnMerge(withBase, ui)() ?? ''
12
+ }
13
+ }
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@falcondev-oss/nuxt-layers-base",
3
3
  "type": "module",
4
- "version": "0.34.0",
4
+ "version": "0.35.2",
5
5
  "description": "Nuxt layer with lots of useful helpers and @nuxt/ui components",
6
6
  "license": "MIT",
7
- "repository": "github:falcondev-oss/nuxt-layers",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "github:falcondev-oss/nuxt-layers"
10
+ },
8
11
  "bugs": {
9
12
  "url": "https://github.com/falcondev-oss/nuxt-layers/issues"
10
13
  },
@@ -14,46 +17,46 @@
14
17
  "pnpm": "11"
15
18
  },
16
19
  "peerDependencies": {
17
- "@falcondev-oss/form-core": ">=0.22.4",
18
- "@falcondev-oss/form-vue": ">=0.22.4",
19
- "@internationalized/date": ">=3.12.0",
20
- "@nuxt/ui": ">=4.6.1"
20
+ "@falcondev-oss/form-core": ">=0.23.5",
21
+ "@falcondev-oss/form-vue": ">=0.23.5",
22
+ "@internationalized/date": ">=3.12.1",
23
+ "@nuxt/ui": ">=4.9.0",
24
+ "tailwind-variants": ">=3.2.2"
21
25
  },
22
26
  "dependencies": {
23
27
  "@falcondev-oss/trpc-typed-form-data": "^0.4.3",
24
28
  "@falcondev-oss/trpc-vue-query": "^0.5.4",
25
- "@iconify-json/lucide": "^1.2.103",
26
- "@nuxt/icon": "^2.2.1",
27
- "@nuxtjs/color-mode": "^4.0.0",
28
- "@tanstack/vue-query": "^5.100.1",
29
- "@trpc/client": "^11.16.0",
30
- "@trpc/server": "^11.16.0",
31
- "@vue/devtools-api": "^8.1.1",
32
- "@vueuse/core": "^14.2.1",
33
- "@vueuse/nuxt": "^14.2.1",
34
- "@vueuse/router": "^14.2.1",
29
+ "@iconify-json/lucide": "^1.2.114",
30
+ "@nuxt/icon": "^2.2.3",
31
+ "@nuxtjs/color-mode": "^4.0.1",
32
+ "@tanstack/vue-query": "^5.101.0",
33
+ "@trpc/client": "^11.18.0",
34
+ "@trpc/server": "^11.18.0",
35
+ "@vue/devtools-api": "^8.1.3",
36
+ "@vueuse/core": "^14.3.0",
37
+ "@vueuse/nuxt": "^14.3.0",
38
+ "@vueuse/router": "^14.3.0",
35
39
  "arkregex": "^0.0.5",
36
40
  "consola": "^3.4.2",
37
41
  "defu": "^6.1.7",
38
42
  "maska": "^3.2.0",
39
- "reka-ui": "^2.9.6",
40
- "remeda": "^2.33.7",
43
+ "reka-ui": "~2.9.10",
44
+ "remeda": "^2.39.0",
41
45
  "superjson": "^2.2.6",
42
- "tailwindcss": "^4.2.4",
43
- "trpc-nuxt": "^2.0.2",
44
- "type-fest": "^5.6.0",
45
- "vue": "^3.5.33",
46
- "vue-router": "^5.0.6"
46
+ "tailwindcss": "^4.3.1",
47
+ "trpc-nuxt": "^2.1.1",
48
+ "type-fest": "^5.7.0",
49
+ "vue": "^3.5.38",
50
+ "vue-router": "^5.1.0"
47
51
  },
48
52
  "devDependencies": {
49
- "nuxt": "^4.4.2",
53
+ "nuxt": "^4.4.8",
50
54
  "typescript": "^5.9.3",
51
- "vue-tsc": "^3.2.7",
52
- "zod": "^4.3.6"
55
+ "vue-tsc": "^3.3.5",
56
+ "zod": "^4.4.3"
53
57
  },
54
58
  "scripts": {
55
59
  "dev": "nuxi dev .playground",
56
- "dev:prepare": "nuxt prepare .playground",
57
60
  "type-check": "vue-tsc --build",
58
61
  "lint": "pnpm -w eslint:cmd \"$PWD\" && pnpm -w prettier:cmd \"$PWD\" --check",
59
62
  "lint:fix": "pnpm -w eslint:cmd \"$PWD\" --fix && pnpm -w prettier:cmd \"$PWD\" --write"