Files
CRM_Montzar/apps/web/src/components/skeleton/CrmSkeletonTitle.vue
T
MahdiandCursor 6c6e32e099 feat(web): adopt vuesax icons and shared skeleton loading
Replace the inline SVG icon set with the vuesax linear pack, add skeleton primitives for loading states, and keep page scroll inside the app shell.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-05 14:46:35 +03:30

56 lines
1.2 KiB
Vue

<script setup lang="ts">
import { computed, toRef } from 'vue';
import { Skeleton, theme } from 'ant-design-vue';
import { useCrmSkeletonLoading } from './context';
const ASkeletonButton = Skeleton.Button;
const props = withDefaults(
defineProps<{
loading?: boolean;
width?: string | number;
/** Typography title level approximation: 1≈38, 2≈30, 3≈24, 4≈20, 5≈16 */
level?: 1 | 2 | 3 | 4 | 5;
}>(),
{ level: 3, width: 180 },
);
const { token } = theme.useToken();
const isLoading = useCrmSkeletonLoading(toRef(props, 'loading'));
const height = computed(() => {
switch (props.level) {
case 1:
return 38;
case 2:
return 30;
case 3:
return 24;
case 4:
return 20;
default:
return 16;
}
});
const widthCss = computed(() =>
typeof props.width === 'number' ? `${props.width}px` : props.width,
);
</script>
<template>
<a-skeleton-button
v-if="isLoading"
active
:style="{
width: widthCss,
minWidth: widthCss,
height: `${height}px`,
borderRadius: `${token.borderRadiusSM}px`,
}"
/>
<div v-else :style="{ minHeight: `${height}px` }">
<slot />
</div>
</template>