@ederzeel/nuxt-schema-form-nightly 0.1.0-29104388.947c8fa → 0.1.0-29104650.63764c1

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, type Ref } 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
@@ -14,13 +19,15 @@ const props = defineProps<{
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
 
@@ -50,12 +57,13 @@ const values = computed(() => {
50
57
  })
51
58
 
52
59
  const add = () => {
60
+ console.log('add')
53
61
  emit('update:modelValue', [...props.modelValue, schemaObject.value.getTemplate()])
54
62
  }
55
63
 
56
64
  const remove = (index: number) => {
57
65
  const res = props.modelValue.splice(index, 1)
58
- emit('update:modelValue', res)
66
+ emit('update:modelValue', props.modelValue)
59
67
  }
60
68
 
61
69
  const massRemove = () => {
@@ -76,24 +84,6 @@ const open = (index: number) => {
76
84
  model.value = { open: true, index: 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,15 +183,25 @@ 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
- res['onUpdate:modelValue'] = value => (selectedRows.value = value)
198
+ // res['onUpdate:modelValue'] = value => (selectedRows.value = value)
153
199
  }
154
200
  if (props.editInline) {
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>
@@ -167,8 +214,15 @@ const options = computed(() => {
167
214
  <div>
168
215
  <div class="flex justify-between items-center w-full px-4 py-3">
169
216
  <div class="flex gap-1.5 items-center">
170
- <UButton v-if="edit" :disabled="maxItems && values.length >= maxItems" @click="add" icon="i-heroicons-plus"
171
- trailing color="neutral" size="xs" />
217
+ <UButton
218
+ v-if="edit"
219
+ :disabled="maxItems && values.length >= maxItems"
220
+ @click="add"
221
+ icon="i-heroicons-plus"
222
+ trailing
223
+ color="neutral"
224
+ size="xs"
225
+ />
172
226
  </div>
173
227
  <div class="flex gap-1.5 items-center">
174
228
  <UDropdownMenu v-if="selectedRows.length > 0" :items="massActions">
@@ -176,39 +230,46 @@ const options = computed(() => {
176
230
  </UDropdownMenu>
177
231
  </div>
178
232
  </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 }">
233
+ <UTable v-bind="options" by="__id" :data="values" :columns="columns" class="flex-1">
234
+ <template #expanded="{ row, index }">
187
235
  <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)"
191
- @submit="() => emit('submit')" />
236
+ {{ row }}
237
+ <SComponent
238
+ :id="id.length <= 0 ? `${index}` : `${id}[${row.index}].${items.id}`"
239
+ :model-value="row.original"
240
+ :json-schema-path="
241
+ jsonSchemaPath?.length <= 0 ? `properties.${index}` : `${jsonSchemaPath}[${row.index}]`
242
+ "
243
+ v-bind="items"
244
+ :isRequired="false"
245
+ class="mt-4"
246
+ @update:model-value="(event: unknown) => onInput(event, row.index)"
247
+ @submit="() => emit('submit')"
248
+ />
192
249
  </div>
193
250
  </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
251
  </UTable>
201
252
  </div>
202
253
  <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>
254
+ <template #content>
255
+ <UCard>
256
+ <SComponent
257
+ :id="id.length <= 0 ? `${model.index}` : `${id}[0].${items.id}`"
258
+ :model-value="values[model.index]"
259
+ :json-schema-path="
260
+ jsonSchemaPath?.length <= 0 ? `properties.${model.index}` : `${jsonSchemaPath}[${model.index}]`
261
+ "
262
+ v-bind="items"
263
+ :isRequired="false"
264
+ class="mt-4"
265
+ @update:model-value="event => onInput(event, model.index)"
266
+ @submit="() => emit('submit')"
267
+ />
268
+ <template #footer>
269
+ <UButton>Save</UButton>
270
+ </template>
271
+ </UCard>
272
+ </template>
212
273
  </UModal>
213
274
  </div>
214
275
  </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-29104650.63764c1",
4
4
  "description": "A runtime form generator for nuxt",
5
5
  "type": "module",
6
6
  "exports": {