Skip to content

Commit 61416b5

Browse files
authored
Merge pull request #549 from devforth/feature/AdminForth/1404/you've-made-new-loader-for-the
feat: implement CreateEditSkeleton loader component and replace Singl…
2 parents 2058b9e + 63666c4 commit 61416b5

File tree

6 files changed

+105
-2
lines changed

6 files changed

+105
-2
lines changed

adminforth/documentation/docs/tutorial/03-Customization/15-afcl.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,24 @@ Skeleton component is used to display a loading state for a component. You can u
13841384
</div>
13851385
</div>
13861386

1387+
### Skeleton input
1388+
<div class="split-screen" >
1389+
<div>
1390+
```html
1391+
<div class="flex flex-col gap-2">
1392+
<Skeleton type="input" class="w-full h-4" />
1393+
<Skeleton type="input" class="w-full h-2" />
1394+
<Skeleton type="input" class="w-full h-2" />
1395+
<Skeleton type="input" class="w-full h-2" />
1396+
<Skeleton type="input" class="w-full h-2" />
1397+
</div>
1398+
```
1399+
</div>
1400+
<div>
1401+
![Spinner](image-100.png)
1402+
</div>
1403+
</div>
1404+
13871405
### Skeleton video
13881406

13891407
<div class="split-screen" >
6.87 KB
Loading

adminforth/spa/src/afcl/Skeleton.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
<svg v-else-if="type === 'avatar'" class="me-3 animate-pulse text-lightSkeletonIconColor dark:text-darkSkeletonBackgroundColor" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
1515
<path d="M10 0a10 10 0 1 0 10 10A10.011 10.011 0 0 0 10 0Zm0 5a3 3 0 1 1 0 6 3 3 0 0 1 0-6Zm0 13a8.949 8.949 0 0 1-4.951-1.488A3.987 3.987 0 0 1 9 13h2a3.987 3.987 0 0 1 3.951 3.512A8.949 8.949 0 0 1 10 18Z"/>
1616
</svg>
17+
<div
18+
v-else-if="type === 'input'"
19+
role="input"
20+
:class="['animate-pulse bg-gray-100 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded', $attrs.class]"
21+
></div>
1722
<div v-else role="status" class="flex items-center justify-center animate-pulse bg-lightSkeletonIconColor rounded-full dark:bg-darkSkeletonBackgroundColor">
1823
<span class="sr-only">Loading...</span>
1924
</div>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<template>
2+
<div class="w-full mt-[36px]">
3+
<div class="w-full border dark:border-darkFormBorder border-gray-200 rounded-lg overflow-hidden shadow-resourseFormShadow dark:shadow-darkResourseFormShadow bg-white dark:bg-darkForm">
4+
5+
<div class="flex px-6 items-center border-b border-gray-200 dark:border-darkFormBorder bg-lightFormHeading dark:bg-darkFormHeading" style="height: 40px;">
6+
<div class="w-[208px] flex-shrink-0 pr-6 text-xs text-lightListTableHeadingText uppercase dark:text-darkListTableHeadingText font-bold">
7+
{{ $t('Field') }}
8+
</div>
9+
<div class="flex-1 text-xs text-lightListTableHeadingText uppercase dark:text-darkListTableHeadingText font-bold">
10+
{{ $t('Value') }}
11+
</div>
12+
</div>
13+
14+
<div v-for="i in 5" :key="i"
15+
class="flex items-center bg-lightForm dark:bg-darkForm border-b border-gray-100 dark:border-darkFormBorder"
16+
:style="{ height: i === 2 ? '95px' : '75px' }"
17+
>
18+
<div class="w-[208px] flex-shrink-0 px-6 flex items-center gap-1">
19+
<Skeleton class="w-24 h-[10px]" />
20+
</div>
21+
22+
<div class="flex-1 px-6">
23+
<div v-if="i === 2">
24+
<Skeleton type="input" class="h-[42px] w-[160px]" />
25+
<Skeleton class="mt-1 h-[12px] w-20" />
26+
</div>
27+
<Skeleton type="input" v-else-if="i === 4 || i === 5" class="h-[42px] w-[160px]" />
28+
<Skeleton v-else type="input" class="h-[42px] w-full" />
29+
</div>
30+
</div>
31+
32+
<div class="flex items-start bg-lightForm dark:bg-darkForm" style="height: 759px;">
33+
<div class="w-[208px] flex-shrink-0 px-6 pt-7">
34+
<Skeleton class="w-24 h-[10px]" />
35+
</div>
36+
37+
<div class="flex-1 px-6 pt-4 h-full flex flex-col">
38+
<div class="flex flex-wrap items-center gap-3 p-1.5 border border-gray-300 dark:border-gray-600 rounded-t-lg bg-gray-50 dark:bg-gray-800 w-full box-border h-[44px]">
39+
<template v-for="btn in skeletonButtons" :key="btn.id">
40+
<div class=" animate-pulse flex items-center justify-center h-8 px-1 text-gray-300 dark:text-gray-600">
41+
<component :is="btn.icon" class="w-5 h-5" />
42+
</div>
43+
<div v-if="btn.sep" class="w-px h-4 bg-gray-300 dark:bg-gray-600 mx-1"></div>
44+
</template>
45+
</div>
46+
<div class="flex-1 animate-pulse bg-white dark:bg-gray-950 border-x border-b border-gray-200 dark:border-gray-700 rounded-b-lg w-full shadow-inner"></div>
47+
<div class="h-10"></div>
48+
</div>
49+
</div>
50+
</div>
51+
</div>
52+
</template>
53+
54+
<script setup lang="ts">
55+
import { markRaw } from 'vue';
56+
import { IconExclamationCircleSolid } from '@iconify-prerendered/vue-flowbite';
57+
import {
58+
IconLinkOutline, IconCodeOutline, IconRectangleListOutline,
59+
IconOrderedListOutline, IconLetterBoldOutline, IconLetterUnderlineOutline,
60+
IconLetterItalicOutline, IconTextSlashOutline
61+
} from '@iconify-prerendered/vue-flowbite';
62+
import { IconH116Solid, IconH216Solid, IconH316Solid } from '@iconify-prerendered/vue-heroicons';
63+
import { Skeleton } from '@/afcl';
64+
65+
const skeletonButtons = [
66+
{ id: 'bold', icon: markRaw(IconLetterBoldOutline), sep: false },
67+
{ id: 'italic', icon: markRaw(IconLetterItalicOutline), sep: false },
68+
{ id: 'underline', icon: markRaw(IconLetterUnderlineOutline), sep: false },
69+
{ id: 'strike', icon: markRaw(IconTextSlashOutline), sep: true },
70+
{ id: 'h1', icon: markRaw(IconH116Solid), sep: false },
71+
{ id: 'h2', icon: markRaw(IconH216Solid), sep: false },
72+
{ id: 'h3', icon: markRaw(IconH316Solid), sep: true },
73+
{ id: 'ul', icon: markRaw(IconRectangleListOutline), sep: false },
74+
{ id: 'ol', icon: markRaw(IconOrderedListOutline), sep: false },
75+
{ id: 'link', icon: markRaw(IconLinkOutline), sep: false },
76+
{ id: 'codeBlock', icon: markRaw(IconCodeOutline), sep: false },
77+
];
78+
</script>

adminforth/spa/src/views/CreateView.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
:adminUser="coreStore.adminUser"
4343
/>
4444

45-
<SingleSkeletLoader v-if="loading"></SingleSkeletLoader>
45+
<CreateEditSkeleton v-if="loading"></CreateEditSkeleton>
4646

4747

4848
<ResourceForm
@@ -88,6 +88,7 @@ import { useI18n } from 'vue-i18n';
8888
import { type AdminForthComponentDeclaration, type AdminForthComponentDeclarationFull } from '@/types/Common.js';
8989
import { saveRecordPreparations } from '@/utils';
9090
import { Spinner } from '@/afcl'
91+
import CreateEditSkeleton from './CreateEditSkeleton.vue';
9192
9293
const isValid = ref(false);
9394
const validatingMode = ref(false);

adminforth/spa/src/views/EditView.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
:adminUser="coreStore.adminUser"
4242
/>
4343

44-
<SingleSkeletLoader v-if="loading"></SingleSkeletLoader>
44+
<CreateEditSkeleton v-if="loading"></CreateEditSkeleton>
4545

4646
<ResourceForm
4747
v-else-if="coreStore.resource"
@@ -88,6 +88,7 @@ import { type AdminForthComponentDeclaration, type AdminForthComponentDeclaratio
8888
import type { AdminForthResourceColumn } from '@/types/Back';
8989
import { scrollToInvalidField, saveRecordPreparations } from '@/utils';
9090
import { Spinner } from '@/afcl'
91+
import CreateEditSkeleton from './CreateEditSkeleton.vue';
9192
9293
const { t } = useI18n();
9394
const coreStore = useCoreStore();

0 commit comments

Comments
 (0)