Skip to content

Commit b72e433

Browse files
committed
added support for Preact
1 parent 2896143 commit b72e433

File tree

12 files changed

+164
-3
lines changed

12 files changed

+164
-3
lines changed

.build.mjs

+24
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@ async function reactBuild() {
5656
await fs.writeFile(resolve(rootDir, "dist/react/index.mjs"), raw)
5757
}
5858

59+
async function preactBuild() {
60+
info("Rolling up Preact package")
61+
await execa("npx", [
62+
"rollup",
63+
"-c",
64+
"rollup.config.js",
65+
"--environment",
66+
"FRAMEWORK:preact",
67+
])
68+
/**
69+
* This is a super hack — for some reason these imports need to be explicitly
70+
* to .mjs files so...we make it so.
71+
*/
72+
let raw = await fs.readFile(resolve(rootDir, "dist/preact/index.mjs"), "utf8")
73+
raw = raw.replace("from '../index'", "from '../index.mjs'")
74+
await fs.writeFile(resolve(rootDir, "dist/preact/index.mjs"), raw)
75+
}
76+
5977
async function vueBuild() {
6078
info("Rolling up Vue package")
6179
await execa("npx", [
@@ -121,6 +139,11 @@ async function bundleDeclarations() {
121139
`${rootDir}/dist/src/react/index.d.ts`,
122140
`${rootDir}/dist/react/index.d.ts`,
123141
])
142+
await execa("shx", [
143+
"mv",
144+
`${rootDir}/dist/src/preact/index.d.ts`,
145+
`${rootDir}/dist/preact/index.d.ts`,
146+
])
124147
await execa("shx", [
125148
"mv",
126149
`${rootDir}/dist/src/vue/index.d.ts`,
@@ -218,6 +241,7 @@ await clean()
218241
await baseBuild()
219242
await baseBuildMin()
220243
await reactBuild()
244+
await preactBuild()
221245
await vueBuild()
222246
await angularBuild()
223247
await declarationsBuild()

docs/src/components/CodeExample.vue

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import IconVue from "./IconVue.vue"
33
import IconReact from "./IconReact.vue"
4+
import IconPreact from "./IconPreact.vue"
45
import IconHTML from "./IconHTML.vue"
56
import IconYarn from "./IconYarn.vue"
67
import IconNPM from "./IconNPM.vue"
@@ -12,7 +13,7 @@ import { computed, PropType, ref } from "vue"
1213
import { vAutoAnimate } from "../../../src"
1314
import "../../assets/prism.css"
1415
15-
type LanguageOption = "react" | "vue" | "html"
16+
type LanguageOption = "react" | "preact" | "vue" | "html"
1617
1718
type Language = {
1819
ext: "jsx" | "vue" | "html"
@@ -98,6 +99,13 @@ function copyCode(value) {
9899
>
99100
<IconReact />React
100101
</li>
102+
<li
103+
v-if="'preact' in props.examples"
104+
@click="current = 'preact'"
105+
:data-selected="current === 'preact' || null"
106+
>
107+
<IconPreact />Preact
108+
</li>
101109
<li
102110
v-if="'vue' in props.examples"
103111
@click="current = 'vue'"

docs/src/components/IconPreact.vue

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<template>
2+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="296px" height="296px" viewBox="-20 0 296 296" version="1.1" preserveAspectRatio="xMidYMid">
3+
<g>
4+
<polygon fill="#673AB8" points="128 0 256 73.8999491 256 221.699847 128 295.599796 0 221.699847 0 73.8999491"/>
5+
<path d="M34.8647584,220.478469 C51.8814262,242.25881 105.959701,225.662965 157.014868,185.774297 C208.070035,145.885628 237.255632,97.428608 220.238964,75.6482664 C203.222296,53.8679249 149.144022,70.4637701 98.0888543,110.352439 C47.0336869,150.241107 17.8480906,198.698127 34.8647584,220.478469 Z M42.1343351,214.798853 C36.4908625,207.575537 38.9565723,193.395881 49.7081913,175.544904 C61.0297348,156.747677 80.2490923,135.997367 103.76847,117.622015 C127.287848,99.2466634 152.071368,85.6181573 173.049166,79.1803727 C192.970945,73.066665 207.325915,74.1045667 212.969387,81.3278822 C218.61286,88.5511977 216.14715,102.730854 205.395531,120.581832 C194.073987,139.379058 174.85463,160.129368 151.335252,178.50472 C127.815874,196.880072 103.032354,210.508578 82.054556,216.946362 C62.1327769,223.06007 47.7778077,222.022168 42.1343351,214.798853 Z" fill="#FFFFFF"/>
6+
<path d="M220.238964,220.478469 C237.255632,198.698127 208.070035,150.241107 157.014868,110.352439 C105.959701,70.4637701 51.8814262,53.8679249 34.8647584,75.6482664 C17.8480906,97.428608 47.0336869,145.885628 98.0888543,185.774297 C149.144022,225.662965 203.222296,242.25881 220.238964,220.478469 Z M212.969387,214.798853 C207.325915,222.022168 192.970945,223.06007 173.049166,216.946362 C152.071368,210.508578 127.287848,196.880072 103.76847,178.50472 C80.2490923,160.129368 61.0297348,139.379058 49.7081913,120.581832 C38.9565723,102.730854 36.4908625,88.5511977 42.1343351,81.3278822 C47.7778077,74.1045667 62.1327769,73.066665 82.054556,79.1803727 C103.032354,85.6181573 127.815874,99.2466634 151.335252,117.622015 C174.85463,135.997367 194.073987,156.747677 205.395531,175.544904 C216.14715,193.395881 218.61286,207.575537 212.969387,214.798853 Z" fill="#FFFFFF"/>
7+
<path d="M127.551861,167.666971 C138.378632,167.666971 147.155465,158.890139 147.155465,148.063368 C147.155465,137.236596 138.378632,128.459764 127.551861,128.459764 C116.72509,128.459764 107.948257,137.236596 107.948257,148.063368 C107.948257,158.890139 116.72509,167.666971 127.551861,167.666971 L127.551861,167.666971 Z" fill="#FFFFFF"/>
8+
</g>
9+
</svg>
10+
</template>

docs/src/components/Navigation.vue

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ if (typeof window !== "undefined") {
3939
<li><a href="#installation">Installation</a></li>
4040
<li><a href="#usage">Usage</a></li>
4141
<li><a href="#usage-react">React</a></li>
42+
<li><a href="#usage-preact">Preact</a></li>
4243
<li><a href="#usage-vue">Vue</a></li>
4344
<li><a href="#usage-svelte">Svelte</a></li>
4445
<li><a href="#usage-angular">Angular</a></li>

docs/src/examples/intro/index.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import vueExample from "./intro.vue?raw"
22
import reactExample from "./intro.jsx?raw"
3+
import preactExample from "./intro-preact.jsx?raw"
34
import htmlExample from "./intro.html?raw"
45
import svelteExample from "./intro.svelte?raw"
56
import angularExample from "./intro.angular?raw"
@@ -10,6 +11,11 @@ export default {
1011
ext: "jsx",
1112
language: "jsx",
1213
},
14+
preact: {
15+
example: preactExample,
16+
ext: "jsx",
17+
language: "jsx",
18+
},
1319
vue: {
1420
ext: "vue",
1521
language: "html",
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { useAutoAnimate } from '@formkit/auto-animate/preact'
2+
3+
function MyList () {
4+
const [animationParent] = useAutoAnimate()
5+
return (
6+
<ul ref={animationParent}>
7+
{/* 🪄 Magic animations for your list */}
8+
</ul>
9+
)
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script setup>
2+
import { useAutoAnimate } from "../../../../src/vue/index.ts"
3+
import { ref } from "vue"
4+
const [parent] = useAutoAnimate()
5+
const items = ref([0, 1, 2])
6+
</script>
7+
8+
<template>
9+
<div class="example preact-example">
10+
<ul ref="parent">
11+
<li v-for="item in items" :key="item">{{ item }}</li>
12+
</ul>
13+
<button @click="items.push(items.length)" class="button button--alt">
14+
Add number
15+
</button>
16+
</div>
17+
</template>
18+
19+
<style scoped>
20+
ul {
21+
list-style-type: disc;
22+
}
23+
li::before {
24+
display: none;
25+
}
26+
</style>

docs/src/examples/preact/index.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export default {
2+
preact: {
3+
language: "jsx",
4+
ext: "jsx",
5+
example: `import { useState } from 'preact/hooks'
6+
import { useAutoAnimate } from '@formkit/auto-animate/preact'
7+
8+
const App = function () {
9+
const [items, setItems] = useState([0, 1, 2])
10+
const [parent, enableAnimations] = useAutoAnimate(/* optional config */)
11+
const add = () => setItems([...items, items.length])
12+
return <>
13+
<ul ref={parent}>
14+
{items.map(
15+
item => <li key={item}>{ item }</li>
16+
)}
17+
</ul>
18+
<button onClick={add}>Add number</button>
19+
<button onClick={() => enableAnimations(false)}>Disable</button>
20+
</>
21+
}
22+
23+
export default App`,
24+
},
25+
}

docs/src/sections/SectionUsage.vue

+16
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import {
1010
} from "../examples/vue"
1111
import { angularDirectiveMain, angularDirectiveApp } from "../examples/angular"
1212
import reactHook from "../examples/react"
13+
import preactHook from "../examples/preact"
1314
import disabledExamples from "../examples/disable"
1415
import ActualReactApp from "../examples/react/ActualReactApp.vue"
16+
import ActualPreactApp from "../examples/preact/ActualPreactApp.vue"
1517
import ActualDropdown from "../examples/dropdown/ActualDropdown.vue"
1618
import svelteAction from "../examples/svelte"
1719
import ActualSvelteApp from "../examples/svelte/ActualSvelteApp.vue"
@@ -20,6 +22,7 @@ import ActualVueAppHook from "../examples/vue/ActualVueAppHook.vue"
2022
import ActualAngularApp from "../examples/angular/ActualAngularApp.vue"
2123
import ActualDisable from "../examples/disable/ActualDisable.vue"
2224
import IconReact from "../components/IconReact.vue"
25+
import IconPreact from "../components/IconPreact.vue"
2326
import IconVue from "../components/IconVue.vue"
2427
import IconAngular from "../components/IconAngular.vue"
2528
import IconSvelte from "../components/IconSvelte.vue"
@@ -111,6 +114,9 @@ import IconSvelte from "../components/IconSvelte.vue"
111114
<li>
112115
<a href="#usage-react"><span>React</span><IconReact /></a>
113116
</li>
117+
<li>
118+
<a href="#usage-preact"><span>Preact</span><IconPreact /></a>
119+
</li>
114120
<li>
115121
<a href="#usage-vue"><span>Vue</span><IconVue /></a>
116122
</li>
@@ -130,6 +136,16 @@ import IconSvelte from "../components/IconSvelte.vue"
130136
</p>
131137
<CodeExample :examples="reactHook" title="App" />
132138
<ActualReactApp />
139+
<h2 id="usage-preact">Preact hook</h2>
140+
<p>
141+
Preact users can use the hook <code>useAutoAnimate</code> by importing it
142+
from <code>@formkit/auto-animate/preact</code>. This hook returns a ref to
143+
apply to the parent element, as well as a function to
144+
<a href="#usage-disable">enable or disable</a> animations.
145+
</p>
146+
<CodeExample :examples="preactHook" title="App" />
147+
<ActualPreactApp />
148+
133149
<h2 id="usage-vue">Vue directive</h2>
134150
<p>
135151
Vue users can globally register the

package.json

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"animation",
88
"transition",
99
"react",
10+
"preact",
1011
"vue",
1112
"angular",
1213
"svelte"
@@ -32,6 +33,11 @@
3233
"types": "./vue/index.d.ts",
3334
"default": "./vue/index.mjs"
3435
},
36+
"./preact": {
37+
"import": "./preact/index.mjs",
38+
"types": "./preact/index.d.ts",
39+
"default": "./preact/index.mjs"
40+
},
3541
"./react": {
3642
"import": "./react/index.mjs",
3743
"types": "./react/index.d.ts",
@@ -60,6 +66,7 @@
6066
"chalk": "^5.0.1",
6167
"cypress": "^9.6.1",
6268
"execa": "^6.1.0",
69+
"preact": "^10.11.3",
6370
"pretty-bytes": "^6.0.0",
6471
"prompts": "^2.4.2",
6572
"react": "^18.1.0",
@@ -73,6 +80,5 @@
7380
"vue": "^3.2.33",
7481
"vue-github-button": "^3.0.3",
7582
"vue-router": "4"
76-
},
77-
"dependencies": {}
83+
}
7884
}

rollup.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const MIN = process.env.MIN || false
77

88
const external = [
99
"vue",
10+
"preact",
1011
"react",
1112
"angular",
1213
"process",

src/preact/index.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { useEffect, useState, useRef } from "preact/hooks"
2+
import autoAnimate, {
3+
AutoAnimateOptions,
4+
AutoAnimationPlugin,
5+
AnimationController,
6+
} from "../index"
7+
8+
/**
9+
* AutoAnimate hook for adding dead-simple transitions and animations to preact.
10+
* @param options - Auto animate options or a plugin
11+
* @returns
12+
*/
13+
export function useAutoAnimate<T extends Element>(options?: Partial<AutoAnimateOptions> | AutoAnimationPlugin): [Object<T>, (enabled: boolean) => void] {
14+
const element = useRef<T>(null)
15+
const [controller, setController] = useState<
16+
AnimationController | undefined
17+
>()
18+
const setEnabled = (enabled: boolean) => {
19+
if (controller) {
20+
enabled ? controller.enable() : controller.disable()
21+
}
22+
}
23+
useEffect(() => {
24+
if (element.current instanceof HTMLElement)
25+
setController(autoAnimate(element.current, options || {}))
26+
}, [])
27+
return [element, setEnabled]
28+
}

0 commit comments

Comments
 (0)