quasar-ui-danx 0.4.82 → 0.4.86

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.86",
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,221 @@
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
+ FaSolidEye as ViewIcon,
69
+ FaSolidFileExport as ExportIcon,
70
+ FaSolidFileImport as ImportIcon,
71
+ FaSolidFloppyDisk as SaveIcon,
72
+ FaSolidFolder as FolderIcon,
73
+ FaSolidMinus as MinusIcon,
74
+ FaSolidPause as PauseIcon,
75
+ FaSolidPencil as EditIcon,
76
+ FaSolidPlay as PlayIcon,
77
+ FaSolidPlus as CreateIcon,
78
+ FaSolidStop as StopIcon,
79
+ FaSolidTrash as TrashIcon
75
80
  } from "danx-icon";
76
81
  import { computed, ref } from "vue";
77
82
  import { ActionTarget, ResourceAction } from "../../../types";
78
83
 
79
84
  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;
85
+ type?: "save" | "trash" | "back" | "create" | "edit" | "copy" | "folder" | "play" | "stop" | "pause" | "refresh" | "restart" | "confirm" | "cancel" | "export" | "import" | "minus" | "merge" | "check" | "clock" | "view";
86
+ color?: "red" | "blue" | "blue-invert" | "sky" | "sky-invert" | "green" | "green-invert" | "lime" | "white" | "gray" | "slate" | "slate-invert" | "yellow" | "orange";
87
+ size?: "xxs" | "xs" | "sm" | "md" | "lg";
88
+ icon?: object | string;
89
+ iconClass?: string;
90
+ label?: string | number;
91
+ labelClass?: string;
92
+ tooltip?: string;
93
+ saving?: boolean;
94
+ action?: ResourceAction;
95
+ target?: ActionTarget;
96
+ input?: object;
97
+ disabled?: boolean;
98
+ disabledClass?: string;
99
+ confirm?: boolean;
100
+ confirmText?: string;
101
+ tooltipClass?: string;
97
102
  }
98
103
 
99
104
  const emit = defineEmits(["success", "error", "always"]);
100
105
  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: ""
106
+ type: null,
107
+ color: null,
108
+ icon: null,
109
+ iconClass: "",
110
+ size: "md",
111
+ label: "",
112
+ labelClass: "",
113
+ tooltip: "",
114
+ action: null,
115
+ target: null,
116
+ input: null,
117
+ confirmText: "Are you sure?",
118
+ disabledClass: "text-slate-800 bg-slate-500 opacity-50",
119
+ tooltipClass: ""
115
120
  });
116
121
 
117
122
  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
- }
123
+ xxs: {
124
+ icon: "w-2",
125
+ button: "px-.5 h-5"
126
+ },
127
+ xs: {
128
+ icon: "w-3",
129
+ button: "px-1.5 h-6"
130
+ },
131
+ sm: {
132
+ icon: "w-4",
133
+ button: "px-2 h-8"
134
+ },
135
+ md: {
136
+ icon: "w-5",
137
+ button: "px-2.5 h-10"
138
+ },
139
+ lg: {
140
+ icon: "w-6",
141
+ button: "px-3 h-12"
142
+ }
138
143
  };
139
144
 
140
145
  const buttonClass = computed(() => {
141
- return {
142
- [props.disabled ? props.disabledClass : colorClass.value]: true,
143
- [mappedSizeClass[props.size].button]: true
144
- };
146
+ return {
147
+ [props.disabled ? props.disabledClass : colorClass.value]: true,
148
+ [mappedSizeClass[props.size].button]: true
149
+ };
145
150
  });
146
151
 
147
152
  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
- }
153
+ switch (props.color) {
154
+ case "red":
155
+ return "text-red-900 bg-red-300 hover:bg-red-400";
156
+ case "lime":
157
+ return "text-lime-900 bg-lime-300 hover:bg-lime-400";
158
+ case "green":
159
+ return "text-green-900 bg-green-300 hover:bg-green-400";
160
+ case "green-invert":
161
+ return "text-green-300 bg-green-900 hover:bg-green-800";
162
+ case "blue":
163
+ return "text-blue-900 bg-blue-300 hover:bg-blue-400";
164
+ case "blue-invert":
165
+ return "text-blue-300 bg-blue-900 hover:bg-blue-800";
166
+ case "sky":
167
+ return "text-sky-900 bg-sky-300 hover:bg-sky-400";
168
+ case "sky-invert":
169
+ return "text-sky-400 bg-sky-800 hover:bg-sky-900";
170
+ case "white":
171
+ return "text-white bg-gray-800 hover:bg-gray-200";
172
+ case "yellow":
173
+ return "text-yellow-300 bg-yellow-800 hover:bg-yellow-700";
174
+ case "orange":
175
+ return "text-orange-400 bg-orange-900 hover:bg-orange-800";
176
+ case "gray":
177
+ return "text-slate-200 bg-slate-800 hover:bg-slate-900";
178
+ case "slate":
179
+ return "text-slate-900 bg-slate-300 hover:bg-slate-400";
180
+ case "slate-invert":
181
+ return "text-slate-300 bg-slate-900 hover:bg-slate-800";
182
+ default:
183
+ return "";
184
+ }
176
185
  });
177
186
 
178
187
  const resolvedIconClass = computed(() => props.iconClass + " " + mappedSizeClass[props.size].icon);
179
188
 
180
189
  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
- }
190
+ switch (props.type) {
191
+ case "save":
192
+ return { icon: SaveIcon };
193
+ case "trash":
194
+ return { icon: TrashIcon };
195
+ case "export":
196
+ return { icon: ExportIcon };
197
+ case "import":
198
+ return { icon: ImportIcon };
199
+ case "back":
200
+ return { icon: BackIcon };
201
+ case "create":
202
+ return { icon: CreateIcon };
203
+ case "confirm":
204
+ return { icon: ConfirmIcon };
205
+ case "cancel":
206
+ return { icon: CancelIcon };
207
+ case "edit":
208
+ return { icon: EditIcon };
209
+ case "copy":
210
+ return { icon: CopyIcon };
211
+ case "folder":
212
+ return { icon: FolderIcon };
213
+ case "clock":
214
+ return { icon: ClockIcon };
215
+ case "play":
216
+ return { icon: PlayIcon };
217
+ case "stop":
218
+ return { icon: StopIcon };
219
+ case "pause":
220
+ return { icon: PauseIcon };
221
+ case "restart":
222
+ return { icon: RestartIcon };
223
+ case "refresh":
224
+ return { icon: RefreshIcon };
225
+ case "minus":
226
+ return { icon: MinusIcon };
227
+ case "merge":
228
+ return { icon: MergeIcon };
229
+ case "check":
230
+ return { icon: CheckIcon };
231
+ case "view":
232
+ return { icon: ViewIcon };
233
+ default:
234
+ return { icon: EditIcon };
235
+ }
217
236
  });
218
237
 
219
238
  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;
239
+ if (props.saving) return true;
240
+ if (props.action) {
241
+ return props.action.isApplying;
242
+ }
243
+ if (props.target) {
244
+ if (Array.isArray(props.target)) {
245
+ return props.target.some((t) => t.isSaving);
246
+ }
247
+ return props.target.isSaving;
248
+ }
249
+ return false;
231
250
  });
232
251
 
233
252
  const isConfirming = ref(false);
253
+
234
254
  function onAction(isConfirmed = false) {
235
- if (props.disabled) return;
255
+ if (props.disabled) return;
236
256
 
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
- }
257
+ // Make sure this action is confirmed if the confirm prop is set
258
+ if (props.confirm && !isConfirmed) {
259
+ isConfirming.value = true;
260
+ return false;
261
+ }
262
+ isConfirming.value = false;
263
+ if (props.action) {
264
+ props.action.trigger(props.target, props.input).then(async (response) => {
265
+ emit("success", typeof response.json === "function" ? await response.json() : response);
266
+ }).catch((e) => {
267
+ console.error(`Action emitted an error: ${props.action.name}`, e, props.target);
268
+ emit("error", e);
269
+ }).finally(() => {
270
+ emit("always");
271
+ });
272
+ } else {
273
+ emit("always");
274
+ }
255
275
  }
256
276
  </script>