@vc-shell/framework 1.0.232 → 1.0.234

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 (75) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/core/types/index.ts +14 -1
  3. package/dist/core/types/index.d.ts +12 -2
  4. package/dist/core/types/index.d.ts.map +1 -1
  5. package/dist/framework.js +14813 -14535
  6. package/dist/index.css +1 -1
  7. package/dist/locales/en.json +8 -2
  8. package/dist/shared/components/notifications/components/notification-container/index.d.ts +1 -1
  9. package/dist/shared/components/user-dropdown-button/user-dropdown-button.vue.d.ts.map +1 -1
  10. package/dist/shared/modules/dynamic/components/fields/GalleryField.d.ts.map +1 -1
  11. package/dist/shared/modules/dynamic/components/fields/StatusField.d.ts.map +1 -1
  12. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts.map +1 -1
  13. package/dist/shared/modules/dynamic/types/index.d.ts +9 -4
  14. package/dist/shared/modules/dynamic/types/index.d.ts.map +1 -1
  15. package/dist/tsconfig.tsbuildinfo +1 -1
  16. package/dist/ui/components/atoms/vc-badge/vc-badge.stories.d.ts +187 -17
  17. package/dist/ui/components/atoms/vc-badge/vc-badge.stories.d.ts.map +1 -1
  18. package/dist/ui/components/atoms/vc-badge/vc-badge.vue.d.ts +19 -3
  19. package/dist/ui/components/atoms/vc-badge/vc-badge.vue.d.ts.map +1 -1
  20. package/dist/ui/components/atoms/vc-button/vc-button.stories.d.ts +91 -91
  21. package/dist/ui/components/atoms/vc-button/vc-button.vue.d.ts +1 -1
  22. package/dist/ui/components/atoms/vc-icon/vc-icon.stories.d.ts +9 -9
  23. package/dist/ui/components/atoms/vc-icon/vc-icon.vue.d.ts +1 -1
  24. package/dist/ui/components/atoms/vc-image/index.d.ts +12 -3
  25. package/dist/ui/components/atoms/vc-image/index.d.ts.map +1 -1
  26. package/dist/ui/components/atoms/vc-image/vc-image.stories.d.ts +12 -3
  27. package/dist/ui/components/atoms/vc-image/vc-image.stories.d.ts.map +1 -1
  28. package/dist/ui/components/atoms/vc-image/vc-image.vue.d.ts +5 -1
  29. package/dist/ui/components/atoms/vc-image/vc-image.vue.d.ts.map +1 -1
  30. package/dist/ui/components/atoms/vc-widget/index.d.ts +6 -0
  31. package/dist/ui/components/atoms/vc-widget/index.d.ts.map +1 -1
  32. package/dist/ui/components/atoms/vc-widget/vc-widget.stories.d.ts +6 -0
  33. package/dist/ui/components/atoms/vc-widget/vc-widget.stories.d.ts.map +1 -1
  34. package/dist/ui/components/atoms/vc-widget/vc-widget.vue.d.ts +1 -0
  35. package/dist/ui/components/atoms/vc-widget/vc-widget.vue.d.ts.map +1 -1
  36. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts +3 -3
  37. package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue.d.ts +1 -1
  38. package/dist/ui/components/molecules/vc-editor/vc-editor.vue.d.ts.map +1 -1
  39. package/dist/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/_internal/vc-app-menu-link.vue.d.ts +1 -0
  40. package/dist/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/_internal/vc-app-menu-link.vue.d.ts.map +1 -1
  41. package/dist/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/vc-app-menu-item.vue.d.ts +1 -0
  42. package/dist/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/vc-app-menu-item.vue.d.ts.map +1 -1
  43. package/dist/ui/components/organisms/vc-app/_internal/vc-app-menu/vc-app-menu.vue.d.ts.map +1 -1
  44. package/dist/ui/components/organisms/vc-app/vc-app.vue.d.ts.map +1 -1
  45. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue.d.ts +1 -1
  46. package/dist/ui/components/organisms/vc-blade/vc-blade.stories.d.ts +2 -0
  47. package/dist/ui/components/organisms/vc-blade/vc-blade.stories.d.ts.map +1 -1
  48. package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts +2 -0
  49. package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts.map +1 -1
  50. package/dist/ui/components/organisms/vc-table/_internal/vc-table-mobile-item/vc-table-mobile-item.vue.d.ts +3 -0
  51. package/dist/ui/components/organisms/vc-table/_internal/vc-table-mobile-item/vc-table-mobile-item.vue.d.ts.map +1 -1
  52. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
  53. package/package.json +4 -4
  54. package/shared/components/app-switcher/components/vc-app-switcher/vc-app-switcher.vue +1 -1
  55. package/shared/components/user-dropdown-button/user-dropdown-button.vue +11 -3
  56. package/shared/modules/dynamic/components/fields/Card.ts +1 -1
  57. package/shared/modules/dynamic/components/fields/GalleryField.ts +1 -0
  58. package/shared/modules/dynamic/components/fields/StatusField.ts +39 -3
  59. package/shared/modules/dynamic/pages/dynamic-blade-form.vue +17 -22
  60. package/shared/modules/dynamic/types/index.ts +14 -6
  61. package/ui/components/atoms/vc-badge/vc-badge.stories.ts +3 -3
  62. package/ui/components/atoms/vc-badge/vc-badge.vue +58 -10
  63. package/ui/components/atoms/vc-container/vc-container.vue +2 -2
  64. package/ui/components/atoms/vc-image/vc-image.vue +3 -1
  65. package/ui/components/atoms/vc-widget/vc-widget.vue +42 -22
  66. package/ui/components/molecules/vc-editor/vc-editor.vue +5 -1
  67. package/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +1 -1
  68. package/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/_internal/vc-app-menu-link.vue +21 -10
  69. package/ui/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/vc-app-menu-item.vue +3 -0
  70. package/ui/components/organisms/vc-app/_internal/vc-app-menu/vc-app-menu.vue +60 -9
  71. package/ui/components/organisms/vc-app/vc-app.vue +0 -1
  72. package/ui/components/organisms/vc-blade/vc-blade.vue +89 -2
  73. package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +1 -0
  74. package/ui/components/organisms/vc-table/_internal/vc-table-mobile-item/vc-table-mobile-item.vue +27 -7
  75. package/ui/components/organisms/vc-table/vc-table.vue +123 -53
@@ -1,16 +1,34 @@
1
1
  import { useI18n } from "vue-i18n";
2
- import { Component, ExtractPropTypes, computed, h, unref } from "vue";
2
+ import { Component, ExtractPropTypes, computed, h, onMounted, ref, unref, watch } from "vue";
3
3
  import componentProps from "./props";
4
4
  import { StatusSchema } from "../../types";
5
5
  import { StatusField } from "../factories";
6
6
  import { VcIcon } from "../../../../../ui/components";
7
7
  import { unrefNested } from "../../helpers/unrefNested";
8
+ import VcButton from "../../../../../ui/components/atoms/vc-button/vc-button.vue";
8
9
 
9
10
  export default {
10
11
  name: "StatusField",
11
12
  props: componentProps,
12
13
  setup(props: ExtractPropTypes<typeof componentProps> & { element: StatusSchema }) {
13
14
  const { t } = useI18n({ useScope: "global" });
15
+ const hasOverflow = ref(false);
16
+ const isExpanded = ref(false);
17
+ const contentRef = ref<HTMLElement | null>(null);
18
+
19
+ const toggle = () => {
20
+ isExpanded.value = !isExpanded.value;
21
+ };
22
+
23
+ const checkOverflow = () => {
24
+ if (contentRef.value) {
25
+ hasOverflow.value = contentRef.value.scrollHeight > 100;
26
+ }
27
+ };
28
+
29
+ onMounted(() => {
30
+ checkOverflow();
31
+ });
14
32
 
15
33
  return () => {
16
34
  const slotContent = computed(() => {
@@ -55,9 +73,27 @@ export default {
55
73
  class: "tw-mr-3",
56
74
  })
57
75
  : undefined,
58
- h("div", [
76
+ h("div", { class: "tw-flex tw-flex-col" }, [
59
77
  h("div", { class: "tw-font-bold" }, computed(() => t(props.element.title ?? "")).value),
60
- h("div", slotContent.value),
78
+ h(
79
+ "div",
80
+ {
81
+ class: {
82
+ "tw-overflow-hidden": true,
83
+ "tw-max-h-[100px] tw-line-clamp-4": !isExpanded.value,
84
+ "tw-max-h-[100%]": isExpanded.value,
85
+ },
86
+ ref: contentRef,
87
+ },
88
+ slotContent.value,
89
+ ),
90
+ hasOverflow.value
91
+ ? h(VcButton, { text: true, class: "tw-self-end", onClick: toggle }, () =>
92
+ isExpanded.value
93
+ ? t("COMPONENTS.ATOMS.VC_STATUS.SHOW_LESS")
94
+ : t("COMPONENTS.ATOMS.VC_STATUS.SHOW_MORE"),
95
+ )
96
+ : undefined,
61
97
  ]),
62
98
  ]);
63
99
  },
@@ -41,24 +41,23 @@
41
41
  ></SchemaRender>
42
42
  </VcForm>
43
43
  </div>
44
- <div
45
- v-if="bladeWidgets && bladeWidgets.length"
46
- class="item-details__widgets"
47
- >
48
- <div
49
- v-for="(item, index) in bladeWidgets"
50
- :key="index"
51
- >
52
- <component
53
- :is="item"
54
- :ref="(el: HTMLElement) => widgetsRefs.set({ component: item, el })"
55
- v-model="bladeContext"
56
- @click="setActiveWidget(item)"
57
- ></component>
58
- </div>
59
- </div>
60
44
  </div>
61
45
  </VcContainer>
46
+
47
+ <template
48
+ v-if="bladeWidgets && bladeWidgets.length"
49
+ #widgets="{ isExpanded }"
50
+ >
51
+ <component
52
+ :is="item"
53
+ v-for="(item, index) in bladeWidgets"
54
+ :key="index"
55
+ :ref="(el: HTMLElement) => widgetsRefs.set({ component: item, el })"
56
+ v-model="bladeContext"
57
+ :is-expanded="isExpanded"
58
+ @click="setActiveWidget(item)"
59
+ ></component>
60
+ </template>
62
61
  </VcBlade>
63
62
  </template>
64
63
 
@@ -387,16 +386,12 @@ defineExpose({
387
386
  @apply tw-text-[#ff4a4a] tw-mr-3;
388
387
  }
389
388
 
390
- .app_phone &__inner {
389
+ .vc-app_mobile &__inner {
391
390
  @apply tw-flex-col;
392
391
  }
393
392
 
394
- .app_phone &__content {
393
+ .vc-app_mobile &__content {
395
394
  @apply tw-border-r-0 tw-border-b tw-border-solid tw-border-b-[#eaedf3] tw-overflow-visible;
396
395
  }
397
-
398
- .app_phone &__widgets {
399
- @apply tw-flex tw-flex-row;
400
- }
401
396
  }
402
397
  </style>
@@ -156,7 +156,16 @@ export interface ListContentSchema {
156
156
  multiselect?: boolean;
157
157
  header?: boolean;
158
158
  footer?: boolean;
159
- columns?: (Omit<ITableColumns, "visible"> & {
159
+ columns?: ((
160
+ | ITableColumns
161
+ | {
162
+ visible?:
163
+ | boolean
164
+ | {
165
+ method: string;
166
+ };
167
+ }
168
+ ) & {
160
169
  id: string;
161
170
  title: string;
162
171
  sortable?: boolean;
@@ -171,11 +180,6 @@ export interface ListContentSchema {
171
180
  onCellBlur?: {
172
181
  method: string;
173
182
  };
174
- visible?:
175
- | boolean
176
- | {
177
- method: string;
178
- };
179
183
  })[];
180
184
  reorderableRows?: boolean;
181
185
  // TODO Add to documentation
@@ -762,6 +766,10 @@ export interface GallerySchema
762
766
  * @type {boolean}
763
767
  */
764
768
  hideAfterUpload?: boolean;
769
+ /**
770
+ * Custom gallery upload icon.
771
+ */
772
+ uploadIcon?: string;
765
773
  }
766
774
 
767
775
  /**
@@ -5,10 +5,10 @@ export default {
5
5
  title: "atoms/VcBadge",
6
6
  component: VcBadge,
7
7
  args: {
8
- default: "42",
8
+ content: "42",
9
9
  },
10
10
  argTypes: {
11
- default: {
11
+ content: {
12
12
  control: "text",
13
13
  },
14
14
  active: {
@@ -38,7 +38,7 @@ export default {
38
38
  const Template: StoryFn<typeof VcBadge> = (args) => ({
39
39
  components: { VcBadge },
40
40
  setup: () => ({ args }),
41
- template: `<VcBadge v-bind="args">{{args.default}}</VcBadge>`,
41
+ template: `<VcBadge v-bind="args"></VcBadge>`,
42
42
  });
43
43
 
44
44
  export const Basic = Template.bind({});
@@ -1,17 +1,28 @@
1
1
  <template>
2
2
  <div
3
- class="tw-inline-block tw-rounded-[var(--badge-border-radius)] tw-py-1 tw-px-2 tw-text-base tw-font-normal tw-bg-[color:var(--badge-background-color)] tw-text-[color:var(--badge-text-color)] tw-border tw-border-solid tw-border-[color:var(--badge-border-color)] tw-transition tw-duration-200"
3
+ class="vc-badge"
4
4
  :class="{
5
- 'tw-bg-[color:var(--badge-background-color-active)] tw-text-[color:var(--badge-text-color-active)] tw-border-[color:var(--badge-border-color-active)]':
6
- active,
7
- 'tw-cursor-pointer hover:tw-bg-[color:var(--badge-background-color-active)] hover:tw-text-[color:var(--badge-text-color-hover)] hover:tw-border-[color:var(--badge-border-color-hover)]':
8
- clickable,
9
- 'cursor-not-allowed tw-bg-[color:var(--badge-background-color-disabled)] tw-text-[color:var(--badge-text-color-disabled)] tw-border-[color:var(--badge-border-color-disabled)] hover:tw-bg-[color:var(--badge-background-color-disabled)] hover:tw-text-[color:var(--badge-text-color-disabled)] hover:tw-border-[color:var(--badge-border-color-disabled)]':
10
- disabled,
5
+ 'vc-badge--small': size === 's',
6
+ 'vc-badge--medium': size === 'm',
11
7
  }"
12
- @click="onClick"
13
8
  >
14
- <slot name="default"></slot>
9
+ <div class="tw-flex tw-relative">
10
+ <slot name="default"></slot>
11
+ <div
12
+ class="vc-badge__badge tw-absolute tw-inline-flex tw-justify-center tw-items-center tw-text-center tw-indent-0 tw-rounded-[var(--badge-border-radius)] tw-text-[13px] tw-leading-[13px] tw-font-normal tw-bg-[color:var(--badge-background-color)] tw-text-[color:var(--badge-text-color)] tw-border tw-border-solid tw-border-[color:var(--badge-border-color)] tw-transition tw-duration-200"
13
+ :class="{
14
+ 'tw-bg-[color:var(--badge-background-color-active)] tw-text-[color:var(--badge-text-color-active)] tw-border-[color:var(--badge-border-color-active)]':
15
+ active,
16
+ 'tw-cursor-pointer hover:tw-bg-[color:var(--badge-background-color-active)] hover:tw-text-[color:var(--badge-text-color-hover)] hover:tw-border-[color:var(--badge-border-color-hover)]':
17
+ clickable,
18
+ 'cursor-not-allowed tw-bg-[color:var(--badge-background-color-disabled)] tw-text-[color:var(--badge-text-color-disabled)] tw-border-[color:var(--badge-border-color-disabled)] hover:tw-bg-[color:var(--badge-background-color-disabled)] hover:tw-text-[color:var(--badge-text-color-disabled)] hover:tw-border-[color:var(--badge-border-color-disabled)]':
19
+ disabled,
20
+ }"
21
+ @click="onClick"
22
+ >
23
+ {{ content }}
24
+ </div>
25
+ </div>
15
26
  </div>
16
27
  </template>
17
28
 
@@ -20,13 +31,17 @@ export interface Props {
20
31
  active?: boolean;
21
32
  disabled?: boolean;
22
33
  clickable?: boolean;
34
+ content?: string | number;
35
+ size?: "s" | "m";
23
36
  }
24
37
 
25
38
  export interface Emits {
26
39
  (event: "click"): void;
27
40
  }
28
41
 
29
- const props = defineProps<Props>();
42
+ const props = withDefaults(defineProps<Props>(), {
43
+ size: "m",
44
+ });
30
45
 
31
46
  const emit = defineEmits<Emits>();
32
47
 
@@ -62,5 +77,38 @@ function onClick(): void {
62
77
  --badge-border-color-hover: #8fb3cc;
63
78
  --badge-border-color-active: #8fb3cc;
64
79
  --badge-border-color-disabled: #b2cbdc;
80
+
81
+ --badge-width-small: 15px;
82
+ --badge-height-small: 15px;
83
+
84
+ --badge-width-medium: 25px;
85
+ --badge-height-medium: 25px;
86
+
87
+ --badge-padding-small: 2px 5px;
88
+ --badge-padding-medium: 4px 6px;
89
+
90
+ --badge-distance-bottom-small: calc(100% - 12px);
91
+ --badge-distance-left-small: calc(100% - 12px);
92
+
93
+ --badge-distance-bottom-medium: calc(100% - 20px);
94
+ --badge-distance-left-medium: calc(100% - 20px);
95
+ }
96
+
97
+ $sizes: small, medium;
98
+
99
+ @each $size in $sizes {
100
+ .vc-badge {
101
+ &--#{$size} {
102
+ .vc-badge__badge {
103
+ width: var(--badge-width-#{$size});
104
+ height: var(--badge-height-#{$size});
105
+ min-width: var(--badge-width-#{$size});
106
+ min-height: var(--badge-height-#{$size});
107
+ padding: var(--badge-padding-#{$size});
108
+ bottom: var(--badge-distance-bottom-#{$size});
109
+ left: var(--badge-distance-left-#{$size});
110
+ }
111
+ }
112
+ }
65
113
  }
66
114
  </style>
@@ -54,7 +54,7 @@ export interface Emits {
54
54
  (event: "scroll:ptr"): void;
55
55
  }
56
56
 
57
- defineProps<Props>();
57
+ const props = defineProps<Props>();
58
58
 
59
59
  const emit = defineEmits<Emits>();
60
60
 
@@ -77,7 +77,7 @@ const scrollTop = () => {
77
77
  };
78
78
 
79
79
  function onTouchstart(e: TouchEvent | MouseEvent) {
80
- if (refreshing.value) return;
80
+ if (refreshing.value || !props.usePtr) return;
81
81
  touching.value = true;
82
82
  touchstartY = "clientY" in e ? e.clientY : e.touches[0].clientY;
83
83
  }
@@ -21,7 +21,7 @@
21
21
  class="tw-absolute tw-w-full tw-h-full tw-flex tw-items-center tw-justify-center tw-text-[#83a3be]"
22
22
  >
23
23
  <VcIcon
24
- icon="fas fa-image"
24
+ :icon="emptyIcon"
25
25
  size="xl"
26
26
  ></VcIcon>
27
27
  </div>
@@ -41,6 +41,7 @@ export interface Props {
41
41
  src?: string;
42
42
  size?: "auto" | "xs" | "s" | "m" | "l" | "xl" | "xxl";
43
43
  background?: "cover" | "contain" | "auto";
44
+ emptyIcon?: string;
44
45
  }
45
46
 
46
47
  export interface Emits {
@@ -51,6 +52,7 @@ const props = withDefaults(defineProps<Props>(), {
51
52
  aspect: "1x1",
52
53
  size: "auto",
53
54
  background: "cover",
55
+ emptyIcon: "fas fa-image",
54
56
  });
55
57
 
56
58
  const emit = defineEmits<Emits>();
@@ -1,28 +1,47 @@
1
1
  <template>
2
- <div
3
- class="vc-widget tw-relative"
4
- :class="{ 'vc-widget_disabled': disabled }"
5
- @click="onClick"
2
+ <VcTooltip
3
+ :placement="$isDesktop.value ? 'bottom' : 'top'"
4
+ :offset="{
5
+ crossAxis: 0,
6
+ mainAxis: -10,
7
+ }"
6
8
  >
7
- <VcIcon
8
- v-if="icon"
9
- class="vc-widget__icon"
10
- :icon="icon"
11
- size="xxl"
12
- ></VcIcon>
13
9
  <div
14
- v-if="title"
15
- class="vc-widget__title"
10
+ class="vc-widget tw-relative tw-shrink-0 tw-py-4 tw-px-2"
11
+ :class="{
12
+ 'tw-w-[80px]': isExpanded,
13
+ 'vc-widget_disabled': disabled,
14
+ 'tw-w-[36px]': !isExpanded,
15
+ 'tw-w-[70px]': $isMobile.value,
16
+ }"
17
+ @click="onClick"
16
18
  >
17
- {{ title }}
19
+ <VcBadge
20
+ :content="value"
21
+ :size="isExpanded ? 'm' : 's'"
22
+ >
23
+ <div class="tw-flex tw-flex-col tw-items-center tw-justify-center">
24
+ <VcIcon
25
+ v-if="icon"
26
+ class="vc-widget__icon"
27
+ :icon="icon"
28
+ :size="isExpanded ? 'xxl' : 'l'"
29
+ ></VcIcon>
30
+ </div>
31
+ </VcBadge>
32
+ <div class="tw-truncate tw-w-full">
33
+ <div
34
+ v-if="title && isExpanded"
35
+ class="vc-widget__title tw-truncate"
36
+ >
37
+ {{ title }}
38
+ </div>
39
+ </div>
18
40
  </div>
19
- <div
20
- v-if="value !== undefined"
21
- class="vc-widget__value"
22
- >
23
- {{ value }}
24
- </div>
25
- </div>
41
+ <template #tooltip>
42
+ {{ title }}
43
+ </template>
44
+ </VcTooltip>
26
45
  </template>
27
46
 
28
47
  <script lang="ts" setup>
@@ -32,6 +51,7 @@ export interface Props {
32
51
  title?: string;
33
52
  value?: string | number;
34
53
  disabled?: boolean;
54
+ isExpanded?: boolean;
35
55
  }
36
56
 
37
57
  export interface Emits {
@@ -51,7 +71,7 @@ function onClick() {
51
71
 
52
72
  <style lang="scss">
53
73
  .vc-widget {
54
- @apply tw-flex tw-w-[100px] tw-overflow-hidden tw-p-5
74
+ @apply tw-flex tw-overflow-hidden
55
75
  tw-box-border tw-flex-col tw-items-center
56
76
  tw-justify-center tw-border-b tw-border-solid
57
77
  tw-border-b-[#eaedf3] tw-cursor-pointer tw-bg-white
@@ -70,7 +90,7 @@ function onClick() {
70
90
  }
71
91
 
72
92
  &__title {
73
- @apply tw-font-medium tw-text-sm tw-text-[#333333] tw-mt-3 tw-mb-1 tw-mx-0 tw-text-center;
93
+ @apply tw-font-medium tw-text-sm tw-text-[#333333] tw-mt-2 tw-mx-0 tw-text-center;
74
94
  }
75
95
 
76
96
  &_disabled &__title {
@@ -168,7 +168,11 @@ function onTextChange() {
168
168
  }
169
169
 
170
170
  if (quill.value.getText().trim() !== props.modelValue?.trim()) {
171
- emit("update:modelValue", quill.value.root.innerHTML);
171
+ if (quill.value.root.innerHTML === "<p><br></p>") {
172
+ emit("update:modelValue", "");
173
+ } else {
174
+ emit("update:modelValue", quill.value.root.innerHTML);
175
+ }
172
176
  }
173
177
  }
174
178
  </script>
@@ -8,7 +8,7 @@
8
8
  <template v-if="!$isMobile.value || quantity === 0">
9
9
  <!-- Logo -->
10
10
  <img
11
- class="tw-h-1/2 tw-cursor-pointer tw-mx-3"
11
+ class="tw-h-1/2 tw-cursor-pointer tw-mx-4"
12
12
  alt="logo"
13
13
  :src="logo"
14
14
  @click="$emit('logo:click')"
@@ -3,9 +3,9 @@
3
3
  class="vc-app-menu-item"
4
4
  :class="[
5
5
  {
6
- 'vc-app-menu-item_active': isActive(url ?? '') && !children?.length,
6
+ 'vc-app-menu-item_active': isMenuItemActive,
7
7
  'vc-app-menu-item_no-hover': !children?.length,
8
- 'vc-app-menu-item_child-opened': isOpened,
8
+ 'vc-app-menu-item_child-opened': expand && isOpened,
9
9
  },
10
10
  ]"
11
11
  @click="onMenuItemClick"
@@ -28,7 +28,10 @@
28
28
  size="m"
29
29
  />
30
30
  </div>
31
- <div class="vc-app-menu-item__title tw-capitalize">
31
+ <div
32
+ v-if="expand"
33
+ class="vc-app-menu-item__title tw-capitalize"
34
+ >
32
35
  {{ title }}
33
36
  <VcIcon
34
37
  v-if="!!children?.length || false"
@@ -40,7 +43,7 @@
40
43
  </div>
41
44
  <!-- Nested menu items -->
42
45
  <div
43
- v-show="isOpened"
46
+ v-show="isOpened && expand"
44
47
  class="vc-app-menu-item__child"
45
48
  >
46
49
  <template
@@ -69,7 +72,7 @@
69
72
  </div>
70
73
  </template>
71
74
  <script lang="ts" setup>
72
- import { ref, watch } from "vue";
75
+ import { ref, watch, computed } from "vue";
73
76
  import { MenuItem } from "../../../../../../../../../core/types";
74
77
  import { VcIcon } from "./../../../../../../../";
75
78
  import { useRoute } from "vue-router";
@@ -80,6 +83,7 @@ export interface Props {
80
83
  icon: string;
81
84
  title?: string;
82
85
  url?: string;
86
+ expand?: boolean;
83
87
  }
84
88
 
85
89
  export interface Emits {
@@ -96,6 +100,12 @@ const isOpened = ref(false);
96
100
  const route = useRoute();
97
101
  const params = Object.fromEntries(Object.entries(route.params).filter(([key]) => key !== "pathMatch"));
98
102
 
103
+ const isMenuItemActive = computed(
104
+ () =>
105
+ (isActive(props.url ?? "") && !props.children?.length) ||
106
+ (!props.expand && isOpened.value && props.children?.some((x) => isActive(x.url ?? ""))),
107
+ );
108
+
99
109
  watch(
100
110
  () => route.path,
101
111
  () => {
@@ -128,7 +138,9 @@ const isActive = (url: string) => {
128
138
  }
129
139
 
130
140
  return active;
131
- } else return false;
141
+ } else {
142
+ return false;
143
+ }
132
144
  };
133
145
  </script>
134
146
 
@@ -182,10 +194,9 @@ const isActive = (url: string) => {
182
194
  }
183
195
 
184
196
  &__icon {
185
- @apply tw-w-[var(--app-menu-item-icon-width)]
186
- tw-text-[color:var(--app-menu-item-icon-color)]
197
+ @apply tw-text-[color:var(--app-menu-item-icon-color)]
187
198
  tw-overflow-hidden tw-flex
188
- tw-justify-center tw-shrink-0 tw-transition-[color] tw-duration-200;
199
+ tw-justify-center tw-shrink-0 tw-transition-[color] tw-duration-200 tw-pr-[7px];
189
200
  }
190
201
 
191
202
  &_active &__icon {
@@ -196,7 +207,7 @@ const isActive = (url: string) => {
196
207
  @apply tw-truncate
197
208
  tw-text-lg
198
209
  tw-font-medium
199
- tw-px-2
210
+ tw-pr-2
200
211
  tw-text-[color:var(--app-menu-item-title-color)]
201
212
  [transition:color_0.2s_ease]
202
213
  tw-opacity-100 tw-w-full tw-flex tw-justify-between tw-items-center;
@@ -11,6 +11,7 @@
11
11
  :icon="icon ?? ''"
12
12
  :title="title ?? ''"
13
13
  :url="url"
14
+ :expand="expand"
14
15
  @on-click="$emit('click')"
15
16
  />
16
17
  </router-link>
@@ -22,6 +23,7 @@
22
23
  :sticky="sticky"
23
24
  :icon="icon ?? ''"
24
25
  :title="title ?? ''"
26
+ :expand="expand"
25
27
  @on-click="$emit('click', $event)"
26
28
  />
27
29
  </template>
@@ -39,6 +41,7 @@ export interface Props {
39
41
  icon?: string;
40
42
  title?: string;
41
43
  children?: MenuItem[];
44
+ expand?: boolean;
42
45
  }
43
46
 
44
47
  export interface Emits {