@vc-shell/framework 1.0.38 → 1.0.39

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 (142) hide show
  1. package/components/atoms/vc-badge/vc-badge.stories.ts +27 -0
  2. package/components/atoms/vc-badge/vc-badge.vue +63 -0
  3. package/components/atoms/vc-button/vc-button.stories.ts +34 -0
  4. package/components/atoms/vc-button/vc-button.vue +219 -0
  5. package/components/atoms/vc-card/vc-card.vue +137 -0
  6. package/components/atoms/vc-checkbox/vc-checkbox.stories.ts +25 -0
  7. package/components/atoms/vc-checkbox/vc-checkbox.vue +130 -0
  8. package/components/atoms/vc-col/vc-col.vue +22 -0
  9. package/components/atoms/vc-container/vc-container.stories.ts +31 -0
  10. package/components/atoms/vc-container/vc-container.vue +220 -0
  11. package/components/atoms/vc-hint/vc-hint.stories.ts +23 -0
  12. package/components/atoms/vc-hint/vc-hint.vue +11 -0
  13. package/components/atoms/vc-icon/vc-icon.stories.ts +32 -0
  14. package/components/atoms/vc-icon/vc-icon.vue +36 -0
  15. package/components/atoms/vc-image/vc-image.stories.ts +40 -0
  16. package/components/atoms/vc-image/vc-image.vue +122 -0
  17. package/components/atoms/vc-info-row/vc-info-row.vue +42 -0
  18. package/components/atoms/vc-label/vc-label.stories.ts +23 -0
  19. package/components/atoms/vc-label/vc-label.vue +49 -0
  20. package/components/atoms/vc-link/vc-link.stories.ts +30 -0
  21. package/components/atoms/vc-link/vc-link.vue +46 -0
  22. package/components/atoms/vc-loading/vc-loading.vue +30 -0
  23. package/components/atoms/vc-progress/vc-progress.stories.ts +25 -0
  24. package/components/atoms/vc-progress/vc-progress.vue +65 -0
  25. package/components/atoms/vc-row/vc-row.vue +13 -0
  26. package/components/atoms/vc-status/vc-status.stories.ts +26 -0
  27. package/components/atoms/vc-status/vc-status.vue +78 -0
  28. package/components/atoms/vc-status-icon/vc-status-icon.vue +21 -0
  29. package/components/atoms/vc-switch/vc-switch.stories.ts +27 -0
  30. package/components/atoms/vc-switch/vc-switch.vue +100 -0
  31. package/components/atoms/vc-widget/vc-widget.vue +85 -0
  32. package/components/index.ts +43 -0
  33. package/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue +103 -0
  34. package/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.ts +39 -0
  35. package/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue +21 -0
  36. package/components/molecules/vc-editor/vc-editor.vue +117 -0
  37. package/components/molecules/vc-file-upload/vc-file-upload.vue +134 -0
  38. package/components/molecules/vc-form/vc-form.stories.ts +23 -0
  39. package/components/molecules/vc-form/vc-form.vue +5 -0
  40. package/components/molecules/vc-input/vc-input.stories.ts +26 -0
  41. package/components/molecules/vc-input/vc-input.vue +443 -0
  42. package/components/molecules/vc-multivalue/vc-multivalue.vue +447 -0
  43. package/components/molecules/vc-notification/vc-notification.vue +101 -0
  44. package/components/molecules/vc-pagination/vc-pagination.stories.ts +23 -0
  45. package/components/molecules/vc-pagination/vc-pagination.vue +169 -0
  46. package/components/molecules/vc-rating/vc-rating.stories.ts +23 -0
  47. package/components/molecules/vc-rating/vc-rating.vue +77 -0
  48. package/components/molecules/vc-select/vc-select.stories.ts +25 -0
  49. package/components/molecules/vc-select/vc-select.vue +402 -0
  50. package/components/molecules/vc-slider/vc-slider.vue +106 -0
  51. package/components/molecules/vc-textarea/vc-textarea.stories.ts +23 -0
  52. package/components/molecules/vc-textarea/vc-textarea.vue +155 -0
  53. package/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +146 -0
  54. package/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/_internal/vc-app-menu-link.vue +148 -0
  55. package/components/organisms/vc-app/_internal/vc-app-menu/_internal/vc-app-menu-item/vc-app-menu-item.vue +157 -0
  56. package/components/organisms/vc-app/_internal/vc-app-menu/vc-app-menu.vue +110 -0
  57. package/components/organisms/vc-app/vc-app.stories.ts +75 -0
  58. package/components/organisms/vc-app/vc-app.vue +171 -0
  59. package/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue +126 -0
  60. package/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue +223 -0
  61. package/components/organisms/vc-blade/_internal/vc-blade-toolbar/vc-blade-toolbar.vue +67 -0
  62. package/components/organisms/vc-blade/vc-blade.stories.ts +46 -0
  63. package/components/organisms/vc-blade/vc-blade.vue +87 -0
  64. package/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +292 -0
  65. package/components/organisms/vc-gallery/_internal/vc-gallery-item/vc-gallery-item.vue +123 -0
  66. package/components/organisms/vc-gallery/_internal/vc-gallery-preview/vc-gallery-preview.vue +93 -0
  67. package/components/organisms/vc-gallery/vc-gallery.vue +186 -0
  68. package/components/organisms/vc-login-form/vc-login-form.stories.ts +55 -0
  69. package/components/organisms/vc-login-form/vc-login-form.vue +48 -0
  70. package/components/organisms/vc-popup/vc-popup.stories.ts +23 -0
  71. package/components/organisms/vc-popup/vc-popup.vue +97 -0
  72. package/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +113 -0
  73. package/components/organisms/vc-table/_internal/vc-table-counter/vc-table-counter.vue +29 -0
  74. package/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue +152 -0
  75. package/components/organisms/vc-table/_internal/vc-table-mobile-item/vc-table-mobile-item.vue +272 -0
  76. package/components/organisms/vc-table/vc-table.stories.ts +99 -0
  77. package/components/organisms/vc-table/vc-table.vue +638 -0
  78. package/core/api/index.ts +1 -0
  79. package/core/api/platform.ts +8332 -0
  80. package/core/composables/index.ts +8 -0
  81. package/core/composables/useAutosave/index.ts +57 -0
  82. package/core/composables/useFunctions/debounce.ts +18 -0
  83. package/core/composables/useFunctions/delay.ts +7 -0
  84. package/core/composables/useFunctions/index.ts +21 -0
  85. package/core/composables/useFunctions/once.ts +14 -0
  86. package/core/composables/useFunctions/sleep.ts +4 -0
  87. package/core/composables/useFunctions/throttle.ts +17 -0
  88. package/core/composables/useI18n/index.ts +28 -0
  89. package/core/composables/useLogger/index.ts +24 -0
  90. package/core/composables/useNotifications/index.ts +116 -0
  91. package/core/composables/usePermissions/index.ts +32 -0
  92. package/core/composables/useSettings/index.ts +36 -0
  93. package/core/composables/useUser/index.ts +266 -0
  94. package/core/directives/autofocus/index.ts +9 -0
  95. package/core/directives/click-outside/index.ts +21 -0
  96. package/core/directives/index.ts +4 -0
  97. package/core/directives/loading/index.ts +28 -0
  98. package/core/directives/permissions/index.ts +20 -0
  99. package/core/plugins/index.ts +1 -0
  100. package/core/plugins/validation/index.ts +2 -0
  101. package/core/plugins/validation/rules.ts +196 -0
  102. package/core/types/index.ts +92 -0
  103. package/core/utilities/camelToSnake.ts +7 -0
  104. package/core/utilities/index.ts +1 -0
  105. package/dist/core/composables/useNotifications/index.d.ts +1 -1
  106. package/dist/core/composables/useNotifications/index.d.ts.map +1 -1
  107. package/dist/core/composables/useUser/index.d.ts +2 -2
  108. package/dist/core/composables/useUser/index.d.ts.map +1 -1
  109. package/dist/core/plugins/validation/index.d.ts.map +1 -1
  110. package/dist/core/types/index.d.ts +1 -1
  111. package/dist/core/types/index.d.ts.map +1 -1
  112. package/dist/framework.js +70 -97
  113. package/dist/framework.js.map +1 -1
  114. package/dist/shared/app-switcher/composables/useAppSwitcher/index.d.ts +1 -1
  115. package/dist/shared/app-switcher/composables/useAppSwitcher/index.d.ts.map +1 -1
  116. package/dist/shared/app-switcher/index.d.ts +2 -2
  117. package/dist/shared/app-switcher/index.d.ts.map +1 -1
  118. package/dist/shared/blade-navigation/composables/useBladeNavigation/index.d.ts +1 -1
  119. package/dist/shared/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
  120. package/dist/shared/blade-navigation/types/index.d.ts +1 -1
  121. package/dist/shared/blade-navigation/types/index.d.ts.map +1 -1
  122. package/dist/style.css +1 -1
  123. package/dist/tsconfig.tsbuildinfo +1 -0
  124. package/dist/vite.config.d.ts.map +1 -1
  125. package/package.json +11 -8
  126. package/shared/app-switcher/components/index.ts +1 -0
  127. package/shared/app-switcher/components/vc-app-switcher/vc-app-switcher.vue +90 -0
  128. package/shared/app-switcher/composables/index.ts +1 -0
  129. package/shared/app-switcher/composables/useAppSwitcher/index.ts +54 -0
  130. package/shared/app-switcher/index.ts +14 -0
  131. package/shared/assets/components/assets-details/assets-details.vue +138 -0
  132. package/shared/assets/components/index.ts +1 -0
  133. package/shared/assets/index.ts +19 -0
  134. package/shared/assets/locales/en.json +29 -0
  135. package/shared/assets/locales/index.ts +2 -0
  136. package/shared/blade-navigation/components/index.ts +1 -0
  137. package/shared/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +84 -0
  138. package/shared/blade-navigation/composables/index.ts +1 -0
  139. package/shared/blade-navigation/composables/useBladeNavigation/index.ts +216 -0
  140. package/shared/blade-navigation/index.ts +15 -0
  141. package/shared/blade-navigation/types/index.ts +52 -0
  142. package/shared/index.ts +16 -0
@@ -0,0 +1,106 @@
1
+ <template>
2
+ <div class="vc-slider relative">
3
+ <swiper-component
4
+ :class="[
5
+ 'vc-slider__swiper',
6
+ {
7
+ 'overflow-visible': overflow,
8
+ 'px-[40px]': navigation,
9
+ },
10
+ ]"
11
+ :space-between="spaceBetweenSlides"
12
+ :navigation="buttonsList"
13
+ :slidesPerView="slidesPerView"
14
+ :resizeObserver="true"
15
+ >
16
+ <swiper-slide v-for="(slide, i) in slides" :key="i">
17
+ <slot :slide="slide"></slot>
18
+ </swiper-slide>
19
+ </swiper-component>
20
+ <!-- Navigation buttons-->
21
+ <div v-show="navigation">
22
+ <div class="vc-slider__prev left-0">
23
+ <slot name="prevBtn">
24
+ <div class="vc-slider__btn">
25
+ <VcIcon icon="fas fa-chevron-left"></VcIcon>
26
+ </div>
27
+ </slot>
28
+ </div>
29
+ <div class="vc-slider__next right-0">
30
+ <slot name="nextBtn">
31
+ <div class="vc-slider__btn">
32
+ <VcIcon icon="fas fa-chevron-right"></VcIcon>
33
+ </div>
34
+ </slot>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </template>
39
+
40
+ <script lang="ts" setup>
41
+ import { computed } from "vue";
42
+ import { Swiper as SwiperComponent, SwiperSlide } from "swiper/vue";
43
+ import SwiperCore, { Navigation } from "swiper";
44
+ import "swiper/swiper-bundle.min.css";
45
+ import "swiper/swiper.min.css";
46
+ import "swiper/components/navigation/navigation.min.css";
47
+ SwiperCore.use([Navigation]);
48
+
49
+ defineProps({
50
+ slides: {
51
+ type: Array,
52
+ default: () => [],
53
+ },
54
+
55
+ navigation: {
56
+ type: Boolean,
57
+ default: false,
58
+ },
59
+
60
+ overflow: {
61
+ type: Boolean,
62
+ default: false,
63
+ },
64
+
65
+ slidesPerView: {
66
+ type: String,
67
+ default: "auto",
68
+ },
69
+
70
+ spaceBetweenSlides: {
71
+ type: Number,
72
+ default: 10,
73
+ },
74
+ });
75
+
76
+ const buttonsList = computed(() => ({
77
+ nextEl: ".vc-slider__next",
78
+ prevEl: ".vc-slider__prev",
79
+ }));
80
+ </script>
81
+
82
+ <style lang="scss" scoped>
83
+ .vc-slider {
84
+ &__swiper {
85
+ .swiper-slide {
86
+ @apply w-auto;
87
+ }
88
+ }
89
+
90
+ &__next,
91
+ &__prev {
92
+ @apply absolute top-2/4 -translate-y-2/4 z-[2];
93
+
94
+ &.swiper-button-disabled .vc-slider__btn {
95
+ @apply text-[#999999];
96
+ }
97
+ }
98
+
99
+ &__btn {
100
+ @apply bg-white border border-solid border-[#eaecf2]
101
+ box-border rounded-[3px]
102
+ flex items-center justify-center
103
+ text-[#43b0e6] w-[30px] h-[30px];
104
+ }
105
+ }
106
+ </style>
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Textarea component.
3
+ * @author Iurii A Taranov <me@flanker72.ru>
4
+ */
5
+ import { Story } from "@storybook/vue3";
6
+ import VcTextarea from "./vc-textarea.vue";
7
+
8
+ export default {
9
+ title: "atoms/vc-textarea",
10
+ component: VcTextarea,
11
+ };
12
+
13
+ const Template: Story = (args) => ({
14
+ components: { VcTextarea },
15
+ setup() {
16
+ return { args };
17
+ },
18
+ template: '<vc-textarea v-bind="args"></vc-textarea>',
19
+ });
20
+
21
+ export const Textarea = Template.bind({});
22
+ Textarea.storyName = "vc-textarea";
23
+ Textarea.args = {};
@@ -0,0 +1,155 @@
1
+ <template>
2
+ <div
3
+ class="vc-textarea"
4
+ :class="{
5
+ 'vc-textarea_error': errorMessage,
6
+ 'vc-textarea_disabled': disabled,
7
+ }"
8
+ >
9
+ <!-- Textarea label -->
10
+ <VcLabel v-if="label" class="mb-2" :required="isRequired">
11
+ <span>{{ label }}</span>
12
+ <template v-if="tooltip" v-slot:tooltip>
13
+ <span v-html="tooltip"></span>
14
+ </template>
15
+ </VcLabel>
16
+
17
+ <!-- Textarea field -->
18
+ <div class="vc-textarea__field-wrapper">
19
+ <textarea
20
+ class="vc-textarea__field"
21
+ :placeholder="placeholder"
22
+ :value="modelValue"
23
+ :disabled="disabled"
24
+ @input="onInput"
25
+ :maxlength="maxchars"
26
+ ></textarea>
27
+ </div>
28
+
29
+ <slot v-if="errorMessage" name="error">
30
+ <VcHint class="vc-textarea__error">
31
+ {{ errorMessage }}
32
+ </VcHint>
33
+ </slot>
34
+ </div>
35
+ </template>
36
+
37
+ <script lang="ts" setup>
38
+ import { watch } from "vue";
39
+ import { VcLabel } from "@/components";
40
+
41
+ const props = defineProps({
42
+ placeholder: {
43
+ type: String,
44
+ default: "",
45
+ },
46
+
47
+ modelValue: {
48
+ type: String,
49
+ default: undefined,
50
+ },
51
+
52
+ isRequired: {
53
+ type: Boolean,
54
+ default: false,
55
+ },
56
+
57
+ disabled: {
58
+ type: Boolean,
59
+ default: false,
60
+ },
61
+
62
+ label: {
63
+ type: String,
64
+ default: undefined,
65
+ },
66
+
67
+ tooltip: {
68
+ type: String,
69
+ default: undefined,
70
+ },
71
+
72
+ name: {
73
+ type: String,
74
+ default: "Field",
75
+ },
76
+
77
+ maxchars: {
78
+ type: String,
79
+ default: "1024",
80
+ },
81
+
82
+ errorMessage: {
83
+ type: String,
84
+ default: undefined,
85
+ },
86
+ });
87
+
88
+ const emit = defineEmits(["update:modelValue"]);
89
+
90
+ watch(
91
+ () => props.modelValue,
92
+ (value) => {
93
+ emit("update:modelValue", value);
94
+ }
95
+ );
96
+
97
+ // Handle input event to propertly validate value and emit changes
98
+ function onInput(e: InputEvent) {
99
+ const newValue = (e.target as HTMLInputElement).value;
100
+ emit("update:modelValue", newValue);
101
+ }
102
+ </script>
103
+
104
+ <style lang="scss">
105
+ :root {
106
+ --textarea-height: 120px;
107
+ --textarea-border-color: #d3dbe9;
108
+ --textarea-border-color-error: #f14e4e;
109
+ --textarea-border-radius: 3px;
110
+ --textarea-background-color: #ffffff;
111
+ --textarea-placeholder-color: #a5a5a5;
112
+ }
113
+
114
+ .vc-textarea {
115
+ &__field-wrapper {
116
+ @apply border border-solid
117
+ border-[color:var(--textarea-border-color)]
118
+ rounded-[var(--textarea-border-radius)]
119
+ box-border
120
+ bg-[color:var(--textarea-background-color)] flex items-stretch;
121
+ }
122
+
123
+ &_error &__field-wrapper {
124
+ @apply border border-solid border-[color:var(--textarea-border-color-error)];
125
+ }
126
+
127
+ &__error {
128
+ @apply text-[color:var(--textarea-border-color-error)] mt-1 #{!important};
129
+ }
130
+
131
+ &__field {
132
+ @apply w-full resize-y box-border border-none outline-none
133
+ min-h-[var(--textarea-height)]
134
+ placeholder:text-[color:var(--textarea-placeholder-color)]
135
+ px-3 py-2;
136
+
137
+ &::-webkit-input-placeholder {
138
+ @apply text-[color:var(--textarea-placeholder-color)];
139
+ }
140
+
141
+ &::-moz-placeholder {
142
+ @apply text-[color:var(--textarea-placeholder-color)];
143
+ }
144
+
145
+ &::-ms-placeholder {
146
+ @apply text-[color:var(--textarea-placeholder-color)];
147
+ }
148
+ }
149
+
150
+ &_disabled &__field-wrapper,
151
+ &_disabled &__field {
152
+ @apply bg-[#fafafa] text-[#424242];
153
+ }
154
+ }
155
+ </style>
@@ -0,0 +1,146 @@
1
+ <template>
2
+ <div
3
+ class="relative flex items-center content-between h-[var(--app-bar-height)] bg-[color:var(--app-bar-background-color)] pl-4"
4
+ >
5
+ <slot name="appSwitcher"></slot>
6
+ <!-- Logo container for mobile devices -->
7
+ <template v-if="$isMobile.value">
8
+ <!-- Show logo on mobile dashboard -->
9
+ <img
10
+ v-if="blades.length === 0"
11
+ class="h-3/6 cursor-pointer"
12
+ :src="logo"
13
+ @click="$emit('logo:click')"
14
+ />
15
+
16
+ <!-- Show blades name when at least one blade is opened -->
17
+ <div
18
+ v-else-if="blades.length === 1"
19
+ class="overflow-ellipsis overflow-hidden whitespace-nowrap text-2xl leading-header"
20
+ >
21
+ {{ blades[0].title }}
22
+ </div>
23
+
24
+ <!-- Show back link when more than one blade is opened -->
25
+ <VcLink v-else @click="$emit('backlink:click')">
26
+ <VcIcon icon="fas fa-chevron-left" size="s"></VcIcon>
27
+ <span class="ml-2 text-lg">{{ $t("Back") }}</span>
28
+ </VcLink>
29
+ </template>
30
+
31
+ <!-- Logo container for desktop devices -->
32
+ <template v-else>
33
+ <img
34
+ class="h-3/6 cursor-pointer"
35
+ :src="logo"
36
+ @click="$emit('logo:click')"
37
+ />
38
+ <div
39
+ class="text-[color:var(--app-bar-version-color)] text-xs ml-[30px]"
40
+ @click="$emit('version:click')"
41
+ >
42
+ {{ version }}
43
+ </div>
44
+ </template>
45
+
46
+ <!-- Product name slot -->
47
+ <div
48
+ class="text-[color:var(--app-bar-product-name-color)] text-[length:var(--app-bar-product-name-size)] font-medium ml-[30px]"
49
+ v-if="$slots['productName']"
50
+ >
51
+ <slot name="productName"></slot>
52
+ </div>
53
+
54
+ <!-- Additional spacer -->
55
+ <div class="grow basis-0 basis-0"></div>
56
+
57
+ <!-- Toolbar container -->
58
+ <div class="flex h-full box-border">
59
+ <template v-for="(item, index) in buttons" :key="index">
60
+ <template v-if="item.isVisible === undefined || item.isVisible">
61
+ <!-- Draw custom component is it is passed -->
62
+ <component
63
+ v-if="item.component"
64
+ :is="item.component"
65
+ v-bind="item.bladeOptions"
66
+ :isAccent="item.isAccent"
67
+ ></component>
68
+
69
+ <!-- Otherwise draw default toolbar button -->
70
+ <div
71
+ v-else
72
+ class="relative flex items-center justify-center w-[var(--app-bar-button-width)] border-l border-solid border-[color:var(--app-bar-button-border-color)] cursor-pointer text-[color: var(--app-bar-button-color)] bg-[color:var(--app-bar-button-background-color)] transition-[color] duration-200 hover:text-[color:var(--app-bar-button-color-hover)] hover:bg-[color:var(--app-bar-button-background-color-hover)]"
73
+ :class="{ 'vc-app-bar__button_accent': item.isAccent }"
74
+ :title="item.title"
75
+ @click="$emit('button:click', item)"
76
+ >
77
+ <VcIcon
78
+ :icon="typeof item.icon === 'function' ? item.icon() : item.icon"
79
+ size="xl"
80
+ ></VcIcon>
81
+ </div>
82
+ </template>
83
+ </template>
84
+ </div>
85
+
86
+ <!-- Show menu toggler on mobile devices -->
87
+ <div
88
+ v-if="$isMobile.value"
89
+ class="text-[#319ed4] w-[var(--app-bar-button-width)] flex items-center justify-center h-full box-border"
90
+ @click="$emit('menubutton:click')"
91
+ >
92
+ <VcIcon icon="fas fa-bars"></VcIcon>
93
+ </div>
94
+ </div>
95
+ </template>
96
+
97
+ <script lang="ts" setup>
98
+ import { VcIcon } from "@/components";
99
+ import { IBladeToolbar, IBladeElement } from "@/core/types";
100
+
101
+ export interface Props {
102
+ logo: string;
103
+ version: string;
104
+ blades: IBladeElement[];
105
+ buttons: IBladeToolbar[];
106
+ }
107
+
108
+ withDefaults(defineProps<Props>(), {
109
+ logo: "",
110
+ version: "",
111
+ blades: () => [],
112
+ buttons: () => [],
113
+ });
114
+
115
+ defineEmits([
116
+ "logo:click",
117
+ "backlink:click",
118
+ "version:click",
119
+ "toolbarbutton:click",
120
+ "menubutton:click",
121
+ ]);
122
+ </script>
123
+
124
+ <style lang="scss">
125
+ :root {
126
+ --app-bar-height: 60px;
127
+ --app-bar-background-color: #ffffff;
128
+ --app-bar-button-width: 50px;
129
+ --app-bar-button-border-color: var(--app-bar-background-color);
130
+ --app-bar-button-color: #7e8e9d;
131
+ --app-bar-button-background-color: var(--app-bar-background-color);
132
+ --app-bar-button-color-hover: #34414f;
133
+ --app-bar-button-background-color-hover: var(--app-bar-background-color);
134
+ --app-bar-version-color: #838d9a;
135
+ --app-bar-product-name-color: #34414f;
136
+ --app-bar-product-name-size: 20px;
137
+ }
138
+
139
+ .vc-app-bar {
140
+ &__button {
141
+ &_accent:before {
142
+ @apply content-[""] block absolute right-3 top-[18px] w-[7px] h-[7px] bg-[#ff4a4a] rounded-full z-[1];
143
+ }
144
+ }
145
+ }
146
+ </style>
@@ -0,0 +1,148 @@
1
+ <template>
2
+ <div
3
+ class="vc-app-menu-item"
4
+ :class="[
5
+ { 'vc-app-menu-item_active': isActive && !children.length },
6
+ { 'vc-app-menu-item_no-hover': children.length },
7
+ ]"
8
+ @click="$emit('onClick')"
9
+ >
10
+ <div
11
+ class="vc-app-menu-item__handler"
12
+ :class="{ 'vc-app-menu-item__handler_enabled': !sticky }"
13
+ >
14
+ <VcIcon icon="fas fa-ellipsis-v" size="m" />
15
+ </div>
16
+ <div v-if="icon" class="vc-app-menu-item__icon">
17
+ <VcIcon :icon="icon" size="m" />
18
+ </div>
19
+ <div class="vc-app-menu-item__title">
20
+ {{ title }}
21
+ <VcIcon
22
+ class="vc-app-menu-item__title-icon"
23
+ icon="fas fa-chevron-down"
24
+ size="xs"
25
+ v-if="children.length"
26
+ ></VcIcon>
27
+ </div>
28
+ </div>
29
+ </template>
30
+ <script lang="ts" setup>
31
+ import { ExtendedComponent } from "@/shared";
32
+
33
+ export interface Props {
34
+ isActive?: boolean;
35
+ children?: ExtendedComponent;
36
+ sticky?: boolean;
37
+ icon: string;
38
+ title: string;
39
+ }
40
+
41
+ export interface Emits {
42
+ (event: "onClick"): void;
43
+ }
44
+
45
+ withDefaults(defineProps<Props>(), {
46
+ isActive: false,
47
+ children: () => ({}),
48
+ sticky: true,
49
+ icon: "",
50
+ title: "",
51
+ });
52
+
53
+ defineEmits<Emits>();
54
+ </script>
55
+
56
+ <style lang="scss">
57
+ :root {
58
+ --app-menu-item-height: 38px;
59
+ --app-menu-item-icon-width: 20px;
60
+ --app-menu-item-icon-color: #337599;
61
+ --app-menu-item-icon-color-active: #ffffff;
62
+ --app-menu-item-handler-width: 10px;
63
+ --app-menu-item-background-color-hover: #337599;
64
+ --app-menu-item-hover-radius: 4px;
65
+ --app-menu-item-title-color: #465769;
66
+ --app-menu-item-title-color-active: #ffffff;
67
+ --app-menu-item-handler-color: #bdd1df;
68
+ }
69
+
70
+ .vc-app-menu-item {
71
+ @apply flex items-center w-full h-[var(--app-menu-item-height)]
72
+ border-none
73
+ flex-nowrap box-border cursor-pointer relative uppercase;
74
+
75
+ &_active {
76
+ @apply bg-[color:var(--app-menu-item-background-color-hover)]
77
+ rounded-[var(--app-menu-item-hover-radius)]
78
+ before:opacity-100;
79
+ }
80
+
81
+ &__handler {
82
+ @apply w-[var(--app-menu-item-handler-width)]
83
+ text-[color:var(--app-menu-item-handler-color)]
84
+ text-center invisible shrink-0;
85
+
86
+ &_enabled {
87
+ @apply cursor-move;
88
+ }
89
+ }
90
+
91
+ &__icon {
92
+ @apply w-[var(--app-menu-item-icon-width)]
93
+ text-[color:var(--app-menu-item-icon-color)]
94
+ overflow-hidden flex
95
+ justify-center shrink-0 transition-[color] duration-200;
96
+ }
97
+
98
+ &_active &__icon {
99
+ @apply text-[color:var(--app-menu-item-icon-color-active)];
100
+ }
101
+
102
+ &__title {
103
+ @apply truncate
104
+ text-lg
105
+ font-medium
106
+ px-3
107
+ text-[color:var(--app-menu-item-title-color)]
108
+ [transition:color_0.2s_ease] [transition:opacity_0.1s_ease]
109
+ opacity-100 w-full;
110
+ }
111
+
112
+ &__title-icon {
113
+ @apply text-[color:var(--app-menu-item-icon-color)] ml-3;
114
+ }
115
+
116
+ &_active &__title {
117
+ @apply text-[color:var(--app-menu-item-title-color-active)]
118
+ font-bold;
119
+ }
120
+
121
+ &_active &__title-icon {
122
+ @apply text-[color:var(--app-menu-item-icon-color-active)];
123
+ }
124
+
125
+ &:hover {
126
+ @apply bg-[color:var(--app-menu-item-background-color-hover)]
127
+ rounded-[var(--app-menu-item-hover-radius)];
128
+ }
129
+
130
+ &:hover &__title {
131
+ @apply text-[color:var(--app-menu-item-title-color-active)];
132
+ }
133
+
134
+ &:hover &__icon {
135
+ @apply text-[color:var(--app-menu-item-icon-color-active)];
136
+ }
137
+
138
+ &:hover &__title-icon {
139
+ @apply text-[color:var(--app-menu-item-icon-color-active)];
140
+ }
141
+
142
+ &:hover &__handler {
143
+ &_enabled {
144
+ @apply invisible;
145
+ }
146
+ }
147
+ }
148
+ </style>