-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1547 from EnergySage/CED-1851-create-es-skeleton
CED-1851 Create esSkeleton, SkeletonWrapper, SkeletonImg
- Loading branch information
Showing
6 changed files
with
323 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<script setup lang="ts"> | ||
const props = defineProps({ | ||
aspect: { | ||
type: String, | ||
default: '16:9', | ||
}, | ||
noAspect: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
}); | ||
const aspects = props.aspect.split(':'); | ||
const aspectRatio = computed(() => `${(parseFloat(aspects[1]) / parseFloat(aspects[0])) * 100}%`); | ||
</script> | ||
|
||
<template> | ||
<!-- if noAspect is set, pass along to esSkeleton with all other props --> | ||
<es-skeleton | ||
v-if="noAspect" | ||
v-bind="$attrs" /> | ||
<!-- if setting the aspect ratio, wrap skeleton in containers to determine responsive size --> | ||
<!-- based on Bootstrap Aspect --> | ||
<div | ||
v-else | ||
class="d-flex"> | ||
<div | ||
class="flex-grow-1" | ||
:style="{ 'padding-bottom': aspectRatio, height: '0px' }" /> | ||
<div | ||
class="flex-grow-1 w-100 mw-100" | ||
style="margin-left: -100%"> | ||
<es-skeleton | ||
v-bind="$attrs" | ||
class="h-100 w-100" /> | ||
</div> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<script setup lang="ts"> | ||
defineProps({ | ||
loading: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
}); | ||
</script> | ||
|
||
<template> | ||
<div> | ||
<slot | ||
v-if="loading" | ||
name="loading" /> | ||
<slot v-else /> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<script setup lang="ts"> | ||
import Skeleton from 'primevue/skeleton'; | ||
defineProps({ | ||
animation: { | ||
type: String, | ||
default: 'wave', | ||
validator: (val: string) => ['wave', 'fade', 'none'].includes(val as string), | ||
}, | ||
height: { | ||
type: String, | ||
default: '1rem', | ||
}, | ||
width: { | ||
type: String, | ||
default: 'auto', | ||
}, | ||
size: { | ||
type: String, | ||
default: null, | ||
}, | ||
}); | ||
</script> | ||
|
||
<template> | ||
<skeleton | ||
:height="size ? size : height" | ||
:width="size ? size : width" | ||
class="es-skeleton rounded-xs mb-25 bg-gray-200" | ||
:class="{ | ||
'es-skeleton-wave': animation == 'wave', | ||
'es-skeleton-fade': animation == 'fade', | ||
}" /> | ||
</template> | ||
|
||
<style lang="scss" scoped> | ||
@use '@energysage/es-ds-styles/scss/variables' as variables; | ||
@keyframes skeleton-animate-wave { | ||
0% { | ||
transform: translateX(-100%); | ||
} | ||
100% { | ||
transform: translateX(100%); | ||
} | ||
} | ||
@keyframes skeleton-animate-fade { | ||
0% { | ||
opacity: 1; | ||
} | ||
100% { | ||
opacity: 0.4; | ||
} | ||
} | ||
.es-skeleton { | ||
overflow: hidden; | ||
&-wave:after { | ||
content: ''; | ||
height: 100%; | ||
position: absolute; | ||
left: 0; | ||
right: 0; | ||
top: 0; | ||
z-index: 1; | ||
// wave animation from PrimeVue Skeleton | ||
background-image: linear-gradient( | ||
90deg, | ||
rgba(variables.$white, 0), | ||
rgba(variables.$white, 0.4), | ||
rgba(variables.$white, 0) | ||
); | ||
animation-name: skeleton-animate-wave; | ||
animation-duration: 1.2s; | ||
animation-timing-function: ease; | ||
animation-delay: 0s; | ||
animation-iteration-count: infinite; | ||
animation-direction: normal; | ||
animation-fill-mode: none; | ||
animation-play-state: running; | ||
} | ||
&-fade { | ||
// fade animation from Bootstrap Skeleton | ||
animation-name: skeleton-animate-fade; | ||
animation-duration: 0.875s; | ||
animation-timing-function: ease-in-out; | ||
animation-delay: 0s; | ||
animation-iteration-count: infinite; | ||
animation-direction: alternate; | ||
animation-fill-mode: none; | ||
animation-play-state: running; | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
<script setup lang="ts"> | ||
const loading = ref(true); | ||
const asyncTimeout = async (seconds = 3) => { | ||
const millisecondTimeout = seconds * 1000; | ||
return new Promise((resolve) => { | ||
setTimeout(resolve, millisecondTimeout); | ||
}); | ||
}; | ||
const startLoading = async () => { | ||
loading.value = true; | ||
await asyncTimeout(); | ||
loading.value = false; | ||
}; | ||
const esSkeletonProps = [ | ||
['animation', 'String', 'wave', `Options are 'wave', 'fade', or 'none'`], | ||
['height', 'String', '1rem', `Manually set height`], | ||
['width', 'String', 'auto', `Manually set width`], | ||
['size', 'String', 'null', `Manually set width and height, overriding 'height' and 'width' props`], | ||
]; | ||
const esSkeletonImgProps = [ | ||
['aspect', 'String', '16:9', `Adds a container around the skeleton image with given aspect ratio`], | ||
['noAspect', 'Boolean', 'false', `Override the default aspect ratio and height, width, or size`], | ||
...esSkeletonProps, | ||
].sort((a, b) => a[0].localeCompare(b[0])); | ||
const esSkeletonWrapperProps = [ | ||
['loading', 'Boolean', 'false', `Determines whether to show loading template or default content`], | ||
]; | ||
const { $prism } = useNuxtApp(); | ||
const compCode = ref(''); | ||
const docCode = ref(''); | ||
onMounted(async () => { | ||
if ($prism) { | ||
const compSource = await import('@energysage/es-ds-components/components/es-skeleton.vue?raw'); | ||
// eslint-disable-next-line import/no-self-import | ||
const docSource = await import('./skeleton.vue?raw'); | ||
compCode.value = $prism.normalizeCode(compSource.default); | ||
docCode.value = $prism.normalizeCode(docSource.default); | ||
$prism.highlight(); | ||
} | ||
startLoading(); | ||
}); | ||
</script> | ||
|
||
<template> | ||
<div> | ||
<h1>Skeleton</h1> | ||
<p> | ||
Extended from | ||
<nuxt-link | ||
href="https://v3.primevue.org/skeleton/" | ||
target="_blank"> | ||
PrimeVue Skeleton | ||
</nuxt-link> | ||
and | ||
<nuxt-link | ||
href="https://bootstrap-vue.org/docs/components/skeleton/" | ||
target="_blank"> | ||
Bootstrap Skeleton | ||
</nuxt-link> | ||
styles | ||
</p> | ||
|
||
<h2>Basic examples</h2> | ||
<p>Wave animation:</p> | ||
<es-row class="mb-200"> | ||
<es-col lg="6"> | ||
<es-skeleton /> | ||
<es-skeleton width="75%" /> | ||
<es-skeleton height="3rem" /> | ||
</es-col> | ||
<es-col | ||
lg="6" | ||
class="d-flex"> | ||
<es-skeleton size="5rem" /> | ||
<es-skeleton | ||
size="4rem" | ||
class="rounded-circle ml-100" /> | ||
</es-col> | ||
</es-row> | ||
|
||
<p>Fade animation:</p> | ||
<es-row class="mb-500"> | ||
<es-col lg="6"> | ||
<es-skeleton | ||
animation="fade" | ||
height="33px" | ||
width="100%" /> | ||
<es-skeleton | ||
animation="fade" | ||
height="25px" | ||
width="100%" /> | ||
</es-col> | ||
</es-row> | ||
|
||
<h2>Helper components</h2> | ||
|
||
<h3>Skeleton image</h3> | ||
<es-row class="mb-500 d-flex"> | ||
<es-col lg="6"> | ||
<es-skeleton-img /> | ||
</es-col> | ||
<es-col lg="6"> | ||
<es-skeleton-img aspect="3:1" /> | ||
</es-col> | ||
<es-col | ||
cols="12" | ||
class="mt-100"> | ||
<es-skeleton-img | ||
no-aspect | ||
height="5rem" /> | ||
</es-col> | ||
</es-row> | ||
|
||
<h3>Skeleton wrapper</h3> | ||
<es-row class="mb-500 d-flex"> | ||
<es-col | ||
cols="12" | ||
lg="3" | ||
class="mb-100 mb-lg-0"> | ||
<es-button @click="startLoading()">Reload content</es-button> | ||
</es-col> | ||
<es-col | ||
lg="7" | ||
class="ml-lg-100"> | ||
<es-skeleton-wrapper :loading="loading"> | ||
<template #loading> | ||
<es-skeleton width="85%"></es-skeleton> | ||
<es-skeleton width="55%"></es-skeleton> | ||
</template> | ||
|
||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas viverra nunc sapien, non | ||
rhoncus elit tincidunt vitae. | ||
</p> | ||
</es-skeleton-wrapper> | ||
</es-col> | ||
</es-row> | ||
|
||
<div class="my-500"> | ||
<h2>EsSkeleton props</h2> | ||
<ds-prop-table :rows="esSkeletonProps" /> | ||
</div> | ||
|
||
<div class="my-500"> | ||
<h2>EsSkeletonImg props</h2> | ||
<ds-prop-table :rows="esSkeletonImgProps" /> | ||
</div> | ||
|
||
<div class="my-500"> | ||
<h2>EsSkeletonWrapper props</h2> | ||
<ds-prop-table :rows="esSkeletonWrapperProps" /> | ||
</div> | ||
|
||
<ds-doc-source | ||
:comp-code="compCode" | ||
comp-source="es-ds-components/components/es-skeleton.vue" | ||
:doc-code="docCode" | ||
doc-source="es-ds-docs/pages/molecules/skeleton.vue" /> | ||
</div> | ||
</template> |