@mythpe/quasar-ui-qui 0.2.25 → 0.2.26

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.
@@ -0,0 +1,403 @@
1
+ <!--
2
+ - MyTh Ahmed Faiz Copyright © 2016-2024 All rights reserved.
3
+ - Email: mythpe@gmail.com
4
+ - Mobile: +966590470092
5
+ - Website: https://www.4myth.com
6
+ - Github: https://github.com/mythpe
7
+ -->
8
+
9
+ <script
10
+ lang="ts"
11
+ setup
12
+ >
13
+
14
+ import { useField } from 'vee-validate'
15
+ import type { MCkeditorProps as Props } from '../../types'
16
+ import { computed, reactive, toValue, useTemplateRef } from 'vue'
17
+ import { useBindInput, useMyth } from '../../composable'
18
+
19
+ import type { EditorConfig } from 'ckeditor5'
20
+ import {
21
+ Alignment,
22
+ Autoformat,
23
+ Base64UploadAdapter,
24
+ BlockQuote,
25
+ Bold,
26
+ CKFinder,
27
+ CKFinderUploadAdapter,
28
+ ClassicEditor,
29
+ CloudServices,
30
+ Code,
31
+ CodeBlock,
32
+ Essentials,
33
+ FontBackgroundColor,
34
+ FontColor,
35
+ FontFamily,
36
+ FontSize,
37
+ Heading,
38
+ Image,
39
+ ImageCaption,
40
+ ImageResize,
41
+ ImageStyle,
42
+ ImageToolbar,
43
+ ImageUpload,
44
+ Indent,
45
+ IndentBlock,
46
+ Italic,
47
+ Link,
48
+ List,
49
+ MediaEmbed,
50
+ Mention,
51
+ Paragraph,
52
+ PasteFromOffice,
53
+ PictureEditing,
54
+ RemoveFormat,
55
+ SourceEditing,
56
+ Strikethrough,
57
+ Subscript,
58
+ Superscript,
59
+ Table,
60
+ TableColumnResize,
61
+ TableToolbar,
62
+ TextTransformation,
63
+ TodoList,
64
+ Underline
65
+ } from 'ckeditor5'
66
+ import { Ckeditor } from '@ckeditor/ckeditor5-vue'
67
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
68
+ // @ts-ignore
69
+ import arTranslations from 'ckeditor5/translations/ar.js'
70
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
71
+ // @ts-ignore
72
+ import enTranslations from 'ckeditor5/translations/en.js'
73
+
74
+ type P = {
75
+ name: Props['name'];
76
+ lang: Props['lang'];
77
+ config?: Props['config'];
78
+ tagName?: Props['tagName'];
79
+ disabled?: Props['disabled'];
80
+ disableTwoWayDataBinding?: Props['disableTwoWayDataBinding'];
81
+
82
+ auto?: Props['auto'];
83
+ col?: Props['col'];
84
+ xs?: Props['xs'];
85
+ sm?: Props['sm'];
86
+ md?: Props['md'];
87
+ lg?: Props['lg'];
88
+ xl?: Props['xl'];
89
+ label?: Props['label'];
90
+ caption?: Props['caption'];
91
+ help?: Props['help'];
92
+ required?: Props['required'];
93
+ rules?: Props['rules'];
94
+ viewMode?: Props['viewMode'];
95
+ viewModeValue?: Props['viewModeValue'];
96
+ fieldOptions?: Props['fieldOptions'];
97
+ }
98
+ const props = withDefaults(defineProps<P>(), {
99
+ name: '',
100
+ lang: 'ar',
101
+ config: undefined,
102
+ tagName: 'div',
103
+ disabled: !1,
104
+ disableTwoWayDataBinding: !1,
105
+
106
+ auto: undefined,
107
+ col: undefined,
108
+ xs: undefined,
109
+ sm: undefined,
110
+ md: undefined,
111
+ lg: undefined,
112
+ xl: undefined,
113
+ label: undefined,
114
+ caption: undefined,
115
+ help: undefined,
116
+ required: undefined,
117
+ rules: undefined,
118
+ viewMode: !1,
119
+ viewModeValue: undefined,
120
+ fieldOptions: undefined
121
+ })
122
+ defineModel<Props['modelValue']>({ required: !1, default: undefined })
123
+ const { __, props: pluginOptions } = useMyth()
124
+ const helper = useBindInput<any>(() => props, 'ckeditor')
125
+ const { getLabel, inputRules } = helper
126
+ const inputScope = useField<Props['modelValue']>(() => props.name, inputRules, {
127
+ validateOnMount: !1,
128
+ validateOnValueUpdate: !1,
129
+ syncVModel: !0,
130
+ label: getLabel,
131
+ ...toValue<any>(props.fieldOptions)
132
+ })
133
+ const { value, errorMessage, handleChange } = inputScope
134
+
135
+ const isRtl = computed(() => props.lang === 'ar')
136
+ const getConfig = computed<any>(() => {
137
+ const inpConfig: EditorConfig = {
138
+ language: {
139
+ ui: props.lang as string,
140
+ content: props.lang as string,
141
+ textPartLanguage: [
142
+ {
143
+ title: __('labels.ar'),
144
+ languageCode: 'ar',
145
+ textDirection: 'rtl'
146
+ },
147
+ {
148
+ title: __('labels.en'),
149
+ languageCode: 'en',
150
+ textDirection: 'ltr'
151
+ }
152
+ ]
153
+ },
154
+ translations: [
155
+ arTranslations,
156
+ enTranslations
157
+ ],
158
+ plugins: [
159
+ Autoformat,
160
+ BlockQuote,
161
+ Bold,
162
+ CKFinder,
163
+ CKFinderUploadAdapter,
164
+ CloudServices,
165
+ Essentials,
166
+ Heading,
167
+ Image,
168
+ ImageCaption,
169
+ ImageResize,
170
+ ImageStyle,
171
+ ImageToolbar,
172
+ ImageUpload,
173
+ Base64UploadAdapter,
174
+ Indent,
175
+ IndentBlock,
176
+ Italic,
177
+ Link,
178
+ List,
179
+ MediaEmbed,
180
+ Mention,
181
+ Paragraph,
182
+ PasteFromOffice,
183
+ PictureEditing,
184
+ Table,
185
+ TableColumnResize,
186
+ TableToolbar,
187
+ TextTransformation,
188
+ Underline,
189
+ FontSize,
190
+ FontFamily,
191
+ FontColor,
192
+ FontBackgroundColor,
193
+ RemoveFormat,
194
+ Strikethrough,
195
+ Subscript,
196
+ Code,
197
+ CodeBlock,
198
+ Alignment,
199
+ Superscript,
200
+ TodoList,
201
+ SourceEditing
202
+ ],
203
+ toolbar: {
204
+ items: [
205
+ 'undo',
206
+ 'redo',
207
+ '|',
208
+ 'bold', 'italic', 'underline', 'strikethrough', 'subscript', 'superscript', 'code',
209
+ '|',
210
+ 'fontfamily', 'fontsize', 'fontColor', 'fontBackgroundColor',
211
+ '|',
212
+ 'alignment',
213
+ 'insertTable',
214
+ 'heading',
215
+ '|',
216
+ 'link', 'uploadImage', 'blockQuote', 'codeBlock',
217
+ '|',
218
+ 'bulletedList', 'numberedList', 'todoList', 'outdent', 'indent',
219
+ '|',
220
+ // 'ckbox',
221
+ 'removeFormat',
222
+ 'mediaEmbed',
223
+ '|',
224
+ 'sourceEditing'
225
+ ],
226
+ shouldNotGroupWhenFull: true
227
+ },
228
+ heading: {
229
+ options: [
230
+ {
231
+ model: 'paragraph',
232
+ title: 'Paragraph',
233
+ class: 'ck-heading_paragraph'
234
+ },
235
+ {
236
+ model: 'heading1',
237
+ view: 'h1',
238
+ title: 'Heading 1',
239
+ class: 'ck-heading_heading1'
240
+ },
241
+ {
242
+ model: 'heading2',
243
+ view: 'h2',
244
+ title: 'Heading 2',
245
+ class: 'ck-heading_heading2'
246
+ },
247
+ {
248
+ model: 'heading3',
249
+ view: 'h3',
250
+ title: 'Heading 3',
251
+ class: 'ck-heading_heading3'
252
+ },
253
+ {
254
+ model: 'heading4',
255
+ view: 'h4',
256
+ title: 'Heading 4',
257
+ class: 'ck-heading_heading4'
258
+ }
259
+ ]
260
+ },
261
+ image: {
262
+ resizeOptions: [
263
+ {
264
+ name: 'resizeImage:original',
265
+ label: 'Default image width',
266
+ value: null
267
+ },
268
+ {
269
+ name: 'resizeImage:50',
270
+ label: '50% page width',
271
+ value: '50'
272
+ },
273
+ {
274
+ name: 'resizeImage:75',
275
+ label: '75% page width',
276
+ value: '75'
277
+ }
278
+ ],
279
+ toolbar: [
280
+ 'imageTextAlternative',
281
+ 'toggleImageCaption',
282
+ '|',
283
+ 'imageStyle:inline',
284
+ 'imageStyle:wrapText',
285
+ 'imageStyle:breakText',
286
+ '|',
287
+ 'resizeImage'
288
+ ]
289
+ },
290
+ menuBar: {
291
+ isVisible: !1
292
+ },
293
+ link: {
294
+ addTargetToExternalLinks: true,
295
+ defaultProtocol: 'https://'
296
+ },
297
+ table: {
298
+ contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells']
299
+ }
300
+ }
301
+ if (props.config) {
302
+ return props.config(inpConfig as EditorConfig)
303
+ }
304
+ return inpConfig
305
+ })
306
+ const listeners = {
307
+ 'update:modelValue': (v: Props['modelValue']) => handleChange(v, !!errorMessage.value)
308
+ }
309
+ const input = useTemplateRef<any>('input')
310
+ const scopes = reactive(inputScope)
311
+ defineExpose<typeof scopes & { input: typeof input }>({ input, ...scopes })
312
+ defineOptions({
313
+ name: 'MCkeditor',
314
+ inheritAttrs: !1
315
+ })
316
+ </script>
317
+
318
+ <template>
319
+ <MCol
320
+ :auto="auto"
321
+ :class="[$attrs.class,{'m--input__required':inputRules?.required!==undefined,'m--input__error':!!errorMessage,'m--input__view':viewMode}]"
322
+ :col="col"
323
+ :lg="lg"
324
+ :md="md"
325
+ :name="name"
326
+ :sm="sm"
327
+ :xs="xs"
328
+ >
329
+ <slot
330
+ name="top-input"
331
+ v-bind="scopes"
332
+ />
333
+ <slot name="top-label">
334
+ <MInputLabel
335
+ v-if="!!getLabel"
336
+ :field="scopes"
337
+ >
338
+ <MHelpRow
339
+ v-if="!!help"
340
+ :text="help"
341
+ tooltip
342
+ />
343
+ </MInputLabel>
344
+ </slot>
345
+ <slot name="caption">
346
+ <div
347
+ v-if="!!caption"
348
+ class="m--input__caption"
349
+ >
350
+ {{ __(caption) }}
351
+ </div>
352
+ </slot>
353
+ <slot
354
+ name="help"
355
+ v-bind="scopes"
356
+ >
357
+ <MHelpRow
358
+ v-if="!getLabel && help"
359
+ :text="help"
360
+ />
361
+ </slot>
362
+ <MTransition>
363
+ <div
364
+ v-if="!!errorMessage"
365
+ class="text-negative text-caption"
366
+ >
367
+ <q-icon
368
+ v-if="!!errorMessage"
369
+ color="negative"
370
+ name="ion-ios-information-circle-outline"
371
+ size="20px"
372
+ />
373
+ {{ errorMessage }}
374
+ </div>
375
+ </MTransition>
376
+ <div
377
+ v-if="viewMode"
378
+ v-html="value"
379
+ />
380
+ <div
381
+ v-else
382
+ :dir="isRtl ? 'rtl' : 'ltr'"
383
+ :style="`direction: ${isRtl ? 'rtl' : 'ltr'}`"
384
+ >
385
+ <ckeditor
386
+ ref="input"
387
+ :config="getConfig"
388
+ :disable-two-way-data-binding="disableTwoWayDataBinding"
389
+ :disabled="disabled"
390
+ :editor="ClassicEditor"
391
+ :model-value="value || ''"
392
+ :tag-name="tagName"
393
+ v-bind="{...$attrs,...pluginOptions.ckeditor}"
394
+ v-on="listeners"
395
+ />
396
+ <slot v-bind="scopes" />
397
+ </div>
398
+ <slot
399
+ name="bottom-input"
400
+ v-bind="scopes"
401
+ />
402
+ </MCol>
403
+ </template>
@@ -10,7 +10,7 @@ import MAxios from './MAxios.vue'
10
10
  import MAvatarViewer from './MAvatarViewer.vue'
11
11
  import MBtn from './MBtn.vue'
12
12
  import MCheckbox from './MCheckbox.vue'
13
- // import MCkeditor from './MCkeditor.vue'
13
+ import MCkeditor from './MCkeditor.vue'
14
14
  import MColor from './MColor.vue'
15
15
  import MDate from './MDate.vue'
16
16
  import MEditor from './MEditor.vue'
@@ -40,7 +40,7 @@ export {
40
40
  MAvatarViewer,
41
41
  MBtn,
42
42
  MCheckbox,
43
- // MCkeditor,
43
+ MCkeditor,
44
44
  MColor,
45
45
  MDate,
46
46
  MEditor,
@@ -0,0 +1,26 @@
1
+ /*
2
+ * MyTh Ahmed Faiz Copyright © 2016-2025 All rights reserved.
3
+ * Email: mythpe@gmail.com
4
+ * Mobile: +966590470092
5
+ * Website: https://www.4myth.com
6
+ * Github: https://github.com/mythpe
7
+ */
8
+
9
+ import { useCKEditorCloud } from '@ckeditor/ckeditor5-vue'
10
+ import { computed } from 'vue'
11
+
12
+ export function useCkeditor () {
13
+ const cloud = useCKEditorCloud({
14
+ version: '45.1.0',
15
+ translations: ['ar', 'en']
16
+ })
17
+ const editor = computed(() => {
18
+ if (!cloud.data.value) {
19
+ return null
20
+ }
21
+
22
+ return cloud.data.value.CKEditor.ClassicEditor
23
+ })
24
+
25
+ return { cloud, editor }
26
+ }
package/src/index.sass CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  //@import 'quasar/src/css/variables.sass'
8
8
  @import './style/main'
9
+ @import './style/m-ck.css' #{"/* rtl:ignore */"}
9
10
  @import './style/ckeditor5'
10
11
  @import './style/m-container'
11
12
  @import './style/m-dt'
@@ -1,4 +1,4 @@
1
- @import 'ckeditor5/ckeditor5.css' #{"/* rtl:ignore */"}
1
+ //@import 'ckeditor5/ckeditor5.css' #{"/* rtl:ignore */"}
2
2
 
3
3
  :root
4
4
  --ck-z-dialog: 9999 !important
@@ -0,0 +1,135 @@
1
+ /*
2
+ * MyTh Ahmed Faiz Copyright © 2016-2025 All rights reserved.
3
+ * Email: mythpe@gmail.com
4
+ * Mobile: +966590470092
5
+ * Website: https://www.4myth.com
6
+ * Github: https://github.com/mythpe
7
+ */
8
+
9
+ @import url('https://fonts.googleapis.com/css2?family=Oswald&family=PT+Serif:ital,wght@0,400;0,700;1,400&display=swap');
10
+ @import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap');
11
+
12
+ @media print {
13
+ body {
14
+ margin: 0 !important;
15
+ }
16
+ }
17
+
18
+ .main-container {
19
+ /*font-family: 'Lato';*/
20
+ width: fit-content;
21
+ margin-left: auto;
22
+ margin-right: auto;
23
+ direction: ltr;
24
+ }
25
+
26
+ .ck-content {
27
+ font-family: 'Lato', sans-serif;
28
+ line-height: 1.6;
29
+ word-break: break-word;
30
+ }
31
+
32
+ .editor-container_classic-editor .editor-container__editor {
33
+ min-width: 795px;
34
+ max-width: 795px;
35
+ }
36
+
37
+ .editor-container_include-block-toolbar {
38
+ margin-left: 42px;
39
+ }
40
+
41
+ .ck-content h3.category {
42
+ font-family: 'Oswald', serif;
43
+ font-size: 20px;
44
+ font-weight: bold;
45
+ color: #555;
46
+ letter-spacing: 10px;
47
+ margin: 0;
48
+ padding: 0;
49
+ }
50
+
51
+ .ck-content h3.document-subtitle {
52
+ font-family: 'Oswald', serif;
53
+ font-size: 20px;
54
+ color: #555;
55
+ margin: 0 0 1em;
56
+ font-weight: bold;
57
+ padding: 0;
58
+ }
59
+
60
+ .ck-content p.info-box {
61
+ --background-size: 30px;
62
+ --background-color: #e91e63;
63
+ padding: 1.2em 2em;
64
+ border: 1px solid var(--background-color);
65
+ background: linear-gradient(135deg, var(--background-color) 0%, var(--background-color) var(--background-size), transparent var(--background-size)),
66
+ linear-gradient(
67
+ 135deg,
68
+ transparent calc(100% - var(--background-size)),
69
+ var(--background-color) calc(100% - var(--background-size)),
70
+ var(--background-color)
71
+ );
72
+ border-radius: 10px;
73
+ margin: 1.5em 2em;
74
+ box-shadow: 5px 5px 0 #ffe6ef;
75
+ }
76
+
77
+ .ck-content span.marker {
78
+ background: yellow;
79
+ }
80
+
81
+ .ck-content span.spoiler {
82
+ background: #000;
83
+ color: #000;
84
+ }
85
+
86
+ .ck-content span.spoiler:hover {
87
+ background: #000;
88
+ color: #fff;
89
+ }
90
+
91
+ .ck-content .button {
92
+ display: inline-block;
93
+ width: 260px;
94
+ border-radius: 8px;
95
+ margin: 0 auto;
96
+ padding: 12px;
97
+ color: #ffffff;
98
+ font-size: 24px;
99
+ font-weight: 700;
100
+ text-align: center;
101
+ text-decoration: none;
102
+ }
103
+
104
+ .ck-content .button--green {
105
+ background-color: #406b1e;
106
+ }
107
+
108
+ .ck-content .button--black {
109
+ background-color: #141517;
110
+ }
111
+
112
+ .editor_container__word-count .ck-word-count {
113
+ color: var(--ck-color-text);
114
+ display: flex;
115
+ height: 20px;
116
+ gap: var(--ck-spacing-small);
117
+ justify-content: flex-end;
118
+ font-size: var(--ck-font-size-base);
119
+ line-height: var(--ck-line-height-base);
120
+ font-family: var(--ck-font-face);
121
+ padding: var(--ck-spacing-small) var(--ck-spacing-standard);
122
+ }
123
+
124
+ .editor-container_include-word-count.editor-container_classic-editor .editor_container__word-count {
125
+ border: 1px solid var(--ck-color-base-border);
126
+ border-radius: var(--ck-border-radius);
127
+ border-top-left-radius: 0;
128
+ border-top-right-radius: 0;
129
+ border-top: none;
130
+ }
131
+
132
+ .editor-container_include-word-count.editor-container_classic-editor .editor-container__editor .ck-editor .ck-editor__editable {
133
+ border-radius: 0;
134
+ }
135
+
@@ -39,7 +39,7 @@ import type { FieldContext, FieldOptions, FormContext, FormOptions, FormState }
39
39
  import type { ThemeShadow, ThemeSize } from './theme'
40
40
  import type { ApiInterface, HelpersStubSchema } from './api-helpers'
41
41
  import type { MDatatableProps, MDatatableSlots, MDtAvatarProps, MDtAvatarSlots, MDtBtnProps, MDtBtnSlots, MDtContextmenuItemsProps, MDtContextmenuItemsSlots } from './m-datatable'
42
- import type { EditorConfig } from 'ckeditor5'
42
+ import type { EditorConfig } from 'https://cdn.ckeditor.com/typings/ckeditor5.d.ts'
43
43
  import type { MAvatarViewerProps, MAvatarViewerSlots } from './api/MAvatarViewer'
44
44
  import type { MTransitionGroupProps, MTransitionProps, MTransitionsSlots } from './api/MTransition'
45
45
  import type { MAxiosProps, MAxiosSlots } from './api/MAxios'
@@ -962,7 +962,7 @@ export type MCkeditorProps = Omit<BaseInputsProps, 'hint' | 'topLabel' | 'placeh
962
962
  * Specifies the configuration of the editor.
963
963
  * https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editorconfig-EditorConfig.html
964
964
  */
965
- config?: ((config: EditorConfig) => EditorConfig) | undefined;
965
+ config?: (config: EditorConfig) => EditorConfig;
966
966
  /**
967
967
  * By default, the editor component creates a <div> container which is used as an element passed to the editor (for example, ClassicEditor#element).
968
968
  * The element can be configured, so for example to create a <textarea>, use the following directive:
@@ -976,10 +976,9 @@ export type MCkeditorProps = Omit<BaseInputsProps, 'hint' | 'topLabel' | 'placeh
976
976
  */
977
977
  disabled?: boolean;
978
978
  /**
979
- * Allows disabling the two-way data binding mechanism.
980
- * Default value: false.
979
+ * Use HTML instead of Markdown.
981
980
  */
982
- disableTwoWayDataBinding?: boolean;
981
+ html?: boolean;
983
982
  }
984
983
  export type MCkeditorSlots = BaseInputsSlots
985
984
 
@@ -1,6 +1,7 @@
1
1
  import type { ThemeContext } from './theme'
2
2
  import type { MythComponentsProps } from './plugin-props-option'
3
3
  import type { ApiContext, MythApi } from './myth-api'
4
+ import type { MInputProps } from './components'
4
5
 
5
6
  export interface InstallOptions extends MythApi {
6
7
  api: ApiContext;
@@ -8,4 +9,6 @@ export interface InstallOptions extends MythApi {
8
9
  props?: Partial<MythComponentsProps>;
9
10
  theme?: Partial<ThemeContext>;
10
11
  rules?: string[];
12
+ mobileRule?: MInputProps['mobile'];
13
+ ckeditorKey?: string;
11
14
  }
@@ -39,5 +39,6 @@ export interface MythApi {
39
39
  * Default is true.
40
40
  * The Length must be 10.
41
41
  */
42
- mobileRule?: MInputProps['mobile'];
42
+ mobileRule: MInputProps['mobile'];
43
+ ckeditorKey: string | null;
43
44
  }
@@ -5,6 +5,7 @@ import { extend } from 'quasar'
5
5
 
6
6
  export const createMyth = (options: InstallOptions) => {
7
7
  const defaultOptions = {
8
+ ckeditorKey: null,
8
9
  asyncComponents: !1,
9
10
  api: {
10
11
  url: '',