@ederzeel/nuxt-schema-form-nightly 0.1.0-29104388.947c8fa → 0.1.0-29104758.61b406e

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,7 +1,12 @@
1
1
  <script lang="ts" setup>
2
2
  import { Draft2019 } from 'json-schema-library'
3
3
  import SComponent from './Component.vue'
4
- import { ref, computed } from 'vue'
4
+ import { ref, computed, h, resolveComponent } from 'vue'
5
+ import type { TableColumn } from '@nuxt/ui'
6
+ import type { Row } from '@tanstack/vue-table'
7
+
8
+ const UDropdownMenu = resolveComponent('UDropdownMenu')
9
+ const UButton = resolveComponent('UButton')
5
10
 
6
11
  const props = defineProps<{
7
12
  id: string
@@ -9,18 +14,20 @@ const props = defineProps<{
9
14
  description?: string
10
15
  jsonSchemaPath: string
11
16
  items: PropertiesType
12
- modelValue: unknown[]
17
+ modelValue: Record<string, unknown>[]
13
18
  isRequired: boolean
14
19
  minItems?: number
15
20
  maxItems?: number
16
21
  edit?: boolean
17
- columns?: ColumnItem[]
22
+ columns?: TableColumn<{}>[]
18
23
  editInline?: boolean
19
24
  }>()
20
25
 
21
26
  type ColumnItem = {
22
27
  key: string
23
28
  label?: string
29
+ header?: string
30
+ accessorKey?: string
24
31
  class?: string
25
32
  }
26
33
 
@@ -31,7 +38,7 @@ type PropertiesType = {
31
38
  [key: string]: unknown
32
39
  }
33
40
  const emit = defineEmits(['update:modelValue', 'submit'])
34
- const onInput = (value: unknown, index: number) => {
41
+ const onInput = (value: Record<string, unknown>, index: number) => {
35
42
  props.modelValue[index] = value
36
43
  emit('update:modelValue', props.modelValue)
37
44
  }
@@ -55,7 +62,7 @@ const add = () => {
55
62
 
56
63
  const remove = (index: number) => {
57
64
  const res = props.modelValue.splice(index, 1)
58
- emit('update:modelValue', res)
65
+ emit('update:modelValue', props.modelValue)
59
66
  }
60
67
 
61
68
  const massRemove = () => {
@@ -67,33 +74,16 @@ const massRemove = () => {
67
74
  emit('update:modelValue', res)
68
75
  }
69
76
 
70
- const model = ref({
77
+ const model = ref<{ open: boolean; index: number; value: Record<string, unknown> }>({
71
78
  open: false,
72
- index: 0
79
+ index: 0,
80
+ value: {}
73
81
  })
74
82
 
75
83
  const open = (index: number) => {
76
- model.value = { open: true, index: index }
84
+ model.value = { open: true, index: index, value: structuredClone(values.value[index]) }
77
85
  }
78
86
 
79
- const actions = (i: number) => [
80
- [
81
- {
82
- label: 'edit',
83
- click: () => open(i)
84
- }
85
- ],
86
- [
87
- {
88
- label: 'delete',
89
- click: () => {
90
- remove(i)
91
- selectedRows.value = []
92
- }
93
- }
94
- ]
95
- ]
96
-
97
87
  const massActions = [
98
88
  [
99
89
  {
@@ -106,39 +96,86 @@ const massActions = [
106
96
  ]
107
97
  ]
108
98
 
109
- const columns = computed(() => {
99
+ const columns = computed<TableColumn<{}>[]>(() => {
110
100
  const columns = props.columns ?? []
101
+ if (props.editInline) {
102
+ columns.push({
103
+ id: 'expand',
104
+ cell: ({ row }) =>
105
+ h(UButton, {
106
+ color: 'neutral',
107
+ variant: 'ghost',
108
+ icon: 'i-lucide-chevron-down',
109
+ square: true,
110
+ 'aria-label': 'Expand',
111
+ ui: {
112
+ leadingIcon: ['transition-transform', row.getIsExpanded() ? 'duration-200 rotate-180' : '']
113
+ },
114
+ onClick: () => row.toggleExpanded()
115
+ })
116
+ })
117
+ }
111
118
 
112
119
  if (props.items.type === 'object') {
113
- for (const column of Object.keys(props?.items?.properties).map(x => ({ key: x, label: x }))) {
120
+ for (const column of Object.keys(props?.items?.properties).map<TableColumn<{}>>(x => ({
121
+ header: x,
122
+ accessorKey: x,
123
+ cell: ({ row }) => row.getValue(x)
124
+ }))) {
114
125
  columns.push(column)
115
126
  }
116
127
  }
117
128
 
118
129
  if (props.edit) {
119
130
  columns.push({
120
- key: 'actions',
121
- class: 'w-2'
131
+ id: 'actions',
132
+ cell: ({ row }) => {
133
+ return h(
134
+ 'div',
135
+ { class: 'text-right' },
136
+ h(
137
+ UDropdownMenu,
138
+ {
139
+ content: {
140
+ align: 'end'
141
+ },
142
+ items: getRowItems(row),
143
+ 'aria-label': 'Actions dropdown'
144
+ },
145
+ () =>
146
+ h(UButton, {
147
+ icon: 'i-lucide-ellipsis-vertical',
148
+ color: 'neutral',
149
+ variant: 'ghost',
150
+ class: 'ml-auto',
151
+ 'aria-label': 'Actions dropdown'
152
+ })
153
+ )
154
+ )
155
+ }
122
156
  })
123
157
  }
124
158
 
125
159
  return columns
126
160
  })
127
161
 
128
- const selectedRows = ref([])
129
-
130
- const todoStatus = [
131
- {
132
- key: 'uncompleted',
133
- label: 'In Progress',
134
- value: false
135
- },
136
- {
137
- key: 'completed',
138
- label: 'Completed',
139
- value: true
140
- }
141
- ]
162
+ function getRowItems(row: Row<{}>) {
163
+ return [
164
+ {
165
+ label: 'edit',
166
+ onSelect: () => open(row.index)
167
+ },
168
+ {
169
+ label: 'delete',
170
+ onSelect: () => {
171
+ remove(row.index)
172
+ selectedRows.value = []
173
+ }
174
+ }
175
+ ]
176
+ }
177
+
178
+ const selectedRows = ref<{ __id: any }[]>([])
142
179
 
143
180
  const expand = ref({
144
181
  openedRows: [],
@@ -146,7 +183,16 @@ const expand = ref({
146
183
  })
147
184
 
148
185
  const options = computed(() => {
149
- const res = {}
186
+ let res: {
187
+ modelValue?: any
188
+ 'onUpdate:modelValue'?: (v: any) => void
189
+ expand?: {
190
+ openedRows: any[]
191
+ row: null
192
+ }
193
+ 'update:expand'?: (v: any) => void
194
+ } = {}
195
+
150
196
  if (props.edit) {
151
197
  res.modelValue = selectedRows.value
152
198
  res['onUpdate:modelValue'] = value => (selectedRows.value = value)
@@ -155,6 +201,7 @@ const options = computed(() => {
155
201
  res.expand = expand.value
156
202
  res['update:expand'] = value => (expand.value = value)
157
203
  }
204
+
158
205
  return res
159
206
  })
160
207
  </script>
@@ -176,39 +223,37 @@ const options = computed(() => {
176
223
  </UDropdownMenu>
177
224
  </div>
178
225
  </div>
179
- <UTable v-bind="options" by="__id" :rows="values" :columns="columns">
180
- <template #name-data="{ row }">
181
- <span :class="[selected.find(person => person.id === row.id) && 'text-primary-500 dark:text-primary-400']">{{
182
- row.name
183
- }}</span>
184
- </template>
185
-
186
- <template #expand="{ row, index }">
226
+ <UTable v-bind="options" by="__id" :data="values" :columns="columns" class="flex-1">
227
+ <template #expanded="{ row }">
228
+ {{ row }}
187
229
  <div class="p-4">
188
- <SComponent :id="id.length <= 0 ? `${index}` : `${id}[${index}].${items.id}`" :model-value="row"
189
- :json-schema-path="jsonSchemaPath?.length <= 0 ? `properties.${index}` : `${jsonSchemaPath}[${index}]`"
190
- v-bind="items" :isRequired="false" class="mt-4" @update:model-value="event => onInput(event, index)"
230
+ <SComponent :id="id.length <= 0 ? `${row.index}` : `${id}[${row.index}].${items.id}`"
231
+ :model-value="row.original" :json-schema-path="jsonSchemaPath?.length <= 0 ? `properties.${row.index}` : `${jsonSchemaPath}[${row.index}]`
232
+ " v-bind="items" :isRequired="false" class="mt-4"
233
+ @update:model-value="(event: Record<string, unknown>) => onInput(event, row.index)"
191
234
  @submit="() => emit('submit')" />
192
235
  </div>
193
236
  </template>
194
-
195
- <template #actions-data="{ index }">
196
- <UDropdownMenu :items="actions(index)">
197
- <UButton color="neutral" variant="ghost" icon="i-heroicons-ellipsis-horizontal-20-solid" />
198
- </UDropdownMenu>
199
- </template>
200
237
  </UTable>
201
238
  </div>
202
239
  <UModal v-model:open="model.open">
203
- <UCard>
204
- <SComponent :id="id.length <= 0 ? `${model.index}` : `${id}[0].${items.id}`" :model-value="values[model.index]"
205
- :json-schema-path="jsonSchemaPath?.length <= 0 ? `properties.${model.index}` : `${jsonSchemaPath}[${model.index}]`
206
- " v-bind="items" :isRequired="false" class="mt-4" @update:model-value="event => onInput(event, model.index)"
207
- @submit="() => emit('submit')" />
208
- <template #footer>
209
- <UButton>Save</UButton>
210
- </template>
211
- </UCard>
240
+ <template #content>
241
+ <UCard>
242
+ <SComponent :id="id.length <= 0 ? `${model.index}` : `${id}[0].${items.id}`" :model-value="model.value"
243
+ :json-schema-path="jsonSchemaPath?.length <= 0 ? `properties.${model.index}` : `${jsonSchemaPath}[${model.index}]`
244
+ " v-bind="items" :isRequired="false" class="mt-4"
245
+ @update:model-value="(event: Record<string, unknown>) => (model.value = event)"
246
+ @submit="() => emit('submit')" />
247
+ <template #footer>
248
+ <UButton @click="
249
+ () => {
250
+ onInput(model.value, model.index)
251
+ model.open = false
252
+ }
253
+ ">Save</UButton>
254
+ </template>
255
+ </UCard>
256
+ </template>
212
257
  </UModal>
213
258
  </div>
214
259
  </template>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ederzeel/nuxt-schema-form-nightly",
3
- "version": "0.1.0-29104388.947c8fa",
3
+ "version": "0.1.0-29104758.61b406e",
4
4
  "description": "A runtime form generator for nuxt",
5
5
  "type": "module",
6
6
  "exports": {
@@ -52,6 +52,7 @@
52
52
  "@nuxt/kit": "^3.15.4",
53
53
  "@nuxt/module-builder": "^0.8.4",
54
54
  "@nuxt/ui": "^3.0.0",
55
+ "@tanstack/vue-table": "^8.21.3",
55
56
  "@types/eslint": "^9.6.1",
56
57
  "eslint": "^9.19.0",
57
58
  "eslint-config-prettier": "^10.0.1",