quasar-ui-danx 0.0.11 → 0.0.13

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 (84) hide show
  1. package/dist/index.css +5 -0
  2. package/dist/index.min.css +5 -0
  3. package/dist/index.rtl.css +5 -0
  4. package/dist/index.rtl.min.css +5 -0
  5. package/package.json +6 -1
  6. package/src/components/ActionTable/ActionTable.vue +49 -41
  7. package/src/components/ActionTable/BatchActionMenu.vue +20 -20
  8. package/src/components/ActionTable/EmptyTableState.vue +5 -5
  9. package/src/components/ActionTable/Filters/CollapsableFiltersSidebar.vue +11 -11
  10. package/src/components/ActionTable/Filters/FilterGroupItem.vue +7 -7
  11. package/src/components/ActionTable/Filters/FilterGroupList.vue +29 -29
  12. package/src/components/ActionTable/Filters/FilterListToggle.vue +15 -15
  13. package/src/components/ActionTable/Filters/FilterableField.vue +82 -80
  14. package/src/components/ActionTable/Filters/index.ts +5 -0
  15. package/src/components/ActionTable/Form/Fields/BooleanField.vue +13 -13
  16. package/src/components/ActionTable/Form/Fields/ConfirmPasswordField.vue +11 -11
  17. package/src/components/ActionTable/Form/Fields/DateField.vue +13 -13
  18. package/src/components/ActionTable/Form/Fields/DateRangeField.vue +25 -25
  19. package/src/components/ActionTable/Form/Fields/DateTimeField.vue +21 -21
  20. package/src/components/ActionTable/Form/Fields/DateTimePicker.vue +23 -23
  21. package/src/components/ActionTable/Form/Fields/FileUploadButton.vue +31 -31
  22. package/src/components/ActionTable/Form/Fields/InlineDateTimeField.vue +19 -19
  23. package/src/components/ActionTable/Form/Fields/IntegerField.vue +7 -7
  24. package/src/components/ActionTable/Form/Fields/LabelValueBlock.vue +22 -0
  25. package/src/components/ActionTable/Form/Fields/LabeledInput.vue +19 -19
  26. package/src/components/ActionTable/Form/Fields/MultiFileField.vue +40 -40
  27. package/src/components/ActionTable/Form/Fields/MultiKeywordField.vue +23 -23
  28. package/src/components/ActionTable/Form/Fields/NewPasswordField.vue +10 -10
  29. package/src/components/ActionTable/Form/Fields/NumberField.vue +29 -29
  30. package/src/components/ActionTable/Form/Fields/NumberRangeField.vue +33 -33
  31. package/src/components/ActionTable/Form/Fields/SelectDrawer.vue +36 -36
  32. package/src/components/ActionTable/Form/Fields/SelectField.vue +66 -66
  33. package/src/components/ActionTable/Form/Fields/SelectWithChildrenField.vue +23 -23
  34. package/src/components/ActionTable/Form/Fields/SingleFileField.vue +32 -32
  35. package/src/components/ActionTable/Form/Fields/TextField.vue +36 -36
  36. package/src/components/ActionTable/Form/Fields/WysiwygField.vue +16 -16
  37. package/src/components/ActionTable/Form/Fields/index.ts +23 -23
  38. package/src/components/ActionTable/Form/RenderedForm.vue +27 -25
  39. package/src/components/ActionTable/Form/index.ts +2 -0
  40. package/src/components/ActionTable/TableSummaryRow.vue +33 -33
  41. package/src/components/ActionTable/index.ts +8 -13
  42. package/src/components/ActionTable/listActions.ts +340 -339
  43. package/src/components/ActionTable/listHelpers.ts +74 -0
  44. package/src/components/ActionTable/tableColumns.ts +56 -56
  45. package/src/components/DragAndDrop/HandleDraggable.vue +29 -29
  46. package/src/components/DragAndDrop/ListItemDraggable.vue +10 -10
  47. package/src/components/DragAndDrop/index.ts +0 -1
  48. package/src/components/DragAndDrop/listDragAndDrop.ts +1 -1
  49. package/src/components/Utility/CollapsableSidebar.vue +35 -35
  50. package/src/components/Utility/ContentDrawer.vue +20 -20
  51. package/src/components/Utility/Dialogs/ConfirmDialog.vue +55 -55
  52. package/src/components/Utility/Dialogs/FullScreenDialog.vue +18 -18
  53. package/src/components/Utility/Dialogs/FullscreenCarouselDialog.vue +105 -0
  54. package/src/components/Utility/Dialogs/InfoDialog.vue +10 -10
  55. package/src/components/Utility/Dialogs/InputDialog.vue +13 -13
  56. package/src/components/Utility/ImagePreview.vue +192 -0
  57. package/src/components/Utility/Popover/PopoverMenu.vue +64 -0
  58. package/src/components/Utility/Transitions/StaggeredListTransition.vue +15 -15
  59. package/src/components/Utility/index.ts +11 -9
  60. package/src/components/index.ts +1 -1
  61. package/src/helpers/FileUpload.ts +274 -273
  62. package/src/helpers/compatibility.ts +45 -45
  63. package/src/helpers/date.ts +2 -2
  64. package/src/helpers/download.ts +166 -158
  65. package/src/helpers/downloadPdf.ts +48 -48
  66. package/src/helpers/files.ts +42 -42
  67. package/src/helpers/index.ts +2 -0
  68. package/src/helpers/multiFileUpload.ts +56 -56
  69. package/src/helpers/singleFileUpload.ts +49 -49
  70. package/src/index.esm.js +3 -4
  71. package/src/svg/FilterIcon.svg +7 -0
  72. package/src/svg/ImageIcon.svg +30 -0
  73. package/src/svg/PdfIcon.svg +21 -0
  74. package/src/svg/PercentIcon.svg +13 -0
  75. package/src/svg/TrashIcon.svg +15 -0
  76. package/src/svg/XIcon.svg +18 -0
  77. package/src/svg/index.ts +8 -0
  78. package/src/vendor/tinymce-config.ts +1 -0
  79. package/src/vue-plugin.js +7 -4
  80. package/tsconfig.json +18 -14
  81. package/src/components/ActionTable/tableHelpers.ts +0 -83
  82. package/src/components/DragAndDrop/Icons/index.ts +0 -2
  83. /package/src/{components/DragAndDrop/Icons → svg}/DragHandleDotsIcon.svg +0 -0
  84. /package/src/{components/DragAndDrop/Icons → svg}/DragHandleIcon.svg +0 -0
@@ -1,44 +1,44 @@
1
1
  <template>
2
- <QBtn v-bind="$props" @click="$refs.fileUpload.click()">
2
+ <q-btn v-bind="$props" @click="$refs.fileUpload.click()">
3
3
  <slot>
4
4
  <PlusIcon class="w-5 mr-2" />
5
5
  {{ text }}
6
6
  </slot>
7
7
 
8
8
  <input
9
- ref="fileUpload"
10
- data-testid="file-upload"
11
- type="file"
12
- :accept="geolocation ? 'image/*;capture=camera' : undefined"
13
- :capture="geolocation ? 'environment' : undefined"
14
- class="hidden"
15
- multiple
16
- @change="onAttachFiles"
9
+ ref="fileUpload"
10
+ data-testid="file-upload"
11
+ type="file"
12
+ :accept="geolocation ? 'image/*;capture=camera' : undefined"
13
+ :capture="geolocation ? 'environment' : undefined"
14
+ class="hidden"
15
+ multiple
16
+ @change="onAttachFiles"
17
17
  />
18
- </QBtn>
18
+ </q-btn>
19
19
  </template>
20
20
  <script setup>
21
- import { PlusIcon } from "@heroicons/vue/outline";
22
- import { FileUpload } from "danx/src/helpers";
23
- import { QBtn } from "quasar";
24
- import { ref } from "vue";
21
+ import { PlusIcon } from '@heroicons/vue/outline';
22
+ import { FileUpload } from '@ui/helpers';
23
+ import { QBtn } from 'quasar';
24
+ import { ref } from 'vue';
25
25
 
26
26
  defineExpose({ upload });
27
27
  const emit = defineEmits([
28
- "uploading",
29
- "file-progress",
30
- "file-complete",
31
- "complete"
28
+ 'uploading',
29
+ 'file-progress',
30
+ 'file-complete',
31
+ 'complete'
32
32
  ]);
33
33
  const props = defineProps({
34
34
  ...QBtn.props,
35
35
  text: {
36
36
  type: String,
37
- default: "Add File"
37
+ default: 'Add File'
38
38
  },
39
39
  locationWaitMessage: {
40
40
  type: String,
41
- default: "Waiting for location..."
41
+ default: 'Waiting for location...'
42
42
  },
43
43
  geolocation: Boolean
44
44
  });
@@ -56,18 +56,18 @@ function upload() {
56
56
  * @returns {Promise<void>}
57
57
  */
58
58
  async function onAttachFiles({ target: { files } }) {
59
- emit("uploading", files);
59
+ emit('uploading', files);
60
60
  let fileUpload = new FileUpload(files)
61
- .onProgress(({ file, progress }) => {
62
- file.progress = progress;
63
- emit("file-progress", file);
64
- })
65
- .onComplete(({ file, uploadedFile }) => {
66
- emit("file-complete", { file, uploadedFile });
67
- })
68
- .onAllComplete(() => {
69
- emit("complete", fileUpload.files);
70
- });
61
+ .onProgress(({ file, progress }) => {
62
+ file.progress = progress;
63
+ emit('file-progress', file);
64
+ })
65
+ .onComplete(({ file, uploadedFile }) => {
66
+ emit('file-complete', { file, uploadedFile });
67
+ })
68
+ .onAllComplete(() => {
69
+ emit('complete', fileUpload.files);
70
+ });
71
71
 
72
72
  if (props.geolocation) {
73
73
  await fileUpload.resolveLocation(props.locationWaitMessage);
@@ -1,33 +1,33 @@
1
1
  <template>
2
2
  <div class="inline-block">
3
3
  <div
4
- class="cursor-pointer py-2 hover:bg-blue-light flex items-center justify-end"
4
+ class="cursor-pointer py-2 hover:bg-blue-light flex items-center justify-end"
5
5
  >
6
- {{ fLocalizedDateTime(modelValue, { empty: "Never" }) }}
6
+ {{ fLocalizedDateTime(modelValue, { empty: 'Never' }) }}
7
7
  <EditIcon class="w-4 font-bold ml-2 text-gray-base" />
8
- <QPopupEdit
9
- v-slot="scope"
10
- :model-value="modelValue"
11
- touch-position
12
- :offset="[0, 20]"
13
- class="bg-blue-base text-white !min-w-0"
8
+ <q-popup-edit
9
+ v-slot="scope"
10
+ :model-value="modelValue"
11
+ touch-position
12
+ :offset="[0, 20]"
13
+ class="bg-blue-base text-white !min-w-0"
14
14
  >
15
15
  <DateTimePicker
16
- v-model="scope.value"
17
- :nullable="nullable"
18
- @save="onSave(scope)"
19
- @cancel="scope.cancel"
16
+ v-model="scope.value"
17
+ :nullable="nullable"
18
+ @save="onSave(scope)"
19
+ @cancel="scope.cancel"
20
20
  />
21
- </QPopupEdit>
21
+ </q-popup-edit>
22
22
  </div>
23
23
  </div>
24
24
  </template>
25
25
  <script setup>
26
- import { PencilIcon as EditIcon } from "@heroicons/vue/solid";
27
- import DateTimePicker from "danx/src/components/ActionTable/Form/Fields/DateTimePicker";
28
- import { fLocalizedDateTime } from "danx/src/helpers/formats";
26
+ import { PencilIcon as EditIcon } from '@heroicons/vue/solid';
27
+ import { fLocalizedDateTime } from '@ui/helpers/formats';
28
+ import DateTimePicker from './DateTimePicker';
29
29
 
30
- const emit = defineEmits(["close", "save", "update:model-value"]);
30
+ const emit = defineEmits(['close', 'save', 'update:model-value']);
31
31
  defineProps({
32
32
  modelValue: {
33
33
  type: String,
@@ -37,8 +37,8 @@ defineProps({
37
37
  });
38
38
 
39
39
  function onSave(scope) {
40
- emit("update:model-value", scope.value);
41
- emit("save", scope.value);
40
+ emit('update:model-value', scope.value);
41
+ emit('save', scope.value);
42
42
  scope.set();
43
43
  }
44
44
  </script>
@@ -1,17 +1,17 @@
1
1
  <template>
2
2
  <NumberField
3
- :field="field"
4
- :precision="0"
5
- :model-value="modelValue"
6
- :show-name="showName"
7
- @update:model-value="$emit('update:model-value', $event)"
3
+ :field="field"
4
+ :precision="0"
5
+ :model-value="modelValue"
6
+ :show-name="showName"
7
+ @update:model-value="$emit('update:model-value', $event)"
8
8
  />
9
9
  </template>
10
10
 
11
11
  <script setup>
12
- import NumberField from "danx/src/components/ActionTable/Form/Fields/NumberField";
12
+ import NumberField from './NumberField';
13
13
 
14
- defineEmits(["update:model-value"]);
14
+ defineEmits(['update:model-value']);
15
15
  defineProps({
16
16
  modelValue: {
17
17
  type: [String, Number],
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <div>
3
+ <div class="text-xs font-bold">{{ label }}</div>
4
+ <div :class="{'mt-2': !dense, 'mt-1': dense, 'text-no-wrap': nowrap}">
5
+ <slot>{{ value || "-" }}</slot>
6
+ </div>
7
+ </div>
8
+ </template>
9
+ <script setup>
10
+ defineProps({
11
+ label: {
12
+ type: String,
13
+ required: true
14
+ },
15
+ value: {
16
+ type: [String, Number],
17
+ default: "-"
18
+ },
19
+ dense: Boolean,
20
+ nowrap: Boolean
21
+ });
22
+ </script>
@@ -4,34 +4,34 @@
4
4
  <slot name="label">{{ label }}</slot>
5
5
  </label>
6
6
  <div class="mt-1">
7
- <QInput
8
- :model-value="modelValue"
9
- :error-message="error"
10
- :error="!!error"
11
- no-error-icon
12
- outlined
13
- dense
14
- :disable="disabled"
15
- :readonly="disabled"
16
- :type="type"
17
- :name="name"
18
- :placeholder="placeholder || label"
19
- :required="required"
20
- :rules="rules"
21
- :lazy-rules="!!rules"
22
- class="w-full"
23
- @update:model-value="$emit('update:model-value', $event)"
7
+ <q-input
8
+ :model-value="modelValue"
9
+ :error-message="error"
10
+ :error="!!error"
11
+ no-error-icon
12
+ outlined
13
+ dense
14
+ :disable="disabled"
15
+ :readonly="disabled"
16
+ :type="type"
17
+ :name="name"
18
+ :placeholder="placeholder || label"
19
+ :required="required"
20
+ :rules="rules"
21
+ :lazy-rules="!!rules"
22
+ class="w-full"
23
+ @update:model-value="$emit('update:model-value', $event)"
24
24
  />
25
25
  </div>
26
26
  </div>
27
27
  </template>
28
28
 
29
29
  <script setup>
30
- defineEmits(["update:model-value"]);
30
+ defineEmits(['update:model-value']);
31
31
  defineProps({
32
32
  type: {
33
33
  type: String,
34
- default: "text"
34
+ default: 'text'
35
35
  },
36
36
  name: {
37
37
  type: String,
@@ -1,58 +1,58 @@
1
1
  <template>
2
2
  <div
3
- class="max-w-full relative overflow-auto"
4
- :class="{'p-4 border rounded border-gray-medium': !readonly}"
5
- @dragover.prevent
6
- @drop.prevent="onDrop"
3
+ class="max-w-full relative overflow-auto"
4
+ :class="{'p-4 border rounded border-gray-medium': !readonly}"
5
+ @dragover.prevent
6
+ @drop.prevent="onDrop"
7
7
  >
8
8
  <FieldLabel
9
- :field="field"
10
- :show-name="showName"
11
- class="text-sm font-semibold"
9
+ :field="field"
10
+ :show-name="showName"
11
+ class="text-sm font-semibold"
12
12
  />
13
13
  <div
14
- v-if="!disable && !readonly"
15
- class="text-sm my-2"
14
+ v-if="!disable && !readonly"
15
+ class="text-sm my-2"
16
16
  >
17
17
  <a
18
- class="text-blue-base"
19
- @click="$refs.file.click()"
18
+ class="text-blue-base"
19
+ @click="$refs.file.click()"
20
20
  >Upload</a>
21
21
  <a
22
- v-if="uploadedFiles.length > 0"
23
- class="ml-3 text-red-dark"
24
- @click="onClear"
22
+ v-if="uploadedFiles.length > 0"
23
+ class="ml-3 text-red-dark"
24
+ @click="onClear"
25
25
  >Clear</a>
26
26
  <input
27
- ref="file"
28
- class="hidden"
29
- type="file"
30
- multiple
31
- @change="onFilesSelected"
27
+ ref="file"
28
+ class="hidden"
29
+ type="file"
30
+ multiple
31
+ @change="onFilesSelected"
32
32
  />
33
33
  </div>
34
34
 
35
35
  <div class="max-w-[50em] flex items-stretch justify-start">
36
36
  <ImagePreview
37
- v-for="file in uploadedFiles"
38
- :key="'file-upload-' + file.id"
39
- class="w-32 m-2 cursor-pointer bg-neutral-plus-5"
40
- :class="{'border border-dashed border-blue-base': !uploadedFiles.length}"
41
- :image="file"
42
- :related-files="uploadedFiles"
43
- downloadable
44
- :removable="!readonly && !disable"
45
- @remove="onRemove(file)"
37
+ v-for="file in uploadedFiles"
38
+ :key="'file-upload-' + file.id"
39
+ class="w-32 m-2 cursor-pointer bg-neutral-plus-5"
40
+ :class="{'border border-dashed border-blue-base': !uploadedFiles.length}"
41
+ :image="file"
42
+ :related-files="uploadedFiles"
43
+ downloadable
44
+ :removable="!readonly && !disable"
45
+ @remove="onRemove(file)"
46
46
  />
47
47
  <ImagePreview
48
- v-if="!disable && !readonly"
49
- class="w-32 m-2 cursor-pointer border border-dashed border-blue-base"
50
- disabled
51
- @click="$refs.file.click()"
48
+ v-if="!disable && !readonly"
49
+ class="w-32 m-2 cursor-pointer border border-dashed border-blue-base"
50
+ disabled
51
+ @click="$refs.file.click()"
52
52
  />
53
53
  <div
54
- v-if="readonly && uploadedFiles.length === 0"
55
- class="p-1"
54
+ v-if="readonly && uploadedFiles.length === 0"
55
+ class="p-1"
56
56
  >
57
57
  --
58
58
  </div>
@@ -61,12 +61,12 @@
61
61
  </template>
62
62
 
63
63
  <script setup>
64
- import ImagePreview from "components/Common/ImagePreview";
65
- import FieldLabel from "danx/src/components/ActionTable/Form/Fields/FieldLabel";
66
- import { useMultiFileUpload } from "src/helpers/multiFileUpload";
67
- import { onMounted } from "vue";
64
+ import { ImagePreview } from '@ui/components';
65
+ import { useMultiFileUpload } from '@ui/helpers';
66
+ import { onMounted } from 'vue';
67
+ import FieldLabel from './FieldLabel';
68
68
 
69
- const emit = defineEmits(["update:model-value"]);
69
+ const emit = defineEmits(['update:model-value']);
70
70
  const props = defineProps({
71
71
  modelValue: {
72
72
  type: [Object, String],
@@ -87,5 +87,5 @@ onMounted(() => {
87
87
  uploadedFiles.value = props.modelValue;
88
88
  }
89
89
  });
90
- onComplete(() => emit("update:model-value", uploadedFiles.value));
90
+ onComplete(() => emit('update:model-value', uploadedFiles.value));
91
91
  </script>
@@ -1,37 +1,37 @@
1
1
  <template>
2
2
  <div>
3
3
  <SelectField
4
- v-model="selectedFieldName"
5
- :label="undefined"
6
- :options="field.options"
7
- class="mb-2"
8
- @update:model-value="onChange"
4
+ v-model="selectedFieldName"
5
+ :label="undefined"
6
+ :options="field.options"
7
+ class="mb-2"
8
+ @update:model-value="onChange"
9
9
  />
10
10
  <TextField
11
- v-model="textInput"
12
- :field="field"
13
- :no-label="!field.label"
14
- label-class="text-xs font-bold text-gray-dark"
15
- parent-class="tight-label"
16
- input-class="!py-0"
17
- dense
18
- type="textarea"
19
- :debounce="500"
20
- @update:model-value="onChange"
11
+ v-model="textInput"
12
+ :field="field"
13
+ :no-label="!field.label"
14
+ label-class="text-xs font-bold text-gray-dark"
15
+ parent-class="tight-label"
16
+ input-class="!py-0"
17
+ dense
18
+ type="textarea"
19
+ :debounce="500"
20
+ @update:model-value="onChange"
21
21
  />
22
22
  </div>
23
23
  </template>
24
24
 
25
25
  <script setup>
26
- import SelectField from "danx/src/components/ActionTable/Form/Fields/SelectField";
27
- import TextField from "danx/src/components/ActionTable/Form/Fields/TextField";
28
- import { computed, ref, watch } from "vue";
26
+ import { computed, ref, watch } from 'vue';
27
+ import SelectField from './SelectField';
28
+ import TextField from './TextField';
29
29
 
30
- const emit = defineEmits(["update:model-value"]);
30
+ const emit = defineEmits(['update:model-value']);
31
31
  const props = defineProps({
32
32
  modelValue: {
33
33
  type: [String, Number, Object],
34
- default: ""
34
+ default: ''
35
35
  },
36
36
  field: {
37
37
  type: Object,
@@ -43,12 +43,12 @@ const selectedFieldName = ref(props.field.defaultOption);
43
43
  const searchList = computed(() => props.modelValue && props.modelValue[selectedFieldName.value]);
44
44
  const textInput = ref(formatModelValue());
45
45
  function onChange() {
46
- textInput.value = textInput.value?.replace(/\n/g, ",").replace(/,{2,}/g, ",") || "";
47
- emit("update:model-value", textInput.value ? { [selectedFieldName.value]: textInput.value.split(",") } : undefined);
46
+ textInput.value = textInput.value?.replace(/\n/g, ',').replace(/,{2,}/g, ',') || '';
47
+ emit('update:model-value', textInput.value ? { [selectedFieldName.value]: textInput.value.split(',') } : undefined);
48
48
  }
49
49
 
50
50
  function formatModelValue() {
51
- return Array.isArray(searchList.value) ? searchList.value?.join(",") : "";
51
+ return Array.isArray(searchList.value) ? searchList.value?.join(',') : '';
52
52
  }
53
53
 
54
54
  watch(() => props.modelValue, () => {
@@ -1,28 +1,28 @@
1
1
  <template>
2
2
  <LabeledInput
3
- type="password"
4
- v-bind="props"
5
- :rules="rules"
6
- @update:model-value="$emit('update:model-value', $event)"
3
+ type="password"
4
+ v-bind="props"
5
+ :rules="rules"
6
+ @update:model-value="$emit('update:model-value', $event)"
7
7
  />
8
8
  </template>
9
9
 
10
10
  <script setup>
11
- import LabeledInput from "danx/src/components/ActionTable/Form/Fields/LabeledInput";
11
+ import LabeledInput from './LabeledInput';
12
12
 
13
- defineEmits(["update:model-value"]);
13
+ defineEmits(['update:model-value']);
14
14
  const props = defineProps({
15
15
  name: {
16
16
  type: String,
17
- default: "password"
17
+ default: 'password'
18
18
  },
19
19
  label: {
20
20
  type: String,
21
- default: "Password"
21
+ default: 'Password'
22
22
  },
23
23
  placeholder: {
24
24
  type: String,
25
- default: "Enter Password"
25
+ default: 'Enter Password'
26
26
  },
27
27
  modelValue: {
28
28
  type: [String, Number],
@@ -35,5 +35,5 @@ const props = defineProps({
35
35
  disabled: Boolean
36
36
  });
37
37
 
38
- const rules = [(val) => val.length >= 8 || "Please use at least 8 characters"];
38
+ const rules = [(val) => val.length >= 8 || 'Please use at least 8 characters'];
39
39
  </script>
@@ -1,34 +1,34 @@
1
1
  <template>
2
- <QInput
3
- :model-value="numberVal"
4
- :data-testid="'number-field-' + fieldOptions.id"
5
- :placeholder="fieldOptions.placeholder"
6
- outlined
7
- dense
8
- inputmode="numeric"
9
- :input-class="{[inputClass]: true, 'text-right bg-white': !hidePrependLabel, 'text-right !text-xs text-black font-normal': hidePrependLabel}"
10
- :class="{'no-prepend-icon w-32': hidePrependLabel, 'prepend-label': !hidePrependLabel}"
11
- @update:model-value="onInput"
2
+ <q-input
3
+ :model-value="numberVal"
4
+ :data-testid="'number-field-' + fieldOptions.id"
5
+ :placeholder="fieldOptions.placeholder"
6
+ outlined
7
+ dense
8
+ inputmode="numeric"
9
+ :input-class="{[inputClass]: true, 'text-right bg-white': !hidePrependLabel, 'text-right !text-xs text-black font-normal': hidePrependLabel}"
10
+ :class="{'no-prepend-icon w-32': hidePrependLabel, 'prepend-label': !hidePrependLabel}"
11
+ @update:model-value="onInput"
12
12
  >
13
13
  <template #prepend>
14
14
  <FieldLabel
15
- :field="fieldOptions"
16
- :show-name="showName"
15
+ :field="fieldOptions"
16
+ :show-name="showName"
17
17
  />
18
18
  </template>
19
- </QInput>
19
+ </q-input>
20
20
  </template>
21
21
 
22
22
  <script setup>
23
- import FieldLabel from "danx/src/components/ActionTable/Form/Fields/FieldLabel";
24
- import { fNumber } from "danx/src/helpers/formats";
25
- import { computed, nextTick, ref, watch } from "vue";
23
+ import { fNumber } from '@ui/helpers/formats';
24
+ import { computed, nextTick, ref, watch } from 'vue';
25
+ import FieldLabel from './FieldLabel';
26
26
 
27
- const emit = defineEmits(["update:model-value"]);
27
+ const emit = defineEmits(['update:model-value']);
28
28
  const props = defineProps({
29
29
  modelValue: {
30
30
  type: [String, Number],
31
- default: ""
31
+ default: ''
32
32
  },
33
33
  precision: {
34
34
  type: Number,
@@ -44,7 +44,7 @@ const props = defineProps({
44
44
  },
45
45
  inputClass: {
46
46
  type: String,
47
- default: ""
47
+ default: ''
48
48
  },
49
49
  hidePrependLabel: Boolean,
50
50
  currency: Boolean,
@@ -54,41 +54,41 @@ const props = defineProps({
54
54
  const numberVal = ref(format(props.modelValue));
55
55
  watch(() => props.modelValue, () => numberVal.value = format(props.modelValue));
56
56
 
57
- const fieldOptions = computed(() => props.field || { label: props.label || "", placeholder: "", id: "" });
57
+ const fieldOptions = computed(() => props.field || { label: props.label || '', placeholder: '', id: '' });
58
58
 
59
59
  function format(number) {
60
- if (!number && number !== 0 && number !== "0") return number;
60
+ if (!number && number !== 0 && number !== '0') return number;
61
61
 
62
- const minimumFractionDigits = Math.min(props.precision, ("" + number).split(".")[1]?.length || 0);
62
+ const minimumFractionDigits = Math.min(props.precision, ('' + number).split('.')[1]?.length || 0);
63
63
  let options = {
64
64
  minimumFractionDigits
65
65
  };
66
66
 
67
67
  if (props.currency) {
68
68
  options = {
69
- style: "currency",
70
- currency: "USD",
69
+ style: 'currency',
70
+ currency: 'USD',
71
71
  minimumFractionDigits
72
72
  };
73
73
  }
74
74
  return fNumber(number, options);
75
75
  }
76
76
  function onInput(value) {
77
- let number = "";
77
+ let number = '';
78
78
 
79
79
  // Prevent invalid characters
80
80
  if (value.match(/[^\d.,$]/)) {
81
81
  const oldVal = numberVal.value;
82
82
  // XXX: To get QInput to show only the value we want
83
- numberVal.value += " ";
83
+ numberVal.value += ' ';
84
84
  return nextTick(() => numberVal.value = oldVal);
85
85
  }
86
86
 
87
- if (value !== "") {
88
- value = value.replace(/[^\d.]/g, "");
87
+ if (value !== '') {
88
+ value = value.replace(/[^\d.]/g, '');
89
89
  number = Number(value);
90
90
  numberVal.value = format(number);
91
91
  }
92
- emit("update:model-value", number === "" ? undefined : number);
92
+ emit('update:model-value', number === '' ? undefined : number);
93
93
  }
94
94
  </script>