@vc-shell/framework 1.1.29 → 1.1.31

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 (109) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/core/composables/useErrorHandler/index.ts +28 -36
  3. package/core/composables/useLanguages/index.ts +1 -0
  4. package/core/services/settings-menu-service.ts +6 -6
  5. package/core/utilities/error.ts +89 -0
  6. package/dist/core/composables/useErrorHandler/index.d.ts +10 -1
  7. package/dist/core/composables/useErrorHandler/index.d.ts.map +1 -1
  8. package/dist/core/composables/useLanguages/index.d.ts.map +1 -1
  9. package/dist/core/services/settings-menu-service.d.ts +3 -3
  10. package/dist/core/services/settings-menu-service.d.ts.map +1 -1
  11. package/dist/core/utilities/error.d.ts +13 -0
  12. package/dist/core/utilities/error.d.ts.map +1 -0
  13. package/dist/framework.js +138 -134
  14. package/dist/{index-Bpzd_lmX.js → index-0JXtGXkU.js} +1 -1
  15. package/dist/{index-DJxEdMUZ.js → index-B4vlCcFR.js} +1 -1
  16. package/dist/{index-Bn87vMP8.js → index-Bo-tMcwW.js} +1 -1
  17. package/dist/{index-CM7z23lM.js → index-Bxzy9NzM.js} +1 -1
  18. package/dist/{index-BhEc39Bx.js → index-C0HMg87C.js} +1 -1
  19. package/dist/{index-DFp2PcZu.js → index-C34EKuYz.js} +1 -1
  20. package/dist/{index-B8e874V3.js → index-CIYNhqa0.js} +1 -1
  21. package/dist/{index-CK1ZmJzV.js → index-D2ktcdHl.js} +30374 -30127
  22. package/dist/{index-CR9ZPpuz.js → index-DKAEB9Q6.js} +1 -1
  23. package/dist/{index-BeTy-tH8.js → index-DWkmlYj4.js} +1 -1
  24. package/dist/{index-Cl-FWJ0z.js → index-Dxs7WOw2.js} +1 -1
  25. package/dist/{index-sElVLLwP.js → index-NFZ0riWN.js} +1 -1
  26. package/dist/{index-BerVe4OV.js → index-W3dvhLJ3.js} +1 -1
  27. package/dist/{index-C-pBZXky.js → index-Yu2Xrty9.js} +1 -1
  28. package/dist/{index-AgS-u96H.js → index-jKOJ5dxS.js} +1 -1
  29. package/dist/{index-HFn5nMnu.js → index-lJ-eV6nh.js} +1 -1
  30. package/dist/{index-NX-Ek0LQ.js → index-uOSH3WBg.js} +1 -1
  31. package/dist/index.css +1 -1
  32. package/dist/locales/de.json +1 -1
  33. package/dist/locales/en.json +1 -1
  34. package/dist/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue.d.ts.map +1 -1
  35. package/dist/shared/components/blade-navigation/components/vc-blade-view/vc-blade-view.d.ts +3 -2
  36. package/dist/shared/components/blade-navigation/components/vc-blade-view/vc-blade-view.d.ts.map +1 -1
  37. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts +2 -0
  38. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
  39. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeState.d.ts +2 -0
  40. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeState.d.ts.map +1 -1
  41. package/dist/shared/components/blade-navigation/types/index.d.ts +3 -2
  42. package/dist/shared/components/blade-navigation/types/index.d.ts.map +1 -1
  43. package/dist/shared/components/draggable-dashboard/composables/useDashboardDragAndDrop.d.ts +18 -363
  44. package/dist/shared/components/draggable-dashboard/composables/useDashboardDragAndDrop.d.ts.map +1 -1
  45. package/dist/shared/components/error-interceptor/interceptor.d.ts +7 -4
  46. package/dist/shared/components/error-interceptor/interceptor.d.ts.map +1 -1
  47. package/dist/shared/components/index.d.ts +1 -0
  48. package/dist/shared/components/index.d.ts.map +1 -1
  49. package/dist/shared/components/multilanguage-selector/index.d.ts +2 -0
  50. package/dist/shared/components/multilanguage-selector/index.d.ts.map +1 -0
  51. package/dist/shared/components/multilanguage-selector/multilanguage-selector.vue.d.ts +43 -0
  52. package/dist/shared/components/multilanguage-selector/multilanguage-selector.vue.d.ts.map +1 -0
  53. package/dist/shared/composables/index.d.ts +1 -0
  54. package/dist/shared/composables/index.d.ts.map +1 -1
  55. package/dist/shared/composables/useModificationTracker/index.d.ts +34 -0
  56. package/dist/shared/composables/useModificationTracker/index.d.ts.map +1 -0
  57. package/dist/shared/index.d.ts +1 -0
  58. package/dist/shared/index.d.ts.map +1 -1
  59. package/dist/tsconfig.tsbuildinfo +1 -1
  60. package/dist/ui/components/atoms/index.d.ts +1 -0
  61. package/dist/ui/components/atoms/index.d.ts.map +1 -1
  62. package/dist/ui/components/atoms/vc-banner/index.d.ts +2 -0
  63. package/dist/ui/components/atoms/vc-banner/index.d.ts.map +1 -0
  64. package/dist/ui/components/atoms/vc-banner/vc-banner.vue.d.ts +25 -0
  65. package/dist/ui/components/atoms/vc-banner/vc-banner.vue.d.ts.map +1 -0
  66. package/dist/ui/components/atoms/vc-card/vc-card.vue.d.ts.map +1 -1
  67. package/dist/ui/components/molecules/vc-checkbox/vc-checkbox.vue.d.ts +1 -0
  68. package/dist/ui/components/molecules/vc-checkbox/vc-checkbox.vue.d.ts.map +1 -1
  69. package/dist/ui/components/organisms/vc-app/vc-app.vue.d.ts +1 -0
  70. package/dist/ui/components/organisms/vc-app/vc-app.vue.d.ts.map +1 -1
  71. package/dist/ui/components/organisms/vc-blade/vc-blade.backupsb.d.ts +5 -1
  72. package/dist/ui/components/organisms/vc-blade/vc-blade.backupsb.d.ts.map +1 -1
  73. package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts +3 -1
  74. package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts.map +1 -1
  75. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-body/vc-table-body.vue.d.ts +0 -1
  76. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-body/vc-table-body.vue.d.ts.map +1 -1
  77. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-row/vc-table-row.vue.d.ts +0 -1
  78. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-row/vc-table-row.vue.d.ts.map +1 -1
  79. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/vc-table-desktop-view.vue.d.ts +0 -1
  80. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/vc-table-desktop-view.vue.d.ts.map +1 -1
  81. package/dist/ui/components/organisms/vc-table/composables/useTableActions.d.ts +4 -4
  82. package/dist/ui/components/organisms/vc-table/composables/useTableActions.d.ts.map +1 -1
  83. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
  84. package/package.json +4 -4
  85. package/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +18 -18
  86. package/shared/components/blade-navigation/components/vc-blade-view/vc-blade-view.ts +5 -3
  87. package/shared/components/blade-navigation/composables/useBladeNavigation/index.ts +12 -1
  88. package/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeState.ts +34 -0
  89. package/shared/components/blade-navigation/types/index.ts +2 -1
  90. package/shared/components/draggable-dashboard/composables/useDashboardDragAndDrop.ts +17 -3
  91. package/shared/components/error-interceptor/interceptor.ts +48 -44
  92. package/shared/components/index.ts +1 -0
  93. package/shared/components/multilanguage-selector/index.ts +1 -0
  94. package/shared/components/multilanguage-selector/multilanguage-selector.vue +144 -0
  95. package/shared/composables/index.ts +2 -1
  96. package/shared/composables/useModificationTracker/index.ts +93 -0
  97. package/shared/index.ts +1 -0
  98. package/ui/components/atoms/index.ts +1 -0
  99. package/ui/components/atoms/vc-banner/index.ts +1 -0
  100. package/ui/components/atoms/vc-banner/vc-banner.vue +138 -0
  101. package/ui/components/atoms/vc-card/vc-card.vue +6 -0
  102. package/ui/components/molecules/vc-checkbox/vc-checkbox.vue +9 -3
  103. package/ui/components/organisms/vc-app/vc-app.vue +6 -1
  104. package/ui/components/organisms/vc-blade/vc-blade.vue +40 -50
  105. package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-body/vc-table-body.vue +0 -2
  106. package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-row/vc-table-row.vue +1 -2
  107. package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/vc-table-desktop-view.vue +0 -2
  108. package/ui/components/organisms/vc-table/composables/useTableActions.ts +13 -8
  109. package/ui/components/organisms/vc-table/vc-table.vue +6 -6
@@ -1,44 +1,48 @@
1
- import { useErrorHandler } from "./../../../core/composables";
2
- import { defineComponent, VNode } from "vue";
3
-
4
- export interface Props {
5
- capture?: boolean;
6
- }
7
-
8
- export interface Emits {
9
- (event: "error", value: string): void;
10
- (event: "reset"): void;
11
- }
12
-
13
- export type Slots = {
14
- slots: {
15
- default: (args: { error: string | null; reset: () => void }) => VNode[];
16
- };
17
- };
18
-
19
- export default defineComponent({
20
- name: "ErrorInterceptor",
21
- props: {
22
- capture: {
23
- default: false,
24
- type: Boolean,
25
- },
26
- },
27
- emits: {
28
- error(value: Error | string) {
29
- return (value && value instanceof Error) || typeof value === "string";
30
- },
31
- reset(): boolean {
32
- return true;
33
- },
34
- },
35
- setup(props, { slots }) {
36
- const { error, reset } = useErrorHandler(props.capture);
37
-
38
- return () =>
39
- slots.default?.({
40
- error: error.value,
41
- reset,
42
- });
43
- },
44
- });
1
+ import { useErrorHandler } from "./../../../core/composables";
2
+ import { defineComponent, VNode } from "vue";
3
+
4
+ // This is an internal type used within useErrorHandler now.
5
+ // We are re-exporting a similar structure for clarity in components that use it.
6
+ export type DisplayableError = Error & { details?: string };
7
+
8
+ export interface Props {
9
+ capture?: boolean;
10
+ }
11
+
12
+ export interface Emits {
13
+ (event: "error", value: DisplayableError): void;
14
+ (event: "reset"): void;
15
+ }
16
+
17
+ export type Slots = {
18
+ slots: {
19
+ default: (args: { error: DisplayableError | null; reset: () => void }) => VNode[];
20
+ };
21
+ };
22
+
23
+ export default defineComponent({
24
+ name: "ErrorInterceptor",
25
+ props: {
26
+ capture: {
27
+ default: false,
28
+ type: Boolean,
29
+ },
30
+ },
31
+ emits: {
32
+ error(value: Error) {
33
+ return value instanceof Error;
34
+ },
35
+ reset(): boolean {
36
+ return true;
37
+ },
38
+ },
39
+ setup(props, { slots }) {
40
+ const { error, reset } = useErrorHandler(props.capture);
41
+
42
+ return () =>
43
+ slots.default?.({
44
+ error: error.value,
45
+ reset,
46
+ });
47
+ },
48
+ });
@@ -15,3 +15,4 @@ export * from "./settings-menu-item";
15
15
  export * from "./generic-dropdown";
16
16
  export * from "./draggable-dashboard";
17
17
  export * from "./dashboard-widget-card";
18
+ export * from "./multilanguage-selector";
@@ -0,0 +1 @@
1
+ export { default as VcLanguageSelector } from "./multilanguage-selector.vue";
@@ -0,0 +1,144 @@
1
+ <template>
2
+ <div class="vc-language-selector">
3
+ <GenericDropdown
4
+ :opened="isOpened"
5
+ :items="options"
6
+ :floating="true"
7
+ placement="bottom-end"
8
+ :offset="{ mainAxis: 10, crossAxis: -15 }"
9
+ :disabled="disabled"
10
+ :empty-text="t('common.no_options', 'No options')"
11
+ :is-item-active="(item: any) => item.value === modelValue"
12
+ @item-click="onItemClick"
13
+ @update:opened="isOpened = $event"
14
+ >
15
+ <template #trigger>
16
+ <div
17
+ class="tw-flex tw-cursor-pointer tw-items-center tw-justify-center tw-bg-[--primary-100] tw-w-8 tw-h-8 tw-rounded-full hover:tw-bg-[--primary-200]"
18
+ @click="onTriggerClick"
19
+ >
20
+ <VcImage
21
+ :src="currentLanguageOption?.flag"
22
+ class="tw-w-6 tw-h-6"
23
+ empty-icon=""
24
+ />
25
+ </div>
26
+ </template>
27
+ <template #item="{ item }">
28
+ <div class="tw-flex tw-items-center tw-gap-2 tw-p-2">
29
+ <VcImage
30
+ :src="item.flag"
31
+ class="tw-w-6 tw-h-6"
32
+ empty-icon=""
33
+ />
34
+ <span class="tw-text-sm">{{ item.label }}</span>
35
+ </div>
36
+ </template>
37
+ <template #empty>
38
+ <div class="tw-p-2 tw-text-sm">
39
+ {{ t("common.no_options", "No options") }}
40
+ </div>
41
+ </template>
42
+ </GenericDropdown>
43
+ </div>
44
+ </template>
45
+
46
+ <script lang="ts" setup>
47
+ import { computed, h, ref, type PropType } from "vue";
48
+ import { VcImage } from "../../../ui/components";
49
+ import { GenericDropdown } from "../../../shared/components";
50
+ import { useI18n } from "vue-i18n";
51
+
52
+ type LanguageOption = {
53
+ value: string;
54
+ label: string;
55
+ flag?: string;
56
+ };
57
+
58
+ const props = defineProps({
59
+ options: {
60
+ type: Array as PropType<LanguageOption[]>,
61
+ default: () => [],
62
+ },
63
+ modelValue: {
64
+ type: String,
65
+ default: "",
66
+ },
67
+ disabled: {
68
+ type: Boolean,
69
+ default: false,
70
+ },
71
+ });
72
+
73
+ const emit = defineEmits(["update:modelValue"]);
74
+
75
+ const { t } = useI18n({ useScope: "global" });
76
+ const isOpened = ref(false);
77
+
78
+ const currentLanguageOption = computed(() => {
79
+ return props.options.find((option) => option.value === props.modelValue);
80
+ });
81
+
82
+ const onTriggerClick = () => {
83
+ if (props.disabled) return;
84
+ isOpened.value = !isOpened.value;
85
+ };
86
+
87
+ const onItemClick = (item: LanguageOption) => {
88
+ isOpened.value = false;
89
+ emit("update:modelValue", item.value);
90
+ };
91
+
92
+ // // We use a computed property to build the dropdown via render function `h`.
93
+ // // This is because the old implementation in `dynamic-blade-form` used this pattern,
94
+ // // and it's a powerful way to construct complex components with custom slots programmatically.
95
+ // const dropdownComponent = computed(() => {
96
+ // return h(
97
+ // GenericDropdown,
98
+ // {
99
+ // opened: isOpened.value,
100
+ // items: props.options,
101
+ // floating: true,
102
+ // placement: "bottom-end",
103
+ // offset: { mainAxis: 10, crossAxis: -15 },
104
+ // variant: "secondary",
105
+ // disabled: props.disabled,
106
+ // emptyText: t("common.no_options", "No options"),
107
+ // isItemActive: (item: any) => item.value === props.modelValue,
108
+ // onItemClick: (item: any) => {
109
+ // isOpened.value = false;
110
+ // emit("update:modelValue", item.value);
111
+ // },
112
+ // "onUpdate:opened": (state: boolean) => {
113
+ // isOpened.value = state;
114
+ // },
115
+ // },
116
+ // {
117
+ // // Custom trigger slot: a circular button with the current language's flag
118
+ // trigger: () =>
119
+ // h(
120
+ // "div",
121
+ // {
122
+ // onClick: () => {
123
+ // if (props.disabled) return;
124
+ // isOpened.value = !isOpened.value;
125
+ // },
126
+ // class: [
127
+ // "tw-flex tw-cursor-pointer tw-items-center tw-justify-center tw-bg-[--primary-100]",
128
+ // "tw-w-8 tw-h-8 tw-rounded-full hover:tw-bg-[--primary-200]",
129
+ // { "tw-cursor-not-allowed tw-opacity-50": props.disabled },
130
+ // ],
131
+ // },
132
+ // [h(VcImage, { src: currentLanguageOption.value?.flag, class: "tw-w-6 tw-h-6", emptyIcon: "" })],
133
+ // ),
134
+ // // Custom item slot: a row with the flag and language name
135
+ // item: ({ item }: { item: any }) =>
136
+ // h("div", { class: "tw-flex tw-items-center tw-gap-2 tw-p-2" }, [
137
+ // h(VcImage, { src: item.flag, class: "tw-w-6 tw-h-6", emptyIcon: "" }),
138
+ // h("span", { class: "tw-text-sm" }, item.label),
139
+ // ]),
140
+ // empty: () => h("div", { class: "tw-p-2 tw-text-sm" }, t("common.no_options", "No options")),
141
+ // },
142
+ // );
143
+ // });
144
+ </script>
@@ -1 +1,2 @@
1
- export * from "./useMenuExpanded";
1
+ export * from "./useMenuExpanded";
2
+ export * from "./useModificationTracker";
@@ -0,0 +1,93 @@
1
+ import { ref, watch, Ref, computed, DeepReadonly, unref, isRef } from "vue";
2
+ import { cloneDeep, isEqual } from "lodash-es";
3
+
4
+ /**
5
+ * Return values from useModificationTracker.
6
+ * @template T Type of the tracked value.
7
+ */
8
+ export interface UseModificationTrackerReturn<T> {
9
+ /**
10
+ * Reactive reference to the current tracked value.
11
+ * It can be changed directly or through v-model.
12
+ */
13
+ currentValue: Ref<T>;
14
+ /**
15
+ * Shows if currentValue has been modified compared to its "pristine" state.
16
+ * Read-only.
17
+ */
18
+ isModified: DeepReadonly<Ref<boolean>>;
19
+ /**
20
+ * Resets the modification state.
21
+ * The new "pristine" state will be set based on the current value of currentValue,
22
+ * or based on `newBaselineValue` if provided.
23
+ * `isModified` will become false.
24
+ * @param newBaselineValue Optional new value (or Ref) that will become "pristine".
25
+ */
26
+ resetModificationState: (newBaselineValue?: T | Ref<T>) => void;
27
+ }
28
+
29
+ /**
30
+ * Composable for tracking value changes (including deeply nested objects).
31
+ *
32
+ * @template T Type of the tracked value.
33
+ * @param initialValueProp Initial value or Ref to it.
34
+ * @returns {UseModificationTrackerReturn<T>} Object with `currentValue`, `isModified` and `resetModificationState`.
35
+ */
36
+ export function useModificationTracker<T>(initialValueProp: T | Ref<T>): UseModificationTrackerReturn<T> {
37
+ const getClonedUnreffedValue = (val: T | Ref<T>): T => cloneDeep(unref(val));
38
+
39
+ const pristineValue = ref(getClonedUnreffedValue(initialValueProp)) as Ref<T>;
40
+ const currentValue = ref(getClonedUnreffedValue(initialValueProp)) as Ref<T>;
41
+ const isModified = ref(false);
42
+
43
+ if (isRef(initialValueProp)) {
44
+ watch(
45
+ initialValueProp,
46
+ (newExternalInitialValue) => {
47
+ // When the external initialValueProp (Ref) changes,
48
+ // we need to decide if we should update currentValue.
49
+ const wasModified = !isEqual(currentValue.value, pristineValue.value);
50
+
51
+ // Always update the "pristine" value (pristineValue), to reflect the new external source.
52
+ pristineValue.value = cloneDeep(newExternalInitialValue);
53
+
54
+ // If the user has not made any changes until this point,
55
+ // we also update currentValue.
56
+ // This prevents false triggering of isModified when loading data asynchronously.
57
+ if (!wasModified) {
58
+ currentValue.value = cloneDeep(newExternalInitialValue);
59
+ }
60
+ // If the user has already made changes (wasModified = true), we do not update currentValue,
61
+ // to not overwrite their changes. isModified will remain true, because
62
+ // currentValue will now be different from the new pristineValue.
63
+ },
64
+ { deep: true }, // Deep tracking, if initialValueProp is a Ref to an object/array
65
+ );
66
+ }
67
+
68
+ watch(
69
+ [currentValue, pristineValue], // Track changes in currentValue or pristineValue
70
+ ([newCurrentVal, newPristineVal]) => {
71
+ isModified.value = !isEqual(newCurrentVal, newPristineVal);
72
+ },
73
+ { deep: true },
74
+ );
75
+
76
+ const resetModificationState = (newBaselineValueInput?: T | Ref<T>) => {
77
+ if (newBaselineValueInput !== undefined) {
78
+ const newClonedBase = getClonedUnreffedValue(newBaselineValueInput);
79
+ pristineValue.value = newClonedBase;
80
+ currentValue.value = cloneDeep(newClonedBase); // Reset currentValue to the new baseline
81
+ } else {
82
+ pristineValue.value = cloneDeep(currentValue.value);
83
+ }
84
+ // isModified will be updated by the watcher above, but for immediate synchronization you can do this:
85
+ // isModified.value = false; // This will happen automatically due to the watch on [currentValue, pristineValue]
86
+ };
87
+
88
+ return {
89
+ currentValue,
90
+ isModified: computed(() => isModified.value),
91
+ resetModificationState,
92
+ };
93
+ }
package/shared/index.ts CHANGED
@@ -20,3 +20,4 @@ export const SharedModule = {
20
20
  export * from "./modules";
21
21
  export * from "./components";
22
22
  export * from "./pages";
23
+ export * from "./composables";
@@ -17,3 +17,4 @@ export * from "./vc-video";
17
17
  export * from "./vc-widget";
18
18
  export * from "./vc-tooltip";
19
19
  export * from "./vc-skeleton";
20
+ export * from "./vc-banner";
@@ -0,0 +1 @@
1
+ export { default as VcBanner } from "./vc-banner.vue";
@@ -0,0 +1,138 @@
1
+ <template>
2
+ <div
3
+ class="vc-banner"
4
+ :class="[`vc-banner_${variant}`]"
5
+ >
6
+ <div class="vc-banner__container">
7
+ <VcIcon
8
+ v-if="icon"
9
+ :icon="icon"
10
+ :size="iconSize"
11
+ :variant="iconVariant"
12
+ class="vc-banner__icon"
13
+ />
14
+ <div class="vc-banner__wrapper">
15
+ <div class="vc-banner__title">
16
+ <slot name="title"></slot>
17
+ </div>
18
+ <div
19
+ ref="contentRef"
20
+ class="vc-banner__content"
21
+ :class="[
22
+ {
23
+ 'tw-max-h-[100px] tw-line-clamp-4': !isExpanded,
24
+ 'tw-max-h-full': isExpanded,
25
+ },
26
+ ]"
27
+ >
28
+ <slot name="default"></slot>
29
+ </div>
30
+ <div v-if="hasOverflow">
31
+ <slot
32
+ name="trigger"
33
+ :is-expanded="isExpanded"
34
+ :toggle="toggle"
35
+ >
36
+ <VcButton
37
+ class="tw-self-end"
38
+ text
39
+ @click="toggle"
40
+ >
41
+ {{ isExpanded ? $t("COMPONENTS.ATOMS.VC_BANNER.SHOW_LESS") : $t("COMPONENTS.ATOMS.VC_BANNER.SHOW_MORE") }}
42
+ </VcButton>
43
+ </slot>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ </template>
49
+ <!-- eslint-disable @typescript-eslint/no-explicit-any -->
50
+ <script lang="ts" setup>
51
+ import { onMounted, ref } from "vue";
52
+ import { VcIcon } from "..";
53
+
54
+ // TODO: Add to docs
55
+
56
+ type StatusVariant = "info" | "warning" | "danger" | "success" | "light-danger" | "info-dark" | "primary";
57
+
58
+ export interface Props {
59
+ variant?: StatusVariant;
60
+ icon?: string;
61
+ iconSize?: InstanceType<typeof VcIcon>["$props"]["size"];
62
+ iconVariant?: InstanceType<typeof VcIcon>["$props"]["variant"];
63
+ }
64
+
65
+ defineSlots<{
66
+ title: (props: any) => any;
67
+ default: (props: any) => any;
68
+ trigger: (props: any) => any;
69
+ }>();
70
+
71
+ const props = withDefaults(defineProps<Props>(), {
72
+ variant: "info",
73
+ iconSize: "xxl",
74
+ });
75
+
76
+ const contentRef = ref<HTMLDivElement>();
77
+ const isExpanded = ref(false);
78
+ const hasOverflow = ref(false);
79
+
80
+ const toggle = () => {
81
+ isExpanded.value = !isExpanded.value;
82
+ };
83
+
84
+ const checkOverflow = () => {
85
+ if (contentRef.value) {
86
+ hasOverflow.value = contentRef.value.scrollHeight > 100;
87
+ }
88
+ };
89
+
90
+ onMounted(() => {
91
+ checkOverflow();
92
+ });
93
+ </script>
94
+
95
+ <style lang="scss">
96
+ :root {
97
+ --banner-text-color: var(--neutrals-700);
98
+ }
99
+ $variants: info, warning, danger, success, light-danger, info-dark, primary;
100
+
101
+ .vc-banner {
102
+ @apply tw-whitespace-normal tw-justify-start tw-max-w-full tw-border-none;
103
+
104
+ border-radius: var(--status-border-radius-extended);
105
+ padding: var(--status-padding-extended);
106
+
107
+ @each $variant in $variants {
108
+ &.vc-banner_#{$variant} {
109
+ background-color: var(--status-#{$variant}-bg-color);
110
+ color: var(--status-#{$variant}-color);
111
+
112
+ .vc-banner__content {
113
+ color: var(--status-#{$variant}-color);
114
+ }
115
+ }
116
+ }
117
+
118
+ &__wrapper {
119
+ @apply tw-flex tw-flex-col tw-text-start;
120
+ }
121
+
122
+ &__container {
123
+ @apply tw-flex tw-flex-row tw-items-center;
124
+ }
125
+
126
+ &__title {
127
+ @apply tw-font-bold;
128
+ }
129
+
130
+ &__content {
131
+ @apply tw-overflow-hidden tw-truncate tw-text-[color:var(--banner-text-color)] tw-font-medium tw-text-xs;
132
+ }
133
+
134
+ &__icon {
135
+ @apply tw-mr-3;
136
+ }
137
+ }
138
+ </style>
@@ -36,6 +36,7 @@
36
36
  <div
37
37
  v-show="!isCollapsedInternal"
38
38
  :class="[{ 'tw-flex': fill }, 'vc-card__body']"
39
+ v-bind="$attrs"
39
40
  >
40
41
  <slot></slot>
41
42
  </div>
@@ -70,6 +71,11 @@ const props = withDefaults(defineProps<Props>(), {
70
71
 
71
72
  const emit = defineEmits<Emits>();
72
73
 
74
+ defineOptions({
75
+ name: "VcCard",
76
+ inheritAttrs: false,
77
+ });
78
+
73
79
  defineSlots<{
74
80
  default: (props?: any) => any;
75
81
  actions: (props?: any) => any;
@@ -25,7 +25,8 @@
25
25
  <label class="vc-checkbox__container">
26
26
  <input
27
27
  ref="checkboxRef"
28
- v-model="value"
28
+ v-model="model"
29
+ :value="value"
29
30
  type="checkbox"
30
31
  class="vc-checkbox__input"
31
32
  :disabled="disabled"
@@ -90,6 +91,7 @@ import { VcLabel } from "../../atoms/vc-label";
90
91
 
91
92
  export interface Props {
92
93
  modelValue: MaybeRef<boolean>;
94
+ value?: any;
93
95
  disabled?: boolean;
94
96
  required?: boolean;
95
97
  name?: string;
@@ -124,7 +126,7 @@ defineSlots<{
124
126
 
125
127
  const checkboxRef = ref<HTMLInputElement | null>(null);
126
128
 
127
- const value = computed({
129
+ const model = computed({
128
130
  get() {
129
131
  return unref(props.modelValue);
130
132
  },
@@ -134,7 +136,11 @@ const value = computed({
134
136
  });
135
137
 
136
138
  const checked = computed(() => {
137
- return value.value === props.trueValue;
139
+ const modelVal = unref(props.modelValue);
140
+ if (Array.isArray(modelVal)) {
141
+ return modelVal.includes(props.value);
142
+ }
143
+ return modelVal === props.trueValue;
138
144
  });
139
145
 
140
146
  // Managing indeterminate state
@@ -23,7 +23,10 @@
23
23
  @backlink:click="closeBlade(blades.length - 1)"
24
24
  @logo:click="openRoot"
25
25
  >
26
- <template #app-switcher>
26
+ <template
27
+ v-if="!disableAppSwitcher"
28
+ #app-switcher
29
+ >
27
30
  <slot name="app-switcher">
28
31
  <VcAppSwitcher
29
32
  :apps-list="appsList"
@@ -95,6 +98,7 @@ import { provideMenuService } from "../../../../core/composables/useMenuService"
95
98
  import { BellIcon } from "../../atoms/vc-icon/icons";
96
99
  import { provideAppBarMobileButtonsService } from "../../../../core/composables/useAppBarMobileButtons";
97
100
  import { useUserManagement } from "../../../../core/composables/useUserManagement";
101
+ import { BladeRegistryKey } from "../../../../core/composables/useBladeRegistry";
98
102
 
99
103
  export interface Props {
100
104
  isReady: boolean;
@@ -104,6 +108,7 @@ export interface Props {
104
108
  avatar?: string;
105
109
  name?: string;
106
110
  disableMenu?: boolean;
111
+ disableAppSwitcher?: boolean;
107
112
  role?: string;
108
113
  }
109
114