@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.
- package/dist/components/Btn.vue.d.ts.map +1 -1
- package/dist/components/DataTable/DataTable.vue.d.ts +31 -0
- package/dist/components/DataTable/DataTable.vue.d.ts.map +1 -0
- package/dist/components/DataTable/tableTypes.d.ts +35 -0
- package/dist/components/DataTable/tableTypes.d.ts.map +1 -0
- package/dist/components/DataTable/useSorting.d.ts +7 -0
- package/dist/components/DataTable/useSorting.d.ts.map +1 -0
- package/dist/components/DataTable/useTableData.d.ts +13 -0
- package/dist/components/DataTable/useTableData.d.ts.map +1 -0
- package/dist/components/DataTable/useTableSelection.d.ts +10 -0
- package/dist/components/DataTable/useTableSelection.d.ts.map +1 -0
- package/dist/components/DataTable/useTableVirtualization.d.ts +25 -0
- package/dist/components/DataTable/useTableVirtualization.d.ts.map +1 -0
- package/dist/components/TableSchema.vue.d.ts +2 -2
- package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/FileUpload.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/index.vue.d.ts +1 -0
- package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts +0 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.cjs +3493 -3395
- package/dist/index.mjs +3494 -3396
- package/dist/style.css +348 -348
- package/dist/types/BagelForm.d.ts +3 -0
- package/dist/types/BagelForm.d.ts.map +1 -1
- package/dist/types/TableSchema.d.ts +36 -0
- package/dist/types/TableSchema.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/Btn.vue +2 -2
- package/src/components/{TableSchema.vue → DataTable/DataTable.vue} +62 -154
- package/src/components/DataTable/tableTypes.d.ts +0 -0
- package/src/components/DataTable/tableTypes.ts +38 -0
- package/src/components/DataTable/useSorting.ts +30 -0
- package/src/components/DataTable/useTableData.ts +95 -0
- package/src/components/DataTable/useTableSelection.ts +45 -0
- package/src/components/DataTable/useTableVirtualization.ts +33 -0
- package/src/components/Icon/Icon.vue +1 -1
- package/src/components/form/BagelForm.vue +9 -15
- package/src/components/form/inputs/FileUpload.vue +1 -0
- package/src/components/form/inputs/RichText/index.vue +36 -31
- package/src/components/form/inputs/SelectInput.vue +1 -3
- package/src/components/form/inputs/Upload/UploadInput.vue +4 -0
- package/src/components/index.ts +3 -2
- package/src/types/BagelForm.ts +1 -0
- 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,
|
|
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
|
|
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]:
|
|
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':
|
|
112
|
+
'modelValue': currentValue,
|
|
120
113
|
'onUpdate:modelValue': (value: any) => {
|
|
121
114
|
if (!field.id) return
|
|
122
|
-
updateFormData(field.id, value
|
|
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
|
-
:
|
|
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
|
|
174
|
+
<template v-for="(field) in resolvedSchema" :key="field.id">
|
|
181
175
|
<component :is="renderSchemaField(field)" />
|
|
182
176
|
</template>
|
|
183
177
|
</template>
|
|
@@ -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
|
|
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="
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
/>
|
package/src/components/index.ts
CHANGED
|
@@ -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'
|
package/src/types/BagelForm.ts
CHANGED
|
@@ -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
|
+
}
|