@vc-shell/framework 1.0.187 → 1.0.189

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 (147) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/core/plugins/moment/humanize.ts +6 -7
  3. package/dist/core/plugins/moment/humanize.d.ts.map +1 -1
  4. package/dist/framework.js +5907 -5885
  5. package/dist/index.css +1 -1
  6. package/dist/shared/modules/dynamic/components/fields/Button.d.ts.map +1 -1
  7. package/dist/shared/modules/dynamic/components/fields/ContentField.d.ts.map +1 -1
  8. package/dist/shared/modules/dynamic/components/fields/DynamicProperty.d.ts.map +1 -1
  9. package/dist/shared/modules/dynamic/components/fields/EditorField.d.ts +4 -1
  10. package/dist/shared/modules/dynamic/components/fields/EditorField.d.ts.map +1 -1
  11. package/dist/shared/modules/dynamic/components/fields/GalleryField.d.ts.map +1 -1
  12. package/dist/shared/modules/dynamic/components/fields/ImageField.d.ts.map +1 -1
  13. package/dist/shared/modules/dynamic/components/fields/MultivalueField.d.ts.map +1 -1
  14. package/dist/shared/modules/dynamic/components/fields/SelectField.d.ts.map +1 -1
  15. package/dist/shared/modules/dynamic/components/fields/StatusField.d.ts.map +1 -1
  16. package/dist/shared/modules/dynamic/components/fields/VideoField.d.ts.map +1 -1
  17. package/dist/shared/modules/dynamic/components/fields/storybook/Button.stories.d.ts +417 -0
  18. package/dist/shared/modules/dynamic/components/fields/storybook/Button.stories.d.ts.map +1 -0
  19. package/dist/shared/modules/dynamic/components/fields/storybook/Card.stories.d.ts +357 -0
  20. package/dist/shared/modules/dynamic/components/fields/storybook/Card.stories.d.ts.map +1 -0
  21. package/dist/shared/modules/dynamic/components/fields/storybook/Checkbox.stories.d.ts +398 -0
  22. package/dist/shared/modules/dynamic/components/fields/storybook/Checkbox.stories.d.ts.map +1 -0
  23. package/dist/shared/modules/dynamic/components/fields/storybook/ContentField.stories.d.ts +392 -0
  24. package/dist/shared/modules/dynamic/components/fields/storybook/ContentField.stories.d.ts.map +1 -0
  25. package/dist/shared/modules/dynamic/components/fields/storybook/EditorField.stories.d.ts +398 -0
  26. package/dist/shared/modules/dynamic/components/fields/storybook/EditorField.stories.d.ts.map +1 -0
  27. package/dist/shared/modules/dynamic/components/fields/storybook/Fieldset.stories.d.ts +372 -0
  28. package/dist/shared/modules/dynamic/components/fields/storybook/Fieldset.stories.d.ts.map +1 -0
  29. package/dist/shared/modules/dynamic/components/fields/storybook/GalleryField.stories.d.ts +391 -0
  30. package/dist/shared/modules/dynamic/components/fields/storybook/GalleryField.stories.d.ts.map +1 -0
  31. package/dist/shared/modules/dynamic/components/fields/storybook/ImageField.stories.d.ts +372 -0
  32. package/dist/shared/modules/dynamic/components/fields/storybook/ImageField.stories.d.ts.map +1 -0
  33. package/dist/shared/modules/dynamic/components/fields/storybook/InputCurrency.stories.d.ts +439 -0
  34. package/dist/shared/modules/dynamic/components/fields/storybook/InputCurrency.stories.d.ts.map +1 -0
  35. package/dist/shared/modules/dynamic/components/fields/storybook/InputField.stories.d.ts +448 -0
  36. package/dist/shared/modules/dynamic/components/fields/storybook/InputField.stories.d.ts.map +1 -0
  37. package/dist/shared/modules/dynamic/components/fields/storybook/MultivalueField.stories.d.ts +459 -0
  38. package/dist/shared/modules/dynamic/components/fields/storybook/MultivalueField.stories.d.ts.map +1 -0
  39. package/dist/shared/modules/dynamic/components/fields/storybook/RatingField.stories.d.ts +359 -0
  40. package/dist/shared/modules/dynamic/components/fields/storybook/RatingField.stories.d.ts.map +1 -0
  41. package/dist/shared/modules/dynamic/components/fields/storybook/SelectField.stories.d.ts +507 -0
  42. package/dist/shared/modules/dynamic/components/fields/storybook/SelectField.stories.d.ts.map +1 -0
  43. package/dist/shared/modules/dynamic/components/fields/storybook/StatusField.stories.d.ts +392 -0
  44. package/dist/shared/modules/dynamic/components/fields/storybook/StatusField.stories.d.ts.map +1 -0
  45. package/dist/shared/modules/dynamic/components/fields/storybook/SwitchField.stories.d.ts +14 -0
  46. package/dist/shared/modules/dynamic/components/fields/storybook/SwitchField.stories.d.ts.map +1 -0
  47. package/dist/shared/modules/dynamic/components/fields/storybook/TextareaField.stories.d.ts +395 -0
  48. package/dist/shared/modules/dynamic/components/fields/storybook/TextareaField.stories.d.ts.map +1 -0
  49. package/dist/shared/modules/dynamic/components/fields/storybook/VideoField.stories.d.ts +322 -0
  50. package/dist/shared/modules/dynamic/components/fields/storybook/VideoField.stories.d.ts.map +1 -0
  51. package/dist/shared/modules/dynamic/components/fields/storybook/common/args.d.ts +113 -0
  52. package/dist/shared/modules/dynamic/components/fields/storybook/common/args.d.ts.map +1 -0
  53. package/dist/shared/modules/dynamic/components/fields/storybook/common/templates.d.ts +3 -0
  54. package/dist/shared/modules/dynamic/components/fields/storybook/common/templates.d.ts.map +1 -0
  55. package/dist/shared/modules/dynamic/components/fields/storybook/pages/DynamicRender.d.ts +235 -0
  56. package/dist/shared/modules/dynamic/components/fields/storybook/pages/DynamicRender.d.ts.map +1 -0
  57. package/dist/shared/modules/dynamic/components/fields/storybook/utils/sourceHighlighter.d.ts +4 -0
  58. package/dist/shared/modules/dynamic/components/fields/storybook/utils/sourceHighlighter.d.ts.map +1 -0
  59. package/dist/shared/modules/dynamic/components/fields/storybook/utils/sourceTransform.d.ts +3 -0
  60. package/dist/shared/modules/dynamic/components/fields/storybook/utils/sourceTransform.d.ts.map +1 -0
  61. package/dist/shared/modules/dynamic/factories/base/useDetailsFactory.d.ts.map +1 -1
  62. package/dist/shared/modules/dynamic/helpers/getters.d.ts.map +1 -1
  63. package/dist/shared/modules/dynamic/types/index.d.ts +73 -38
  64. package/dist/shared/modules/dynamic/types/index.d.ts.map +1 -1
  65. package/dist/shared/modules/dynamic/types/models.d.ts.map +1 -1
  66. package/dist/tsconfig.tsbuildinfo +1 -1
  67. package/dist/ui/components/atoms/vc-card/vc-card.vue.d.ts.map +1 -1
  68. package/dist/ui/components/atoms/vc-switch/index.d.ts +1 -39
  69. package/dist/ui/components/atoms/vc-switch/index.d.ts.map +1 -1
  70. package/dist/ui/components/atoms/vc-switch/vc-switch.stories.d.ts +30 -11
  71. package/dist/ui/components/atoms/vc-switch/vc-switch.stories.d.ts.map +1 -1
  72. package/dist/ui/components/atoms/vc-switch/vc-switch.vue.d.ts +22 -3
  73. package/dist/ui/components/atoms/vc-switch/vc-switch.vue.d.ts.map +1 -1
  74. package/dist/ui/components/atoms/vc-video/index.d.ts +1 -35
  75. package/dist/ui/components/atoms/vc-video/index.d.ts.map +1 -1
  76. package/dist/ui/components/atoms/vc-video/vc-video.stories.d.ts +5 -27
  77. package/dist/ui/components/atoms/vc-video/vc-video.stories.d.ts.map +1 -1
  78. package/dist/ui/components/atoms/vc-video/vc-video.vue.d.ts +3 -18
  79. package/dist/ui/components/atoms/vc-video/vc-video.vue.d.ts.map +1 -1
  80. package/dist/ui/components/molecules/vc-editor/vc-editor.vue.d.ts.map +1 -1
  81. package/dist/ui/components/molecules/vc-input-currency/vc-input-currency.vue.d.ts.map +1 -1
  82. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.stories.d.ts +252 -42
  83. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.stories.d.ts.map +1 -1
  84. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts +36 -6
  85. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts.map +1 -1
  86. package/dist/ui/components/molecules/vc-select/vc-select.stories.d.ts +96 -32
  87. package/dist/ui/components/molecules/vc-select/vc-select.stories.d.ts.map +1 -1
  88. package/dist/ui/components/molecules/vc-select/vc-select.vue.d.ts +3 -3
  89. package/dist/ui/components/molecules/vc-select/vc-select.vue.d.ts.map +1 -1
  90. package/dist/ui/components/molecules/vc-textarea/vc-textarea.vue.d.ts.map +1 -1
  91. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
  92. package/package.json +4 -4
  93. package/shared/modules/dynamic/components/fields/Button.ts +5 -2
  94. package/shared/modules/dynamic/components/fields/Card.ts +4 -4
  95. package/shared/modules/dynamic/components/fields/ContentField.ts +1 -0
  96. package/shared/modules/dynamic/components/fields/DynamicProperty.ts +5 -6
  97. package/shared/modules/dynamic/components/fields/EditorField.ts +4 -3
  98. package/shared/modules/dynamic/components/fields/Fieldset.ts +1 -1
  99. package/shared/modules/dynamic/components/fields/GalleryField.ts +6 -3
  100. package/shared/modules/dynamic/components/fields/ImageField.ts +0 -1
  101. package/shared/modules/dynamic/components/fields/InputCurrency.ts +1 -1
  102. package/shared/modules/dynamic/components/fields/MultivalueField.ts +3 -2
  103. package/shared/modules/dynamic/components/fields/SelectField.ts +1 -0
  104. package/shared/modules/dynamic/components/fields/StatusField.ts +20 -10
  105. package/shared/modules/dynamic/components/fields/VideoField.ts +0 -1
  106. package/shared/modules/dynamic/components/fields/storybook/Button.stories.ts +247 -0
  107. package/shared/modules/dynamic/components/fields/storybook/Card.stories.ts +167 -0
  108. package/shared/modules/dynamic/components/fields/storybook/Checkbox.stories.ts +186 -0
  109. package/shared/modules/dynamic/components/fields/storybook/ContentField.stories.ts +246 -0
  110. package/shared/modules/dynamic/components/fields/storybook/EditorField.stories.ts +185 -0
  111. package/shared/modules/dynamic/components/fields/storybook/Fieldset.stories.ts +409 -0
  112. package/shared/modules/dynamic/components/fields/storybook/GalleryField.stories.ts +239 -0
  113. package/shared/modules/dynamic/components/fields/storybook/ImageField.stories.ts +186 -0
  114. package/shared/modules/dynamic/components/fields/storybook/InputCurrency.stories.ts +267 -0
  115. package/shared/modules/dynamic/components/fields/storybook/InputField.stories.ts +286 -0
  116. package/shared/modules/dynamic/components/fields/storybook/MultivalueField.stories.ts +347 -0
  117. package/shared/modules/dynamic/components/fields/storybook/RatingField.stories.ts +131 -0
  118. package/shared/modules/dynamic/components/fields/storybook/SelectField.stories.ts +653 -0
  119. package/shared/modules/dynamic/components/fields/storybook/StatusField.stories.ts +202 -0
  120. package/shared/modules/dynamic/components/fields/storybook/SwitchField.stories.ts +178 -0
  121. package/shared/modules/dynamic/components/fields/storybook/TextareaField.stories.ts +191 -0
  122. package/shared/modules/dynamic/components/fields/storybook/VideoField.stories.ts +92 -0
  123. package/shared/modules/dynamic/components/fields/storybook/common/args.ts +130 -0
  124. package/shared/modules/dynamic/components/fields/storybook/common/templates.ts +8 -0
  125. package/shared/modules/dynamic/components/fields/storybook/pages/DynamicRender.ts +54 -0
  126. package/shared/modules/dynamic/components/fields/storybook/utils/sourceHighlighter.ts +16 -0
  127. package/shared/modules/dynamic/components/fields/storybook/utils/sourceTransform.ts +41 -0
  128. package/shared/modules/dynamic/factories/base/useDetailsFactory.ts +4 -2
  129. package/shared/modules/dynamic/helpers/getters.ts +3 -0
  130. package/shared/modules/dynamic/helpers/nodeBuilder.ts +1 -1
  131. package/shared/modules/dynamic/helpers/setters.ts +1 -1
  132. package/shared/modules/dynamic/types/index.ts +78 -40
  133. package/shared/modules/dynamic/types/models.ts +8 -7
  134. package/ui/components/atoms/vc-card/vc-card.vue +12 -2
  135. package/ui/components/atoms/vc-switch/index.ts +1 -3
  136. package/ui/components/atoms/vc-switch/vc-switch.vue +10 -3
  137. package/ui/components/atoms/vc-video/index.ts +1 -3
  138. package/ui/components/atoms/vc-video/vc-video.stories.ts +1 -15
  139. package/ui/components/atoms/vc-video/vc-video.vue +4 -37
  140. package/ui/components/molecules/vc-editor/vc-editor.vue +28 -9
  141. package/ui/components/molecules/vc-field/_internal/vc-field-type/vc-field-type.vue +2 -2
  142. package/ui/components/molecules/vc-input-currency/vc-input-currency.vue +8 -0
  143. package/ui/components/molecules/vc-multivalue/vc-multivalue.vue +21 -9
  144. package/ui/components/molecules/vc-select/vc-select.stories.ts +74 -3
  145. package/ui/components/molecules/vc-select/vc-select.vue +35 -38
  146. package/ui/components/molecules/vc-textarea/vc-textarea.vue +1 -9
  147. package/ui/components/organisms/vc-table/vc-table.vue +1 -0
@@ -13,7 +13,7 @@
13
13
  <input
14
14
  type="checkbox"
15
15
  class="vc-switch__input"
16
- :checked="modelValue"
16
+ :checked="invertValue(modelValue)"
17
17
  :disabled="disabled"
18
18
  @input="onInput"
19
19
  />
@@ -37,19 +37,26 @@ export interface Props {
37
37
  tooltip?: string;
38
38
  required?: boolean;
39
39
  label?: string;
40
+ trueValue?: boolean;
41
+ falseValue?: boolean;
40
42
  }
41
43
 
42
44
  export interface Emits {
43
45
  (event: "update:modelValue", value: boolean): void;
44
46
  }
45
47
 
46
- defineProps<Props>();
48
+ const props = withDefaults(defineProps<Props>(), {
49
+ trueValue: true,
50
+ falseValue: false,
51
+ });
47
52
 
48
53
  const emit = defineEmits<Emits>();
49
54
 
55
+ const invertValue = (value: boolean) => (props.trueValue ? value : !value);
56
+
50
57
  function onInput(e: Event) {
51
58
  const newValue = (e.target as HTMLInputElement).checked;
52
- emit("update:modelValue", newValue);
59
+ emit("update:modelValue", invertValue(newValue));
53
60
  }
54
61
  </script>
55
62
 
@@ -1,3 +1 @@
1
- import _Video from "./vc-video.vue";
2
-
3
- export const VcVideo = _Video as typeof _Video;
1
+ export { default as VcVideo } from "./vc-video.vue";
@@ -1,27 +1,13 @@
1
1
  import type { Meta, StoryFn } from "@storybook/vue3";
2
2
  import { VcVideo } from "./";
3
3
 
4
- const SIZE = ["auto", "xs", "s", "m", "l", "xl", "xxl"];
5
-
6
4
  export default {
7
5
  title: "atoms/VcVideo",
8
6
  component: VcVideo,
9
7
  args: {
10
8
  source: "https://www.youtube.com/embed/PeXX-V-dwpA",
11
- size: "auto",
12
9
  label: "Video",
13
10
  },
14
- argTypes: {
15
- size: {
16
- options: SIZE,
17
- control: "radio",
18
- table: {
19
- type: {
20
- summary: SIZE.join(" | "),
21
- },
22
- },
23
- },
24
- },
25
11
  } satisfies Meta<typeof VcVideo>;
26
12
 
27
13
  export const Primary: StoryFn<typeof VcVideo> = (args) => ({
@@ -29,5 +15,5 @@ export const Primary: StoryFn<typeof VcVideo> = (args) => ({
29
15
  setup() {
30
16
  return { args };
31
17
  },
32
- template: '<div style="width: 400px"><vc-video v-bind="args"></vc-video></div>',
18
+ template: '<vc-video v-bind="args" />',
33
19
  });
@@ -1,8 +1,5 @@
1
1
  <template>
2
- <div
3
- class="vc-video"
4
- :class="[`vc-video_${size}`]"
5
- >
2
+ <div class="tw-inline-block tw-relative">
6
3
  <VcLabel
7
4
  v-if="label"
8
5
  class="tw-mb-2"
@@ -15,12 +12,12 @@
15
12
  >
16
13
  </VcLabel>
17
14
 
18
- <div :class="[`vc-video_auto`, 'tw-relative']">
15
+ <div class="tw-w-full tw-relative">
19
16
  <div v-if="source">
20
17
  <iframe
21
18
  :src="`${source}`"
22
19
  width="100%"
23
- height="300"
20
+ height="300px"
24
21
  frameborder="0"
25
22
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
26
23
  allowfullscreen="false"
@@ -47,43 +44,13 @@ export interface Props {
47
44
  label?: string;
48
45
  tooltip?: string;
49
46
  source?: string;
50
- size?: "auto" | "xs" | "s" | "m" | "l" | "xl" | "xxl";
51
47
  }
52
48
 
53
49
  export interface Emits {
54
50
  (event: "click"): void;
55
51
  }
56
52
 
57
- withDefaults(defineProps<Props>(), {
58
- size: "auto",
59
- });
53
+ defineProps<Props>();
60
54
 
61
55
  defineEmits<Emits>();
62
56
  </script>
63
-
64
- <style lang="scss">
65
- :root {
66
- --image-size-xs: 32px;
67
- --image-size-s: 48px;
68
- --image-size-m: 64px;
69
- --image-size-l: 96px;
70
- --image-size-xl: 128px;
71
- --image-size-xxl: 145px;
72
- }
73
-
74
- $paddings: xs, s, m, l, xl, xxl;
75
-
76
- .vc-video {
77
- @apply tw-inline-block tw-relative;
78
-
79
- @each $padding in $paddings {
80
- &_#{$padding} {
81
- @apply tw-w-[var(--image-size-#{$padding})];
82
- }
83
- }
84
-
85
- &_auto {
86
- @apply tw-w-full;
87
- }
88
- }
89
- </style>
@@ -26,9 +26,10 @@
26
26
 
27
27
  <!-- Editor field -->
28
28
  <QuillEditor
29
- :key="`${disabled}`"
29
+ :id="id"
30
+ :key="`${id}-${disabled}`"
30
31
  ref="quillRef"
31
- v-model:content="content"
32
+ :content="content"
32
33
  class="quill-editor tw-border tw-border-solid tw-border-[color:var(--editor-border-color)] tw-rounded-b-[var(--editor-border-radius)] tw-h-[200px]"
33
34
  :class="{ 'tw-bg-[#fafafa] tw-text-[#424242] tw-cursor-default': disabled }"
34
35
  theme="snow"
@@ -37,6 +38,7 @@
37
38
  content-type="html"
38
39
  :read-only="disabled"
39
40
  :placeholder="placeholder"
41
+ :options="options"
40
42
  @update:content="onInput"
41
43
  />
42
44
  <slot
@@ -53,9 +55,9 @@
53
55
  <script lang="ts" setup>
54
56
  import { QuillEditor, Quill } from "@vueup/vue-quill";
55
57
  import "@vueup/vue-quill/dist/vue-quill.snow.css";
56
- import { ref, unref, watch, onMounted, onUpdated, Ref } from "vue";
58
+ import { ref, unref, watch, onMounted, onUpdated, getCurrentInstance } from "vue";
57
59
  import ImageUploader from "quill-image-uploader";
58
- import { VcLabel, VcHint } from "./../../";
60
+ import { VcLabel, VcHint } from "../..";
59
61
 
60
62
  export interface Props {
61
63
  placeholder?: string;
@@ -77,6 +79,8 @@ export interface Emits {
77
79
  const props = defineProps<Props>();
78
80
 
79
81
  const emit = defineEmits<Emits>();
82
+ const uid = getCurrentInstance()?.uid;
83
+ const id = `editor-${uid}`;
80
84
 
81
85
  defineSlots<{
82
86
  error?: (props: any) => any;
@@ -102,6 +106,10 @@ const toolbar = {
102
106
  handlers: {},
103
107
  };
104
108
 
109
+ const options = {
110
+ bounds: ".quill-editor",
111
+ };
112
+
105
113
  const modules = {
106
114
  name: "imageUploader",
107
115
  module: ImageUploader,
@@ -110,7 +118,7 @@ const modules = {
110
118
  const formData = new FormData();
111
119
  formData.append("image", file);
112
120
 
113
- const result = await fetch(`/api/assets?folderUrl=/catalog/${props.assetsFolder}`, {
121
+ const result = await fetch(`/api/assets?folderUrl=/${props.assetsFolder}`, {
114
122
  method: "POST",
115
123
  body: formData,
116
124
  });
@@ -145,17 +153,17 @@ watch(
145
153
 
146
154
  function removeBlankClass() {
147
155
  // fixes quill editor placeholder visibility issue when content is not empty
148
- const editor = document.querySelector(".ql-editor.ql-blank");
156
+ const editor = document.getElementById(id)?.querySelector(".ql-editor.ql-blank");
149
157
  if (editor && content.value) {
150
158
  editor.classList.remove("ql-blank");
151
159
  }
152
160
  }
153
161
 
154
- function onInput() {
155
- if (isQuillEmpty(content.value)) {
162
+ function onInput(value: string) {
163
+ if (isQuillEmpty(value)) {
156
164
  emit("update:modelValue", null);
157
165
  } else {
158
- emit("update:modelValue", content.value);
166
+ emit("update:modelValue", value);
159
167
  }
160
168
  }
161
169
 
@@ -209,6 +217,17 @@ function isQuillEmpty(value: string) {
209
217
  right: 15px;
210
218
  }
211
219
  }
220
+
221
+ .quill-editor {
222
+ & .ql-tooltip {
223
+ display: flex;
224
+ flex-flow: wrap;
225
+
226
+ &.ql-hidden {
227
+ display: none !important;
228
+ }
229
+ }
230
+ }
212
231
  }
213
232
 
214
233
  .ql-language.ql-picker .ql-picker-label:before {
@@ -12,7 +12,7 @@
12
12
  <template v-if="type === 'date'">
13
13
  <div class="tw-flex tw-flex-row tw-justify-stretch tw-truncate">
14
14
  <div class="tw-text-wrap">
15
- <p>{{ value.toLocaleDateString() }}</p>
15
+ <p>{{ value instanceof Date ? value.toLocaleDateString() : value }}</p>
16
16
  </div>
17
17
  </div>
18
18
  </template>
@@ -21,7 +21,7 @@
21
21
  <template v-if="type === 'date-ago'">
22
22
  <div class="tw-flex tw-flex-row tw-justify-stretch tw-truncate">
23
23
  <div class="tw-text-wrap">
24
- <p>{{ moment(value).fromNow() ?? "N/A" }}</p>
24
+ <p>{{ value instanceof Date ? moment(value).fromNow() ?? "N/A" : value }}</p>
25
25
  </div>
26
26
  </div>
27
27
  </template>
@@ -20,6 +20,7 @@
20
20
  :prefix="prefix"
21
21
  :suffix="suffix"
22
22
  :name="name"
23
+ :model-value="numberValue"
23
24
  :loading="loading"
24
25
  :disabled="disabled"
25
26
  :autofocus="autofocus"
@@ -28,6 +29,7 @@
28
29
  :maxlength="maxlength"
29
30
  class="tw-w-full"
30
31
  type="number"
32
+ @update:model-value="updateModel"
31
33
  >
32
34
  <template #append-inner>
33
35
  <slot
@@ -210,4 +212,10 @@ watch(
210
212
  watch(numberValue, (value) => {
211
213
  emit("update:model-value", value);
212
214
  });
215
+
216
+ function updateModel(value: string | number | Date | null | undefined) {
217
+ inputRef.value.value = value as string;
218
+ numberValue.value = value as number | null;
219
+ emit("update:model-value", value as number);
220
+ }
213
221
  </script>
@@ -40,11 +40,22 @@
40
40
  v-if="item"
41
41
  class="vc-multivalue__field-value"
42
42
  >
43
- <span class="tw-truncate">{{
44
- type === "number"
45
- ? Number(item[props.optionLabel as keyof T]).toFixed(3)
46
- : item[props.optionLabel as keyof T]
47
- }}</span>
43
+ <slot
44
+ name="selected-item"
45
+ :value="
46
+ type === 'number'
47
+ ? Number(item[props.optionLabel as keyof T]).toFixed(3)
48
+ : item[props.optionLabel as keyof T]
49
+ "
50
+ :item="item"
51
+ :remove="() => onDelete(i)"
52
+ >
53
+ <span class="tw-truncate">{{
54
+ type === "number"
55
+ ? Number(item[props.optionLabel as keyof T]).toFixed(3)
56
+ : item[props.optionLabel as keyof T]
57
+ }}</span>
58
+ </slot>
48
59
  <VcIcon
49
60
  v-if="!disabled"
50
61
  class="vc-multivalue__field-value-clear"
@@ -88,7 +99,7 @@
88
99
  @click="onItemSelect(item)"
89
100
  >
90
101
  <slot
91
- name="item"
102
+ name="option"
92
103
  :item="item"
93
104
  >{{ item[optionLabel as keyof T] }}</slot
94
105
  >
@@ -192,7 +203,8 @@ const props = withDefaults(defineProps<Props<T>>(), {
192
203
 
193
204
  const emit = defineEmits<Emits<T>>();
194
205
  defineSlots<{
195
- item: (args: { item: T }) => any;
206
+ option: (args: { item: T }) => any;
207
+ "selected-item": (args: { value: string | T[keyof T]; item: T; remove: () => void }) => any;
196
208
  hint: void;
197
209
  error: void;
198
210
  }>();
@@ -381,7 +393,7 @@ function onSearch(event: Event) {
381
393
  }
382
394
 
383
395
  &__field {
384
- @apply tw-border-none tw-outline-none tw-h-[var(--multivalue-height)]
396
+ @apply tw-border-none tw-outline-none tw-min-h-[var(--multivalue-height)]
385
397
  tw-min-w-[120px] tw-box-border placeholder:tw-text-[color:var(--multivalue-placeholder-color)];
386
398
 
387
399
  &::-webkit-input-placeholder {
@@ -397,7 +409,7 @@ function onSearch(event: Event) {
397
409
  }
398
410
 
399
411
  &-value-wrapper {
400
- @apply tw-h-[var(--multivalue-height)] tw-ml-2 tw-flex tw-items-center;
412
+ @apply tw-min-h-[var(--multivalue-height)] tw-ml-2 tw-flex tw-items-center;
401
413
  }
402
414
 
403
415
  &-value {
@@ -11,21 +11,92 @@ export default {
11
11
  },
12
12
  argTypes: {
13
13
  options: {
14
+ description: `Method that is used to get select options.
15
+ Method should be defined in the blade \`scope\` and could be:
16
+ \n1) async method with the following arguments: (\`keyword: string\`, \`skip\`, \`ids?: string[]\`).
17
+ \n2) any array
18
+ \n3) composable returning array`,
14
19
  table: {
15
20
  type: {
16
21
  summary: "((keyword?: string, skip?: number, ids?: string[]) => Promise<P>) | T[]",
17
22
  },
18
23
  },
19
24
  },
20
- optionLabel: {
25
+ optionValue: {
26
+ description: "Property which holds the `value`",
21
27
  control: "text",
28
+ table: {
29
+ type: {
30
+ summary: "string",
31
+ },
32
+ defaultValue: {
33
+ summary: "id",
34
+ },
35
+ },
22
36
  },
23
- optionValue: {
37
+ optionLabel: {
38
+ description: "Property which holds the `label`",
24
39
  control: "text",
40
+ table: {
41
+ type: {
42
+ summary: "string",
43
+ },
44
+ defaultValue: {
45
+ summary: "title",
46
+ },
47
+ },
25
48
  },
26
49
  debounce: {
27
50
  control: "number",
28
51
  },
52
+ clearable: {
53
+ description: "Whether the select is clearable or not.",
54
+ control: "boolean",
55
+ table: {
56
+ type: {
57
+ summary: "boolean",
58
+ },
59
+ defaultValue: {
60
+ summary: false,
61
+ },
62
+ },
63
+ },
64
+ emitValue: {
65
+ description: `Update model with the value of the selected option instead of the whole option.
66
+ \n Example:
67
+ \nIf emitValue is \`true\` and the selected option is { id: 1, title: "Option 1" }, the model will be updated with 1.
68
+ \nIf emitValue is \`false\`, the model will be updated with the whole option.`,
69
+ table: {
70
+ type: {
71
+ summary: "boolean",
72
+ },
73
+ defaultValue: {
74
+ summary: "true",
75
+ },
76
+ },
77
+ },
78
+ searchable: {
79
+ description: "Whether the select is searchable or not.",
80
+ table: {
81
+ type: {
82
+ summary: "boolean",
83
+ },
84
+ defaultValue: {
85
+ summary: false,
86
+ },
87
+ },
88
+ },
89
+ multiple: {
90
+ description: "Select multiple values.",
91
+ table: {
92
+ type: {
93
+ summary: "boolean",
94
+ },
95
+ defaultValue: {
96
+ summary: false,
97
+ },
98
+ },
99
+ },
29
100
  },
30
101
  } satisfies Meta<typeof VcSelect>;
31
102
 
@@ -61,7 +132,7 @@ export const AsyncOptions: StoryFn<typeof VcSelect> = (args) => ({
61
132
  components: { VcSelect } as Record<keyof typeof VcSelect, unknown>,
62
133
  setup() {
63
134
  const val = ref();
64
- const getItems = async () =>
135
+ const getItems = async (keyword?: string, skip = 0, ids?: string[]) =>
65
136
  new Promise((resolve) => {
66
137
  setTimeout(() => {
67
138
  resolve({
@@ -73,45 +73,42 @@
73
73
  <template v-else>{{ t("COMPONENTS.MOLECULES.VC_SELECT.CLICK_TO_SELECT") }}</template>
74
74
  </div>
75
75
  <template v-else-if="selectedScope && selectedScope.length && hasValue">
76
- <template v-if="$slots['selected-item']">
77
- <template
76
+ <div class="tw-flex tw-flex-wrap tw-gap-1 tw-py-1">
77
+ <div
78
78
  v-for="(item, i) in selectedScope"
79
+ v-bind="item"
79
80
  :key="i"
81
+ class="tw-flex tw-items-center"
80
82
  >
81
- <slot
82
- v-bind="item"
83
- name="selected-item"
84
- ></slot>
85
- </template>
86
- </template>
87
- <template v-else>
88
- <div class="tw-flex tw-flex-wrap tw-gap-1 tw-py-1">
89
- <div
90
- v-for="(item, i) in selectedScope"
91
- v-bind="item"
92
- :key="i"
93
- class="tw-flex tw-items-center"
94
- >
95
- <template v-if="multiple">
96
- <div
97
- class="tw-bg-[#fbfdfe] tw-border tw-border-solid tw-border-[color:#bdd1df] tw-rounded-[2px] tw-flex tw-items-center tw-h-[28px] tw-box-border tw-px-2"
83
+ <template v-if="multiple">
84
+ <div
85
+ class="tw-bg-[#fbfdfe] tw-border tw-border-solid tw-border-[color:#bdd1df] tw-rounded-[2px] tw-flex tw-items-center tw-h-[28px] tw-box-border tw-px-2"
86
+ >
87
+ <slot
88
+ name="selected-item"
89
+ v-bind="item"
98
90
  >
99
91
  <span>{{ getOptionLabel(item.opt) }}</span>
100
- <VcIcon
101
- v-if="!disabled"
102
- class="tw-text-[#a9bfd2] tw-ml-2 tw-cursor-pointer hover:tw-text-[color:var(--select-clear-color-hover)]"
103
- icon="fas fa-times"
104
- size="s"
105
- @click.stop="removeAtIndex(item.index)"
106
- ></VcIcon>
107
- </div>
108
- </template>
109
- <template v-else-if="!multiple">
92
+ </slot>
93
+ <VcIcon
94
+ v-if="!disabled"
95
+ class="tw-text-[#a9bfd2] tw-ml-2 tw-cursor-pointer hover:tw-text-[color:var(--select-clear-color-hover)]"
96
+ icon="fas fa-times"
97
+ size="s"
98
+ @click.stop="removeAtIndex(item.index)"
99
+ ></VcIcon>
100
+ </div>
101
+ </template>
102
+ <template v-else-if="!multiple">
103
+ <slot
104
+ name="selected-item"
105
+ v-bind="item"
106
+ >
110
107
  {{ getEmittingOptionValue(item.opt) }}
111
- </template>
112
- </div>
108
+ </slot>
109
+ </template>
113
110
  </div>
114
- </template>
111
+ </div>
115
112
  </template>
116
113
  </div>
117
114
  <div
@@ -375,8 +372,8 @@ const props = withDefaults(
375
372
 
376
373
  modelValue?: any;
377
374
  /**
378
- * Try to map labels of model from 'options' Array; If you are using emit-value you will probably need to use map-options to display the label text in the select field rather than the value;
379
- * Default value: true
375
+ * Try to map labels of model from 'options' Array; If you are using emit-value you will probably need to use map-options to display the label text in the select field rather than the value.
376
+ * @default true
380
377
  */
381
378
  mapOptions?: boolean;
382
379
  /**
@@ -422,19 +419,19 @@ const props = withDefaults(
422
419
  multiple?: boolean;
423
420
  /**
424
421
  * Available options that the user can select from.
425
- * Default value: []
422
+ * @default []
426
423
  */
427
424
  options?: ((keyword?: string, skip?: number, ids?: string[]) => Promise<P>) | T[];
428
425
  /**
429
426
  * Property of option which holds the 'value'
430
- * Default value: id
427
+ * @default id
431
428
  * @param option The current option being processed
432
429
  * @returns Value of the current option
433
430
  */
434
431
  optionValue?: OptionProp<Option>;
435
432
  /**
436
433
  * Property of option which holds the 'label'
437
- * Default value: title
434
+ * @default title
438
435
  * @param option The current option being processed
439
436
  * @returns Label of the current option
440
437
  */
@@ -445,7 +442,7 @@ const props = withDefaults(
445
442
  emitValue?: boolean;
446
443
  /**
447
444
  * Debounce the search input update with an amount of milliseconds
448
- * Default value: 500
445
+ * @default 500
449
446
  */
450
447
  debounce?: number | string;
451
448
  /**
@@ -73,21 +73,13 @@ defineSlots<{
73
73
  error: (props: any) => any;
74
74
  }>();
75
75
 
76
- const props = withDefaults(defineProps<Props>(), {
76
+ withDefaults(defineProps<Props>(), {
77
77
  name: "Field",
78
78
  maxchars: "1024",
79
79
  });
80
80
 
81
81
  const emit = defineEmits<Emits>();
82
82
 
83
- watch(
84
- () => props.modelValue,
85
- (value) => {
86
- emit("update:modelValue", value);
87
- },
88
- );
89
-
90
- // Handle input event to propertly validate value and emit changes
91
83
  function onInput(e: Event) {
92
84
  const newValue = (e.target as HTMLInputElement).value;
93
85
  emit("update:modelValue", newValue);
@@ -1052,6 +1052,7 @@ function restoreState() {
1052
1052
  alwaysVisible: column.alwaysVisible,
1053
1053
  width: column.width,
1054
1054
  type: column.type,
1055
+ format: column.format,
1055
1056
  };
1056
1057
  }
1057
1058
  return item;