@finema/core 1.4.159 → 1.4.161

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 (62) hide show
  1. package/README.md +60 -60
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +59 -17
  4. package/dist/runtime/components/Alert.vue +48 -48
  5. package/dist/runtime/components/Avatar.vue +27 -27
  6. package/dist/runtime/components/Badge.vue +11 -11
  7. package/dist/runtime/components/Breadcrumb.vue +44 -44
  8. package/dist/runtime/components/Button/Group.vue +37 -37
  9. package/dist/runtime/components/Button/index.vue +75 -75
  10. package/dist/runtime/components/Card.vue +38 -38
  11. package/dist/runtime/components/Core.vue +45 -45
  12. package/dist/runtime/components/Dialog/index.vue +108 -108
  13. package/dist/runtime/components/Dropdown/index.vue +70 -70
  14. package/dist/runtime/components/FlexDeck/Base.vue +143 -143
  15. package/dist/runtime/components/FlexDeck/index.vue +68 -68
  16. package/dist/runtime/components/Form/FieldWrapper.vue +23 -23
  17. package/dist/runtime/components/Form/Fields.vue +230 -230
  18. package/dist/runtime/components/Form/InputCheckbox/index.vue +28 -28
  19. package/dist/runtime/components/Form/InputDateTime/index.vue +60 -60
  20. package/dist/runtime/components/Form/InputDateTimeRange/index.vue +83 -83
  21. package/dist/runtime/components/Form/InputNumber/index.vue +27 -27
  22. package/dist/runtime/components/Form/InputRadio/index.vue +27 -27
  23. package/dist/runtime/components/Form/InputSelect/index.vue +45 -45
  24. package/dist/runtime/components/Form/InputSelectMultiple/index.vue +54 -54
  25. package/dist/runtime/components/Form/InputStatic/index.vue +16 -16
  26. package/dist/runtime/components/Form/InputTags/index.vue +145 -145
  27. package/dist/runtime/components/Form/InputText/index.vue +67 -67
  28. package/dist/runtime/components/Form/InputTextarea/index.vue +25 -25
  29. package/dist/runtime/components/Form/InputToggle/index.vue +14 -14
  30. package/dist/runtime/components/Form/InputUploadDropzone/index.vue +206 -206
  31. package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.vue +342 -342
  32. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/ItemUpload.vue +241 -241
  33. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/ItemView.vue +89 -89
  34. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.vue +164 -164
  35. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/ItemUpload.vue +161 -161
  36. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/ItemView.vue +64 -64
  37. package/dist/runtime/components/Form/InputUploadDropzoneImageAutoMultiple/index.vue +172 -172
  38. package/dist/runtime/components/Form/InputUploadFileClassic/index.vue +95 -95
  39. package/dist/runtime/components/Form/InputUploadFileClassicAuto/index.vue +151 -151
  40. package/dist/runtime/components/Form/InputUploadImageAuto/index.vue +219 -219
  41. package/dist/runtime/components/Form/InputWYSIWYG/index.vue +53 -53
  42. package/dist/runtime/components/Form/index.vue +6 -6
  43. package/dist/runtime/components/Icon.vue +23 -23
  44. package/dist/runtime/components/Image.vue +36 -36
  45. package/dist/runtime/components/Loader.vue +27 -27
  46. package/dist/runtime/components/Modal/index.vue +146 -146
  47. package/dist/runtime/components/QRCode.vue +22 -22
  48. package/dist/runtime/components/SimplePagination.vue +96 -96
  49. package/dist/runtime/components/Slideover/index.vue +110 -110
  50. package/dist/runtime/components/Table/Base.vue +139 -139
  51. package/dist/runtime/components/Table/ColumnDate.vue +16 -16
  52. package/dist/runtime/components/Table/ColumnDateTime.vue +18 -18
  53. package/dist/runtime/components/Table/ColumnImage.vue +15 -15
  54. package/dist/runtime/components/Table/ColumnNumber.vue +14 -14
  55. package/dist/runtime/components/Table/ColumnText.vue +25 -25
  56. package/dist/runtime/components/Table/Simple.vue +69 -69
  57. package/dist/runtime/components/Table/index.vue +65 -65
  58. package/dist/runtime/components/Tabs/index.vue +64 -64
  59. package/dist/runtime/components/TeleportSafe.vue +40 -40
  60. package/dist/runtime/composables/useNotification.mjs +13 -4
  61. package/dist/runtime/ui.config/notification.mjs +4 -0
  62. package/package.json +95 -95
@@ -1,219 +1,219 @@
1
- <template>
2
- <FieldWrapper v-bind="wrapperProps">
3
- <div :class="[ui.base]">
4
- <input
5
- ref="fileInputRef"
6
- type="file"
7
- class="hidden"
8
- :name="name"
9
- :accept="acceptFile"
10
- :disabled="isDisabled"
11
- @change="handleChange"
12
- />
13
-
14
- <div :class="[ui.imageItem.wrapper]">
15
- <div v-if="!selectedFile && !value" class="w-full">
16
- <div :class="[ui.action.addingWrapper]" @click="handleOpenFile">
17
- <Icon :name="ui.action.addingIcon" :class="[ui.action.addingBtnClass]" />
18
- <p :class="[ui.action.addingTextClass]">{{ uploadAddLabel }}</p>
19
- </div>
20
- </div>
21
-
22
- <!-- Loading State -->
23
- <div v-if="selectedFile && upload.status.value.isLoading" class="w-full">
24
- <div :class="[ui.imageItem.onLoading.wrapper]">
25
- <div :class="[ui.imageItem.onLoading.percentClass]">{{ percent }}%</div>
26
- <UProgress :value="percent" />
27
- </div>
28
- </div>
29
-
30
- <!-- Success State -->
31
- <div v-if="(selectedFile && upload.status.value.isSuccess) || value" class="w-full">
32
- <div :class="[ui.imageItem.onPreview.wrapper]">
33
- <img :class="[ui.imageItem.onPreview.previewImgClass]" :src="value?.url" alt="img" />
34
- <div :class="[ui.imageItem.onPreview.previewActionWrapper]">
35
- <Icon
36
- title="ดูตัวอย่าง"
37
- :name="ui.action.previewIcon"
38
- :class="[ui.imageItem.onPreview.actionBtnClass]"
39
- @click="() => (isPreviewOpen = true)"
40
- />
41
- <Icon
42
- title="ลบไฟล์"
43
- :name="ui.action.deleteIcon"
44
- :class="[ui.imageItem.onPreview.actionBtnClass]"
45
- @click="handleDeleteFile"
46
- />
47
- <Modal v-model="isPreviewOpen" size="xl">
48
- <div class="absolute -top-8 left-0 flex w-full justify-between text-gray-600">
49
- <p>{{ selectedFile?.name }}</p>
50
- <Icon
51
- name="i-heroicons-x-mark"
52
- class="size-6 cursor-pointer hover:text-gray-400"
53
- @click="() => (isPreviewOpen = false)"
54
- />
55
- </div>
56
- <img :src="value?.url" alt="img-preview" class="w-full rounded-lg" />
57
- </Modal>
58
- </div>
59
- </div>
60
-
61
- <div v-if="selectedFile" :class="[ui.imageItem.onPreview.previewTextWrapper]">
62
- <p :class="[ui.imageItem.onPreview.previewText]">{{ selectedFile.name }}</p>
63
- </div>
64
- </div>
65
-
66
- <!-- Failed State -->
67
- <div v-if="selectedFile && upload.status.value.isError" class="w-full">
68
- <div :class="[ui.imageItem.onFailed.wrapper]">
69
- <img
70
- :class="[ui.imageItem.onFailed.failedImgClass]"
71
- :src="generateURL(selectedFile)"
72
- alt="img"
73
- />
74
- <div :class="[ui.imageItem.onFailed.failedActionWrapper]">
75
- <Icon
76
- title="ลบไฟล์"
77
- :name="ui.action.deleteIcon"
78
- :class="[ui.imageItem.onFailed.actionBtnClass]"
79
- @click="handleDeleteFile"
80
- />
81
- </div>
82
- </div>
83
- </div>
84
- </div>
85
- </div>
86
- </FieldWrapper>
87
- </template>
88
-
89
- <script lang="ts" setup>
90
- import { type IUploadImageAutoProps } from './types'
91
- import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
92
- import { useFieldHOC } from '#core/composables/useForm'
93
- import {
94
- computed,
95
- ref,
96
- toRef,
97
- useUI,
98
- useUiConfig,
99
- useWatchTrue,
100
- useUploadLoader,
101
- _get,
102
- type IUploadRequest,
103
- } from '#imports'
104
- import { uploadImage } from '#core/ui.config'
105
- import {
106
- checkMaxSize,
107
- generateURL,
108
- useFileAllocate,
109
- useFileProgress,
110
- } from '#core/helpers/componentHelper'
111
- import type { IFileValue } from '#core/components/Form/types'
112
- import i18next from 'i18next'
113
-
114
- const config = useUiConfig<typeof uploadImage>(uploadImage, 'uploadImage')
115
-
116
- const props = withDefaults(defineProps<IUploadImageAutoProps>(), {
117
- accept: 'image/*',
118
- bodyKey: 'file',
119
- responseURL: 'url',
120
- responsePath: 'path',
121
- uploadAddLabel: 'อัพโหลด',
122
- })
123
-
124
- const emits = defineEmits(['change', 'success', 'delete', 'error'])
125
-
126
- const request: IUploadRequest = {
127
- pathURL: props.uploadPathURL,
128
- requestOptions: props.requestOptions,
129
- }
130
-
131
- const selectedFile = ref<File>()
132
- const isPreviewOpen = ref<boolean>(false)
133
-
134
- const { wrapperProps, value, errorMessage } = useFieldHOC<IFileValue | undefined>(props)
135
-
136
- const upload = useUploadLoader(request)
137
- const { ui } = useUI('uploadImage', toRef(props, 'ui'), config)
138
-
139
- const fileInputRef = ref<HTMLInputElement | null>()
140
-
141
- const fileAllocate = useFileAllocate(toRef(selectedFile), props)
142
- const { onUploadProgress, onDownloadProgress, percent } = useFileProgress()
143
- const acceptFile = computed(() =>
144
- typeof props.accept === 'string' ? props.accept : props.accept?.join(',')
145
- )
146
-
147
- const handleChange = (e: Event) => {
148
- if (props.isDisabled) return
149
-
150
- const file = (e.target as HTMLInputElement).files?.[0]
151
- const result = handleCheckFileCondition(file)
152
-
153
- if (result && file) {
154
- selectedFile.value = file
155
- emits('change', selectedFile.value)
156
- const formData = new FormData()
157
-
158
- formData.append(props.bodyKey, file)
159
- upload.run(formData, { data: { onUploadProgress, onDownloadProgress } })
160
- }
161
- }
162
-
163
- const handleCheckFileCondition = (file: File | undefined): boolean => {
164
- if (!file) return false
165
- const maxSize = checkMaxSize(file, fileAllocate.acceptFileSizeKb.value)
166
-
167
- if (!maxSize) {
168
- if (fileAllocate.isAcceptFileUseMb.value) {
169
- errorMessage.value = i18next.t('custom:invalid_file_size_mb', {
170
- size: fileAllocate.acceptFileSizeMb.value,
171
- })
172
- } else {
173
- errorMessage.value = i18next.t('custom:invalid_file_size_kb', {
174
- size: fileAllocate.acceptFileSizeKb.value,
175
- })
176
- }
177
-
178
- return false
179
- }
180
-
181
- errorMessage.value = ''
182
-
183
- return true
184
- }
185
-
186
- const handleOpenFile = () => {
187
- fileInputRef.value?.click()
188
- }
189
-
190
- const handleDeleteFile = () => {
191
- fileInputRef.value!.value = ''
192
- selectedFile.value = undefined
193
- value.value = undefined
194
- emits('change', undefined)
195
-
196
- emits('delete')
197
- }
198
-
199
- useWatchTrue(
200
- () => upload.status.value.isSuccess,
201
- () => {
202
- value.value = {
203
- url: _get(upload.data.value, props.responseURL),
204
- path: _get(upload.data.value, props.responsePath),
205
- name: upload.data.value.name,
206
- size: upload.data.value.size,
207
- }
208
-
209
- emits('success', value.value)
210
- }
211
- )
212
-
213
- useWatchTrue(
214
- () => upload.status.value.isError,
215
- () => {
216
- emits('error', upload.status.value.errorData)
217
- }
218
- )
219
- </script>
1
+ <template>
2
+ <FieldWrapper v-bind="wrapperProps">
3
+ <div :class="[ui.base]">
4
+ <input
5
+ ref="fileInputRef"
6
+ type="file"
7
+ class="hidden"
8
+ :name="name"
9
+ :accept="acceptFile"
10
+ :disabled="isDisabled"
11
+ @change="handleChange"
12
+ />
13
+
14
+ <div :class="[ui.imageItem.wrapper]">
15
+ <div v-if="!selectedFile && !value" class="w-full">
16
+ <div :class="[ui.action.addingWrapper]" @click="handleOpenFile">
17
+ <Icon :name="ui.action.addingIcon" :class="[ui.action.addingBtnClass]" />
18
+ <p :class="[ui.action.addingTextClass]">{{ uploadAddLabel }}</p>
19
+ </div>
20
+ </div>
21
+
22
+ <!-- Loading State -->
23
+ <div v-if="selectedFile && upload.status.value.isLoading" class="w-full">
24
+ <div :class="[ui.imageItem.onLoading.wrapper]">
25
+ <div :class="[ui.imageItem.onLoading.percentClass]">{{ percent }}%</div>
26
+ <UProgress :value="percent" />
27
+ </div>
28
+ </div>
29
+
30
+ <!-- Success State -->
31
+ <div v-if="(selectedFile && upload.status.value.isSuccess) || value" class="w-full">
32
+ <div :class="[ui.imageItem.onPreview.wrapper]">
33
+ <img :class="[ui.imageItem.onPreview.previewImgClass]" :src="value?.url" alt="img" />
34
+ <div :class="[ui.imageItem.onPreview.previewActionWrapper]">
35
+ <Icon
36
+ title="ดูตัวอย่าง"
37
+ :name="ui.action.previewIcon"
38
+ :class="[ui.imageItem.onPreview.actionBtnClass]"
39
+ @click="() => (isPreviewOpen = true)"
40
+ />
41
+ <Icon
42
+ title="ลบไฟล์"
43
+ :name="ui.action.deleteIcon"
44
+ :class="[ui.imageItem.onPreview.actionBtnClass]"
45
+ @click="handleDeleteFile"
46
+ />
47
+ <Modal v-model="isPreviewOpen" size="xl">
48
+ <div class="absolute -top-8 left-0 flex w-full justify-between text-gray-600">
49
+ <p>{{ selectedFile?.name }}</p>
50
+ <Icon
51
+ name="i-heroicons-x-mark"
52
+ class="size-6 cursor-pointer hover:text-gray-400"
53
+ @click="() => (isPreviewOpen = false)"
54
+ />
55
+ </div>
56
+ <img :src="value?.url" alt="img-preview" class="w-full rounded-lg" />
57
+ </Modal>
58
+ </div>
59
+ </div>
60
+
61
+ <div v-if="selectedFile" :class="[ui.imageItem.onPreview.previewTextWrapper]">
62
+ <p :class="[ui.imageItem.onPreview.previewText]">{{ selectedFile.name }}</p>
63
+ </div>
64
+ </div>
65
+
66
+ <!-- Failed State -->
67
+ <div v-if="selectedFile && upload.status.value.isError" class="w-full">
68
+ <div :class="[ui.imageItem.onFailed.wrapper]">
69
+ <img
70
+ :class="[ui.imageItem.onFailed.failedImgClass]"
71
+ :src="generateURL(selectedFile)"
72
+ alt="img"
73
+ />
74
+ <div :class="[ui.imageItem.onFailed.failedActionWrapper]">
75
+ <Icon
76
+ title="ลบไฟล์"
77
+ :name="ui.action.deleteIcon"
78
+ :class="[ui.imageItem.onFailed.actionBtnClass]"
79
+ @click="handleDeleteFile"
80
+ />
81
+ </div>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </FieldWrapper>
87
+ </template>
88
+
89
+ <script lang="ts" setup>
90
+ import { type IUploadImageAutoProps } from './types'
91
+ import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
92
+ import { useFieldHOC } from '#core/composables/useForm'
93
+ import {
94
+ computed,
95
+ ref,
96
+ toRef,
97
+ useUI,
98
+ useUiConfig,
99
+ useWatchTrue,
100
+ useUploadLoader,
101
+ _get,
102
+ type IUploadRequest,
103
+ } from '#imports'
104
+ import { uploadImage } from '#core/ui.config'
105
+ import {
106
+ checkMaxSize,
107
+ generateURL,
108
+ useFileAllocate,
109
+ useFileProgress,
110
+ } from '#core/helpers/componentHelper'
111
+ import type { IFileValue } from '#core/components/Form/types'
112
+ import i18next from 'i18next'
113
+
114
+ const config = useUiConfig<typeof uploadImage>(uploadImage, 'uploadImage')
115
+
116
+ const props = withDefaults(defineProps<IUploadImageAutoProps>(), {
117
+ accept: 'image/*',
118
+ bodyKey: 'file',
119
+ responseURL: 'url',
120
+ responsePath: 'path',
121
+ uploadAddLabel: 'อัพโหลด',
122
+ })
123
+
124
+ const emits = defineEmits(['change', 'success', 'delete', 'error'])
125
+
126
+ const request: IUploadRequest = {
127
+ pathURL: props.uploadPathURL,
128
+ requestOptions: props.requestOptions,
129
+ }
130
+
131
+ const selectedFile = ref<File>()
132
+ const isPreviewOpen = ref<boolean>(false)
133
+
134
+ const { wrapperProps, value, errorMessage } = useFieldHOC<IFileValue | undefined>(props)
135
+
136
+ const upload = useUploadLoader(request)
137
+ const { ui } = useUI('uploadImage', toRef(props, 'ui'), config)
138
+
139
+ const fileInputRef = ref<HTMLInputElement | null>()
140
+
141
+ const fileAllocate = useFileAllocate(toRef(selectedFile), props)
142
+ const { onUploadProgress, onDownloadProgress, percent } = useFileProgress()
143
+ const acceptFile = computed(() =>
144
+ typeof props.accept === 'string' ? props.accept : props.accept?.join(',')
145
+ )
146
+
147
+ const handleChange = (e: Event) => {
148
+ if (props.isDisabled) return
149
+
150
+ const file = (e.target as HTMLInputElement).files?.[0]
151
+ const result = handleCheckFileCondition(file)
152
+
153
+ if (result && file) {
154
+ selectedFile.value = file
155
+ emits('change', selectedFile.value)
156
+ const formData = new FormData()
157
+
158
+ formData.append(props.bodyKey, file)
159
+ upload.run(formData, { data: { onUploadProgress, onDownloadProgress } })
160
+ }
161
+ }
162
+
163
+ const handleCheckFileCondition = (file: File | undefined): boolean => {
164
+ if (!file) return false
165
+ const maxSize = checkMaxSize(file, fileAllocate.acceptFileSizeKb.value)
166
+
167
+ if (!maxSize) {
168
+ if (fileAllocate.isAcceptFileUseMb.value) {
169
+ errorMessage.value = i18next.t('custom:invalid_file_size_mb', {
170
+ size: fileAllocate.acceptFileSizeMb.value,
171
+ })
172
+ } else {
173
+ errorMessage.value = i18next.t('custom:invalid_file_size_kb', {
174
+ size: fileAllocate.acceptFileSizeKb.value,
175
+ })
176
+ }
177
+
178
+ return false
179
+ }
180
+
181
+ errorMessage.value = ''
182
+
183
+ return true
184
+ }
185
+
186
+ const handleOpenFile = () => {
187
+ fileInputRef.value?.click()
188
+ }
189
+
190
+ const handleDeleteFile = () => {
191
+ fileInputRef.value!.value = ''
192
+ selectedFile.value = undefined
193
+ value.value = undefined
194
+ emits('change', undefined)
195
+
196
+ emits('delete')
197
+ }
198
+
199
+ useWatchTrue(
200
+ () => upload.status.value.isSuccess,
201
+ () => {
202
+ value.value = {
203
+ url: _get(upload.data.value, props.responseURL),
204
+ path: _get(upload.data.value, props.responsePath),
205
+ name: upload.data.value.name,
206
+ size: upload.data.value.size,
207
+ }
208
+
209
+ emits('success', value.value)
210
+ }
211
+ )
212
+
213
+ useWatchTrue(
214
+ () => upload.status.value.isError,
215
+ () => {
216
+ emits('error', upload.status.value.errorData)
217
+ }
218
+ )
219
+ </script>
@@ -1,55 +1,55 @@
1
- <template>
2
- <FieldWrapper v-bind="wrapperProps">
3
- <ClientOnly>
4
- <QuillEditor
5
- v-model:content="value"
6
- :placeholder="placeholder ?? label"
7
- :autofocus="autoFocus"
8
- :disabled="isDisabled || isReadonly"
9
- :name="name"
10
- class="ql-snow focus:ring-primary-500 min-h-[300px] rounded-b-md ring-1 ring-inset ring-gray-300 focus:ring-2"
11
- content-type="html"
12
- :options="options"
13
- />
14
- </ClientOnly>
15
- </FieldWrapper>
16
- </template>
17
- <script lang="ts" setup>
18
- import { useFieldHOC } from '#core/composables/useForm'
19
- import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
20
- import '@vueup/vue-quill/dist/vue-quill.snow.css'
21
- import type { IWYSIWYGFieldProps } from '#core/components/Form/InputWYSIWYG/types'
22
-
23
- const props = withDefaults(defineProps<IWYSIWYGFieldProps>(), {})
24
- const { value, wrapperProps } = useFieldHOC<string>(props)
25
-
26
- const options = {
27
- modules: {
28
- toolbar: [
29
- // [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
30
- ['bold', 'italic', 'underline'], // toggled buttons
31
- // ['blockquote', 'code-block'],
32
- // ['link', 'image', 'video'], // link and image, video
33
- ['link'],
34
-
35
- // [{ header: 1 }, { header: 2 }], // custom button values
36
- // [{ list: 'ordered' }, { list: 'bullet' }],
37
- // [{ script: 'sub' }, { script: 'super' }], // superscript/subscript
38
- // [{ indent: '-1' }, { indent: '+1' }], // outdent/indent
39
- // [{ direction: 'rtl' }], // text direction
40
-
41
- // [{ header: [1, 2, 3, 4, 5, 6, false] }],
42
-
43
- [{ color: [] }, { background: [] }], // dropdown with defaults from theme
44
- // [{ font: [] }],
45
- // [{ align: [] }],
46
- //
47
- ['clean'], // remove formatting button
48
- ],
49
- },
50
- theme: 'snow',
51
- }
52
- </script>
1
+ <template>
2
+ <FieldWrapper v-bind="wrapperProps">
3
+ <ClientOnly>
4
+ <QuillEditor
5
+ v-model:content="value"
6
+ :placeholder="placeholder ?? label"
7
+ :autofocus="autoFocus"
8
+ :disabled="isDisabled || isReadonly"
9
+ :name="name"
10
+ class="ql-snow focus:ring-primary-500 min-h-[300px] rounded-b-md ring-1 ring-inset ring-gray-300 focus:ring-2"
11
+ content-type="html"
12
+ :options="options"
13
+ />
14
+ </ClientOnly>
15
+ </FieldWrapper>
16
+ </template>
17
+ <script lang="ts" setup>
18
+ import { useFieldHOC } from '#core/composables/useForm'
19
+ import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
20
+ import '@vueup/vue-quill/dist/vue-quill.snow.css'
21
+ import type { IWYSIWYGFieldProps } from '#core/components/Form/InputWYSIWYG/types'
22
+
23
+ const props = withDefaults(defineProps<IWYSIWYGFieldProps>(), {})
24
+ const { value, wrapperProps } = useFieldHOC<string>(props)
25
+
26
+ const options = {
27
+ modules: {
28
+ toolbar: [
29
+ // [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
30
+ ['bold', 'italic', 'underline'], // toggled buttons
31
+ // ['blockquote', 'code-block'],
32
+ // ['link', 'image', 'video'], // link and image, video
33
+ ['link'],
34
+
35
+ // [{ header: 1 }, { header: 2 }], // custom button values
36
+ // [{ list: 'ordered' }, { list: 'bullet' }],
37
+ // [{ script: 'sub' }, { script: 'super' }], // superscript/subscript
38
+ // [{ indent: '-1' }, { indent: '+1' }], // outdent/indent
39
+ // [{ direction: 'rtl' }], // text direction
40
+
41
+ // [{ header: [1, 2, 3, 4, 5, 6, false] }],
42
+
43
+ [{ color: [] }, { background: [] }], // dropdown with defaults from theme
44
+ // [{ font: [] }],
45
+ // [{ align: [] }],
46
+ //
47
+ ['clean'], // remove formatting button
48
+ ],
49
+ },
50
+ theme: 'snow',
51
+ }
52
+ </script>
53
53
  <style>
54
54
  .ql-toolbar.ql-snow{@apply rounded-t-md border-b-0}.ql-container.ql-snow,.ql-snow{@apply border-0}
55
- </style>
55
+ </style>
@@ -1,6 +1,6 @@
1
- <template>
2
- <form class="form">
3
- <slot />
4
- </form>
5
- </template>
6
- <script lang="ts" setup></script>
1
+ <template>
2
+ <form class="form">
3
+ <slot />
4
+ </form>
5
+ </template>
6
+ <script lang="ts" setup></script>
@@ -1,23 +1,23 @@
1
- <template>
2
- <UIcon :name="name" :dynamic="dynamicValue" />
3
- </template>
4
-
5
- <script lang="ts" setup>
6
- import { computed, useUiConfig } from '#imports'
7
- import { icon } from '#core/ui.config'
8
-
9
- const props = defineProps({
10
- name: {
11
- type: String,
12
- required: true,
13
- },
14
- dynamic: {
15
- type: Boolean,
16
- default: false,
17
- },
18
- })
19
-
20
- const config = useUiConfig<typeof icon>(icon, 'icon')
21
-
22
- const dynamicValue = computed(() => props.dynamic || config.dynamic)
23
- </script>
1
+ <template>
2
+ <UIcon :name="name" :dynamic="dynamicValue" />
3
+ </template>
4
+
5
+ <script lang="ts" setup>
6
+ import { computed, useUiConfig } from '#imports'
7
+ import { icon } from '#core/ui.config'
8
+
9
+ const props = defineProps({
10
+ name: {
11
+ type: String,
12
+ required: true,
13
+ },
14
+ dynamic: {
15
+ type: Boolean,
16
+ default: false,
17
+ },
18
+ })
19
+
20
+ const config = useUiConfig<typeof icon>(icon, 'icon')
21
+
22
+ const dynamicValue = computed(() => props.dynamic || config.dynamic)
23
+ </script>