@bagelink/vue 1.0.33 → 1.0.41

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 (32) hide show
  1. package/dist/components/DataPreview.vue.d.ts.map +1 -1
  2. package/dist/components/DataTable/DataTable.vue.d.ts +2 -2
  3. package/dist/components/DataTable/DataTable.vue.d.ts.map +1 -1
  4. package/dist/components/DataTable/useTableData.d.ts +2 -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 +17 -11
  10. package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
  11. package/dist/components/form/FieldArray.vue.d.ts.map +1 -1
  12. package/dist/composables/index.d.ts +1 -1
  13. package/dist/composables/index.d.ts.map +1 -1
  14. package/dist/index.cjs +441 -307
  15. package/dist/index.mjs +442 -308
  16. package/dist/style.css +502 -83
  17. package/dist/types/BagelForm.d.ts +1 -1
  18. package/dist/types/BagelForm.d.ts.map +1 -1
  19. package/package.json +1 -1
  20. package/src/components/DataPreview.vue +30 -4
  21. package/src/components/DataTable/DataTable.vue +9 -7
  22. package/src/components/DataTable/useTableData.ts +75 -9
  23. package/src/components/DataTable/useTableSelection.ts +17 -3
  24. package/src/components/DataTable/useTableVirtualization.ts +11 -2
  25. package/src/components/Loading.vue +2 -2
  26. package/src/components/form/BagelForm.vue +138 -78
  27. package/src/components/form/FieldArray.vue +129 -54
  28. package/src/components/layout/BottomMenu.vue +1 -1
  29. package/src/composables/index.ts +14 -4
  30. package/src/styles/layout.css +240 -0
  31. package/src/styles/mobilLayout.css +240 -0
  32. package/src/types/BagelForm.ts +1 -1
@@ -7,7 +7,8 @@ import type {
7
7
  BglFormSchemaFnT,
8
8
  Field,
9
9
  } from '@bagelink/vue'
10
- import { BagelForm, Btn } from '@bagelink/vue'
10
+ import { BagelForm, Btn, Loading } from '@bagelink/vue'
11
+ import { ref, onMounted } from 'vue'
11
12
  import { useSchemaField } from '../../composables/useSchemaField'
12
13
 
13
14
  const props = withDefaults(
@@ -39,50 +40,82 @@ const props = withDefaults(
39
40
 
40
41
  const emit = defineEmits(['update:modelValue'])
41
42
 
42
- const data = $ref<T[]>(props.modelValue || [])
43
+ // State
44
+ const minimizedItems = ref<boolean[]>([])
45
+ const internalData = ref<any[]>(props.modelValue || [])
46
+ const schemaState = ref<'loading' | 'loaded' | 'error'>('loaded')
47
+ const resolvedSchemaData = ref<any[]>([])
43
48
 
49
+ // Resolve schema (handles sync, async, function, and direct values)
50
+ async function resolveSchema() {
51
+ if (!props.schema) {
52
+ resolvedSchemaData.value = []
53
+ schemaState.value = 'loaded'
54
+ return
55
+ }
56
+
57
+ try {
58
+ schemaState.value = 'loading'
59
+ const isPromise = (obj: any) => obj && typeof obj.then === 'function'
60
+
61
+ let result: any
62
+ if (typeof props.schema === 'function') {
63
+ result = props.schema()
64
+ result = isPromise(result) ? await result : result
65
+ } else {
66
+ result = isPromise(props.schema) ? await props.schema : props.schema
67
+ }
68
+
69
+ resolvedSchemaData.value = result
70
+ schemaState.value = 'loaded'
71
+ } catch (error) {
72
+ console.error('Schema error:', error)
73
+ schemaState.value = 'error'
74
+ resolvedSchemaData.value = []
75
+ }
76
+ }
77
+
78
+ // Initialize schema on mount
79
+ onMounted(() => {
80
+ resolveSchema()
81
+ })
82
+
83
+ // Event handlers
44
84
  function emitValue() {
45
- emit('update:modelValue', data)
85
+ emit('update:modelValue', internalData.value)
46
86
  }
47
87
 
48
88
  function deleteItem(i: number) {
49
- data.splice(i, 1)
89
+ internalData.value.splice(i, 1)
50
90
  emitValue()
51
91
  }
52
92
 
53
93
  function addItem() {
54
- data.push({} as any)
94
+ internalData.value.push({})
55
95
  emitValue()
56
96
  }
57
97
 
58
- const computedField = $computed(
59
- () => ({
60
- label: props.label,
61
- placeholder: props.placeholder,
62
- children: props.children,
63
- // class: props.class,
64
- attrs: props.attrs,
65
- required: props.required,
66
- disabled: props.disabled,
67
- helptext: props.helptext,
68
- options: props.options,
69
- defaultValue: props.defaultValue,
70
- transform: props.transform,
71
- $el: props.el,
72
- }) as Field<T>
73
- ) as Field<Record<string, any>>
74
-
75
- const { renderField } = useSchemaField<Record<string, any>>({
76
- mode: 'form',
77
- getRowData: () => data,
78
- onUpdate: (field, value) => {
79
- if (!field.id) return
80
- const index = Number.parseInt(field.id)
81
- if (Number.isNaN(index)) return
82
- data[index] = value
83
- emitValue()
84
- }
85
- })
98
+ function toggleMinimized(index: number) {
99
+ minimizedItems.value[index] = !minimizedItems.value[index]
100
+ }
101
+
102
+ function updateItem(index: number, value: any) {
103
+ internalData.value[index] = value
104
+ emitValue()
105
+ }
106
+
107
+ // // Field rendering
108
+ // const { renderField } = useSchemaField<any>({
109
+ // mode: 'form',
110
+ // getRowData: () => internalData.value,
111
+ // onUpdate: (field, value) => {
112
+ // if (!field.id) return
113
+ // const index = Number.parseInt(field.id)
114
+ // if (Number.isNaN(index)) return
115
+ // internalData.value[index] = value
116
+ // emitValue()
117
+ // }
118
+ // })
86
119
  </script>
87
120
 
88
121
  <template>
@@ -90,37 +123,78 @@ const { renderField } = useSchemaField<Record<string, any>>({
90
123
  <p class="label mb-05">
91
124
  {{ label }}
92
125
  </p>
126
+ <div v-if="resolvedSchemaData.length > 0" class="ps-025 border-start mb-05">
127
+ <!-- Loading state -->
128
+ <div v-if="schemaState === 'loading'" class="flex-center h-300px">
129
+ <Loading />
130
+ </div>
93
131
 
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">
98
- <Btn
99
- v-if="props.delete"
100
- icon="delete"
101
- class="txt10 opacity-7"
102
- thin
103
- flat
104
- @click="deleteItem(i)"
132
+ <!-- Error state -->
133
+ <div v-else-if="schemaState === 'error'" class="flex-center h-300px txt-red">
134
+ Error
135
+ </div>
136
+
137
+ <!-- Render items -->
138
+ <template v-else>
139
+ <div
140
+ v-for="(item, i) in internalData" :key="i" outline thin
141
+ class="mb-05 itemBox transition ps-05 pb-025 pt-025 radius-05 gap-05 overflow-hidden"
142
+ :class="{ minimized: minimizedItems[i] }"
143
+ >
144
+ <p v-if="minimizedItems[i]" class="minimizedText txt14 p-025 opacity-7">
145
+ {{ label }} {{ i + 1 }}
146
+ </p>
147
+ <BagelForm
148
+ v-else
149
+ :model-value="item"
150
+ :schema="resolvedSchemaData"
151
+ @update:model-value="val => updateItem(i, val)"
105
152
  />
153
+ <div class="bg-gray-80 -my-05 px-025 pt-065 pb-05 txt-center space-between flex column">
154
+ <Btn
155
+ v-if="resolvedSchemaData.length > 4"
156
+ class="block rotate-180 txt10 opacity-7 p-025"
157
+ flat thin icon="keyboard_arrow_down"
158
+ @click="toggleMinimized(i)"
159
+ />
160
+ <Btn
161
+ v-if="props.delete"
162
+ icon="delete"
163
+ class="txt10 opacity-7"
164
+ thin
165
+ flat
166
+ @click="deleteItem(i)"
167
+ />
168
+ </div>
106
169
  </div>
107
- </div>
108
- <Btn v-if="add" thin icon="add" color="gray" class="txt12" @click="addItem">
109
- <p>{{ label }}</p>
110
- </Btn>
170
+ <Btn v-if="add" thin icon="add" color="gray" class="txt12" @click="addItem">
171
+ <p>{{ label }}</p>
172
+ </Btn>
173
+ </template>
111
174
  </div>
175
+
112
176
  <template v-else>
113
- <component
114
- :is="renderField({ ...computedField, id: String(i) })"
115
- v-for="(_, i) in data"
116
- :key="i"
117
- @update:model-value="emitValue"
118
- />
177
+ <div v-for="(_, i) in internalData" :key="i">
178
+ <p>No schema available</p>
179
+ </div>
119
180
  </template>
120
181
  </div>
121
182
  </template>
122
183
 
123
184
  <style>
185
+ .minimized{
186
+ height: 2.4rem;
187
+ overflow: hidden;
188
+ }
189
+ .minimizedText{
190
+ display: none;
191
+ }
192
+ .minimized .minimizedText{
193
+ display: block;
194
+ }
195
+ .minimized .rotate-180{
196
+ transform: rotate(0deg);
197
+ }
124
198
  .itemBox{
125
199
  background: var(--input-bg);
126
200
  grid-template-columns: 1fr auto;
@@ -129,6 +203,7 @@ const { renderField } = useSchemaField<Record<string, any>>({
129
203
  --input-height: 30px;
130
204
  --input-font-size: 14px;
131
205
  }
206
+
132
207
  .pt-065{
133
208
  padding-top: 0.65rem;
134
209
  }
@@ -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>
@@ -10,13 +10,23 @@ interface useBglSchemaParamsT<T> {
10
10
  data?: any[]
11
11
  }
12
12
 
13
- export function useBglSchema<T = { [key: string]: unknown }>(
13
+ export async function useBglSchema<T = { [key: string]: unknown }>(
14
14
  { schema, columns, data }: useBglSchemaParamsT<T> = {}
15
- ): BglFormSchemaT<T> {
15
+ ): Promise<BglFormSchemaT<T>> {
16
16
  let _schema = schema
17
+
18
+ // Handle async schema functions
17
19
  if (typeof _schema === 'function') {
18
- _schema = _schema()
20
+ const result = _schema()
21
+ if (result instanceof Promise) {
22
+ _schema = await result
23
+ } else {
24
+ _schema = result
25
+ }
26
+ } else if (_schema instanceof Promise) {
27
+ _schema = await _schema
19
28
  }
29
+
20
30
  if (_schema) {
21
31
  return (
22
32
  columns && columns.length > 0
@@ -41,7 +51,7 @@ export function localRef<T>(
41
51
  localStorage.setItem(key, JSON.stringify(val))
42
52
  }, { immediate: true, deep: true })
43
53
 
44
- return value
54
+ return value as any
45
55
  }
46
56
 
47
57
  export const useLocalStorage = localRef
@@ -2759,6 +2759,36 @@
2759
2759
  min-height: 200px;
2760
2760
  }
2761
2761
 
2762
+ .h-250,
2763
+ .h250p,
2764
+ .h-250p {
2765
+ height: 250%;
2766
+ }
2767
+
2768
+ .vh-250,
2769
+ .h-250vh,
2770
+ .h250vh {
2771
+ height: 250vh;
2772
+ }
2773
+
2774
+ .h-250px,
2775
+ .h250px {
2776
+ height: 250px;
2777
+ }
2778
+
2779
+ .hm-250px,
2780
+ .max-h-250px,
2781
+ .h-max-250px,
2782
+ .max-h250px {
2783
+ max-height: 250px;
2784
+ }
2785
+
2786
+ .min-h-250px,
2787
+ .h-min-250px,
2788
+ .min-h250px {
2789
+ min-height: 250px;
2790
+ }
2791
+
2762
2792
  .h-300,
2763
2793
  .h300p,
2764
2794
  .h-300p {
@@ -2789,6 +2819,36 @@
2789
2819
  min-height: 300px;
2790
2820
  }
2791
2821
 
2822
+ .h-350,
2823
+ .h350p,
2824
+ .h-350p {
2825
+ height: 350%;
2826
+ }
2827
+
2828
+ .vh-350,
2829
+ .h-350vh,
2830
+ .h350vh {
2831
+ height: 350vh;
2832
+ }
2833
+
2834
+ .h-350px,
2835
+ .h350px {
2836
+ height: 350px;
2837
+ }
2838
+
2839
+ .hm-350px,
2840
+ .max-h-350px,
2841
+ .h-max-350px,
2842
+ .max-h350px {
2843
+ max-height: 350px;
2844
+ }
2845
+
2846
+ .min-h-350px,
2847
+ .h-min-350px,
2848
+ .min-h350px {
2849
+ min-height: 350px;
2850
+ }
2851
+
2792
2852
  .h-400,
2793
2853
  .h400p,
2794
2854
  .h-400p {
@@ -2819,6 +2879,36 @@
2819
2879
  min-height: 400px;
2820
2880
  }
2821
2881
 
2882
+ .h-450,
2883
+ .h450p,
2884
+ .h-450p {
2885
+ height: 450%;
2886
+ }
2887
+
2888
+ .vh-450,
2889
+ .h-450vh,
2890
+ .h450vh {
2891
+ height: 450vh;
2892
+ }
2893
+
2894
+ .h-450px,
2895
+ .h450px {
2896
+ height: 450px;
2897
+ }
2898
+
2899
+ .hm-450px,
2900
+ .max-h-450px,
2901
+ .h-max-450px,
2902
+ .max-h450px {
2903
+ max-height: 450px;
2904
+ }
2905
+
2906
+ .min-h-450px,
2907
+ .h-min-450px,
2908
+ .min-h450px {
2909
+ min-height: 450px;
2910
+ }
2911
+
2822
2912
  .h-500,
2823
2913
  .h500p,
2824
2914
  .h-500p {
@@ -2849,6 +2939,36 @@
2849
2939
  min-height: 500px;
2850
2940
  }
2851
2941
 
2942
+ .h-550,
2943
+ .h550p,
2944
+ .h-550p {
2945
+ height: 550%;
2946
+ }
2947
+
2948
+ .vh-550,
2949
+ .h-550vh,
2950
+ .h550vh {
2951
+ height: 550vh;
2952
+ }
2953
+
2954
+ .h-550px,
2955
+ .h550px {
2956
+ height: 550px;
2957
+ }
2958
+
2959
+ .hm-550px,
2960
+ .max-h-550px,
2961
+ .h-max-550px,
2962
+ .max-h550px {
2963
+ max-height: 550px;
2964
+ }
2965
+
2966
+ .min-h-550px,
2967
+ .h-min-550px,
2968
+ .min-h550px {
2969
+ min-height: 550px;
2970
+ }
2971
+
2852
2972
  .h-600,
2853
2973
  .h600p,
2854
2974
  .h-600p {
@@ -2879,6 +2999,36 @@
2879
2999
  min-height: 600px;
2880
3000
  }
2881
3001
 
3002
+ .h-650,
3003
+ .h650p,
3004
+ .h-650p {
3005
+ height: 650%;
3006
+ }
3007
+
3008
+ .vh-650,
3009
+ .h-650vh,
3010
+ .h650vh {
3011
+ height: 650vh;
3012
+ }
3013
+
3014
+ .h-650px,
3015
+ .h650px {
3016
+ height: 650px;
3017
+ }
3018
+
3019
+ .hm-650px,
3020
+ .max-h-650px,
3021
+ .h-max-650px,
3022
+ .max-h650px {
3023
+ max-height: 650px;
3024
+ }
3025
+
3026
+ .min-h-650px,
3027
+ .h-min-650px,
3028
+ .min-h650px {
3029
+ min-height: 650px;
3030
+ }
3031
+
2882
3032
  .h-700,
2883
3033
  .h700p,
2884
3034
  .h-700p {
@@ -2909,6 +3059,36 @@
2909
3059
  min-height: 700px;
2910
3060
  }
2911
3061
 
3062
+ .h-750,
3063
+ .h750p,
3064
+ .h-750p {
3065
+ height: 750%;
3066
+ }
3067
+
3068
+ .vh-750,
3069
+ .h-750vh,
3070
+ .h750vh {
3071
+ height: 750vh;
3072
+ }
3073
+
3074
+ .h-750px,
3075
+ .h750px {
3076
+ height: 750px;
3077
+ }
3078
+
3079
+ .hm-750px,
3080
+ .max-h-750px,
3081
+ .h-max-750px,
3082
+ .max-h750px {
3083
+ max-height: 750px;
3084
+ }
3085
+
3086
+ .min-h-750px,
3087
+ .h-min-750px,
3088
+ .min-h750px {
3089
+ min-height: 750px;
3090
+ }
3091
+
2912
3092
  .h-800,
2913
3093
  .h800p,
2914
3094
  .h-800p {
@@ -2939,6 +3119,36 @@
2939
3119
  min-height: 800px;
2940
3120
  }
2941
3121
 
3122
+ .h-850,
3123
+ .h850p,
3124
+ .h-850p {
3125
+ height: 850%;
3126
+ }
3127
+
3128
+ .vh-850,
3129
+ .h-850vh,
3130
+ .h850vh {
3131
+ height: 850vh;
3132
+ }
3133
+
3134
+ .h-850px,
3135
+ .h850px {
3136
+ height: 850px;
3137
+ }
3138
+
3139
+ .hm-850px,
3140
+ .max-h-850px,
3141
+ .h-max-850px,
3142
+ .max-h850px {
3143
+ max-height: 850px;
3144
+ }
3145
+
3146
+ .min-h-850px,
3147
+ .h-min-850px,
3148
+ .min-h850px {
3149
+ min-height: 850px;
3150
+ }
3151
+
2942
3152
  .h-900,
2943
3153
  .h900p,
2944
3154
  .h-900p {
@@ -2969,6 +3179,36 @@
2969
3179
  min-height: 900px;
2970
3180
  }
2971
3181
 
3182
+ .h-950,
3183
+ .h950p,
3184
+ .h-950p {
3185
+ height: 950%;
3186
+ }
3187
+
3188
+ .vh-950,
3189
+ .h-950vh,
3190
+ .h950vh {
3191
+ height: 950vh;
3192
+ }
3193
+
3194
+ .h-950px,
3195
+ .h950px {
3196
+ height: 950px;
3197
+ }
3198
+
3199
+ .hm-950px,
3200
+ .max-h-950px,
3201
+ .h-max-950px,
3202
+ .max-h950px {
3203
+ max-height: 950px;
3204
+ }
3205
+
3206
+ .min-h-950px,
3207
+ .h-min-950px,
3208
+ .min-h950px {
3209
+ min-height: 950px;
3210
+ }
3211
+
2972
3212
  .h-1000,
2973
3213
  .h1000p,
2974
3214
  .h-1000p {