@bagelink/vue 1.0.30 → 1.0.38

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 (33) hide show
  1. package/dist/components/DataPreview.vue.d.ts.map +1 -1
  2. package/dist/components/DataTable/DataTable.vue.d.ts +8 -3
  3. package/dist/components/DataTable/DataTable.vue.d.ts.map +1 -1
  4. package/dist/components/DataTable/useTableData.d.ts +7 -1
  5. package/dist/components/DataTable/useTableData.d.ts.map +1 -1
  6. package/dist/components/DataTable/useTableSelection.d.ts +4 -1
  7. package/dist/components/DataTable/useTableSelection.d.ts.map +1 -1
  8. package/dist/components/DataTable/useTableVirtualization.d.ts.map +1 -1
  9. package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
  10. package/dist/components/form/FieldArray.vue.d.ts.map +1 -1
  11. package/dist/components/form/inputs/RadioPillsInput.vue.d.ts.map +1 -1
  12. package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
  13. package/dist/index.cjs +194 -107
  14. package/dist/index.mjs +194 -107
  15. package/dist/style.css +487 -68
  16. package/dist/types/BagelForm.d.ts +1 -1
  17. package/dist/types/BagelForm.d.ts.map +1 -1
  18. package/dist/types/index.d.ts +1 -1
  19. package/dist/types/index.d.ts.map +1 -1
  20. package/package.json +1 -1
  21. package/src/components/DataPreview.vue +30 -4
  22. package/src/components/DataTable/DataTable.vue +13 -18
  23. package/src/components/DataTable/useTableData.ts +76 -10
  24. package/src/components/DataTable/useTableSelection.ts +17 -3
  25. package/src/components/DataTable/useTableVirtualization.ts +11 -2
  26. package/src/components/form/FieldArray.vue +44 -5
  27. package/src/components/form/inputs/RadioPillsInput.vue +2 -0
  28. package/src/components/form/inputs/SelectInput.vue +2 -0
  29. package/src/components/layout/BottomMenu.vue +1 -1
  30. package/src/styles/layout.css +240 -0
  31. package/src/styles/mobilLayout.css +240 -0
  32. package/src/types/BagelForm.ts +1 -0
  33. package/src/types/index.ts +1 -0
@@ -14,7 +14,7 @@ export type BagelFieldOptions<T = {
14
14
  }> = (string | ({
15
15
  label?: string;
16
16
  value: string | number;
17
- } | string | number | {
17
+ } | string | number | boolean | {
18
18
  [key: string]: any;
19
19
  })[] | ((val: any, rowData?: T) => void));
20
20
  type GenericAssertFn<T> = (val: any, row: T) => boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"BagelForm.d.ts","sourceRoot":"","sources":["../../src/types/BagelForm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BagelForm.d.ts","sourceRoot":"","sources":["../../src/types/BagelForm.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ export type Tab = {
12
12
  icon?: IconType;
13
13
  } | string;
14
14
  export type ThemeType = 'light' | 'white' | 'red' | 'gray' | 'gray-light' | 'black' | 'green' | 'yellow' | 'primary' | 'blue';
15
- export type Option = string | number | {
15
+ export type Option = string | number | boolean | {
16
16
  [key: string]: any;
17
17
  } | {
18
18
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,mBAAmB,EACnB,mBAAmB,IAAI,uBAAuB,EAC9C,YAAY,GACZ,MAAM,uBAAuB,CAAA;AAE9B,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAEvE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAA;AAEvC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAEzC,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,YAAY,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAE/D,MAAM,MAAM,GAAG,GAAG;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,QAAQ,CAAA;CACf,GAAG,MAAM,CAAA;AAEV,MAAM,MAAM,SAAS,GACpB,OAAO,GACL,OAAO,GACP,KAAK,GACL,MAAM,GACN,YAAY,GACZ,OAAO,GACP,OAAO,GACP,QAAQ,GACR,SAAS,GACT,MAAM,CAAA;AAET,MAAM,MAAM,MAAM,GACf,MAAM,GACN,MAAM,GACN;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,GACtB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAA;AAE5C,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,mBAAmB,EACnB,mBAAmB,IAAI,uBAAuB,EAC9C,YAAY,GACZ,MAAM,uBAAuB,CAAA;AAE9B,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAEvE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAA;AAEvC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAEzC,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,YAAY,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAE/D,MAAM,MAAM,GAAG,GAAG;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,QAAQ,CAAA;CACf,GAAG,MAAM,CAAA;AAEV,MAAM,MAAM,SAAS,GACpB,OAAO,GACL,OAAO,GACP,KAAK,GACL,MAAM,GACN,YAAY,GACZ,OAAO,GACP,OAAO,GACP,QAAQ,GACR,SAAS,GACT,MAAM,CAAA;AAET,MAAM,MAAM,MAAM,GACf,MAAM,GACN,MAAM,GACN,OAAO,GACP;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,GACtB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAA;AAE5C,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "1.0.30",
4
+ "version": "1.0.38",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Neveh Allon",
@@ -9,7 +9,14 @@ import { useTableData } from './DataTable/useTableData'
9
9
  const props = defineProps<Omit<TableSchemaProps<T>, 'data'> & { modelValue: T, includeUnset?: boolean }>()
10
10
  const slots = useSlots() as Slots & Record<string, (props: { row: T, field: BaseBagelField<T> }) => any>
11
11
 
12
- const data = computed(() => Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue])
12
+ const data = computed(() => {
13
+ // Handle undefined or null modelValue
14
+ if (!props.modelValue) {
15
+ return []
16
+ }
17
+
18
+ return Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue]
19
+ })
13
20
 
14
21
  const {
15
22
  computedSchema,
@@ -21,7 +28,14 @@ const {
21
28
  useServerSort: false
22
29
  })
23
30
 
24
- const firstItem = computed(() => computedData.value[0] || {} as T)
31
+ const firstItem = computed(() => {
32
+ // Handle empty computedData
33
+ if (!computedData.value || computedData.value.length === 0) {
34
+ return {} as T
35
+ }
36
+
37
+ return computedData.value[0] || {} as T
38
+ })
25
39
 
26
40
  const { renderField } = useSchemaField<T>({
27
41
  mode: 'preview',
@@ -32,9 +46,14 @@ const { renderField } = useSchemaField<T>({
32
46
 
33
47
  <template>
34
48
  <div class="data-preview">
35
- <template v-for="field in computedSchema" :key="field.id">
36
- <component :is="renderField(field, slots)" />
49
+ <template v-if="computedSchema && computedSchema.length > 0">
50
+ <template v-for="field in computedSchema" :key="field.id">
51
+ <component :is="renderField(field, slots)" />
52
+ </template>
37
53
  </template>
54
+ <div v-else class="empty-preview">
55
+ No data to display
56
+ </div>
38
57
  </div>
39
58
  </template>
40
59
 
@@ -61,4 +80,11 @@ const { renderField } = useSchemaField<T>({
61
80
  .field-value {
62
81
  font-size: 0.95rem;
63
82
  }
83
+
84
+ .empty-preview {
85
+ font-size: 0.9rem;
86
+ color: var(--bgl-black-tint);
87
+ padding: 1rem 0;
88
+ text-align: center;
89
+ }
64
90
  </style>
@@ -19,23 +19,16 @@ export type EmitOrderT = `${string} ${SortDirectionsT}`
19
19
  const props = defineProps<TableSchemaProps<T>>()
20
20
 
21
21
  const emit = defineEmits<{
22
- 'update:selectedItems': [string[]]
23
- 'orderBy': [EmitOrderT]
24
- 'select': [T]
25
- 'lastItemVisible': []
22
+ orderBy: [EmitOrderT]
23
+ select: [T]
24
+ lastItemVisible: []
26
25
  }>()
27
26
 
28
27
  const slots = useSlots() as Slots & Record<string, (props: { row: T, field: BaseBagelField<T> }) => any>
29
28
 
30
29
  const loading = defineModel('loading', { default: false })
31
30
  const itemHeight = defineModel('itemHeight', { default: 50 })
32
- const selectedItems = defineModel<string[]>(
33
- 'selectedItems',
34
- {
35
- default: [] as string[],
36
- set: (value: string[]) => value,
37
- }
38
- )
31
+ const selectedItems = defineModel<string[]>('selectedItems', { default: [] as string[] })
39
32
 
40
33
  const data = computed(() => props.data)
41
34
  const schema = computed(() => props.schema)
@@ -47,7 +40,8 @@ const {
47
40
  computedData,
48
41
  sortField,
49
42
  sortDirection,
50
- toggleSort
43
+ toggleSort,
44
+ cleanTransformedData
51
45
  } = useTableData<T>({ data, schema, columns, useServerSort, onSort: (field, direction) => {
52
46
  emit('orderBy', `${field} ${direction}`.trim() as EmitOrderT)
53
47
  } })
@@ -62,6 +56,7 @@ const {
62
56
  } = useTableSelection<T>({
63
57
  selectable: props.selectable,
64
58
  selectedItems,
59
+ cleanData: cleanTransformedData,
65
60
  onSelect: (item) => { emit('select', item) }
66
61
  })
67
62
 
@@ -149,10 +144,10 @@ watch(
149
144
  @click="toggleSort(field?.id || '')"
150
145
  >
151
146
  <div class="flex">
152
- {{ field.label || keyToLabel(field.id) }}
147
+ {{ field.label || keyToLabel(field?.id) }}
153
148
  <div
154
149
  class="list-arrows"
155
- :class="{ sorted: sortField === field.id }"
150
+ :class="{ sorted: sortField === field?.id }"
156
151
  >
157
152
  <Icon
158
153
  :class="{ desc: sortDirection === 'DESC' }"
@@ -165,9 +160,9 @@ watch(
165
160
  <tbody>
166
161
  <tr
167
162
  v-for="{ data: row } in list"
168
- :key="row.id"
163
+ :key="row?.id || `row-${Math.random()}`"
169
164
  class="row row-item position-relative"
170
- :class="{ selected: computedSelectedItems.includes(row.id ?? '') }"
165
+ :class="{ selected: row?.id && computedSelectedItems.includes(row.id) }"
171
166
  @click="toggleSelectItem(row)"
172
167
  >
173
168
  <td v-if="isSelectable">
@@ -175,13 +170,13 @@ watch(
175
170
  <input
176
171
  v-model="selectedItems"
177
172
  type="checkbox"
178
- :value="row.id"
173
+ :value="row?.id || ''"
179
174
  >
180
175
  </div>
181
176
  </td>
182
177
  <td
183
178
  v-for="field in computedSchema"
184
- :key="`${field.id}-${row.id}`"
179
+ :key="`${field.id}-${row?.id || Math.random()}`"
185
180
  class="col"
186
181
  >
187
182
  <slot
@@ -1,7 +1,7 @@
1
1
  import type { ComputedRef } from 'vue'
2
2
  import type { TableDataOptions, SortDirectionsT } from '../../types/TableSchema'
3
- import { useBglSchema, isDate } from '@bagelink/vue'
4
- import { computed, ref, watch } from 'vue'
3
+ import { useBglSchema, isDate, keyToLabel } from '@bagelink/vue'
4
+ import { computed, ref } from 'vue'
5
5
 
6
6
  const NON_DIGIT_REGEX = /[^\d.-]/g
7
7
 
@@ -34,19 +34,63 @@ export function useTableData<T extends Record<string, any>>(options: UseTableDat
34
34
  const sortField = ref('')
35
35
  const sortDirection = ref<SortDirectionsT>('ASC')
36
36
  // Helper function to get the value from a possibly computed ref
37
- function getValue<V>(value: ComputedRef<V> | V): V {
38
- return (value as ComputedRef<V>).value !== undefined
39
- ? (value as ComputedRef<V>).value
40
- : value as V
37
+ function getValue<V>(value: ComputedRef<V> | V | undefined): V | undefined {
38
+ if (value === undefined || value === null) {
39
+ return undefined
40
+ }
41
+
42
+ try {
43
+ // Check if it's a computed ref with a value property
44
+ if (value && typeof value === 'object' && 'value' in value) {
45
+ return (value as ComputedRef<V>).value
46
+ }
47
+ // Otherwise return the value directly
48
+ return value as V
49
+ } catch (error) {
50
+ console.error('Error in getValue:', error)
51
+ return undefined
52
+ }
41
53
  }
42
54
 
43
55
  // Create a computed property for the schema that will react to changes in options.columns
44
56
  const computedSchema = computed(() => {
45
- return useBglSchema<T>({
57
+ // Get the data safely
58
+ const dataValue = options.data.value || []
59
+
60
+ // Get the schema from useBglSchema
61
+ const schema = useBglSchema<T>({
46
62
  schema: getValue(options.schema),
47
63
  columns: getValue(options.columns),
48
- data: options.data.value,
64
+ data: dataValue,
49
65
  })
66
+
67
+ // If we have a valid schema with fields, filter out fields without an ID
68
+ if (Array.isArray(schema) && schema.length > 0) {
69
+ return schema.filter(field => field && field.id)
70
+ }
71
+
72
+ // If no schema is provided or it's empty, generate a default schema from the data
73
+ if (Array.isArray(dataValue) && dataValue.length > 0) {
74
+ const firstItem = dataValue[0]
75
+
76
+ // Create a schema based on the keys of the first item
77
+ return Object.keys(firstItem || {})
78
+ .filter(key => key !== 'id' && !key.startsWith('_')) // Exclude id and internal fields
79
+ .map(key => ({
80
+ id: key,
81
+ label: keyToLabel(key),
82
+ $el: 'div',
83
+ transform: (val?: any) => {
84
+ // Handle date fields
85
+ const dateFields = ['created_at', 'updated_at']
86
+ if (dateFields.includes(key)) return val ? new Date(val).toLocaleString() : val
87
+ return val
88
+ }
89
+ }))
90
+ }
91
+
92
+ // Return an empty array if no data or schema
93
+ return []
50
94
  })
51
95
 
52
96
  function transform(rowData: T): TransformedData<T> {
@@ -82,10 +126,31 @@ export function useTableData<T extends Record<string, any>>(options: UseTableDat
82
126
  return transformed
83
127
  }
84
128
 
129
+ // Helper function to clean up transformed data by removing all added properties
130
+ function cleanTransformedData<T extends Record<string, any>>(data: TransformedData<T>): T {
131
+ const cleanData = { ...data } as T
132
+
133
+ // Remove all keys that start with underscore (these are added by the transform function)
134
+ Object.keys(cleanData).forEach((key) => {
135
+ if (key.startsWith('_')) {
136
+ delete cleanData[key]
137
+ }
138
+ })
139
+
140
+ return cleanData
141
+ }
142
+
85
143
  const computedSortField = computed(() => sortField.value ? `_transformed_${sortField.value}` : '')
86
144
 
87
145
  const computedData = computed(() => {
88
- const currentData = options.data.value
146
+ // Get the data safely
147
+ const currentData = options.data.value || []
148
+
149
+ // If there's no data, return an empty array
150
+ if (!Array.isArray(currentData) || currentData.length === 0) {
151
+ return []
152
+ }
153
+
89
154
  const useServerSortValue = getValue(options.useServerSort)
90
155
 
91
156
  if (!sortField.value || useServerSortValue === true) {
@@ -139,6 +204,7 @@ export function useTableData<T extends Record<string, any>>(options: UseTableDat
139
204
  transform,
140
205
  sortField: computed(() => sortField.value),
141
206
  sortDirection: computed(() => sortDirection.value),
142
- toggleSort
207
+ toggleSort,
208
+ cleanTransformedData
143
209
  }
144
210
  }
@@ -1,7 +1,11 @@
1
1
  import type { TableSelectionOptions } from '../../types/TableSchema'
2
2
  import { computed, ref } from 'vue'
3
3
 
4
- export function useTableSelection<T extends Record<string, any>>(options: TableSelectionOptions<T>) {
4
+ export interface UseTableSelectionOptions<T> extends TableSelectionOptions<T> {
5
+ cleanData?: (item: T) => T
6
+ }
7
+
8
+ export function useTableSelection<T extends Record<string, any>>(options: UseTableSelectionOptions<T>) {
5
9
  const allSelectorEl = ref<HTMLInputElement>()
6
10
  const computedSelectedItems = computed(() => options.selectedItems.value)
7
11
  const isSelectable = computed(() => options.selectable === true && Array.isArray(options.selectedItems.value))
@@ -16,8 +20,18 @@ export function useTableSelection<T extends Record<string, any>>(options: TableS
16
20
 
17
21
  function toggleSelectItem(item: T) {
18
22
  if (computedSelectedItems.value.length === 0) {
19
- const cleanItem = { ...item }
20
- Object.keys(cleanItem).forEach(key => key.startsWith('_transformed_') && delete cleanItem[key])
23
+ // Clean the item if a cleanData function is provided, otherwise use the default cleaning
24
+ const cleanItem = options.cleanData ? options.cleanData(item) : { ...item }
25
+
26
+ // If no cleanData function is provided, use the default cleaning
27
+ if (!options.cleanData) {
28
+ Object.keys(cleanItem).forEach((key) => {
29
+ if (key.startsWith('_')) {
30
+ delete cleanItem[key]
31
+ }
32
+ })
33
+ }
34
+
21
35
  options.onSelect(cleanItem)
22
36
  return
23
37
  }
@@ -1,6 +1,6 @@
1
1
  import type { TableVirtualizationOptions } from '../../types/TableSchema'
2
2
  import { useVirtualList, useIntersectionObserver, until } from '@vueuse/core'
3
- import { ref } from 'vue'
3
+ import { ref, isRef } from 'vue'
4
4
 
5
5
  export function useTableVirtualization<T>(options: TableVirtualizationOptions<T>) {
6
6
  const lastItemEl = ref<HTMLTableRowElement | null>(null)
@@ -16,7 +16,16 @@ export function useTableVirtualization<T>(options: TableVirtualizationOptions<T>
16
16
  await until(() => lastItemEl.value).toBeTruthy()
17
17
 
18
18
  useIntersectionObserver(lastItemEl, ([entry]) => {
19
- if (entry.isIntersecting && options.data.value.length) {
19
+ // Check if options.data.value exists and has length
20
+ let dataLength = 0
21
+
22
+ if (isRef(options.data) && options.data.value) {
23
+ dataLength = Array.isArray(options.data.value) ? options.data.value.length : 0
24
+ } else if (Array.isArray(options.data)) {
25
+ dataLength = options.data.length
26
+ }
27
+
28
+ if (entry.isIntersecting && dataLength > 0) {
20
29
  options.onLastItemVisible?.()
21
30
  }
22
31
  })
@@ -5,6 +5,7 @@ import type {
5
5
  Attributes,
6
6
  BagelFieldOptions,
7
7
  BglFormSchemaFnT,
8
+ BglFormSchemaT,
8
9
  Field,
9
10
  } from '@bagelink/vue'
10
11
  import { BagelForm, Btn } from '@bagelink/vue'
@@ -39,6 +40,8 @@ const props = withDefaults(
39
40
 
40
41
  const emit = defineEmits(['update:modelValue'])
41
42
 
43
+ const minimizedItems = $ref<boolean[]>([])
44
+
42
45
  const data = $ref<T[]>(props.modelValue || [])
43
46
 
44
47
  function emitValue() {
@@ -55,6 +58,10 @@ function addItem() {
55
58
  emitValue()
56
59
  }
57
60
 
61
+ function toggleMinimized(index: number) {
62
+ minimizedItems[index] = !minimizedItems[index]
63
+ }
64
+
58
65
  const computedField = $computed(
59
66
  () => ({
60
67
  label: props.label,
@@ -72,6 +79,11 @@ const computedField = $computed(
72
79
  }) as Field<T>
73
80
  ) as Field<Record<string, any>>
74
81
 
82
+ const resolvedSchema = $computed<BglFormSchemaT<T>>(() => {
83
+ if (!props.schema) return [] as BglFormSchemaT<T>
84
+ return typeof props.schema === 'function' ? props.schema() : props.schema
85
+ })
86
+
75
87
  const { renderField } = useSchemaField<Record<string, any>>({
76
88
  mode: 'form',
77
89
  getRowData: () => data,
@@ -90,11 +102,23 @@ const { renderField } = useSchemaField<Record<string, any>>({
90
102
  <p class="label mb-05">
91
103
  {{ label }}
92
104
  </p>
93
-
94
- <div v-if="schema" class="ps-025 border-start mb-05">
95
- <div v-for="(_, i) in data" :key="i" outline thin class="mb-05 itemBox transition ps-05 pb-025 pt-025 radius-05 gap-05 overflow-hidden">
96
- <BagelForm v-model="data[i]" :schema="schema" @update:model-value="emitValue" />
97
- <div class="bg-gray-80 -my-05 px-025 pt-065 txt-center">
105
+ <div v-if="resolvedSchema" class="ps-025 border-start mb-05">
106
+ <div
107
+ v-for="(_, i) in data" :key="i" outline thin
108
+ class="mb-05 itemBox transition ps-05 pb-025 pt-025 radius-05 gap-05 overflow-hidden"
109
+ :class="{ minimized: minimizedItems[i] }"
110
+ >
111
+ <p v-if="minimizedItems[i]" class="minimizedText txt14 p-025 opacity-7">
112
+ {{ label }} {{ i + 1 }}
113
+ </p>
114
+ <BagelForm v-else v-model="data[i]" :schema="resolvedSchema" @update:model-value="emitValue" />
115
+ <div class="bg-gray-80 -my-05 px-025 pt-065 pb-05 txt-center space-between flex column">
116
+ <Btn
117
+ v-if="resolvedSchema.length > 4"
118
+ class="block rotate-180 txt10 opacity-7 p-025"
119
+ flat thin icon="keyboard_arrow_down"
120
+ @click="toggleMinimized(i)"
121
+ />
98
122
  <Btn
99
123
  v-if="props.delete"
100
124
  icon="delete"
@@ -109,6 +133,7 @@ const { renderField } = useSchemaField<Record<string, any>>({
109
133
  <p>{{ label }}</p>
110
134
  </Btn>
111
135
  </div>
136
+
112
137
  <template v-else>
113
138
  <component
114
139
  :is="renderField({ ...computedField, id: String(i) })"
@@ -121,6 +146,19 @@ const { renderField } = useSchemaField<Record<string, any>>({
121
146
  </template>
122
147
 
123
148
  <style>
149
+ .minimized{
150
+ height: 2.4rem;
151
+ overflow: hidden;
152
+ }
153
+ .minimizedText{
154
+ display: none;
155
+ }
156
+ .minimized .minimizedText{
157
+ display: block;
158
+ }
159
+ .minimized .rotate-180{
160
+ transform: rotate(0deg);
161
+ }
124
162
  .itemBox{
125
163
  background: var(--input-bg);
126
164
  grid-template-columns: 1fr auto;
@@ -129,6 +167,7 @@ const { renderField } = useSchemaField<Record<string, any>>({
129
167
  --input-height: 30px;
130
168
  --input-font-size: 14px;
131
169
  }
170
+
132
171
  .pt-065{
133
172
  padding-top: 0.65rem;
134
173
  }
@@ -22,12 +22,14 @@ const emits = defineEmits(['update:modelValue'])
22
22
  function getLabel(option: Option) {
23
23
  if (typeof option === 'string') return option
24
24
  if (typeof option === 'number') return `${option}`
25
+ if (typeof option === 'boolean') return option ? 'Yes' : 'No'
25
26
  return option.label
26
27
  }
27
28
 
28
29
  function getValue(option: Option) {
29
30
  if (typeof option === 'string') return option
30
31
  if (typeof option === 'number') return option
32
+ if (typeof option === 'boolean') return option ? 'Yes' : 'No'
31
33
  return option.value
32
34
  }
33
35
 
@@ -121,6 +121,7 @@ function getLabel(option: Option) {
121
121
  if (!option) return ''
122
122
  if (typeof option === 'string') return option
123
123
  if (typeof option === 'number') return `${option}`
124
+ if (typeof option === 'boolean') return option ? 'Yes' : 'No'
124
125
  return option.label
125
126
  }
126
127
 
@@ -128,6 +129,7 @@ function getValue(option?: Option) {
128
129
  if (!option) return
129
130
  if (typeof option === 'string') return option
130
131
  if (typeof option === 'number') return option
132
+ if (typeof option === 'boolean') return option ? 'Yes' : 'No'
131
133
  return option.value
132
134
  }
133
135
 
@@ -23,7 +23,7 @@ defineProps<{
23
23
  @click="nav.onClick"
24
24
  >
25
25
  <Icon :icon="nav.icon" :size="1.4" class="m-0 line-height-14" />
26
- <p class="m-0 pb-025 txt14 line-height-1 w60 menu-text">
26
+ <p class="m-0 pb-025 txt10 line-height-1 w60 menu-text">
27
27
  {{ nav.label }}
28
28
  </p>
29
29
  </Btn>