Skip to content

Commit

Permalink
feat(m): add <SM> (motion) component
Browse files Browse the repository at this point in the history
  • Loading branch information
kiaking committed Nov 6, 2023
1 parent 3ab347a commit ff215d0
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 2 deletions.
56 changes: 56 additions & 0 deletions lib/components/SM.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script setup lang="ts">
import { useIntersectionObserver } from '@vueuse/core'
import { ref } from 'vue'
export interface Props {
as?: string
x?: string
y?: string
opacity?: string | number
duration?: string
delay?: string
once?: boolean
}
const props = withDefaults(defineProps<Props>(), {
as: 'div',
x: '0',
y: '0',
opacity: 1,
duration: '0.75s',
delay: '0s',
once: true
})
const target = ref<HTMLElement | null>(null)
const on = ref(false)
const { stop } = useIntersectionObserver(target, ([{ isIntersecting }]) => {
on.value = isIntersecting
if (on.value && props.once) {
stop()
}
})
</script>

<template>
<component :is="as" class="SM" :class="{ on }" ref="target">
<slot :on="on" />
</component>
</template>

<style scoped lang="postcss">
.SM {
position: relative;
opacity: v-bind(opacity);
transform: translate(v-bind(x), v-bind(y));
transition: opacity, transform;
transition-duration: v-bind(duration);
transition-delay: v-bind(delay);
}
.SM.on {
opacity: 1;
transform: translate(0, 0);
}
</style>

Check warning on line 56 in lib/components/SM.vue

View check run for this annotation

Codecov / codecov/patch

lib/components/SM.vue#L2-L56

Added lines #L2 - L56 were not covered by tests
18 changes: 18 additions & 0 deletions lib/components/SMFade.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
import SM, { type Props as BaseProps } from './SM.vue'
export type Props = Omit<BaseProps, 'opacity'>
defineProps<Props>()
</script>

<template>
<SM
class="SMFade"
opacity="0"
v-bind="$props"
v-slot="{ on }"
>
<slot :on="on" />
</SM>
</template>

Check warning on line 18 in lib/components/SMFade.vue

View check run for this annotation

Codecov / codecov/patch

lib/components/SMFade.vue#L2-L18

Added lines #L2 - L18 were not covered by tests
66 changes: 66 additions & 0 deletions stories/components/SM.01_Playground.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<script setup lang="ts">
import SM from 'sefirot/components/SM.vue'
const title = 'Components / SM / 01. Playground'
const docs = '/components/m'
function state() {
return {
opacity: 0,
x: '16px',
y: '0',
duration: '0.75s',
delay: '0s',
once: true
}
}
</script>

<template>
<Story :title="title" :init-state="state" source="Not available" auto-props-disabled>
<template #controls="{ state }">
<HstText
title="opacity"
v-model="state.opacity"
/>
<HstText
title="x"
v-model="state.x"
/>
<HstText
title="y"
v-model="state.y"
/>
<HstText
title="duration"
v-model="state.duration"
/>
<HstText
title="delay"
v-model="state.delay"
/>
<HstCheckbox
title="once"
v-model="state.once"
/>
</template>

<template #default="{ state }">
<Board :title="title" :docs="docs">
<div>Scroll down to see animation.</div>
<div v-for="i in [...Array(5).keys()]" :key="i" class="py-256">
<SM
:opacity="state.opacity"
:x="state.x"
:y="state.y"
:duration="state.duration"
:delay="state.delay"
:once="state.once"
>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</SM>
</div>
</Board>
</template>
</Story>
</template>
60 changes: 60 additions & 0 deletions stories/components/SM.02_Presets_SMFade.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<script setup lang="ts">
import SMFade from 'sefirot/components/SMFade.vue'
const title = 'Components / SM / 02. Presets: SMFade'
const docs = '/components/m'
function state() {
return {
x: '16px',
y: '0',
duration: '0.75s',
delay: '0s',
once: true
}
}
</script>

<template>
<Story :title="title" :init-state="state" source="Not available" auto-props-disabled>
<template #controls="{ state }">
<HstText
title="x"
v-model="state.x"
/>
<HstText
title="y"
v-model="state.y"
/>
<HstText
title="duration"
v-model="state.duration"
/>
<HstText
title="delay"
v-model="state.delay"
/>
<HstCheckbox
title="once"
v-model="state.once"
/>
</template>

<template #default="{ state }">
<Board :title="title" :docs="docs">
<div>Scroll down to see animation.</div>
<div v-for="i in [...Array(5).keys()]" :key="i" class="py-256">
<SMFade
:x="state.x"
:y="state.y"
:duration="state.duration"
:delay="state.delay"
:once="state.once"
>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</SMFade>
</div>
</Board>
</template>
</Story>
</template>
10 changes: 8 additions & 2 deletions stories/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,14 @@ body {

.rounded-6 { border-radius: 6px; }

.p-8 { padding: 8px; }
.p-12 { padding: 12px; }
.p-8 { padding: 8px; }
.p-12 { padding: 12px; }
.p-256 { padding: 256px; }

.py-256 { padding: 256px 0 256px; }

.pt-256 { padding-top: 256px; }
.pt-512 { padding-top: 512px; }

.flex {
display: flex;
Expand Down

0 comments on commit ff215d0

Please sign in to comment.