Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion build/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,22 @@ async function bundleDeclarations() {
await execa("shx", ["rm", `${rootDir}/dist/index.js`])
}

async function markoBuild() {
info("Copying Marko tag")
await execa("shx", ["mkdir", "-p", `${rootDir}/dist/tags`])
await execa("shx", [
"cp",
`${rootDir}/src/marko/auto-animate.marko`,
`${rootDir}/dist/tags/auto-animate.marko`,
])
// The taglib manifest (marko.json) is a committed static file, copied to dist
// by addAssets() alongside README/LICENSE — see there. The tag's `../index`
// import is left extensionless on purpose: it is NOT compiled by rollup (the
// consumer's @marko/vite compiles it), and Vite resolves the extension to
// `index.mjs` in dist and to `index.ts` against source in a dev harness — so
// no `.mjs` fixup is needed here, unlike the JS-framework builds.
}

async function addPackageJSON() {
info("Writing package.json")
const raw = await readFile(resolve(rootDir, "package.json"), "utf8")
Expand All @@ -222,13 +238,21 @@ async function addPackageJSON() {
}

async function addAssets() {
info("Writing readme and license.")
info("Writing readme, license, and marko manifest.")
await execa("shx", [
"cp",
`${rootDir}/README.md`,
`${rootDir}/dist/README.md`,
])
await execa("shx", ["cp", `${rootDir}/LICENSE`, `${rootDir}/dist/LICENSE`])
// marko.json is a committed, static taglib manifest — copied verbatim like
// README/LICENSE, never generated. Its "exports" path is authored relative to
// the published package root (dist), so "./tags" resolves to dist/tags.
await execa("shx", [
"cp",
`${rootDir}/marko.json`,
`${rootDir}/dist/marko.json`,
])
}

async function prepareForPublishing() {
Expand Down Expand Up @@ -291,6 +315,7 @@ async function main() {
if (!process.env.NO_NUXT) {
await nuxtBuild()
}
await markoBuild()
await addPackageJSON()
await addAssets()
await outputSize()
Expand Down
11 changes: 10 additions & 1 deletion docs/src/components/CodeExample.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import IconPNPM from "./IconPNPM.vue"
import IconJavaScript from "./IconJavaScript.vue"
import IconSvelte from "./IconSvelte.vue"
import IconAngular from "./IconAngular.vue"
import IconMarko from "./IconMarko.vue"
import IconNuxt from "./IconNuxt.vue"
import IconBun from "./IconBun.vue"
import { computed, ref } from "vue"
Expand All @@ -25,6 +26,7 @@ type LanguageOption =
| "solid"
| "svelte"
| "angular"
| "marko"
| "qwik"
| "js"
| "yarn"
Expand All @@ -34,7 +36,7 @@ type LanguageOption =
| "bun"

type Language = {
ext: "jsx" | "vue" | "html"
ext: "jsx" | "vue" | "html" | "marko"
example: string
title?: string
language: string
Expand Down Expand Up @@ -154,6 +156,13 @@ function copyCode(value: string) {
>
<IconAngular />Angular
</li>
<li
v-if="'marko' in props.examples"
@click="current = 'marko'"
:data-selected="current === 'marko' || null"
>
<IconMarko />Marko
</li>
<li
v-if="'qwik' in props.examples"
@click="current = 'qwik'"
Expand Down
38 changes: 38 additions & 0 deletions docs/src/components/IconMarko.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script setup>
// Official multi-color Marko logomark. It uses internal id references (clipPath +
// <use>) to draw the darker two-tone overlays; because this icon renders multiple
// times on a page (every code-window framework switcher plus the jump-link), the
// ids are made unique per instance via useId() so there are no duplicate-id
// collisions. useId() is SSR-stable, which the vite-ssg docs build needs.
import { useId } from "vue"
const uid = useId()
</script>

<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 78 347 191">
<title>Marko Logo</title>
<path :id="uid + 'f'" fill="#00CFFB" d="M72.6 141c1.2-2 1.2-4.6 0-6.6L49.8 95.3a3.5 3.5 0 00-6.2 0L.9 170.2a6.6 6.6 0 000 6.6l51.8 88.8a6.6 6.6 0 005.8 3.3h44c3.5 0 5.6-3.7 3.8-6.7l-52-88.8"/>
<path :id="uid + 'g'" fill="#7CED64" d="M114 173.5h48c2.4 0 4.6-1.3 5.8-3.4L183.9 141c1.2-2 1.1-4.5 0-6.6l-22.8-39a3.5 3.5 0 00-6.2 0l-17 30.3-26-44.4A6.6 6.6 0 00106.2 78H62.3a4.4 4.4 0 00-3.8 6.7l49.8 85.5c1.2 2 3.4 3.3 5.8 3.3"/>
<path :id="uid + 'h'" fill="#FFD100" d="M221.3 173.4l-51.8 88.8c-1.7 3 .4 6.6 3.8 6.6h44.2c2.3 0 4.5-1.2 5.7-3.3l52-88.7c1.2-2 1.2-4.6 0-6.7l-52-88.8A6.6 6.6 0 00217.5 78H173.3a4.4 4.4 0 00-3.8 6.7l51.8 88.7"/>
<path :id="uid + 'i'" fill="#FF5467" d="M244.5 78h44.1c2.4 0 4.5 1.3 5.7 3.3l51.8 88.8c1.2 2 1.2 4.6 0 6.7l-51.8 88.7a6.6 6.6 0 01-5.7 3.3H244.5a4.4 4.4 0 01-3.9-6.6l51.8-88.8-51.8-88.7c-1.7-3 .4-6.7 3.9-6.7"/>
<use fill="#0073D8" :clip-path="'url(#' + uid + 'a)'" :href="'#' + uid + 'b'"/>
<use fill="#00B068" :clip-path="'url(#' + uid + 'c)'" :href="'#' + uid + 'b'"/>
<use fill="#FC5C00" :clip-path="'url(#' + uid + 'd)'" :href="'#' + uid + 'b'"/>
<use fill="#CC0067" :clip-path="'url(#' + uid + 'e)'" :href="'#' + uid + 'b'"/>
<defs>
<clipPath :id="uid + 'a'">
<use :href="'#' + uid + 'f'"/>
</clipPath>
<clipPath :id="uid + 'c'">
<use :href="'#' + uid + 'g'"/>
</clipPath>
<clipPath :id="uid + 'd'">
<use :href="'#' + uid + 'h'"/>
</clipPath>
<clipPath :id="uid + 'e'">
<use :href="'#' + uid + 'i'"/>
</clipPath>
<path :id="uid + 'b'" d="M0 173.4H111.1376L137.9 125.7V78H157l51 95.4H347V425H0"/>
</defs>
</svg>
</template>
1 change: 1 addition & 0 deletions docs/src/components/Navigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ if (typeof window !== "undefined") {
<li><a href="#usage-solid">Solid</a></li>
<li><a href="#usage-svelte">Svelte</a></li>
<li><a href="#usage-angular">Angular</a></li>
<li><a href="#usage-marko">Marko</a></li>
<!-- <li><a href="#usage-qwik">Qwik</a></li> -->
<li><a href="#usage-disable">Disable</a></li>
<li><a href="#examples">Examples</a></li>
Expand Down
23 changes: 23 additions & 0 deletions docs/src/examples/disable/disable.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import AutoAnimate from "@formkit/auto-animate/marko"

<let/balls = ["red", "green", "blue"]>
<let/isEnabled = true>

<script>
// Rotate the list every 600ms so there is always something to animate.
const id = setInterval(() => {
balls = [...balls.slice(1), balls[0]];
}, 600);
$signal.onabort = () => clearInterval(id);
</script>

<ul/listRef class="balls">
<for|color| of=balls by=(color => color)>
<li class=color>${color}</li>
</for>
</ul>
<AutoAnimate parent=listRef options=({ duration: 500 }) enabled=isEnabled/>

<button onClick() { isEnabled = !isEnabled }>
${isEnabled ? "🚫 Disable" : "✅ Enable"} animations
</button>
6 changes: 6 additions & 0 deletions docs/src/examples/disable/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import vueExample from "./disable.vue?raw"
import reactExample from "./disable.jsx?raw"
import markoExample from "./disable.marko?raw"
// import htmlExample from "./disable.html?raw"

export default {
Expand All @@ -13,6 +14,11 @@ export default {
language: "html",
example: vueExample,
},
marko: {
ext: "marko",
language: "html",
example: markoExample,
},
// js: {
// example: htmlExample,
// ext: "html",
Expand Down
13 changes: 13 additions & 0 deletions docs/src/examples/dropdown/dropdown.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import AutoAnimate from "@formkit/auto-animate/marko"

<let/show = false>

<div/dropdown class="dropdown">
<strong class="dropdown-label" onClick() { show = !show }>
Click me to open!
</strong>
<if=show>
<p class="dropdown-content">Lorum ipsum...</p>
</if>
</div>
<AutoAnimate parent=dropdown/>
6 changes: 6 additions & 0 deletions docs/src/examples/dropdown/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import vueExample from "./dropdown.vue?raw"
import reactExample from "./dropdown.jsx?raw"
import solidExample from "./dropdown-solid.tsx?raw"
import nativeExample from "./dropdown.html?raw"
import markoExample from "./dropdown.marko?raw"
export default {
react: {
language: "jsx",
Expand All @@ -18,6 +19,11 @@ export default {
ext: "vue",
example: vueExample,
},
marko: {
language: "html",
ext: "marko",
example: markoExample,
},
js: {
language: "html",
ext: "html",
Expand Down
6 changes: 6 additions & 0 deletions docs/src/examples/intro/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import solidExample from "./intro-solid.jsx?raw"
import htmlExample from "./intro.html?raw"
import svelteExample from "./intro.svelte?raw"
import angularExample from "./intro.angular?raw"
import markoExample from "./intro.marko?raw"

export default {
react: {
Expand Down Expand Up @@ -37,6 +38,11 @@ export default {
ext: "angular",
language: "html",
},
marko: {
example: markoExample,
ext: "marko",
language: "html",
},
js: {
example: htmlExample,
ext: "html",
Expand Down
6 changes: 6 additions & 0 deletions docs/src/examples/intro/intro.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import AutoAnimate from "@formkit/auto-animate/marko"

<ul/listRef>
<!-- 🪄 Magic animations for your list -->
</ul>
<AutoAnimate parent=listRef/>
33 changes: 33 additions & 0 deletions docs/src/examples/marko/ActualMarkoApp.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script setup>
// Like the other framework demos on this page (e.g. ActualReactApp.vue), the *live*
// preview is implemented with the Vue adapter so nothing Marko has to enter the docs'
// vite-ssg build. The Marko-specific code is shown in the adjacent code sample; the
// animation behavior is identical because it all runs on the same auto-animate core.
import { useAutoAnimate } from "../../../../src/vue/index.ts"
import { ref } from "vue"
const [parent, setEnabled] = useAutoAnimate()
const items = ref([0, 1, 2])
</script>

<template>
<div class="example marko-example">
<ul ref="parent">
<li v-for="item in items" :key="item">{{ item }}</li>
</ul>
<button @click="items.push(items.length)" class="button button--alt add">
Add number
</button>
<button @click="setEnabled(false)" class="button button--alt">
Disable
</button>
</div>
</template>

<style scoped>
ul {
list-style-type: disc;
}
li::before {
display: none;
}
</style>
20 changes: 20 additions & 0 deletions docs/src/examples/marko/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default {
marko: {
language: "html",
ext: "marko",
example: `import AutoAnimate from "@formkit/auto-animate/marko"

<let/items = [0, 1, 2]>
<let/enabled = true>

<ul/listRef>
<for|item| of=items by=(n => String(n))>
<li>\${item}</li>
</for>
</ul>
<AutoAnimate parent=listRef enabled=enabled/>

<button onClick() { items = [...items, items.length] }>Add number</button>
<button onClick() { enabled = false }>Disable</button>`,
},
}
44 changes: 44 additions & 0 deletions docs/src/sections/SectionUsage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import ActualPreactApp from "../examples/preact/ActualPreactApp.vue"
import ActualSolidApp from "../examples/solid/ActualSolidApp.vue"
import ActualDropdown from "../examples/dropdown/ActualDropdown.vue"
import svelteAction from "../examples/svelte"
import markoTag from "../examples/marko"
import ActualMarkoApp from "../examples/marko/ActualMarkoApp.vue"
import qwikHook from "../examples/qwik"
import ActualSvelteApp from "../examples/svelte/ActualSvelteApp.vue"
import ActualVueApp from "../examples/vue/ActualVueApp.vue"
Expand All @@ -30,6 +32,7 @@ import IconVue from "../components/IconVue.vue"
import IconAngular from "../components/IconAngular.vue"
import IconSvelte from "../components/IconSvelte.vue"
import IconSolid from "../components/IconSolid.vue"
import IconMarko from "../components/IconMarko.vue"
import IconQwik from "../components/IconQwik.vue"
</script>
<template>
Expand Down Expand Up @@ -140,6 +143,9 @@ import IconQwik from "../components/IconQwik.vue"
<li>
<a href="#usage-angular"><span>Angular</span><IconAngular /></a>
</li>
<li>
<a href="#usage-marko"><span>Marko</span><IconMarko /></a>
</li>
<!-- <li>
<a href="#usage-qwik"><span>Qwik</span><IconQwik /></a>
</li> -->
Expand Down Expand Up @@ -277,6 +283,44 @@ import IconQwik from "../components/IconQwik.vue"
but you can easily write a wrapper.
</AsideTip>

<h2 id="usage-marko">Marko tag</h2>
<p>
Marko users can import the <code>&lt;auto-animate&gt;</code> tag from
<code>@formkit/auto-animate/marko</code>. Rather than returning a ref, the
tag takes one: give your parent element a
<a
href="https://markojs.com/docs/reference/language/#tag-variables"
target="_blank"
rel="noopener noreferrer"
>tag variable</a
>
(for example <code>&lt;ul/listRef&gt;</code>) and pass it to the tag’s
<code>parent</code> attribute. The tag attaches AutoAnimate to that element
on mount and tears it down automatically when it leaves the DOM.
</p>
<CodeExample :examples="markoTag" title="App" />
<ActualMarkoApp />
<AsideTip>
To <a href="#usage-disable">enable or disable</a> animations, set the
reactive <code>enabled</code> attribute
(<code>&lt;auto-animate parent=listRef enabled=animationsOn/&gt;</code>) —
flipping it on or off is all that’s needed; the tag is not re-created.
</AsideTip>
<AsideTip>
Options are passed once via the <code>options</code> attribute
(<code>options=(&#123; duration: 200 &#125;)</code>) and are read
a single time when the tag mounts, mirroring the core’s API (there is no
<code>setOptions</code>). To apply different options later, re-mount the tag.
</AsideTip>
<AsideTip>
For reorderable lists, key your <code>&lt;for&gt;</code> by identity so
Marko moves nodes instead of recreating them — otherwise moves and exits
won’t animate. Use <code>by="id"</code> for objects, or an identity function
for primitives (<code>by=(n =&gt; String(n))</code>). Under SSR, prefer
plain serializable <code>options</code>; plugin functions are a client-only
path.
</AsideTip>

<!-- <h2 id="usage-qwik">Qwik hook</h2>
<p>
Qwik users can use the hook <code>useAutoAnimate</code> by importing it
Expand Down
3 changes: 3 additions & 0 deletions marko.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exports": "./tags"
}
Loading