quasar-ui-danx 0.4.82 → 0.4.84

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quasar-ui-danx",
3
- "version": "0.4.82",
3
+ "version": "0.4.84",
4
4
  "author": "Dan <dan@flytedesk.com>",
5
5
  "description": "DanX Vue / Quasar component library",
6
6
  "license": "MIT",
@@ -5,7 +5,7 @@
5
5
  :contenteditable="readonly ? 'false' : 'true'"
6
6
  class="relative inline-block transition duration-300 outline-none outline-offset-0 border-none rounded-sm z-10 min-w-10 min-h-10"
7
7
  :style="{minWidth, minHeight}"
8
- :class="contentClass"
8
+ :class="contentClassComputed"
9
9
  @input="onInput"
10
10
  @focusin="hasFocus = true"
11
11
  @focusout="hasFocus = false"
@@ -32,6 +32,7 @@ const props = withDefaults(defineProps<{
32
32
  debounceDelay?: number;
33
33
  readonly?: boolean;
34
34
  placeholder?: string;
35
+ contentClass?: string;
35
36
  }>(), {
36
37
  modelValue: "",
37
38
  // NOTE: You must safe-list required colors in tailwind.config.js
@@ -39,7 +40,8 @@ const props = withDefaults(defineProps<{
39
40
  color: "blue-200",
40
41
  textColor: "blue-900",
41
42
  debounceDelay: 1000,
42
- placeholder: "Enter Text..."
43
+ placeholder: "Enter Text...",
44
+ contentClass: ""
43
45
  });
44
46
 
45
47
  const text = ref(props.modelValue);
@@ -80,12 +82,13 @@ function onInput(e) {
80
82
  debouncedChange();
81
83
  }
82
84
 
83
- const contentClass = computed(() => [
85
+ const contentClassComputed = computed(() => [
84
86
  ...(props.readonly ? [] : [
85
87
  `hover:bg-${props.color} focus:bg-${props.color}`,
86
88
  `hover:text-${props.textColor} focus:text-${props.textColor}`,
87
89
  `hover:outline-${props.color} focus:outline-${props.color}`,
88
- "focus:outline-4 hover:outline-4"
90
+ "focus:outline-4 hover:outline-4",
91
+ props.contentClass || ""
89
92
  ]),
90
93
  text.value ? "" : "!bg-none"
91
94
  ]);
@@ -80,43 +80,61 @@ import { FormField, UploadedFile } from "../../../../types";
80
80
  import { FilePreview } from "../../../Utility";
81
81
  import FieldLabel from "./FieldLabel";
82
82
 
83
- const emit = defineEmits(["update:model-value"]);
83
+ const emit = defineEmits(["update:model-value", "uploading", "complete"]);
84
84
  const props = withDefaults(defineProps<{
85
- modelValue?: UploadedFile[];
86
- field?: FormField;
87
- label?: string;
88
- showName?: boolean;
89
- disabled?: boolean;
90
- readonly?: boolean;
91
- width?: number | string;
92
- height?: number | string;
93
- addIconClass?: string;
94
- filePreviewClass?: string;
95
- filePreviewBtnSize?: string;
96
- showTranscodes?: boolean;
85
+ modelValue?: UploadedFile[];
86
+ field?: FormField;
87
+ label?: string;
88
+ showName?: boolean;
89
+ disabled?: boolean;
90
+ readonly?: boolean;
91
+ width?: number | string;
92
+ height?: number | string;
93
+ addIconClass?: string;
94
+ filePreviewClass?: string;
95
+ filePreviewBtnSize?: string;
96
+ showTranscodes?: boolean;
97
97
  }>(), {
98
- modelValue: null,
99
- field: null,
100
- label: "",
101
- width: 128,
102
- height: 128,
103
- addIconClass: "w-10",
104
- filePreviewClass: "rounded-2xl",
105
- filePreviewBtnSize: "sm"
98
+ modelValue: null,
99
+ field: null,
100
+ label: "",
101
+ width: 128,
102
+ height: 128,
103
+ addIconClass: "w-10",
104
+ filePreviewClass: "rounded-2xl",
105
+ filePreviewBtnSize: "sm"
106
106
  });
107
107
 
108
- const { onComplete, onDrop, onFilesSelected, uploadedFiles, clearUploadedFiles, onRemove } = useMultiFileUpload();
108
+ const {
109
+ onComplete,
110
+ onDrop,
111
+ onFilesChange,
112
+ onFilesSelected,
113
+ uploadedFiles,
114
+ clearUploadedFiles,
115
+ onRemove
116
+ } = useMultiFileUpload();
109
117
  onMounted(() => {
110
- if (props.modelValue) {
111
- uploadedFiles.value = props.modelValue;
112
- }
118
+ if (props.modelValue) {
119
+ uploadedFiles.value = props.modelValue;
120
+ }
121
+ });
122
+
123
+ onFilesChange(() => {
124
+ // Check if the files are currently uploading
125
+ if (uploadedFiles.value.some(file => file.progress < 1)) {
126
+ emit("uploading");
127
+ }
128
+ });
129
+ onComplete(() => {
130
+ emit("update:model-value", uploadedFiles.value);
131
+ emit("complete");
113
132
  });
114
- onComplete(() => emit("update:model-value", uploadedFiles.value));
115
133
 
116
134
  const styleSize = computed(() => {
117
- return {
118
- width: typeof props.width === "number" ? `${props.width}px` : props.width,
119
- height: typeof props.height === "number" ? `${props.height}px` : props.height
120
- };
135
+ return {
136
+ width: typeof props.width === "number" ? `${props.width}px` : props.width,
137
+ height: typeof props.height === "number" ? `${props.height}px` : props.height
138
+ };
121
139
  });
122
140
  </script>
@@ -18,6 +18,7 @@
18
18
  :placeholder="placeholder || (placeholder === '' ? '' : `Enter ${label}`)"
19
19
  outlined
20
20
  dense
21
+ name=""
21
22
  :readonly="readonly"
22
23
  :autogrow="autogrow"
23
24
  :disable="disabled"
@@ -66,15 +67,15 @@ import FieldLabel from "./FieldLabel";
66
67
 
67
68
  defineEmits(["update:model-value", "submit"]);
68
69
  withDefaults(defineProps<TextFieldProps>(), {
69
- modelValue: "",
70
- field: null,
71
- type: "text",
72
- label: "",
73
- labelClass: "",
74
- inputClass: "",
75
- maxLength: null,
76
- rows: 3,
77
- debounce: 0,
78
- placeholder: null
70
+ modelValue: "",
71
+ field: null,
72
+ type: "text",
73
+ label: "",
74
+ labelClass: "",
75
+ inputClass: "",
76
+ maxLength: null,
77
+ rows: 3,
78
+ debounce: 0,
79
+ placeholder: null
79
80
  });
80
81
  </script>
@@ -56,201 +56,218 @@
56
56
  </template>
57
57
  <script setup lang="ts">
58
58
  import {
59
- FaSolidArrowRotateRight as RestartIcon,
60
- FaSolidArrowsRotate as RefreshIcon,
61
- FaSolidCircleCheck as ConfirmIcon,
62
- FaSolidCircleXmark as CancelIcon,
63
- FaSolidCodeMerge as MergeIcon,
64
- FaSolidCopy as CopyIcon,
65
- FaSolidFileExport as ExportIcon,
66
- FaSolidFileImport as ImportIcon,
67
- FaSolidFolder as FolderIcon,
68
- FaSolidMinus as MinusIcon,
69
- FaSolidPause as PauseIcon,
70
- FaSolidPencil as EditIcon,
71
- FaSolidPlay as PlayIcon,
72
- FaSolidPlus as CreateIcon,
73
- FaSolidStop as StopIcon,
74
- FaSolidTrash as TrashIcon
59
+ FaSolidArrowRotateRight as RestartIcon,
60
+ FaSolidArrowsRotate as RefreshIcon,
61
+ FaSolidBackward as BackIcon,
62
+ FaSolidCheck as CheckIcon,
63
+ FaSolidCircleCheck as ConfirmIcon,
64
+ FaSolidCircleXmark as CancelIcon,
65
+ FaSolidClock as ClockIcon,
66
+ FaSolidCodeMerge as MergeIcon,
67
+ FaSolidCopy as CopyIcon,
68
+ FaSolidFileExport as ExportIcon,
69
+ FaSolidFileImport as ImportIcon,
70
+ FaSolidFloppyDisk as SaveIcon,
71
+ FaSolidFolder as FolderIcon,
72
+ FaSolidMinus as MinusIcon,
73
+ FaSolidPause as PauseIcon,
74
+ FaSolidPencil as EditIcon,
75
+ FaSolidPlay as PlayIcon,
76
+ FaSolidPlus as CreateIcon,
77
+ FaSolidStop as StopIcon,
78
+ FaSolidTrash as TrashIcon
75
79
  } from "danx-icon";
76
80
  import { computed, ref } from "vue";
77
81
  import { ActionTarget, ResourceAction } from "../../../types";
78
82
 
79
83
  export interface ActionButtonProps {
80
- type?: "trash" | "create" | "edit" | "copy" | "folder" | "play" | "stop" | "pause" | "refresh" | "restart" | "confirm" | "cancel" | "export" | "import" | "minus" | "merge";
81
- color?: "red" | "blue" | "blue-invert" | "sky" | "sky-invert" | "green" | "green-invert" | "lime" | "white" | "gray" | "yellow" | "orange";
82
- size?: "xxs" | "xs" | "sm" | "md" | "lg";
83
- icon?: object | string;
84
- iconClass?: string;
85
- label?: string | number;
86
- labelClass?: string;
87
- tooltip?: string;
88
- saving?: boolean;
89
- action?: ResourceAction;
90
- target?: ActionTarget;
91
- input?: object;
92
- disabled?: boolean;
93
- disabledClass?: string;
94
- confirm?: boolean;
95
- confirmText?: string;
96
- tooltipClass?: string;
84
+ type?: "save" | "trash" | "back" | "create" | "edit" | "copy" | "folder" | "play" | "stop" | "pause" | "refresh" | "restart" | "confirm" | "cancel" | "export" | "import" | "minus" | "merge" | "check" | "clock";
85
+ color?: "red" | "blue" | "blue-invert" | "sky" | "sky-invert" | "green" | "green-invert" | "lime" | "white" | "gray" | "slate" | "slate-invert" | "yellow" | "orange";
86
+ size?: "xxs" | "xs" | "sm" | "md" | "lg";
87
+ icon?: object | string;
88
+ iconClass?: string;
89
+ label?: string | number;
90
+ labelClass?: string;
91
+ tooltip?: string;
92
+ saving?: boolean;
93
+ action?: ResourceAction;
94
+ target?: ActionTarget;
95
+ input?: object;
96
+ disabled?: boolean;
97
+ disabledClass?: string;
98
+ confirm?: boolean;
99
+ confirmText?: string;
100
+ tooltipClass?: string;
97
101
  }
98
102
 
99
103
  const emit = defineEmits(["success", "error", "always"]);
100
104
  const props = withDefaults(defineProps<ActionButtonProps>(), {
101
- type: null,
102
- color: null,
103
- icon: null,
104
- iconClass: "",
105
- size: "md",
106
- label: "",
107
- labelClass: "",
108
- tooltip: "",
109
- action: null,
110
- target: null,
111
- input: null,
112
- confirmText: "Are you sure?",
113
- disabledClass: "text-slate-800 bg-slate-500 opacity-50",
114
- tooltipClass: ""
105
+ type: null,
106
+ color: null,
107
+ icon: null,
108
+ iconClass: "",
109
+ size: "md",
110
+ label: "",
111
+ labelClass: "",
112
+ tooltip: "",
113
+ action: null,
114
+ target: null,
115
+ input: null,
116
+ confirmText: "Are you sure?",
117
+ disabledClass: "text-slate-800 bg-slate-500 opacity-50",
118
+ tooltipClass: ""
115
119
  });
116
120
 
117
121
  const mappedSizeClass = {
118
- xxs: {
119
- icon: "w-2",
120
- button: "px-.5 h-5"
121
- },
122
- xs: {
123
- icon: "w-3",
124
- button: "px-1.5 h-6"
125
- },
126
- sm: {
127
- icon: "w-4",
128
- button: "px-2 h-8"
129
- },
130
- md: {
131
- icon: "w-5",
132
- button: "px-2.5 h-10"
133
- },
134
- lg: {
135
- icon: "w-6",
136
- button: "px-3 h-12"
137
- }
122
+ xxs: {
123
+ icon: "w-2",
124
+ button: "px-.5 h-5"
125
+ },
126
+ xs: {
127
+ icon: "w-3",
128
+ button: "px-1.5 h-6"
129
+ },
130
+ sm: {
131
+ icon: "w-4",
132
+ button: "px-2 h-8"
133
+ },
134
+ md: {
135
+ icon: "w-5",
136
+ button: "px-2.5 h-10"
137
+ },
138
+ lg: {
139
+ icon: "w-6",
140
+ button: "px-3 h-12"
141
+ }
138
142
  };
139
143
 
140
144
  const buttonClass = computed(() => {
141
- return {
142
- [props.disabled ? props.disabledClass : colorClass.value]: true,
143
- [mappedSizeClass[props.size].button]: true
144
- };
145
+ return {
146
+ [props.disabled ? props.disabledClass : colorClass.value]: true,
147
+ [mappedSizeClass[props.size].button]: true
148
+ };
145
149
  });
146
150
 
147
151
  const colorClass = computed(() => {
148
- switch (props.color) {
149
- case "red":
150
- return "text-red-900 bg-red-300 hover:bg-red-400";
151
- case "lime":
152
- return "text-lime-900 bg-lime-300 hover:bg-lime-400";
153
- case "green":
154
- return "text-green-900 bg-green-300 hover:bg-green-400";
155
- case "green-invert":
156
- return "text-green-300 bg-green-900 hover:bg-green-800";
157
- case "blue":
158
- return "text-blue-900 bg-blue-300 hover:bg-blue-400";
159
- case "blue-invert":
160
- return "text-blue-300 bg-blue-900 hover:bg-blue-800";
161
- case "sky":
162
- return "text-sky-900 bg-sky-300 hover:bg-sky-400";
163
- case "sky-invert":
164
- return "text-sky-400 bg-sky-800 hover:bg-sky-900";
165
- case "white":
166
- return "text-white bg-gray-800 hover:bg-gray-200";
167
- case "yellow":
168
- return "text-yellow-300 bg-yellow-800 hover:bg-yellow-700";
169
- case "orange":
170
- return "text-orange-400 bg-orange-900 hover:bg-orange-800";
171
- case "gray":
172
- return "text-slate-200 bg-slate-800 hover:bg-slate-900";
173
- default:
174
- return "";
175
- }
152
+ switch (props.color) {
153
+ case "red":
154
+ return "text-red-900 bg-red-300 hover:bg-red-400";
155
+ case "lime":
156
+ return "text-lime-900 bg-lime-300 hover:bg-lime-400";
157
+ case "green":
158
+ return "text-green-900 bg-green-300 hover:bg-green-400";
159
+ case "green-invert":
160
+ return "text-green-300 bg-green-900 hover:bg-green-800";
161
+ case "blue":
162
+ return "text-blue-900 bg-blue-300 hover:bg-blue-400";
163
+ case "blue-invert":
164
+ return "text-blue-300 bg-blue-900 hover:bg-blue-800";
165
+ case "sky":
166
+ return "text-sky-900 bg-sky-300 hover:bg-sky-400";
167
+ case "sky-invert":
168
+ return "text-sky-400 bg-sky-800 hover:bg-sky-900";
169
+ case "white":
170
+ return "text-white bg-gray-800 hover:bg-gray-200";
171
+ case "yellow":
172
+ return "text-yellow-300 bg-yellow-800 hover:bg-yellow-700";
173
+ case "orange":
174
+ return "text-orange-400 bg-orange-900 hover:bg-orange-800";
175
+ case "gray":
176
+ return "text-slate-200 bg-slate-800 hover:bg-slate-900";
177
+ case "slate":
178
+ return "text-slate-900 bg-slate-300 hover:bg-slate-400";
179
+ case "slate-invert":
180
+ return "text-slate-300 bg-slate-900 hover:bg-slate-800";
181
+ default:
182
+ return "";
183
+ }
176
184
  });
177
185
 
178
186
  const resolvedIconClass = computed(() => props.iconClass + " " + mappedSizeClass[props.size].icon);
179
187
 
180
188
  const typeOptions = computed(() => {
181
- switch (props.type) {
182
- case "trash":
183
- return { icon: TrashIcon };
184
- case "export":
185
- return { icon: ExportIcon };
186
- case "import":
187
- return { icon: ImportIcon };
188
- case "create":
189
- return { icon: CreateIcon };
190
- case "confirm":
191
- return { icon: ConfirmIcon };
192
- case "cancel":
193
- return { icon: CancelIcon };
194
- case "edit":
195
- return { icon: EditIcon };
196
- case "copy":
197
- return { icon: CopyIcon };
198
- case "folder":
199
- return { icon: FolderIcon };
200
- case "play":
201
- return { icon: PlayIcon };
202
- case "stop":
203
- return { icon: StopIcon };
204
- case "pause":
205
- return { icon: PauseIcon };
206
- case "restart":
207
- return { icon: RestartIcon };
208
- case "refresh":
209
- return { icon: RefreshIcon };
210
- case "minus":
211
- return { icon: MinusIcon };
212
- case "merge":
213
- return { icon: MergeIcon };
214
- default:
215
- return { icon: EditIcon };
216
- }
189
+ switch (props.type) {
190
+ case "save":
191
+ return { icon: SaveIcon };
192
+ case "trash":
193
+ return { icon: TrashIcon };
194
+ case "export":
195
+ return { icon: ExportIcon };
196
+ case "import":
197
+ return { icon: ImportIcon };
198
+ case "back":
199
+ return { icon: BackIcon };
200
+ case "create":
201
+ return { icon: CreateIcon };
202
+ case "confirm":
203
+ return { icon: ConfirmIcon };
204
+ case "cancel":
205
+ return { icon: CancelIcon };
206
+ case "edit":
207
+ return { icon: EditIcon };
208
+ case "copy":
209
+ return { icon: CopyIcon };
210
+ case "folder":
211
+ return { icon: FolderIcon };
212
+ case "clock":
213
+ return { icon: ClockIcon };
214
+ case "play":
215
+ return { icon: PlayIcon };
216
+ case "stop":
217
+ return { icon: StopIcon };
218
+ case "pause":
219
+ return { icon: PauseIcon };
220
+ case "restart":
221
+ return { icon: RestartIcon };
222
+ case "refresh":
223
+ return { icon: RefreshIcon };
224
+ case "minus":
225
+ return { icon: MinusIcon };
226
+ case "merge":
227
+ return { icon: MergeIcon };
228
+ case "check":
229
+ return { icon: CheckIcon };
230
+ default:
231
+ return { icon: EditIcon };
232
+ }
217
233
  });
218
234
 
219
235
  const isSaving = computed(() => {
220
- if (props.saving) return true;
221
- if (props.action) {
222
- return props.action.isApplying;
223
- }
224
- if (props.target) {
225
- if (Array.isArray(props.target)) {
226
- return props.target.some((t) => t.isSaving);
227
- }
228
- return props.target.isSaving;
229
- }
230
- return false;
236
+ if (props.saving) return true;
237
+ if (props.action) {
238
+ return props.action.isApplying;
239
+ }
240
+ if (props.target) {
241
+ if (Array.isArray(props.target)) {
242
+ return props.target.some((t) => t.isSaving);
243
+ }
244
+ return props.target.isSaving;
245
+ }
246
+ return false;
231
247
  });
232
248
 
233
249
  const isConfirming = ref(false);
250
+
234
251
  function onAction(isConfirmed = false) {
235
- if (props.disabled) return;
252
+ if (props.disabled) return;
236
253
 
237
- // Make sure this action is confirmed if the confirm prop is set
238
- if (props.confirm && !isConfirmed) {
239
- isConfirming.value = true;
240
- return false;
241
- }
242
- isConfirming.value = false;
243
- if (props.action) {
244
- props.action.trigger(props.target, props.input).then(async (response) => {
245
- emit("success", typeof response.json === "function" ? await response.json() : response);
246
- }).catch((e) => {
247
- console.error(`Action emitted an error: ${props.action.name}`, e, props.target);
248
- emit("error", e);
249
- }).finally(() => {
250
- emit("always");
251
- });
252
- } else {
253
- emit("always");
254
- }
254
+ // Make sure this action is confirmed if the confirm prop is set
255
+ if (props.confirm && !isConfirmed) {
256
+ isConfirming.value = true;
257
+ return false;
258
+ }
259
+ isConfirming.value = false;
260
+ if (props.action) {
261
+ props.action.trigger(props.target, props.input).then(async (response) => {
262
+ emit("success", typeof response.json === "function" ? await response.json() : response);
263
+ }).catch((e) => {
264
+ console.error(`Action emitted an error: ${props.action.name}`, e, props.target);
265
+ emit("error", e);
266
+ }).finally(() => {
267
+ emit("always");
268
+ });
269
+ } else {
270
+ emit("always");
271
+ }
255
272
  }
256
273
  </script>