pukaad-ui-lib 1.42.0 → 1.44.0

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/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
3
  "configKey": "pukaadUI",
4
- "version": "1.42.0",
4
+ "version": "1.44.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -93,6 +93,9 @@ const module$1 = defineNuxtModule({
93
93
  _nuxt.options.css.push(resolver.resolve("./runtime/assets/css/main.css"));
94
94
  _nuxt.hook("vite:extendConfig", (config) => {
95
95
  config.plugins.push(tailwindcss());
96
+ config.optimizeDeps = config.optimizeDeps || {};
97
+ config.optimizeDeps.include = config.optimizeDeps.include || [];
98
+ config.optimizeDeps.include.push("quill", "quill-delta");
96
99
  });
97
100
  _nuxt.options.runtimeConfig.public.BASE_URL_API = process.env.BASE_URL_API ?? "";
98
101
  _nuxt.options.runtimeConfig.public.RECAPTCHA_KEY = process.env.RECAPTCHA_KEY ?? "";
@@ -37,8 +37,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
37
37
  name: string;
38
38
  placeholder: string;
39
39
  description: string;
40
- limit: number;
41
40
  options: AutocompleteOption[] | string[] | number[];
41
+ limit: number;
42
42
  disabledErrorMessage: boolean;
43
43
  disabledBorder: boolean;
44
44
  showCounter: boolean;
@@ -37,8 +37,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
37
37
  name: string;
38
38
  placeholder: string;
39
39
  description: string;
40
- limit: number;
41
40
  options: AutocompleteOption[] | string[] | number[];
41
+ limit: number;
42
42
  disabledErrorMessage: boolean;
43
43
  disabledBorder: boolean;
44
44
  showCounter: boolean;
@@ -2,6 +2,7 @@ export interface InputContentProps {
2
2
  height?: string | number;
3
3
  placeholder?: string;
4
4
  disabledBorder?: boolean;
5
+ disableMedia?: boolean;
5
6
  }
6
7
  type __VLS_Props = InputContentProps;
7
8
  type __VLS_ModelProps = {
@@ -14,6 +15,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
14
15
  "onUpdate:modelValue"?: ((value: any) => any) | undefined;
15
16
  }>, {
16
17
  height: string | number;
18
+ disableMedia: boolean;
17
19
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
20
  declare const _default: typeof __VLS_export;
19
21
  export default _default;
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div>
3
- <div class="quill-wrapper">
3
+ <div class="quill-wrapper" :class="{ 'drag-not-allowed': isDraggingMedia }">
4
4
  <div ref="contentRef" :style="{ '--height': `${props.height}px` }" />
5
5
  </div>
6
6
  </div>
@@ -15,9 +15,11 @@ let quillEditor = null;
15
15
  const props = defineProps({
16
16
  height: { type: [String, Number], required: false, default: 288 },
17
17
  placeholder: { type: String, required: false },
18
- disabledBorder: { type: Boolean, required: false }
18
+ disabledBorder: { type: Boolean, required: false },
19
+ disableMedia: { type: Boolean, required: false, default: false }
19
20
  });
20
21
  const modelValue = defineModel();
22
+ const isDraggingMedia = ref(false);
21
23
  onMounted(() => {
22
24
  if (contentRef.value) {
23
25
  const toolbarOptions = [
@@ -28,15 +30,43 @@ onMounted(() => {
28
30
  [{ indent: "-1" }, { indent: "+1" }],
29
31
  [{ color: [] }, { background: [] }],
30
32
  [{ align: [] }],
31
- ["link", "image", "video"]
33
+ props.disableMedia ? ["link"] : ["link", "image", "video"]
32
34
  ];
35
+ const modules = {
36
+ toolbar: toolbarOptions
37
+ };
38
+ if (props.disableMedia) {
39
+ modules.clipboard = {
40
+ matchers: [
41
+ [
42
+ "IMG",
43
+ () => {
44
+ return { ops: [] };
45
+ }
46
+ ],
47
+ [
48
+ "VIDEO",
49
+ () => {
50
+ return { ops: [] };
51
+ }
52
+ ]
53
+ ]
54
+ };
55
+ }
33
56
  quillEditor = new $quill(contentRef.value, {
34
57
  theme: "snow",
35
58
  placeholder: props.placeholder,
36
- modules: {
37
- toolbar: toolbarOptions
38
- }
59
+ modules
39
60
  });
61
+ if (props.disableMedia) {
62
+ const toolbar = quillEditor.getModule("toolbar");
63
+ if (toolbar && toolbar.addHandler) {
64
+ toolbar.addHandler("image", () => {
65
+ });
66
+ toolbar.addHandler("video", () => {
67
+ });
68
+ }
69
+ }
40
70
  if (modelValue.value) {
41
71
  quillEditor.setContents(modelValue.value);
42
72
  }
@@ -44,14 +74,72 @@ onMounted(() => {
44
74
  if (source === "user") {
45
75
  if (!quillEditor) return;
46
76
  const currentDeltaJson = quillEditor.getContents();
47
- modelValue.value = currentDeltaJson;
77
+ if (props.disableMedia && currentDeltaJson.ops) {
78
+ const filteredOps = currentDeltaJson.ops.filter((op) => {
79
+ if (op.insert && typeof op.insert === "object") {
80
+ return !op.insert.image && !op.insert.video;
81
+ }
82
+ return true;
83
+ });
84
+ if (filteredOps.length !== currentDeltaJson.ops.length) {
85
+ quillEditor.setContents({ ops: filteredOps });
86
+ }
87
+ modelValue.value = { ops: filteredOps };
88
+ } else {
89
+ modelValue.value = currentDeltaJson;
90
+ }
48
91
  }
49
92
  });
93
+ if (props.disableMedia) {
94
+ const editorRoot = quillEditor.root;
95
+ editorRoot.addEventListener("dragenter", handleDragEnter);
96
+ editorRoot.addEventListener("dragover", handleDragOver);
97
+ editorRoot.addEventListener("dragleave", handleDragLeave);
98
+ editorRoot.addEventListener("drop", handleDrop);
99
+ }
50
100
  }
51
101
  });
102
+ const hasMediaFiles = (dataTransfer) => {
103
+ if (!dataTransfer) return false;
104
+ return Array.from(dataTransfer.items).some(
105
+ (item) => item.type.startsWith("image/") || item.type.startsWith("video/")
106
+ );
107
+ };
108
+ const handleDragEnter = (e) => {
109
+ if (hasMediaFiles(e.dataTransfer)) {
110
+ isDraggingMedia.value = true;
111
+ }
112
+ };
113
+ const handleDragOver = (e) => {
114
+ if (hasMediaFiles(e.dataTransfer)) {
115
+ e.preventDefault();
116
+ e.dataTransfer.dropEffect = "none";
117
+ isDraggingMedia.value = true;
118
+ }
119
+ };
120
+ const handleDragLeave = (e) => {
121
+ const relatedTarget = e.relatedTarget;
122
+ if (!relatedTarget || !quillEditor?.root.contains(relatedTarget)) {
123
+ isDraggingMedia.value = false;
124
+ }
125
+ };
126
+ const handleDrop = (e) => {
127
+ isDraggingMedia.value = false;
128
+ if (hasMediaFiles(e.dataTransfer)) {
129
+ e.preventDefault();
130
+ e.stopPropagation();
131
+ }
132
+ };
52
133
  onUnmounted(() => {
53
134
  if (quillEditor && contentRef.value) {
54
135
  quillEditor.off("text-change");
136
+ if (props.disableMedia) {
137
+ const editorRoot = quillEditor.root;
138
+ editorRoot.removeEventListener("dragenter", handleDragEnter);
139
+ editorRoot.removeEventListener("dragover", handleDragOver);
140
+ editorRoot.removeEventListener("dragleave", handleDragLeave);
141
+ editorRoot.removeEventListener("drop", handleDrop);
142
+ }
55
143
  const toolbar = contentRef.value.previousElementSibling;
56
144
  if (toolbar && toolbar.classList.contains("ql-toolbar")) {
57
145
  toolbar.remove();
@@ -63,5 +151,5 @@ onUnmounted(() => {
63
151
  </script>
64
152
 
65
153
  <style scoped>
66
- .quill-wrapper :deep(.ql-toolbar.ql-snow){background-color:#fafafa;border:none;border-radius:8px}.quill-wrapper :deep(.ql-container.ql-snow){border:none;border-bottom-left-radius:8px;border-bottom-right-radius:8px;overflow:hidden}.quill-wrapper :deep(.ql-editor){font-family:Sarabun-Regular;font-size:16px;margin-top:8px;min-height:var(--height)!important;padding:4px 12px}.quill-wrapper :deep(.ql-editor.ql-blank:before){color:#c4c4c4;content:attr(data-placeholder);font-size:16px;font-style:normal}
154
+ .quill-wrapper :deep(.ql-toolbar.ql-snow){background-color:#fafafa;border:none;border-radius:8px}.quill-wrapper :deep(.ql-container.ql-snow){border:none;border-bottom-left-radius:8px;border-bottom-right-radius:8px;overflow:hidden}.quill-wrapper :deep(.ql-editor){font-family:Sarabun-Regular;font-size:16px;margin-top:8px;min-height:var(--height)!important;padding:4px 12px}.quill-wrapper :deep(.ql-editor.ql-blank:before){color:#c4c4c4;content:attr(data-placeholder);font-size:16px;font-style:normal}.quill-wrapper.drag-not-allowed :deep(.ql-editor){background-color:#fef2f2;border:2px dashed #ef4444;cursor:not-allowed}
67
155
  </style>
@@ -2,6 +2,7 @@ export interface InputContentProps {
2
2
  height?: string | number;
3
3
  placeholder?: string;
4
4
  disabledBorder?: boolean;
5
+ disableMedia?: boolean;
5
6
  }
6
7
  type __VLS_Props = InputContentProps;
7
8
  type __VLS_ModelProps = {
@@ -14,6 +15,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
14
15
  "onUpdate:modelValue"?: ((value: any) => any) | undefined;
15
16
  }>, {
16
17
  height: string | number;
18
+ disableMedia: boolean;
17
19
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
20
  declare const _default: typeof __VLS_export;
19
21
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
- "version": "1.42.0",
3
+ "version": "1.44.0",
4
4
  "description": "pukaad-ui for MeMSG",
5
5
  "repository": {
6
6
  "type": "git",