@vc-shell/framework 1.0.197 → 1.0.199
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.
- package/CHANGELOG.md +26 -0
- package/core/composables/useBreadcrumbs/index.ts +15 -9
- package/core/plugins/modularity/index.ts +1 -1
- package/dist/core/composables/useBreadcrumbs/index.d.ts +1 -6
- package/dist/core/composables/useBreadcrumbs/index.d.ts.map +1 -1
- package/dist/framework.js +27636 -27362
- package/dist/index.css +1 -1
- package/dist/locales/en.json +2 -1
- package/dist/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/components/vc-blade-view/vc-blade-view.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts +1 -2
- package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/types/index.d.ts +1 -1
- package/dist/shared/components/blade-navigation/types/index.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/SchemaRender.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/Button.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/Card.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/Checkbox.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/ContentField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/CustomComponent.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/DynamicProperty.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/DynamicProperty.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/EditorField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/Fieldset.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/GalleryField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/ImageField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/InputCurrency.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/InputField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/MultivalueField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/RatingField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/SelectField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/StatusField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/SwitchField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/Table.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/TextareaField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/VideoField.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/props.d.ts +1 -1
- package/dist/shared/modules/dynamic/components/fields/storybook/Button.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/Card.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/Checkbox.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/ContentField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/EditorField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/Fieldset.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/GalleryField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/ImageField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/InputCurrency.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/InputField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/MultivalueField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/RatingField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/SelectField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/StatusField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/TextareaField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/VideoField.stories.d.ts +3 -3
- package/dist/shared/modules/dynamic/components/fields/storybook/pages/DynamicRender.d.ts +3 -3
- package/dist/shared/modules/dynamic/composables/index.d.ts +1 -0
- package/dist/shared/modules/dynamic/composables/index.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/composables/useDynamicViewsUtils/index.d.ts +10 -0
- package/dist/shared/modules/dynamic/composables/useDynamicViewsUtils/index.d.ts.map +1 -0
- package/dist/shared/modules/dynamic/factories/types/index.d.ts +14 -2
- package/dist/shared/modules/dynamic/factories/types/index.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/index.d.ts +2 -3
- package/dist/shared/modules/dynamic/index.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts +2 -1
- package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts +2 -0
- package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/components/atoms/vc-card/vc-card.stories.d.ts +26 -7
- package/dist/ui/components/atoms/vc-card/vc-card.stories.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue.d.ts +1 -0
- package/dist/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-breadcrumbs/index.d.ts +1 -13
- package/dist/ui/components/molecules/vc-breadcrumbs/index.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts +33 -0
- package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.stories.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue.d.ts +14 -0
- package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-input/vc-input.stories.d.ts +26 -7
- package/dist/ui/components/molecules/vc-input/vc-input.stories.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-input/vc-input.vue.d.ts +9 -2
- package/dist/ui/components/molecules/vc-input/vc-input.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.stories.d.ts +84 -63
- package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.stories.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts +14 -10
- package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-select/vc-select.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue.d.ts +1 -1
- package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts +3 -9
- package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts.map +1 -1
- package/dist/ui/types/index.d.ts +3 -2
- package/dist/ui/types/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +84 -38
- package/shared/components/blade-navigation/components/vc-blade-view/vc-blade-view.ts +11 -4
- package/shared/components/blade-navigation/composables/useBladeNavigation/index.ts +37 -54
- package/shared/components/blade-navigation/types/index.ts +1 -1
- package/shared/modules/assets-manager/components/assets-manager/assets-manager.vue +2 -2
- package/shared/modules/dynamic/components/fields/DynamicProperty.ts +7 -3
- package/shared/modules/dynamic/components/fields/GalleryField.ts +1 -1
- package/shared/modules/dynamic/composables/index.ts +1 -0
- package/shared/modules/dynamic/composables/useDynamicViewsUtils/index.ts +46 -0
- package/shared/modules/dynamic/factories/types/index.ts +17 -2
- package/shared/modules/dynamic/index.ts +2 -3
- package/shared/modules/dynamic/pages/dynamic-blade-form.vue +1 -0
- package/shared/modules/dynamic/pages/dynamic-blade-list.vue +7 -1
- package/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue +3 -0
- package/ui/components/molecules/vc-breadcrumbs/index.ts +1 -3
- package/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue +124 -5
- package/ui/components/molecules/vc-input/vc-input.vue +58 -18
- package/ui/components/molecules/vc-multivalue/vc-multivalue.vue +124 -83
- package/ui/components/molecules/vc-select/vc-select.vue +42 -17
- package/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +10 -14
- package/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +49 -16
- package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +1 -1
- package/ui/types/index.ts +3 -2
|
@@ -94,7 +94,7 @@ export interface BladeVNode extends VNode {
|
|
|
94
94
|
onOpen?: () => void;
|
|
95
95
|
onClose?: () => void;
|
|
96
96
|
onBeforeClose?: () => Promise<boolean | undefined>;
|
|
97
|
-
instance:
|
|
97
|
+
instance: CoreBladeExposed | undefined | null;
|
|
98
98
|
idx: number;
|
|
99
99
|
};
|
|
100
100
|
onVnodeUnmounted?: VNodeMountHook | VNodeMountHook[];
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
icon="fas fa-cloud-upload-alt"
|
|
41
41
|
class="tw-text-[100px] tw-text-[#41afe6]"
|
|
42
42
|
></VcIcon>
|
|
43
|
-
<div class="tw-m-4 tw-text-xl tw-font-medium">
|
|
43
|
+
<div class="tw-m-4 tw-text-xl tw-font-medium tw-text-center">
|
|
44
44
|
{{ t("ASSETS_MANAGER.EMPTY.UPLOAD_ASSETS") }}
|
|
45
45
|
</div>
|
|
46
46
|
<VcButton @click="toggleUploader">{{ t("ASSETS_MANAGER.EMPTY.UPLOAD") }}</VcButton>
|
|
47
47
|
</template>
|
|
48
48
|
<template v-else>
|
|
49
|
-
<div class="tw-m-4 tw-text-xl tw-font-medium">
|
|
49
|
+
<div class="tw-m-4 tw-text-xl tw-font-medium tw-text-center">
|
|
50
50
|
{{ t("ASSETS_MANAGER.EMPTY.NO_ASSETS") }}
|
|
51
51
|
</div>
|
|
52
52
|
</template>
|
|
@@ -85,17 +85,21 @@ export default {
|
|
|
85
85
|
),
|
|
86
86
|
),
|
|
87
87
|
optionsGetter: props.bladeContext.scope?.dynamicProperties?.loadDictionaries as (
|
|
88
|
-
|
|
88
|
+
propertyId: string,
|
|
89
89
|
keyword?: string | undefined,
|
|
90
90
|
locale?: string | undefined,
|
|
91
91
|
) => Promise<Record<string, any>[]>,
|
|
92
92
|
"onUpdate:model-value": (args: {
|
|
93
|
-
property: Record<string, any>;
|
|
94
93
|
value: string | Record<string, any>[];
|
|
95
94
|
dictionary?: Record<string, any>[];
|
|
96
95
|
locale?: string;
|
|
97
96
|
}) => {
|
|
98
|
-
props.bladeContext.scope?.dynamicProperties?.setPropertyValue(
|
|
97
|
+
props.bladeContext.scope?.dynamicProperties?.setPropertyValue({
|
|
98
|
+
property: prop,
|
|
99
|
+
value: args.value,
|
|
100
|
+
dictionary: args.dictionary,
|
|
101
|
+
locale: args.locale,
|
|
102
|
+
});
|
|
99
103
|
if (props.fieldContext) {
|
|
100
104
|
setModel({ context: props.fieldContext, property: props.element.property, value: internalModel.value });
|
|
101
105
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ref, WatchStopHandle, watch, onMounted, onUnmounted, getCurrentInstance, Ref } from "vue";
|
|
2
|
+
import { ListBaseBladeScope, DetailsBaseBladeScope, DetailsBladeExposed, ListBladeExposed } from "../..";
|
|
3
|
+
|
|
4
|
+
export interface IUseDynamicViewsUtils {
|
|
5
|
+
getBladeExposedData: <BladeScope extends ListBaseBladeScope | DetailsBaseBladeScope>(
|
|
6
|
+
scope: BladeScope,
|
|
7
|
+
) => BladeScope extends ListBaseBladeScope ? Ref<ListBladeExposed<BladeScope>> : Ref<DetailsBladeExposed<BladeScope>>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default () => {
|
|
11
|
+
const instance = getCurrentInstance();
|
|
12
|
+
|
|
13
|
+
function getBladeExposedData<BladeScope extends ListBaseBladeScope | DetailsBaseBladeScope>() {
|
|
14
|
+
const reactiveBlade = ref<BladeScope | null>(null);
|
|
15
|
+
|
|
16
|
+
const blade = ref(instance?.vnode);
|
|
17
|
+
|
|
18
|
+
let unwatch: WatchStopHandle | null = null;
|
|
19
|
+
|
|
20
|
+
const updateReactiveBlade = () => {
|
|
21
|
+
if (blade.value && blade.value.props?.navigation?.instance) {
|
|
22
|
+
reactiveBlade.value = blade.value.props.navigation.instance;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
unwatch = watch(blade, updateReactiveBlade, { immediate: true, deep: true });
|
|
27
|
+
|
|
28
|
+
onMounted(() => {
|
|
29
|
+
updateReactiveBlade();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
onUnmounted(() => {
|
|
33
|
+
if (unwatch) {
|
|
34
|
+
unwatch();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return reactiveBlade as unknown as BladeScope extends ListBaseBladeScope
|
|
39
|
+
? Ref<ListBladeExposed<BladeScope>>
|
|
40
|
+
: Ref<DetailsBladeExposed<BladeScope>>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
getBladeExposedData,
|
|
45
|
+
};
|
|
46
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { ComputedRef, MaybeRef, Ref, UnwrapNestedRefs } from "vue";
|
|
3
3
|
import { AsyncAction } from "../../../../../core/composables";
|
|
4
|
-
import { SettingsSchema } from "../../types";
|
|
4
|
+
import { SettingsDetails, SettingsGrid, SettingsSchema } from "../../types";
|
|
5
5
|
import { AssetsHandler, IBladeToolbar, ICommonAsset } from "../../../../../core/types";
|
|
6
6
|
import { useBladeNavigation } from "../../../../components";
|
|
7
7
|
import { FormContext } from "vee-validate";
|
|
@@ -96,7 +96,7 @@ export interface DetailsBaseBladeScope extends BaseBladeScope {
|
|
|
96
96
|
dynamicProperties?: {
|
|
97
97
|
loading: ComputedRef<boolean>;
|
|
98
98
|
loadDictionaries: (
|
|
99
|
-
|
|
99
|
+
propertyId: string,
|
|
100
100
|
keyword?: string,
|
|
101
101
|
locale?: string,
|
|
102
102
|
) => Promise<Record<string, any>[] | undefined>;
|
|
@@ -122,3 +122,18 @@ export interface ListBladeContext extends UseList<Record<string, any>[], Record<
|
|
|
122
122
|
settings: ComputedRef<SettingsSchema>;
|
|
123
123
|
selectedIds: ComputedRef<string[]>;
|
|
124
124
|
}
|
|
125
|
+
|
|
126
|
+
export interface BaseBladeExposed {
|
|
127
|
+
updateActiveWidgetCount: () => void;
|
|
128
|
+
readonly title: MaybeRef<string>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export type ListBladeExposed<Scope extends ListBaseBladeScope> = BaseBladeExposed & {
|
|
132
|
+
readonly selectedIds: string[];
|
|
133
|
+
reload: () => void;
|
|
134
|
+
readonly settings: SettingsGrid;
|
|
135
|
+
} & UnwrapNestedRefs<Scope>;
|
|
136
|
+
|
|
137
|
+
export type DetailsBladeExposed<Scope extends DetailsBaseBladeScope> = BaseBladeExposed & {
|
|
138
|
+
readonly settings: SettingsDetails;
|
|
139
|
+
} & UnwrapNestedRefs<Scope>;
|
|
@@ -171,8 +171,7 @@ export const createDynamicAppModule = (args: {
|
|
|
171
171
|
};
|
|
172
172
|
};
|
|
173
173
|
|
|
174
|
-
export * from "./pages";
|
|
175
|
-
export * from "./composables";
|
|
176
|
-
export * from "./components";
|
|
177
174
|
export * from "./factories";
|
|
178
175
|
export * from "./types";
|
|
176
|
+
export * from "./pages";
|
|
177
|
+
export { useDynamicViewsUtils } from "./composables";
|
|
@@ -262,6 +262,9 @@ const { load, remove, items, loading, pagination, query, scope } = props.composa
|
|
|
262
262
|
emit,
|
|
263
263
|
props,
|
|
264
264
|
mounted: useMounted(),
|
|
265
|
+
/**
|
|
266
|
+
* @deprecated use `useDynamicViewsUtils` instead. This will be removed in the next major version.
|
|
267
|
+
*/
|
|
265
268
|
bladeContext: {
|
|
266
269
|
settings,
|
|
267
270
|
selectedIds: computed(() => selectedIds.value),
|
|
@@ -382,7 +385,8 @@ const toolbarComputed =
|
|
|
382
385
|
[];
|
|
383
386
|
|
|
384
387
|
onBeforeMount(async () => {
|
|
385
|
-
if (props.composables)
|
|
388
|
+
if (props.composables)
|
|
389
|
+
await load({ sort: sort.value, ...query.value, ...(props.isWidgetView ? {} : getNavigationQuery()) });
|
|
386
390
|
});
|
|
387
391
|
|
|
388
392
|
watch(
|
|
@@ -658,5 +662,7 @@ defineExpose({
|
|
|
658
662
|
title,
|
|
659
663
|
updateActiveWidgetCount,
|
|
660
664
|
...toRefs(scope?.value ?? {}),
|
|
665
|
+
selectedIds,
|
|
666
|
+
settings: toValue(settings),
|
|
661
667
|
});
|
|
662
668
|
</script>
|
package/ui/components/molecules/vc-breadcrumbs/_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
class="vc-breadcrumbs-item"
|
|
4
4
|
:class="{
|
|
5
5
|
'vc-breadcrumbs-item_current': current,
|
|
6
|
+
'tw-px-1 tw-h-[var(--breadcrumbs-item-height-light)]': variant === 'light',
|
|
6
7
|
}"
|
|
7
8
|
@click="onClick"
|
|
8
9
|
>
|
|
@@ -24,6 +25,7 @@ import { VcIcon } from "./../../../../";
|
|
|
24
25
|
|
|
25
26
|
export interface Props extends Breadcrumbs {
|
|
26
27
|
current: boolean;
|
|
28
|
+
variant?: "default" | "light";
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
export interface Emits {
|
|
@@ -48,6 +50,7 @@ function onClick(): void {
|
|
|
48
50
|
<style lang="scss">
|
|
49
51
|
:root {
|
|
50
52
|
--breadcrumbs-item-height: 28px;
|
|
53
|
+
--breadcrumbs-item-height-light: 20px;
|
|
51
54
|
--breadcrumbs-item-border-color: #a1c0d4;
|
|
52
55
|
--breadcrumbs-item-border-color-hover: #8fb0c6;
|
|
53
56
|
--breadcrumbs-item-border-color-current: #838d9a;
|
|
@@ -1,26 +1,145 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
v-if="items && items.length"
|
|
4
|
+
ref="el"
|
|
4
5
|
class="tw-flex tw-items-center tw-flex-wrap tw-gap-[10px]"
|
|
5
6
|
>
|
|
6
7
|
<VcBreadcrumbsItem
|
|
7
|
-
v-
|
|
8
|
-
:
|
|
9
|
-
|
|
10
|
-
:current="
|
|
8
|
+
v-if="items.length"
|
|
9
|
+
:id="items[0]?.id"
|
|
10
|
+
:title="items[0]?.title"
|
|
11
|
+
:current="items.length === 1"
|
|
12
|
+
:variant="variant"
|
|
13
|
+
@click="items[0]?.clickHandler && items[0]?.clickHandler(items[0]?.id)"
|
|
14
|
+
>
|
|
15
|
+
</VcBreadcrumbsItem>
|
|
16
|
+
<VcIcon
|
|
17
|
+
v-if="withArrow && canExpand"
|
|
18
|
+
:icon="arrowIcon"
|
|
19
|
+
:size="arrowSize"
|
|
20
|
+
class="tw-text-[color:var(--chevron-color)]"
|
|
11
21
|
/>
|
|
22
|
+
<VcBreadcrumbsItem
|
|
23
|
+
v-if="canExpand"
|
|
24
|
+
id="Expand"
|
|
25
|
+
:current="false"
|
|
26
|
+
title="..."
|
|
27
|
+
:variant="variant"
|
|
28
|
+
@click="expand"
|
|
29
|
+
>
|
|
30
|
+
</VcBreadcrumbsItem>
|
|
31
|
+
<template
|
|
32
|
+
v-for="(item, i) in visibleBreadcrumbs"
|
|
33
|
+
:key="item?.id ?? `breadcrumb-item-${i}`"
|
|
34
|
+
>
|
|
35
|
+
<div v-if="item && item.title && item.isVisible">
|
|
36
|
+
<VcIcon
|
|
37
|
+
v-if="withArrow && i < items.length - 1"
|
|
38
|
+
:icon="arrowIcon"
|
|
39
|
+
:size="arrowSize"
|
|
40
|
+
class="tw-text-[color:var(--chevron-color)] tw-mr-[10px]"
|
|
41
|
+
/>
|
|
42
|
+
<VcBreadcrumbsItem
|
|
43
|
+
v-bind="item"
|
|
44
|
+
:current="i === items.length - 1"
|
|
45
|
+
:variant="variant"
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
</template>
|
|
12
49
|
</div>
|
|
13
50
|
</template>
|
|
14
51
|
|
|
15
52
|
<script lang="ts" setup>
|
|
16
53
|
import { Breadcrumbs } from "../../../types";
|
|
17
54
|
import VcBreadcrumbsItem from "./_internal/vc-breadcrumbs-item/vc-breadcrumbs-item.vue";
|
|
55
|
+
import { VcIcon } from "./../../atoms/vc-icon";
|
|
56
|
+
import { useElementBounding } from "@vueuse/core";
|
|
57
|
+
import { MaybeRef, Ref, computed, ref, toRefs, toValue, watch } from "vue";
|
|
58
|
+
import * as _ from "lodash-es";
|
|
18
59
|
|
|
19
60
|
export interface Props {
|
|
20
61
|
items?: Breadcrumbs[];
|
|
62
|
+
variant?: "default" | "light";
|
|
63
|
+
withArrow?: boolean;
|
|
64
|
+
arrowIcon?: string;
|
|
65
|
+
arrowSize?: InstanceType<typeof VcIcon>["$props"]["size"];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface InternalBreadcrumbs extends Breadcrumbs {
|
|
69
|
+
isVisible?: boolean;
|
|
21
70
|
}
|
|
22
71
|
|
|
23
|
-
withDefaults(defineProps<Props>(), {
|
|
72
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
24
73
|
items: () => [],
|
|
74
|
+
variant: "default",
|
|
75
|
+
arrowIcon: "fas fa-chevron-right",
|
|
76
|
+
arrowSize: "xs",
|
|
25
77
|
});
|
|
78
|
+
|
|
79
|
+
const el = ref(null);
|
|
80
|
+
const visibleBreadcrumbs = ref([]) as Ref<InternalBreadcrumbs[]>;
|
|
81
|
+
|
|
82
|
+
const { width } = useElementBounding(el);
|
|
83
|
+
|
|
84
|
+
const { items } = toRefs(props);
|
|
85
|
+
|
|
86
|
+
const canExpand = computed(
|
|
87
|
+
() =>
|
|
88
|
+
visibleBreadcrumbs.value &&
|
|
89
|
+
_.some(
|
|
90
|
+
visibleBreadcrumbs.value,
|
|
91
|
+
(breadcrumb) => !(typeof breadcrumb?.isVisible === "undefined" ? true : breadcrumb.isVisible),
|
|
92
|
+
),
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
watch(items, computeVisibleBreadcrumbs, { deep: true });
|
|
96
|
+
|
|
97
|
+
function computeVisibleBreadcrumbs(breadcrumbs: InternalBreadcrumbs[]) {
|
|
98
|
+
if (!(breadcrumbs && breadcrumbs.length)) return [];
|
|
99
|
+
|
|
100
|
+
const expanderWidth = 40;
|
|
101
|
+
const availableWidth = width.value;
|
|
102
|
+
let widthOfItems = calculateTotalWidth(breadcrumbs[0].title);
|
|
103
|
+
|
|
104
|
+
const items = _.tail(_.cloneDeep(breadcrumbs)).reverse();
|
|
105
|
+
|
|
106
|
+
for (let i = 0; i < items.length; i++) {
|
|
107
|
+
const x = items[i];
|
|
108
|
+
const elWidth = calculateTotalWidth(x.title);
|
|
109
|
+
if (widthOfItems + elWidth <= availableWidth) {
|
|
110
|
+
x.isVisible = true;
|
|
111
|
+
widthOfItems += elWidth;
|
|
112
|
+
} else {
|
|
113
|
+
if (i > 0) items[i - 1].isVisible = false;
|
|
114
|
+
widthOfItems += expanderWidth;
|
|
115
|
+
if (widthOfItems > availableWidth) break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
visibleBreadcrumbs.value = items.reverse();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function calculateTotalWidth(title: MaybeRef<string | undefined>) {
|
|
123
|
+
const unrefTitle = toValue(title);
|
|
124
|
+
if (!unrefTitle) return 0;
|
|
125
|
+
|
|
126
|
+
const paddings = 40;
|
|
127
|
+
const averageCharacterWidth = 4.87;
|
|
128
|
+
|
|
129
|
+
const wordWidth = Math.floor(unrefTitle.length * averageCharacterWidth) + paddings;
|
|
130
|
+
|
|
131
|
+
return wordWidth;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function expand() {
|
|
135
|
+
visibleBreadcrumbs.value.forEach((breadcrumb) => {
|
|
136
|
+
breadcrumb.isVisible = true;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
26
139
|
</script>
|
|
140
|
+
|
|
141
|
+
<style lang="scss">
|
|
142
|
+
:root {
|
|
143
|
+
--chevron-color: #a1c0d4;
|
|
144
|
+
}
|
|
145
|
+
</style>
|
|
@@ -54,22 +54,22 @@
|
|
|
54
54
|
name="control"
|
|
55
55
|
:editable="disabled"
|
|
56
56
|
:focused="autofocus"
|
|
57
|
-
:model-value="
|
|
57
|
+
:model-value="handleValue"
|
|
58
58
|
:emit-value="emitValue"
|
|
59
59
|
:placeholder="placeholder"
|
|
60
60
|
>
|
|
61
61
|
<input
|
|
62
62
|
ref="inputRef"
|
|
63
|
-
v-model="
|
|
63
|
+
v-model="handleValue"
|
|
64
64
|
:placeholder="placeholder"
|
|
65
|
-
:type="
|
|
65
|
+
:type="internalTypeComputed"
|
|
66
66
|
:disabled="disabled"
|
|
67
67
|
:name="name"
|
|
68
68
|
:maxlength="maxlength"
|
|
69
69
|
:autofocus="autofocus"
|
|
70
70
|
:max="maxDate"
|
|
71
71
|
class="vc-input__input"
|
|
72
|
-
@
|
|
72
|
+
@keydown="onKeyDown"
|
|
73
73
|
/>
|
|
74
74
|
</slot>
|
|
75
75
|
<div
|
|
@@ -191,7 +191,11 @@ export interface Props {
|
|
|
191
191
|
* Input type
|
|
192
192
|
* Default value: text
|
|
193
193
|
*/
|
|
194
|
-
type?: "text" | "password" | "email" | "tel" | "number" | "url" | "time" | "date" | "datetime-local";
|
|
194
|
+
type?: "text" | "password" | "email" | "tel" | "number" | "integer" | "url" | "time" | "date" | "datetime-local";
|
|
195
|
+
/**
|
|
196
|
+
* The step attribute is a number that specifies the granularity that the value must adhere to.
|
|
197
|
+
*/
|
|
198
|
+
step?: string;
|
|
195
199
|
/**
|
|
196
200
|
* Input description (hint) text below input component
|
|
197
201
|
*/
|
|
@@ -271,6 +275,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
271
275
|
type: "text",
|
|
272
276
|
name: "Field",
|
|
273
277
|
maxlength: "1024",
|
|
278
|
+
step: "1",
|
|
274
279
|
});
|
|
275
280
|
|
|
276
281
|
const emit = defineEmits<Emits>();
|
|
@@ -336,18 +341,45 @@ const inputRef = ref();
|
|
|
336
341
|
|
|
337
342
|
const internalType = ref(unref(props.type));
|
|
338
343
|
|
|
344
|
+
const internalTypeComputed = computed({
|
|
345
|
+
get() {
|
|
346
|
+
if (internalType.value === "integer") {
|
|
347
|
+
return "number";
|
|
348
|
+
}
|
|
349
|
+
return internalType.value;
|
|
350
|
+
},
|
|
351
|
+
set(value) {
|
|
352
|
+
internalType.value = value;
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
|
|
339
356
|
const maxDate = computed(() => (props.type === "date" && "9999-12-31") || undefined);
|
|
340
357
|
|
|
341
358
|
const rawModel = computed(() => unref(props.modelValue));
|
|
359
|
+
const handleValue = computed({
|
|
360
|
+
get() {
|
|
361
|
+
return props.type === "integer" || props.type === "number" ? (isNaN(temp.value) ? "" : temp.value) : temp.value;
|
|
362
|
+
},
|
|
363
|
+
set(value) {
|
|
364
|
+
temp.value = value;
|
|
365
|
+
onInput(value);
|
|
366
|
+
},
|
|
367
|
+
});
|
|
342
368
|
const mutatedModel = ref();
|
|
343
369
|
|
|
344
370
|
watch(
|
|
345
371
|
rawModel,
|
|
346
372
|
(newVal) => {
|
|
347
|
-
if (
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
373
|
+
if (props.type === "datetime-local" || props.type === "date") {
|
|
374
|
+
if (newVal instanceof Date && !isNaN(newVal.valueOf())) {
|
|
375
|
+
mutatedModel.value = moment(newVal).format(props.type === "datetime-local" ? "YYYY-MM-DDTHH:mm" : "YYYY-MM-DD");
|
|
376
|
+
} else if (typeof newVal === "string") {
|
|
377
|
+
mutatedModel.value = new Date(newVal).toISOString().slice(0, props.type === "datetime-local" ? 16 : 10);
|
|
378
|
+
}
|
|
379
|
+
} else if (props.type === "number" && newVal !== null) {
|
|
380
|
+
mutatedModel.value = parseFloat(newVal as string);
|
|
381
|
+
} else if (props.type === "integer" && newVal !== null) {
|
|
382
|
+
mutatedModel.value = Math.trunc(newVal as number);
|
|
351
383
|
} else {
|
|
352
384
|
mutatedModel.value = newVal;
|
|
353
385
|
}
|
|
@@ -359,24 +391,32 @@ watch(
|
|
|
359
391
|
{ immediate: true },
|
|
360
392
|
);
|
|
361
393
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
394
|
+
function onKeyDown(e: KeyboardEvent) {
|
|
395
|
+
const allowedKeys = ["Backspace", "Delete", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
|
|
396
|
+
const keypressed = e.key;
|
|
397
|
+
if (props.type === "integer") {
|
|
398
|
+
if (!/^\d$/.test(keypressed) && !allowedKeys.includes(keypressed)) {
|
|
399
|
+
e.preventDefault();
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
366
402
|
}
|
|
403
|
+
}
|
|
367
404
|
|
|
368
|
-
|
|
369
|
-
|
|
405
|
+
// Handle input event and emit changes
|
|
406
|
+
function onInput(value: string | number | Date | null) {
|
|
407
|
+
emitValue(value);
|
|
370
408
|
}
|
|
371
409
|
|
|
372
410
|
function emitValue(val: string | number | Date | null) {
|
|
373
411
|
emitValueFn = () => {
|
|
374
412
|
if (mutatedModel.value !== val) {
|
|
375
413
|
let value;
|
|
376
|
-
if (
|
|
414
|
+
if (internalTypeComputed.value === "datetime-local" || internalTypeComputed.value === "date") {
|
|
377
415
|
value = val ? moment(val).toDate() : undefined;
|
|
378
|
-
} else if (
|
|
379
|
-
value =
|
|
416
|
+
} else if (props.type === "number" && val !== null) {
|
|
417
|
+
value = parseFloat(val as string);
|
|
418
|
+
} else if (props.type === "integer" && val !== null) {
|
|
419
|
+
value = Math.trunc(parseInt(val as string));
|
|
380
420
|
} else {
|
|
381
421
|
value = val;
|
|
382
422
|
}
|