@bagelink/vue 0.0.1139 → 0.0.1143

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 (48) hide show
  1. package/dist/components/Btn.vue.d.ts.map +1 -1
  2. package/dist/components/DataTable/DataTable.vue.d.ts +31 -0
  3. package/dist/components/DataTable/DataTable.vue.d.ts.map +1 -0
  4. package/dist/components/DataTable/tableTypes.d.ts +35 -0
  5. package/dist/components/DataTable/tableTypes.d.ts.map +1 -0
  6. package/dist/components/DataTable/useSorting.d.ts +7 -0
  7. package/dist/components/DataTable/useSorting.d.ts.map +1 -0
  8. package/dist/components/DataTable/useTableData.d.ts +13 -0
  9. package/dist/components/DataTable/useTableData.d.ts.map +1 -0
  10. package/dist/components/DataTable/useTableSelection.d.ts +10 -0
  11. package/dist/components/DataTable/useTableSelection.d.ts.map +1 -0
  12. package/dist/components/DataTable/useTableVirtualization.d.ts +25 -0
  13. package/dist/components/DataTable/useTableVirtualization.d.ts.map +1 -0
  14. package/dist/components/TableSchema.vue.d.ts +2 -2
  15. package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
  16. package/dist/components/form/inputs/FileUpload.vue.d.ts.map +1 -1
  17. package/dist/components/form/inputs/RichText/index.vue.d.ts +1 -0
  18. package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
  19. package/dist/components/form/inputs/SelectInput.vue.d.ts +0 -1
  20. package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
  21. package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts.map +1 -1
  22. package/dist/components/index.d.ts +2 -1
  23. package/dist/components/index.d.ts.map +1 -1
  24. package/dist/index.cjs +3493 -3395
  25. package/dist/index.mjs +3494 -3396
  26. package/dist/style.css +348 -348
  27. package/dist/types/BagelForm.d.ts +3 -0
  28. package/dist/types/BagelForm.d.ts.map +1 -1
  29. package/dist/types/TableSchema.d.ts +36 -0
  30. package/dist/types/TableSchema.d.ts.map +1 -0
  31. package/package.json +1 -1
  32. package/src/components/Btn.vue +2 -2
  33. package/src/components/{TableSchema.vue → DataTable/DataTable.vue} +62 -154
  34. package/src/components/DataTable/tableTypes.d.ts +0 -0
  35. package/src/components/DataTable/tableTypes.ts +38 -0
  36. package/src/components/DataTable/useSorting.ts +30 -0
  37. package/src/components/DataTable/useTableData.ts +95 -0
  38. package/src/components/DataTable/useTableSelection.ts +45 -0
  39. package/src/components/DataTable/useTableVirtualization.ts +33 -0
  40. package/src/components/Icon/Icon.vue +1 -1
  41. package/src/components/form/BagelForm.vue +9 -15
  42. package/src/components/form/inputs/FileUpload.vue +1 -0
  43. package/src/components/form/inputs/RichText/index.vue +36 -31
  44. package/src/components/form/inputs/SelectInput.vue +1 -3
  45. package/src/components/form/inputs/Upload/UploadInput.vue +4 -0
  46. package/src/components/index.ts +3 -2
  47. package/src/types/BagelForm.ts +1 -0
  48. package/src/types/TableSchema.ts +39 -0
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import type { BglFormSchemaT, BglFormSchemaFnT, Field } from '@bagelink/vue'
3
3
  import type { VNode } from 'vue'
4
- import { BglForm, CheckInput, DateInput, FieldArray, FileUpload, NumberInput, RichText, SelectInput, TabsNav, TextInput, ToggleInput, UploadInput } from '@bagelink/vue'
4
+ import { BglForm, CheckInput, DateInput, FieldArray, FileUpload, NumberInput, RichText, SelectInput, TabsNav, TextInput, ToggleInput, UploadInput } from '@bagelink/vue'
5
5
  import { h, watch } from 'vue'
6
6
 
7
7
  interface Props {
@@ -63,17 +63,10 @@ function getComponent(field: Field) {
63
63
  return componentMap[field.$el as keyof typeof componentMap] ?? field.$el ?? 'div'
64
64
  }
65
65
 
66
- function processFieldValue(fieldType: any, value: any): any {
67
- if (value == null) return value
68
- if (fieldType === 'select' && typeof value === 'object') return value.value
69
- if (typeof value === 'object' && 'value' in value) return value.value
70
- return value
71
- }
72
-
73
- function updateFormData(fieldId: string, value: any, fieldType?: any) {
66
+ function updateFormData(fieldId: string, value: any) {
74
67
  formData = {
75
68
  ...formData,
76
- [fieldId]: processFieldValue(fieldType, value)
69
+ [fieldId]: value
77
70
  }
78
71
  emit('update:modelValue', formData)
79
72
  }
@@ -116,10 +109,10 @@ function renderSchemaField(field: Field): VNode | null {
116
109
  label,
117
110
  placeholder,
118
111
  disabled,
119
- 'modelValue': processFieldValue(field.$el, currentValue),
112
+ 'modelValue': currentValue,
120
113
  'onUpdate:modelValue': (value: any) => {
121
114
  if (!field.id) return
122
- updateFormData(field.id, value, field.$el)
115
+ updateFormData(field.id, value)
123
116
  field.onUpdate?.(value, formData)
124
117
  }
125
118
  }
@@ -151,9 +144,10 @@ function renderSchemaField(field: Field): VNode | null {
151
144
  ? {
152
145
  default: () => field.children!
153
146
  .map(child => typeof child === 'string' ? child : renderSchemaField(child))
154
- .filter(Boolean)
147
+ .filter(Boolean),
148
+ ...field.slots
155
149
  }
156
- : undefined
150
+ : field.slots
157
151
 
158
152
  return h(Component as any, props, slots)
159
153
  }
@@ -177,7 +171,7 @@ defineExpose({ form, isDirty, validateForm })
177
171
  <template>
178
172
  <form ref="form" @submit.prevent="handleSubmit">
179
173
  <template v-if="resolvedSchema">
180
- <template v-for="(field, index) in resolvedSchema" :key="field.id || index">
174
+ <template v-for="(field) in resolvedSchema" :key="field.id">
181
175
  <component :is="renderSchemaField(field)" />
182
176
  </template>
183
177
  </template>
@@ -462,6 +462,7 @@ function drop(e: DragEvent) {
462
462
  </div>
463
463
  <Image
464
464
  v-if="isImage(fileQ.file.type)"
465
+ v-lightbox="{ src: fileToUrl(fileQ.file), download: true }"
465
466
  class="single-preview"
466
467
  :src="fileToUrl(fileQ.file)"
467
468
  alt=""
@@ -1,13 +1,13 @@
1
1
  <script setup lang="ts">
2
2
  import type { ToolbarConfig } from './richTextTypes'
3
3
  import { CodeEditor, copyText, Btn } from '@bagelink/vue'
4
- import { watch, computed } from 'vue'
4
+ import { watch } from 'vue'
5
5
  import EditorToolbar from './components/EditorToolbar.vue'
6
6
  import { useCommands } from './composables/useCommands'
7
7
  import { useEditor } from './composables/useEditor'
8
8
  import { useEditorKeyboard } from './composables/useEditorKeyboard'
9
9
 
10
- const props = defineProps<{ modelValue: string, toolbarConfig?: ToolbarConfig, debug?: boolean }>()
10
+ const props = defineProps<{ modelValue: string, toolbarConfig?: ToolbarConfig, debug?: boolean, label?: string }>()
11
11
  const emit = defineEmits(['update:modelValue'])
12
12
 
13
13
  const iframe = $ref<HTMLIFrameElement>()
@@ -15,8 +15,8 @@ const editor = useEditor()
15
15
  const commands = useCommands(editor.state, props.debug ? editor.debug : undefined)
16
16
 
17
17
  // Expose debug methods if debug mode is enabled
18
- const debugMethods = computed(() => props.debug ? editor.debug : undefined)
19
-
18
+ const debugMethods = $computed(() => props.debug ? editor.debug : undefined)
19
+ const hasRTL = $computed(() => /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/.test(props.modelValue))
20
20
  async function initEditor() {
21
21
  if (!iframe) {
22
22
  setTimeout(initEditor, 100)
@@ -30,7 +30,6 @@ async function initEditor() {
30
30
  doc.body.contentEditable = 'true'
31
31
 
32
32
  // Set default direction based on content
33
- const hasRTL = /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/.test(props.modelValue)
34
33
  doc.body.dir = hasRTL ? 'rtl' : 'ltr'
35
34
 
36
35
  const style = doc.createElement('style')
@@ -79,38 +78,44 @@ watch(() => props.modelValue, (newValue) => {
79
78
  })
80
79
 
81
80
  watch(() => editor.state.content, (newValue) => {
81
+ if (editor.state.doc?.body.innerHTML) {
82
+ editor.state.doc.body.dir = hasRTL ? 'rtl' : 'ltr'
83
+ }
82
84
  emit('update:modelValue', newValue)
83
85
  })
84
86
  </script>
85
87
 
86
88
  <template>
87
- <div class="rich-text-editor rounded pt-05 px-05 pb-075 mb-05" :class="{ 'fullscreen-mode': editor.state.isFullscreen }">
88
- <EditorToolbar
89
- v-if="editor.state.hasInit" :config="toolbarConfig" :selectedStyles="editor.state.selectedStyles"
90
- @action="commands.execute"
91
- />
92
- <div class="editor-container" :class="{ 'split-view': editor.state.isSplitView }">
93
- <div class="content-area radius-05">
94
- <iframe id="rich-text-iframe" ref="iframe" class="editableContent" title="Editor" @load="initEditor" />
95
- </div>
96
- <CodeEditor
97
- v-if="editor.state.isSplitView" v-model="editor.state.content" language="html"
98
- @update:modelValue="editor.updateContent('html')"
89
+ <div class="bagel-input">
90
+ <label>{{ label }}</label>
91
+ <div class="rich-text-editor rounded pt-05 px-05 pb-075 mb-05" :class="{ 'fullscreen-mode': editor.state.isFullscreen }">
92
+ <EditorToolbar
93
+ v-if="editor.state.hasInit" :config="toolbarConfig" :selectedStyles="editor.state.selectedStyles"
94
+ @action="commands.execute"
99
95
  />
100
- </div>
101
- <div v-if="debug" class="flex">
102
- <p class="text12 txt-gray mb-0 p-0">
103
- Debug
104
- </p>
105
- <Btn thin color="gray" icon="delete" @click="debugMethods?.clearSession">
106
- Clear Session
107
- </Btn>
108
- <Btn thin color="gray" icon="download" @click="debugMethods?.downloadSession">
109
- Download Log
110
- </Btn>
111
- <Btn thin color="gray" icon="content_copy" @click="copyText(debugMethods?.exportDebugWithPrompt() || '')">
112
- Copy Log
113
- </Btn>
96
+ <div class="editor-container" :class="{ 'split-view': editor.state.isSplitView }">
97
+ <div class="content-area radius-05">
98
+ <iframe id="rich-text-iframe" ref="iframe" class="editableContent" title="Editor" @load="initEditor" />
99
+ </div>
100
+ <CodeEditor
101
+ v-if="editor.state.isSplitView" v-model="editor.state.content" language="html"
102
+ @update:modelValue="editor.updateContent('html')"
103
+ />
104
+ </div>
105
+ <div v-if="debug" class="flex">
106
+ <p class="text12 txt-gray mb-0 p-0">
107
+ Debug
108
+ </p>
109
+ <Btn thin color="gray" icon="delete" @click="debugMethods?.clearSession">
110
+ Clear Session
111
+ </Btn>
112
+ <Btn thin color="gray" icon="download" @click="debugMethods?.downloadSession">
113
+ Download Log
114
+ </Btn>
115
+ <Btn thin color="gray" icon="content_copy" @click="copyText(debugMethods?.exportDebugWithPrompt() || '')">
116
+ Copy Log
117
+ </Btn>
118
+ </div>
114
119
  </div>
115
120
  </div>
116
121
  </template>
@@ -31,14 +31,11 @@ interface PropTypes {
31
31
  }
32
32
 
33
33
  const props = withDefaults(defineProps<PropTypes>(), {
34
- searchPlaceholder: 'Search',
35
34
  placeholder: 'Select',
36
35
  })
37
36
 
38
37
  const emit = defineEmits(['update:modelValue']) // Add 'search' event
39
38
 
40
- const searchPlaceholder = $computed(() => props.searchPlaceholder)
41
-
42
39
  const searchInput = $ref<HTMLElement | undefined>()
43
40
 
44
41
  let selectedItems = $ref<Option[]>([])
@@ -61,6 +58,7 @@ const selectedLabel = $computed((): string => {
61
58
  }
62
59
  return selectedItems.map(item => getLabel(item)).join(', ')
63
60
  })
61
+ const searchPlaceholder = $computed(() => props.searchPlaceholder ?? selectedLabel ?? 'Search')
64
62
 
65
63
  let serverOptions: Option[] = $ref([])
66
64
  let isSearching = $ref(false)
@@ -308,6 +308,8 @@ watch(() => props.dirPath, () => {
308
308
  </div>
309
309
  <div v-if="isImage(path_key)" class="h-100">
310
310
  <Image
311
+ v-lightbox="{ src: pathToUrl(path_key), download: true }"
312
+
311
313
  class="single-preview"
312
314
  :pathKey="path_key"
313
315
  alt=""
@@ -341,7 +343,9 @@ watch(() => props.dirPath, () => {
341
343
  </div>
342
344
  <Image
343
345
  v-if="isImage(file.file.type)"
346
+ v-lightbox="{ src: fileToUrl(file.file), download: true }"
344
347
  class="single-preview"
348
+
345
349
  :src="fileToUrl(file.file)"
346
350
  alt=""
347
351
  />
@@ -11,6 +11,8 @@ export { default as Card } from './Card.vue'
11
11
  export { default as Carousel } from './Carousel.vue'
12
12
  export * from './dashboard'
13
13
  export { default as DataPreview } from './DataPreview.vue'
14
+ export { default as DataTable } from './DataTable/DataTable.vue'
15
+ export { default as TableSchema } from './DataTable/DataTable.vue'
14
16
  export { default as Dropdown } from './Dropdown.vue'
15
17
  export { default as FieldSetVue } from './FieldSetVue.vue'
16
18
  export { default as Flag } from './Flag.vue'
@@ -22,8 +24,8 @@ export * from './layout'
22
24
  export { default as ListItem } from './ListItem.vue'
23
25
  export { default as ListView } from './ListView.vue'
24
26
  export { default as Loading } from './Loading.vue'
25
- export { default as MapEmbed } from './MapEmbed.vue'
26
27
 
28
+ export { default as MapEmbed } from './MapEmbed.vue'
27
29
  export { default as Modal } from './Modal.vue'
28
30
  export { default as ModalConfirm } from './ModalConfirm.vue'
29
31
  export { default as ModalForm } from './ModalForm.vue'
@@ -31,7 +33,6 @@ export { default as NavBar } from './NavBar.vue'
31
33
  export { default as PageTitle } from './PageTitle.vue'
32
34
  export { default as Pill } from './Pill.vue'
33
35
  export { default as RouterWrapper } from './RouterWrapper.vue'
34
- export { default as TableSchema } from './TableSchema.vue'
35
36
 
36
37
  export { default as Title } from './Title.vue'
37
38
  export { default as ToolBar } from './ToolBar.vue'
@@ -36,6 +36,7 @@ export interface BaseBagelField<T = { [key: string]: any }> {
36
36
  'disabled'?: boolean
37
37
  'helptext'?: string
38
38
  'options'?: BagelFieldOptions<T>
39
+ 'slots'?: { [key: string]: any }
39
40
  'defaultValue'?: any
40
41
  'transform'?: (val?: any, rowData?: T) => any
41
42
  'onUpdate'?: (val: any, rowData?: T) => void
@@ -0,0 +1,39 @@
1
+ import type { BglFormSchemaT } from '@bagelink/vue'
2
+ import type { Ref, ComputedRef } from 'vue'
3
+
4
+ export type SortDirectionsT = 'ASC' | 'DESC'
5
+ export type EmitOrderT = `${string} ${SortDirectionsT}`
6
+
7
+ export interface TableSchemaProps<T extends Record<string, any> = Record<string, any>> {
8
+ data: T[]
9
+ schema?: BglFormSchemaT<T> | (() => BglFormSchemaT<T>)
10
+ showFields?: string[]
11
+ useServerSort?: boolean
12
+ selectable?: boolean
13
+ onLastItemVisible?: () => void
14
+ }
15
+
16
+ export interface SortingOptions<T> {
17
+ onSort: (field: string, direction: SortDirectionsT) => void
18
+ }
19
+
20
+ export interface TableSelectionOptions<T> {
21
+ selectable: boolean | undefined
22
+ selectedItems: { value: string[] }
23
+ onSelect: (item: T) => void
24
+ }
25
+
26
+ export interface TableVirtualizationOptions<T> {
27
+ data: Ref<T[]> | ComputedRef<T[]>
28
+ itemHeight: number
29
+ onLastItemVisible?: () => void
30
+ }
31
+
32
+ export interface TableDataOptions<T> {
33
+ data: Ref<T[]> | ComputedRef<T[]>
34
+ schema?: BglFormSchemaT<T> | (() => BglFormSchemaT<T>)
35
+ showFields?: string[]
36
+ sortField: string
37
+ sortDirection: SortDirectionsT
38
+ useServerSort?: boolean
39
+ }