@bagelink/vue 0.0.564 → 0.0.566

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 (51) hide show
  1. package/dist/components/DataPreview.vue.d.ts.map +1 -1
  2. package/dist/components/MaterialIcon.vue.d.ts +2 -0
  3. package/dist/components/MaterialIcon.vue.d.ts.map +1 -1
  4. package/dist/components/TableSchema.vue.d.ts +34 -21
  5. package/dist/components/TableSchema.vue.d.ts.map +1 -1
  6. package/dist/components/form/BglForm.vue.d.ts.map +1 -1
  7. package/dist/components/form/inputs/CheckInput.vue.d.ts +21 -11
  8. package/dist/components/form/inputs/CheckInput.vue.d.ts.map +1 -1
  9. package/dist/components/form/inputs/DateInput.vue.d.ts +2 -0
  10. package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
  11. package/dist/components/form/inputs/FileUpload.vue.d.ts +31 -41
  12. package/dist/components/form/inputs/FileUpload.vue.d.ts.map +1 -1
  13. package/dist/components/form/inputs/RadioPillsInput.vue.d.ts +1 -1
  14. package/dist/components/form/inputs/RadioPillsInput.vue.d.ts.map +1 -1
  15. package/dist/components/form/inputs/TelInput.vue.d.ts +11 -11
  16. package/dist/components/form/inputs/TelInput.vue.d.ts.map +1 -1
  17. package/dist/components/form/inputs/ToggleInput.vue.d.ts +18 -3
  18. package/dist/components/form/inputs/ToggleInput.vue.d.ts.map +1 -1
  19. package/dist/components/layout/TabbedLayout.vue.d.ts.map +1 -1
  20. package/dist/composables/index.d.ts +10 -0
  21. package/dist/composables/index.d.ts.map +1 -0
  22. package/dist/index.cjs +608 -195
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.mjs +609 -196
  26. package/dist/style.css +262 -119
  27. package/dist/types/BagelForm.d.ts +1 -0
  28. package/dist/types/BagelForm.d.ts.map +1 -1
  29. package/dist/utils/index.d.ts +3 -2
  30. package/dist/utils/index.d.ts.map +1 -1
  31. package/package.json +15 -14
  32. package/src/components/Btn.vue +1 -1
  33. package/src/components/DataPreview.vue +12 -13
  34. package/src/components/MapEmbed.vue +2 -2
  35. package/src/components/MaterialIcon.vue +7 -3
  36. package/src/components/TableSchema.vue +283 -104
  37. package/src/components/form/BglFieldSet.vue +0 -2
  38. package/src/components/form/BglForm.vue +2 -4
  39. package/src/components/form/inputs/CheckInput.vue +13 -6
  40. package/src/components/form/inputs/DateInput.vue +2 -0
  41. package/src/components/form/inputs/FileUpload.vue +63 -47
  42. package/src/components/form/inputs/ToggleInput.vue +22 -5
  43. package/src/components/layout/TabbedLayout.vue +1 -1
  44. package/src/composables/index.ts +24 -0
  45. package/src/index.ts +1 -0
  46. package/src/styles/layout.css +24 -0
  47. package/src/styles/mobilLayout.css +23 -0
  48. package/src/styles/text.css +0 -2
  49. package/src/styles/theme.css +2 -1
  50. package/src/types/BagelForm.ts +2 -0
  51. package/src/utils/index.ts +22 -2
@@ -1,11 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { onMounted, watch } from 'vue'
3
- import {
4
- Btn,
5
- MaterialIcon,
6
- type StorageFile,
7
- useBagel,
8
- } from '@bagelink/vue'
3
+ import { Btn, MaterialIcon, type StorageFile, useBagel } from '@bagelink/vue'
9
4
 
10
5
  const props = defineProps<{
11
6
  label?: string
@@ -13,6 +8,7 @@ const props = defineProps<{
13
8
  files?: StorageFile | StorageFile[]
14
9
  deleteEndpoint?: string
15
10
  bindkey?: StrKey
11
+ modelValue?: FSValue
16
12
  width?: string
17
13
  }>()
18
14
 
@@ -32,32 +28,41 @@ type FSValue = string[] | string | number
32
28
 
33
29
  const bindKey: StrKey = props.bindkey || 'id'
34
30
 
35
- const file_bindkeys = defineModel<FSValue>('modelValue')
31
+ const emit = defineEmits(['update:modelValue'])
32
+
33
+ let file_bindkeys = $ref<FSValue>(props.modelValue || [])
36
34
  const storageFiles = $ref<StorageFile[]>([])
37
35
 
38
- const compareIds = (v1?: FSValue, v2?: FSValue) => [v1].flat().join(',') === [v2].flat().join(',')
36
+ const compareIds = (v1?: FSValue, v2?: FSValue) =>
37
+ [v1].flat().join(',') === [v2].flat().join(',')
39
38
 
40
39
  onMounted(() => {
41
- if (!props.files && [file_bindkeys.value].flat().length) {
42
- const ids = [file_bindkeys.value].flat().filter(Boolean)
40
+ if (!props.files && [file_bindkeys].flat().length) {
41
+ const ids = [file_bindkeys].flat().filter(Boolean)
43
42
  if (!ids.length) return
44
43
  if (props.multiple) {
45
- ids.forEach((id) => {
46
- void bagel.get<StorageFile>(`/files/${id}`).then((file) => {
47
- storageFiles.push(file)
48
- }).catch(console.error)
44
+ ids.forEach(id => {
45
+ void bagel
46
+ .get<StorageFile>(`/files/${id}`)
47
+ .then(file => {
48
+ storageFiles.push(file)
49
+ })
50
+ .catch(console.error)
49
51
  })
50
52
  } else {
51
- void bagel.get<StorageFile>(`/files/${ids[0]}`).then((file) => {
52
- storageFiles.push(file)
53
- }).catch(console.error)
53
+ void bagel
54
+ .get<StorageFile>(`/files/${ids[0]}`)
55
+ .then(file => {
56
+ storageFiles.push(file)
57
+ })
58
+ .catch(console.error)
54
59
  }
55
60
  }
56
61
  })
57
62
 
58
63
  watch(
59
64
  () => props.files,
60
- (newFiles) => {
65
+ newFiles => {
61
66
  if (newFiles) {
62
67
  const filesToAdd = [newFiles]
63
68
  .flat()
@@ -67,24 +72,24 @@ watch(
67
72
  }
68
73
  }
69
74
  },
70
- { immediate: true },
75
+ { immediate: true }
71
76
  )
72
77
 
73
- watch(
74
- () => storageFiles,
75
- (newFiles) => {
76
- let idValue: FSValue
77
- if (props.multiple) { idValue = newFiles.map(f => f[bindKey]) as FSValue
78
- }
79
- else {
80
- idValue = (newFiles[0][bindKey] as string) || ''
81
- }
82
- if (!compareIds(file_bindkeys.value, idValue)) {
83
- file_bindkeys.value = idValue
84
- }
85
- },
86
- { deep: true },
87
- )
78
+ function updateModelValue() {
79
+ let idValue: FSValue
80
+ if (props.multiple) {
81
+ idValue = storageFiles.map(f => f[bindKey]) as FSValue
82
+ } else {
83
+ idValue = (storageFiles[0][bindKey] as string) || ''
84
+ }
85
+ const isSame = [idValue]
86
+ .flat()
87
+ .every(id => [file_bindkeys].flat().includes(id))
88
+ if (!isSame) {
89
+ file_bindkeys = idValue
90
+ emit('update:modelValue', file_bindkeys)
91
+ }
92
+ }
88
93
 
89
94
  const fileQueue = $ref<QueueFile[]>([])
90
95
  let isDragOver = $ref(false)
@@ -102,17 +107,21 @@ function removeFile(file: StorageFile) {
102
107
  if (props.deleteEndpoint) {
103
108
  void bagel.delete(`${props.deleteEndpoint}/${file.id}`)
104
109
  }
110
+ updateModelValue()
105
111
  }
106
112
 
107
- function flushQueue() {
108
- fileQueue.forEach(async (file, i) => {
113
+ async function flushQueue() {
114
+ for (const file of fileQueue) {
115
+ file.uploading = true
109
116
  if (!props.multiple) storageFiles.splice(0, 1)
110
117
  const serverFile = await bagel.uploadFile<StorageFile>(file.file, {
111
118
  onUploadProgress: (e: any) => (file.progress = e.progress * 100 - 1),
112
119
  })
113
120
  storageFiles.push(serverFile)
121
+ const i = fileQueue.indexOf(file)
114
122
  fileQueue.splice(i, 1)
115
- })
123
+ }
124
+ updateModelValue()
116
125
  }
117
126
 
118
127
  function browse() {
@@ -122,7 +131,9 @@ function browse() {
122
131
  input.onchange = (e: Event) => {
123
132
  const target = e.target as HTMLInputElement
124
133
  if (target.files) {
125
- Array.from(target.files).forEach((file: File) => fileQueue.push({ name: file.name, file, progress: 0 }))
134
+ Array.from(target.files).forEach((file: File) =>
135
+ fileQueue.push({ name: file.name, file, progress: 0 })
136
+ )
126
137
  }
127
138
  flushQueue()
128
139
  }
@@ -144,7 +155,9 @@ function dragover(e: DragEvent) {
144
155
  function drop(e: DragEvent) {
145
156
  preventDefault(e)
146
157
  if (e.dataTransfer) {
147
- Array.from(e.dataTransfer.files).forEach((file: File) => fileQueue.push({ name: file.name, file, progress: 0 }))
158
+ Array.from(e.dataTransfer.files).forEach((file: File) =>
159
+ fileQueue.push({ name: file.name, file, progress: 0 })
160
+ )
148
161
  }
149
162
  isDragOver = false
150
163
  flushQueue()
@@ -170,13 +183,13 @@ function drop(e: DragEvent) {
170
183
  <slot name="files" :files="storageFiles" :fileQueue>
171
184
  <template v-for="file in storageFiles" :key="file.id">
172
185
  <div v-if="!multiple" class="single-image">
173
- <img class="single preview" :src="file.url" alt="">
174
- <!-- <p class="no-margin">
186
+ <img class="single preview" :src="file.url" alt="" />
187
+ <!-- <p class="no-margin">
175
188
  {{ file.name }}
176
189
  </p> -->
177
190
  </div>
178
191
  <div v-if="multiple" class="multi-image-item previewName">
179
- <img class="preview" :src="file.url" alt="">
192
+ <img class="preview" :src="file.url" alt="" />
180
193
  <p class="no-margin">
181
194
  {{ file.name }}
182
195
  </p>
@@ -191,7 +204,7 @@ function drop(e: DragEvent) {
191
204
  </template>
192
205
  <template v-for="fileQ in fileQueue" :key="fileQ.file">
193
206
  <div v-if="!multiple" class="imagePreviewWrap">
194
- <img class="preview" :src="fileToUrl(fileQ.file)" alt="">
207
+ <img class="preview" :src="fileToUrl(fileQ.file)" alt="" />
195
208
  </div>
196
209
  <div class="previewName">
197
210
  <img
@@ -200,7 +213,7 @@ function drop(e: DragEvent) {
200
213
  class="preview"
201
214
  :src="fileToUrl(fileQ.file)"
202
215
  alt=""
203
- >
216
+ />
204
217
  <p class="no-margin">
205
218
  {{ fileQ.name }}
206
219
  </p>
@@ -218,7 +231,11 @@ function drop(e: DragEvent) {
218
231
  </div>
219
232
  </template>
220
233
  </slot>
221
- <slot v-if="(!storageFiles.length && !fileQueue.length) || multiple" name="placeholder" :browse>
234
+ <slot
235
+ v-if="(!storageFiles.length && !fileQueue.length) || multiple"
236
+ name="placeholder"
237
+ :browse
238
+ >
222
239
  <p>Drop files here or click to upload</p>
223
240
  </slot>
224
241
  </div>
@@ -273,10 +290,9 @@ img.preview {
273
290
  object-fit: cover;
274
291
  background: var(--bgl-gray-light);
275
292
  box-shadow: 0 0 10px #00000012;
276
-
277
293
  }
278
294
 
279
- img.preview.single{
295
+ img.preview.single {
280
296
  max-width: var(--width);
281
297
  width: auto;
282
298
  object-fit: contain;
@@ -6,10 +6,13 @@ const props = withDefaults(defineProps<{
6
6
  id?: string
7
7
  title?: string
8
8
  small?: boolean
9
+ required?: boolean
9
10
  defaultValue?: boolean
10
11
  }>(), { defaultValue: false })
11
12
 
12
- const checked = defineModel<boolean>('modelValue')
13
+ const inputId = $ref(props.id || Math.random().toString(36).substring(7))
14
+
15
+ const checked = defineModel<boolean | undefined>('modelValue', { default: undefined })
13
16
 
14
17
  onMounted(() => {
15
18
  if (checked.value === undefined) checked.value = props.defaultValue
@@ -17,13 +20,27 @@ onMounted(() => {
17
20
  </script>
18
21
 
19
22
  <template>
20
- <div class="bagel-input bgl-checkbox justify-content-center gap-1" :title="title" :class="{ small }">
23
+ <div
24
+ class="bagel-input bgl-checkbox justify-content-center gap-1"
25
+ :title
26
+ :class="{ small }"
27
+ @click.prevent="checked = !checked"
28
+ >
21
29
  <div class="switch" :class="{ checked }">
22
30
  <span class="slider round" />
23
31
  </div>
24
- <label>
25
- {{ label }}
26
- <input :id="id" v-model="checked" type="checkbox">
32
+
33
+ <input
34
+ :id="inputId"
35
+ v-model="checked"
36
+ type="checkbox"
37
+ :required
38
+ >
39
+
40
+ <label :for="inputId">
41
+ <slot name="label">
42
+ {{ label }}
43
+ </slot>
27
44
  </label>
28
45
  </div>
29
46
  </template>
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
- import { onMounted } from 'vue'
3
2
  import type { Router } from 'vue-router'
3
+ import { onMounted } from 'vue'
4
4
 
5
5
  const props = defineProps<{
6
6
  title?: string
@@ -0,0 +1,24 @@
1
+ import { type BglFormSchemaFnT, type BglFormSchemaT, getFallbackSchema } from '@bagelink/vue'
2
+
3
+ interface useBglSchemaParamsT {
4
+ schema?: BglFormSchemaFnT
5
+ showFields?: string[]
6
+ data?: any[]
7
+ }
8
+
9
+ export function useBglSchema(
10
+ { schema, showFields, data }: useBglSchemaParamsT = {}
11
+ ): BglFormSchemaT {
12
+ let _schema = schema
13
+ if (typeof _schema === 'function') {
14
+ _schema = _schema()
15
+ }
16
+ if (_schema) {
17
+ return (
18
+ showFields && showFields.length
19
+ ? _schema.filter(f => showFields.includes(f.id as string))
20
+ : _schema
21
+ ) as BglFormSchemaT
22
+ }
23
+ return getFallbackSchema(data, showFields)
24
+ }
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ export {
9
9
  export { ModalPlugin, useModal } from './plugins/modal'
10
10
  export * from './utils'
11
11
  export * from './types'
12
+ export * from './composables'
12
13
  export * from './components'
13
14
  export * from './utils/allCountries'
14
15
  import './styles/bagel.css'
@@ -2185,6 +2185,30 @@
2185
2185
  .direction-rtl {
2186
2186
  direction: rtl;
2187
2187
  }
2188
+ .inset-0, .inset{
2189
+ inset: 0;
2190
+ }
2191
+ .inset-1{
2192
+ inset: 1rem;
2193
+ }
2194
+ .inset-2{
2195
+ inset: 2rem;
2196
+ }
2197
+
2198
+ .inset-3{
2199
+ inset: 3rem;
2200
+ }
2201
+
2202
+ .inset-4{
2203
+ inset: 4rem;
2204
+ }
2205
+
2206
+ .inset-5{
2207
+ inset: 5rem;
2208
+ }
2209
+ .inset-6{
2210
+ inset: 6rem;
2211
+ }
2188
2212
 
2189
2213
 
2190
2214
  @media screen and (max-width: 910px) {
@@ -2085,5 +2085,28 @@
2085
2085
  .m_-bottom-8{
2086
2086
  bottom: -8rem !important;
2087
2087
  }
2088
+ .m_inset-0, .m_inset{
2089
+ inset: 0;
2090
+ }
2091
+ .m_inset-1{
2092
+ inset: 1rem;
2093
+ }
2094
+ .m_inset-2{
2095
+ inset: 2rem;
2096
+ }
2097
+
2098
+ .m_inset-3{
2099
+ inset: 3rem;
2100
+ }
2088
2101
 
2102
+ .m_inset-4{
2103
+ inset: 4rem;
2104
+ }
2105
+
2106
+ .m_inset-5{
2107
+ inset: 5rem;
2108
+ }
2109
+ .m_inset-6{
2110
+ inset: 6rem;
2111
+ }
2089
2112
  }
@@ -215,7 +215,6 @@
215
215
  }
216
216
 
217
217
  .black,
218
- .txt-black,
219
218
  .font-black {
220
219
  font-weight: 900;
221
220
  }
@@ -593,7 +592,6 @@
593
592
  }
594
593
 
595
594
  .m_black,
596
- .m_txt-black,
597
595
  .m_font-black {
598
596
  font-weight: 900;
599
597
  }
@@ -1,6 +1,7 @@
1
1
  /* @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@300;400;500;600;700&display=swap"); */
2
2
  /*noinspection CssUnknownTarget*/
3
- @import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&display=swap");
3
+ /* @import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&display=swap"); */
4
+ @import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200");
4
5
  @import url("https://fonts.googleapis.com/css2?family=Lexend:wght@100;200;300;400;500;600;700;800;900&display=swap");
5
6
 
6
7
  :root {
@@ -54,3 +54,5 @@ export interface SelectBagelField<T> extends BaseBagelField<T> {
54
54
  export type Field<T = Record<string, any>> = BaseBagelField<T> | InputBagelField<T> | SelectBagelField<T>
55
55
 
56
56
  export type BglFormSchemaT<T = Record<string, any>> = Field<T>[]
57
+
58
+ export type BglFormSchemaFnT<T = Record<string, any>> = (() => BglFormSchemaT<T>) | BglFormSchemaT<T>
@@ -1,4 +1,4 @@
1
- import type { Attributes } from '../types'
1
+ import type { Attributes, BglFormSchemaT } from '@bagelink/vue'
2
2
 
3
3
  let timeout: any
4
4
  export function debounce(fn: () => void, delay = 500) {
@@ -55,7 +55,10 @@ export function iffer(field: any, itemData: any) {
55
55
  return true
56
56
  }
57
57
 
58
- export const denullify = (itemData?: Record<string, any>, fieldID?: string) => (fieldID && itemData ? itemData[fieldID] : null)
58
+ export function denullify(itemData?: Record<string, any>, fieldID?: string) {
59
+ if (!fieldID) return null
60
+ return itemData ? itemData[fieldID] : null
61
+ }
59
62
 
60
63
  export const isDate = (dateToTest: any) => !Number.isNaN(Date.parse(dateToTest))
61
64
 
@@ -64,3 +67,20 @@ export { formatString } from './strings'
64
67
  export * as bagelFormUtils from './BagelFormUtils'
65
68
 
66
69
  export { useLang } from './lang'
70
+
71
+ export function getFallbackSchema(data?: any[], showFields?: string[]): BglFormSchemaT {
72
+ const keys = [
73
+ ...new Set((data ?? []).map(Object.keys).flat()),
74
+ ] as string[]
75
+
76
+ const schema: BglFormSchemaT = keys.map(
77
+ id => ({
78
+ id,
79
+ label: keyToLabel(id),
80
+ })
81
+ )
82
+
83
+ return showFields
84
+ ? schema.filter(f => showFields.includes(f.id as string) || !f.id)
85
+ : schema
86
+ }