@pyreon/kinetic 0.11.10 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js.map +1 -0
- package/package.json +4 -5
- package/src/Collapse.tsx +12 -18
- package/src/Stagger.tsx +20 -14
- package/src/Transition.tsx +26 -44
- package/src/TransitionGroup.tsx +15 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index2.d.ts","names":[],"sources":["../../src/types.ts","../../src/kinetic/types.ts","../../src/kinetic.ts","../../src/presets.ts","../../src/useAnimationEnd.ts","../../src/useTransitionState.ts"],"mappings":"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"}
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["applyEnter","applyLeave","applyReducedMotion","isVNode"],"sources":["../src/useAnimationEnd.ts","../src/useReducedMotion.ts","../src/kinetic/CollapseRenderer.tsx","../src/useTransitionState.ts","../src/utils.ts","../src/kinetic/TransitionItem.tsx","../src/kinetic/GroupRenderer.tsx","../src/kinetic/StaggerRenderer.tsx","../src/kinetic/TransitionRenderer.tsx","../src/kinetic/createKineticComponent.tsx","../src/kinetic.ts","../src/presets.ts"],"sourcesContent":["import type { Ref } from '@pyreon/core'\nimport { watch } from '@pyreon/reactivity'\n\nconst DEFAULT_TIMEOUT = 5000\n\nexport type UseAnimationEnd = (options: {\n ref: Ref<HTMLElement>\n onEnd: () => void\n active: () => boolean\n timeout?: number | undefined\n}) => void\n\nconst useAnimationEnd: UseAnimationEnd = ({ ref, onEnd, active, timeout = DEFAULT_TIMEOUT }) => {\n let called = false\n\n watch(\n active,\n (isActive) => {\n if (!isActive) {\n called = false\n return\n }\n\n const el = ref.current\n if (!el) return\n\n called = false\n\n const done = () => {\n if (called) return\n called = true\n el.removeEventListener('transitionend', handleEnd)\n el.removeEventListener('animationend', handleEnd)\n clearTimeout(timer)\n onEnd()\n }\n\n const handleEnd = (e: Event) => {\n // Ignore bubbled events from children\n if (e.target !== el) return\n done()\n }\n\n el.addEventListener('transitionend', handleEnd)\n el.addEventListener('animationend', handleEnd)\n\n const timer = setTimeout(done, timeout)\n\n return () => {\n el.removeEventListener('transitionend', handleEnd)\n el.removeEventListener('animationend', handleEnd)\n clearTimeout(timer)\n }\n },\n { immediate: true },\n )\n}\n\nexport default useAnimationEnd\n","import { onMount, onUnmount } from '@pyreon/core'\nimport { signal } from '@pyreon/reactivity'\n\n/**\n * Inline reduced-motion check for kinetic package.\n * Avoids depending on @pyreon/hooks for a single media query.\n */\nexport function useReducedMotion(): () => boolean {\n const matches = signal(false)\n let mql: MediaQueryList | undefined\n\n const onChange = (e: MediaQueryListEvent) => {\n matches.set(e.matches)\n }\n\n onMount(() => {\n mql = window.matchMedia('(prefers-reduced-motion: reduce)')\n matches.set(mql.matches)\n mql.addEventListener('change', onChange)\n return undefined\n })\n\n onUnmount(() => {\n mql?.removeEventListener('change', onChange)\n })\n\n return matches\n}\n","import type { VNode } from '@pyreon/core'\nimport { createRef, h, Show } from '@pyreon/core'\nimport { runUntracked, signal, watch } from '@pyreon/reactivity'\nimport type { CSSProperties, TransitionCallbacks, TransitionStage } from '../types'\nimport useAnimationEnd from '../useAnimationEnd'\nimport { useReducedMotion } from '../useReducedMotion'\nimport type { KineticConfig } from './types'\n\ntype CollapseRendererProps = {\n config: KineticConfig\n htmlProps: Record<string, unknown>\n show: () => boolean\n appear?: boolean | undefined\n timeout?: number | undefined\n transition?: string | undefined\n callbacks: Partial<TransitionCallbacks>\n children: VNode | VNode[]\n}\n\n/**\n * Renders a height-animated collapse. The config.tag becomes the outer\n * wrapper (overflow:hidden + animated height). An inner div measures\n * scrollHeight for the target value.\n */\nconst CollapseRenderer = ({\n config,\n htmlProps,\n show,\n appear,\n timeout,\n transition,\n callbacks,\n children,\n}: CollapseRendererProps): VNode | null => {\n const reducedMotion = useReducedMotion()\n let wrapperRef: { current: HTMLElement | null } = createRef<HTMLElement>()\n const contentRef = createRef<HTMLDivElement>()\n\n const effectiveAppear = appear ?? config.appear ?? false\n const effectiveTimeout = timeout ?? config.timeout ?? 5000\n const effectiveTransition = transition ?? config.transition ?? 'height 300ms ease'\n\n const initialShow = show()\n const needsAppear = effectiveAppear && initialShow\n const stage = signal<TransitionStage>(initialShow ? 'entered' : 'hidden')\n let isInitialMount = true\n let appearTriggered = false\n\n // Intercept ref assignment to trigger appear after all refs are wired\n if (needsAppear) {\n const orig = wrapperRef\n const proxy = { current: null as HTMLElement | null }\n Object.defineProperty(proxy, 'current', {\n get() {\n return orig.current\n },\n set(node: HTMLElement | null) {\n orig.current = node\n if (node && !appearTriggered) {\n appearTriggered = true\n queueMicrotask(() => stage.set('entering'))\n }\n },\n })\n wrapperRef = proxy\n }\n\n // State machine transitions\n watch(\n show,\n (showVal) => {\n if (isInitialMount) {\n isInitialMount = false\n // appear case is handled by ref proxy above\n return\n }\n\n const currentStage = runUntracked(() => stage())\n if (showVal && (currentStage === 'hidden' || currentStage === 'leaving')) {\n stage.set('entering')\n } else if (!showVal && (currentStage === 'entered' || currentStage === 'entering')) {\n stage.set('leaving')\n }\n },\n { immediate: true },\n )\n\n // Animate height\n watch(\n () => stage(),\n (currentStage) => {\n const wrapper = wrapperRef.current\n const content = contentRef.current\n if (!wrapper || !content) return\n\n if (reducedMotion()) {\n if (currentStage === 'entering') {\n callbacks.onEnter?.()\n wrapper.style.height = 'auto'\n wrapper.style.overflow = ''\n callbacks.onAfterEnter?.()\n stage.set('entered')\n } else if (currentStage === 'leaving') {\n callbacks.onLeave?.()\n wrapper.style.height = '0px'\n wrapper.style.overflow = 'hidden'\n callbacks.onAfterLeave?.()\n stage.set('hidden')\n }\n return\n }\n\n if (currentStage === 'entering') {\n callbacks.onEnter?.()\n const height = content.scrollHeight\n wrapper.style.transition = 'none'\n wrapper.style.height = '0px'\n wrapper.style.overflow = 'hidden'\n // Force reflow\n void wrapper.offsetHeight\n wrapper.style.transition = effectiveTransition\n wrapper.style.height = `${height}px`\n }\n\n if (currentStage === 'leaving') {\n callbacks.onLeave?.()\n const height = content.scrollHeight\n wrapper.style.transition = 'none'\n wrapper.style.height = `${height}px`\n wrapper.style.overflow = 'hidden'\n // Force reflow\n void wrapper.offsetHeight\n wrapper.style.transition = effectiveTransition\n wrapper.style.height = '0px'\n }\n },\n { immediate: true },\n )\n\n useAnimationEnd({\n ref: wrapperRef,\n active: () => (stage() === 'entering' || stage() === 'leaving') && !reducedMotion(),\n timeout: effectiveTimeout,\n onEnd: () => {\n const wrapper = wrapperRef.current\n if (stage() === 'entering') {\n if (wrapper) {\n wrapper.style.height = 'auto'\n wrapper.style.overflow = ''\n wrapper.style.transition = ''\n }\n callbacks.onAfterEnter?.()\n stage.set('entered')\n } else if (stage() === 'leaving') {\n callbacks.onAfterLeave?.()\n stage.set('hidden')\n }\n },\n })\n\n const shouldRender = () => stage() !== 'hidden'\n\n const wrapperStyle: CSSProperties = {\n ...((htmlProps.style as CSSProperties) ?? {}),\n ...(stage() !== 'entered' ? { overflow: 'hidden' } : {}),\n ...(stage() === 'hidden' ? { height: '0px' } : stage() === 'entered' ? { height: 'auto' } : {}),\n }\n\n return h(\n config.tag,\n { ref: wrapperRef, ...htmlProps, style: wrapperStyle },\n <Show when={shouldRender}>\n <div ref={contentRef}>{children}</div>\n </Show>,\n )\n}\n\nexport default CollapseRenderer\n","import { createRef } from '@pyreon/core'\nimport { runUntracked, signal, watch } from '@pyreon/reactivity'\nimport type { TransitionStage, TransitionStateResult } from './types'\n\nexport type UseTransitionState = (options: {\n show: () => boolean\n appear?: boolean | undefined\n}) => TransitionStateResult\n\nconst useTransitionState: UseTransitionState = ({ show, appear = false }) => {\n const initialShow = show()\n // When appear=true and show starts true, mount the element (stage='entered')\n // but defer the enter animation until the ref is connected.\n const needsAppear = appear && initialShow\n const stage = signal<TransitionStage>(initialShow ? 'entered' : 'hidden')\n const elementRef = createRef<HTMLElement>()\n let isInitialMount = true\n let appearTriggered = false\n\n // Ref callback that triggers the appear animation once the element is wired\n const refCallback = (node: HTMLElement | null) => {\n elementRef.current = node\n if (node && needsAppear && !appearTriggered) {\n appearTriggered = true\n stage.set('entering')\n }\n }\n\n watch(\n show,\n (showVal) => {\n if (isInitialMount) {\n isInitialMount = false\n // appear case is handled by refCallback above\n return\n }\n\n const currentStage = runUntracked(() => stage())\n if (showVal && (currentStage === 'hidden' || currentStage === 'leaving')) {\n stage.set('entering')\n } else if (!showVal && (currentStage === 'entered' || currentStage === 'entering')) {\n stage.set('leaving')\n }\n },\n { immediate: true },\n )\n\n const complete = () => {\n const current = stage()\n if (current === 'entering') stage.set('entered')\n if (current === 'leaving') stage.set('hidden')\n }\n\n return {\n stage,\n ref: refCallback,\n shouldMount: () => stage() !== 'hidden',\n complete,\n }\n}\n\nexport default useTransitionState\n","import type { Ref, VNode } from '@pyreon/core'\nimport type { CSSProperties } from './types'\n\nconst splitCache = new Map<string, string[]>()\nconst splitClasses = (classes: string): string[] => {\n let cached = splitCache.get(classes)\n if (!cached) {\n cached = classes.split(/\\s+/).filter(Boolean)\n splitCache.set(classes, cached)\n }\n return cached\n}\n\n/** Adds space-separated CSS classes to an element. */\nexport const addClasses = (el: HTMLElement, classes: string | undefined) => {\n if (!classes) return\n const list = splitClasses(classes)\n if (list.length > 0) el.classList.add(...list)\n}\n\n/** Removes space-separated CSS classes from an element. */\nexport const removeClasses = (el: HTMLElement, classes: string | undefined) => {\n if (!classes) return\n const list = splitClasses(classes)\n if (list.length > 0) el.classList.remove(...list)\n}\n\n/**\n * Executes callback after two animation frames (double-rAF).\n * Ensures the browser paints the current state before applying changes,\n * which is required for CSS transitions to trigger.\n */\nexport const nextFrame = (callback: () => void): number =>\n requestAnimationFrame(() => {\n requestAnimationFrame(callback)\n })\n\n/** Merges two className strings, filtering undefined/empty. */\nexport const mergeClassNames = (\n existing: string | undefined,\n additional: string | undefined,\n): string | undefined => {\n const parts = [existing, additional].filter(Boolean)\n return parts.length > 0 ? parts.join(' ') : undefined\n}\n\n/** Merges two CSSProperties objects, with `b` taking precedence. */\nexport const mergeStyles = (\n a: CSSProperties | undefined,\n b: CSSProperties | undefined,\n): CSSProperties | undefined => {\n if (!a && !b) return undefined\n if (!a) return b\n if (!b) return a\n return { ...a, ...b }\n}\n\n// ─── Ref & Motion Utilities ─────────────────────────────────\n\ntype RefCallback<T> = (node: T | null) => void\ntype RefLike<T> = RefCallback<T> | Ref<T>\n\n/** Merges multiple refs (callback or object) into a single callback ref. */\nexport const mergeRefs = <T>(...refs: (RefLike<T> | undefined)[]): ((node: T | null) => void) => {\n return (node: T | null) => {\n for (const ref of refs) {\n if (!ref) continue\n if (typeof ref === 'function') {\n ref(node)\n } else {\n ;(ref as { current: unknown }).current = node\n }\n }\n }\n}\n\n/** Clones a VNode with merged props. */\nexport const cloneVNode = (vnode: VNode, extraProps: Record<string, unknown>): VNode => ({\n ...vnode,\n props: { ...vnode.props, ...extraProps },\n})\n","import type { VNode } from '@pyreon/core'\nimport { createRef, Show } from '@pyreon/core'\nimport { watch } from '@pyreon/reactivity'\nimport type { ClassTransitionProps, StyleTransitionProps, TransitionCallbacks } from '../types'\nimport useAnimationEnd from '../useAnimationEnd'\nimport { useReducedMotion } from '../useReducedMotion'\nimport useTransitionState from '../useTransitionState'\nimport { addClasses, cloneVNode, mergeRefs, mergeStyles, nextFrame, removeClasses } from '../utils'\n\ntype TransitionItemProps = ClassTransitionProps &\n StyleTransitionProps &\n TransitionCallbacks & {\n show: () => boolean\n appear?: boolean | undefined\n unmount?: boolean | undefined\n timeout?: number | undefined\n delay?: number | undefined\n children: VNode\n }\n\nconst applyEnter = (el: HTMLElement, config: ClassTransitionProps & StyleTransitionProps) => {\n addClasses(el, config.enter)\n addClasses(el, config.enterFrom)\n if (config.enterStyle) Object.assign(el.style, config.enterStyle)\n if (config.enterTransition) el.style.transition = config.enterTransition\n\n return nextFrame(() => {\n removeClasses(el, config.enterFrom)\n addClasses(el, config.enterTo)\n if (config.enterToStyle) Object.assign(el.style, config.enterToStyle)\n })\n}\n\nconst applyLeave = (el: HTMLElement, config: ClassTransitionProps & StyleTransitionProps) => {\n removeClasses(el, config.enter)\n removeClasses(el, config.enterTo)\n\n addClasses(el, config.leave)\n addClasses(el, config.leaveFrom)\n if (config.leaveStyle) Object.assign(el.style, config.leaveStyle)\n if (config.leaveTransition) el.style.transition = config.leaveTransition\n\n return nextFrame(() => {\n removeClasses(el, config.leaveFrom)\n addClasses(el, config.leaveTo)\n if (config.leaveToStyle) Object.assign(el.style, config.leaveToStyle)\n })\n}\n\nconst applyReducedMotion = (\n stage: string,\n callbacks: Partial<TransitionCallbacks>,\n complete: () => void,\n) => {\n if (stage === 'entering') {\n callbacks.onEnter?.()\n callbacks.onAfterEnter?.()\n complete()\n } else if (stage === 'leaving') {\n callbacks.onLeave?.()\n callbacks.onAfterLeave?.()\n complete()\n }\n}\n\n/**\n * Internal per-child transition component. Used by StaggerRenderer and\n * GroupRenderer to give each child its own animation state.\n *\n * Uses cloneVNode to inject ref onto the child — the child must accept ref.\n */\nconst TransitionItem = ({\n show,\n appear = false,\n unmount = true,\n timeout = 5000,\n enter,\n enterFrom,\n enterTo,\n leave,\n leaveFrom,\n leaveTo,\n enterStyle,\n enterToStyle,\n enterTransition,\n leaveStyle,\n leaveToStyle,\n leaveTransition,\n onEnter,\n onAfterEnter,\n onLeave,\n onAfterLeave,\n children,\n}: TransitionItemProps): VNode | null => {\n const reducedMotion = useReducedMotion()\n const { stage, ref: stateRef, shouldMount, complete } = useTransitionState({ show, appear })\n\n const elementRef = createRef<HTMLElement>()\n const mergedRef = mergeRefs(\n elementRef,\n stateRef,\n (children.props as Record<string, unknown>)?.ref as\n | ((el: HTMLElement | null) => void)\n | undefined,\n )\n\n const callbacks = {\n onEnter,\n onAfterEnter,\n onLeave,\n onAfterLeave,\n }\n\n const transitionConfig = {\n enter,\n enterFrom,\n enterTo,\n leave,\n leaveFrom,\n leaveTo,\n enterStyle,\n enterToStyle,\n enterTransition,\n leaveStyle,\n leaveToStyle,\n leaveTransition,\n }\n\n useAnimationEnd({\n ref: elementRef,\n active: () => (stage() === 'entering' || stage() === 'leaving') && !reducedMotion(),\n timeout,\n onEnd: () => {\n if (stage() === 'entering') {\n callbacks.onAfterEnter?.()\n } else if (stage() === 'leaving') {\n callbacks.onAfterLeave?.()\n }\n complete()\n },\n })\n\n watch(\n () => stage(),\n (currentStage) => {\n const el = elementRef.current\n if (!el) return\n\n if (reducedMotion()) {\n applyReducedMotion(currentStage, callbacks, complete)\n return\n }\n\n if (currentStage === 'entering') {\n callbacks.onEnter?.()\n const frameId = applyEnter(el, transitionConfig)\n return () => cancelAnimationFrame(frameId)\n }\n\n if (currentStage === 'leaving') {\n callbacks.onLeave?.()\n const frameId = applyLeave(el, transitionConfig)\n return () => cancelAnimationFrame(frameId)\n }\n\n if (currentStage === 'entered') {\n removeClasses(el, enter)\n el.style.transition = ''\n }\n },\n { immediate: true },\n )\n\n return (\n <Show\n when={shouldMount}\n fallback={\n unmount\n ? null\n : cloneVNode(children, {\n ref: mergedRef,\n style: mergeStyles(\n (children.props as Record<string, unknown>)?.style as\n | Record<string, string | number | undefined>\n | undefined,\n { display: 'none' },\n ),\n })\n }\n >\n {cloneVNode(children, { ref: mergedRef })}\n </Show>\n )\n}\n\nexport default TransitionItem\n","import type { VNode } from '@pyreon/core'\nimport { h } from '@pyreon/core'\nimport { signal } from '@pyreon/reactivity'\nimport type { TransitionCallbacks } from '../types'\nimport TransitionItem from './TransitionItem'\nimport type { KineticConfig } from './types'\n\ntype GroupRendererProps = {\n config: KineticConfig\n htmlProps: Record<string, unknown>\n appear?: boolean | undefined\n timeout?: number | undefined\n callbacks: Partial<TransitionCallbacks>\n /**\n * Children can be a static array OR a reactive accessor `() => VNode[]`.\n * When passed as an accessor, GroupRenderer tracks changes and\n * animates entering/leaving children automatically.\n */\n children: VNode[] | (() => VNode[])\n}\n\ntype KeyedChild = { key: string | number; element: VNode }\n\nconst isVNode = (child: unknown): child is VNode =>\n child != null && typeof child === 'object' && 'type' in (child as object)\n\nconst getKeyedChildren = (children: VNode[]): KeyedChild[] => {\n const result: KeyedChild[] = []\n for (const child of children) {\n if (isVNode(child)) {\n const key = (child as VNode & { key?: string | number }).key\n if (key != null) {\n result.push({ key, element: child })\n }\n }\n }\n return result\n}\n\n/**\n * Renders children with key-based enter/exit animation (no `show` prop).\n * Children that appear (new key) animate in. Children that disappear\n * (removed key) stay in DOM during leave animation, then unmount.\n * config.tag wraps all children as a container element.\n *\n * In Pyreon, components run once. Pass children as a reactive accessor\n * `() => VNode[]` for the group to detect changes and animate entries/exits.\n */\nconst GroupRenderer = ({\n config,\n htmlProps,\n appear,\n timeout,\n callbacks,\n children,\n}: GroupRendererProps): VNode | null => {\n const effectiveAppear = appear ?? config.appear ?? false\n const effectiveTimeout = timeout ?? config.timeout ?? 5000\n\n const prevMap = new Map<string | number, VNode>()\n const leavingMap = new Map<string | number, VNode>()\n const forceUpdate = signal(0)\n\n // Normalize children to an accessor\n const getChildren = typeof children === 'function' ? (children as () => VNode[]) : () => children\n\n // Track initial keys for appear animation logic\n const initialKeyed = getKeyedChildren(getChildren())\n const initialKeys = new Set(initialKeyed.map((c) => c.key))\n for (const { key, element } of initialKeyed) {\n prevMap.set(key, element)\n }\n\n const handleAfterLeave = (key: string | number) => {\n leavingMap.delete(key)\n callbacks.onAfterLeave?.()\n forceUpdate.update((c) => c + 1)\n }\n\n // Reactive accessor — re-evaluates when children() or forceUpdate changes\n return (() => {\n forceUpdate()\n\n const currentChildren = getChildren()\n const currentKeyed = getKeyedChildren(currentChildren)\n const currentMap = new Map<string | number, VNode>()\n for (const { key, element } of currentKeyed) {\n currentMap.set(key, element)\n }\n\n // Detect leaving children\n for (const [key, child] of prevMap) {\n if (!currentMap.has(key) && !leavingMap.has(key)) {\n leavingMap.set(key, child)\n }\n }\n\n // Cancel leave if child reappears\n for (const key of currentMap.keys()) {\n leavingMap.delete(key)\n }\n\n // Update prev for next diff\n prevMap.clear()\n for (const [key, element] of currentMap) {\n prevMap.set(key, element)\n }\n\n // Merge current + leaving\n const allEntries: KeyedChild[] = [...currentKeyed]\n for (const [key, element] of leavingMap) {\n allEntries.push({ key, element })\n }\n\n const groupedChildren = allEntries.map(({ key, element }) => {\n const isInitial = initialKeys.has(key)\n const isShowing = currentMap.has(key)\n\n return (\n <TransitionItem\n show={() => isShowing}\n appear={isInitial ? effectiveAppear : true}\n timeout={effectiveTimeout}\n enterStyle={config.enterStyle}\n enterToStyle={config.enterToStyle}\n enterTransition={config.enterTransition}\n leaveStyle={config.leaveStyle}\n leaveToStyle={config.leaveToStyle}\n leaveTransition={config.leaveTransition}\n enter={config.enter}\n enterFrom={config.enterFrom}\n enterTo={config.enterTo}\n leave={config.leave}\n leaveFrom={config.leaveFrom}\n leaveTo={config.leaveTo}\n onAfterLeave={() => handleAfterLeave(key)}\n >\n {element}\n </TransitionItem>\n )\n })\n\n return h(config.tag, { ...htmlProps }, ...groupedChildren)\n }) as unknown as VNode\n}\n\nexport default GroupRenderer\n","import type { VNode } from '@pyreon/core'\nimport { h } from '@pyreon/core'\nimport type { CSSProperties, TransitionCallbacks } from '../types'\nimport { cloneVNode } from '../utils'\nimport TransitionItem from './TransitionItem'\nimport type { KineticConfig } from './types'\n\ntype StaggerRendererProps = {\n config: KineticConfig\n htmlProps: Record<string, unknown>\n show: () => boolean\n appear?: boolean | undefined\n timeout?: number | undefined\n interval?: number | undefined\n reverseLeave?: boolean | undefined\n callbacks: Partial<TransitionCallbacks>\n children: VNode[]\n}\n\nconst isVNode = (child: unknown): child is VNode =>\n child != null && typeof child === 'object' && 'type' in (child as object)\n\n/**\n * Renders children with staggered enter/exit animation.\n * config.tag wraps the staggered children as a container element.\n * Each child is individually animated via TransitionItem.\n */\nconst StaggerRenderer = ({\n config,\n htmlProps,\n show,\n appear,\n timeout,\n interval,\n reverseLeave,\n callbacks,\n children,\n}: StaggerRendererProps): VNode | null => {\n const effectiveAppear = appear ?? config.appear ?? false\n const effectiveTimeout = timeout ?? config.timeout ?? 5000\n const effectiveInterval = interval ?? config.interval ?? 50\n const effectiveReverseLeave = reverseLeave ?? config.reverseLeave ?? false\n\n const childArray = (Array.isArray(children) ? children : [children]).filter(isVNode)\n const count = childArray.length\n\n const staggeredChildren = childArray.map((child, index) => {\n const staggerIndex = !show() && effectiveReverseLeave ? count - 1 - index : index\n const delay = staggerIndex * effectiveInterval\n\n return (\n <TransitionItem\n key={(child as VNode & { key?: string | number }).key ?? index}\n show={show}\n appear={effectiveAppear}\n timeout={effectiveTimeout + delay}\n enterStyle={config.enterStyle}\n enterToStyle={config.enterToStyle}\n enterTransition={config.enterTransition}\n leaveStyle={config.leaveStyle}\n leaveToStyle={config.leaveToStyle}\n leaveTransition={config.leaveTransition}\n enter={config.enter}\n enterFrom={config.enterFrom}\n enterTo={config.enterTo}\n leave={config.leave}\n leaveFrom={config.leaveFrom}\n leaveTo={config.leaveTo}\n onAfterLeave={\n index === (effectiveReverseLeave ? 0 : count - 1) ? callbacks.onAfterLeave : undefined\n }\n >\n {cloneVNode(child, {\n style: {\n ...((child.props as Record<string, unknown>)?.style as CSSProperties | undefined),\n '--stagger-index': staggerIndex,\n '--stagger-interval': `${effectiveInterval}ms`,\n transitionDelay: `${delay}ms`,\n } as CSSProperties,\n })}\n </TransitionItem>\n )\n })\n\n return h(config.tag, { ...htmlProps }, ...staggeredChildren)\n}\n\nexport default StaggerRenderer\n","import type { VNode } from '@pyreon/core'\nimport { createRef, h, Show } from '@pyreon/core'\nimport { watch } from '@pyreon/reactivity'\nimport type { CSSProperties, TransitionCallbacks } from '../types'\nimport useAnimationEnd from '../useAnimationEnd'\nimport { useReducedMotion } from '../useReducedMotion'\nimport useTransitionState from '../useTransitionState'\nimport { addClasses, mergeRefs, nextFrame, removeClasses } from '../utils'\nimport type { KineticConfig } from './types'\n\ntype TransitionRendererProps = {\n config: KineticConfig\n htmlProps: Record<string, unknown>\n show: () => boolean\n appear?: boolean | undefined\n unmount?: boolean | undefined\n timeout?: number | undefined\n callbacks: Partial<TransitionCallbacks>\n children: VNode | VNode[]\n}\n\nconst applyEnter = (el: HTMLElement, config: KineticConfig) => {\n addClasses(el, config.enter)\n addClasses(el, config.enterFrom)\n if (config.enterStyle) Object.assign(el.style, config.enterStyle)\n if (config.enterTransition) el.style.transition = config.enterTransition\n\n return nextFrame(() => {\n removeClasses(el, config.enterFrom)\n addClasses(el, config.enterTo)\n if (config.enterToStyle) Object.assign(el.style, config.enterToStyle)\n })\n}\n\nconst applyLeave = (el: HTMLElement, config: KineticConfig) => {\n removeClasses(el, config.enter)\n removeClasses(el, config.enterTo)\n\n addClasses(el, config.leave)\n addClasses(el, config.leaveFrom)\n if (config.leaveStyle) Object.assign(el.style, config.leaveStyle)\n if (config.leaveTransition) el.style.transition = config.leaveTransition\n\n return nextFrame(() => {\n removeClasses(el, config.leaveFrom)\n addClasses(el, config.leaveTo)\n if (config.leaveToStyle) Object.assign(el.style, config.leaveToStyle)\n })\n}\n\nconst applyReducedMotion = (\n stage: string,\n cbs: Partial<TransitionCallbacks>,\n complete: () => void,\n) => {\n if (stage === 'entering') {\n cbs.onEnter?.()\n cbs.onAfterEnter?.()\n complete()\n } else if (stage === 'leaving') {\n cbs.onLeave?.()\n cbs.onAfterLeave?.()\n complete()\n }\n}\n\n/**\n * Renders a single element with CSS transition enter/exit animation.\n * Uses h(config.tag) — no cloneElement needed.\n */\nconst TransitionRenderer = ({\n config,\n htmlProps,\n show,\n appear,\n unmount,\n timeout,\n callbacks,\n children,\n}: TransitionRendererProps): VNode | null => {\n const reducedMotion = useReducedMotion()\n const {\n stage,\n ref: stateRef,\n shouldMount,\n complete,\n } = useTransitionState({\n show,\n appear: appear ?? config.appear ?? false,\n })\n\n const elementRef = createRef<HTMLElement>()\n const mergedRef = mergeRefs(elementRef, stateRef)\n\n const effectiveUnmount = unmount ?? config.unmount ?? true\n const effectiveTimeout = timeout ?? config.timeout ?? 5000\n\n useAnimationEnd({\n ref: elementRef,\n active: () => (stage() === 'entering' || stage() === 'leaving') && !reducedMotion(),\n timeout: effectiveTimeout,\n onEnd: () => {\n if (stage() === 'entering') {\n callbacks.onAfterEnter?.()\n } else if (stage() === 'leaving') {\n callbacks.onAfterLeave?.()\n }\n complete()\n },\n })\n\n watch(\n () => stage(),\n (currentStage) => {\n const el = elementRef.current\n if (!el) return\n\n if (reducedMotion()) {\n applyReducedMotion(currentStage, callbacks, complete)\n return\n }\n\n if (currentStage === 'entering') {\n callbacks.onEnter?.()\n const frameId = applyEnter(el, config)\n return () => cancelAnimationFrame(frameId)\n }\n\n if (currentStage === 'leaving') {\n callbacks.onLeave?.()\n const frameId = applyLeave(el, config)\n return () => cancelAnimationFrame(frameId)\n }\n\n if (currentStage === 'entered') {\n removeClasses(el, config.enter)\n el.style.transition = ''\n }\n },\n { immediate: true },\n )\n\n return (\n <Show\n when={shouldMount}\n fallback={\n effectiveUnmount\n ? null\n : h(\n config.tag,\n {\n ref: mergedRef,\n ...htmlProps,\n style: {\n ...((htmlProps.style as CSSProperties) ?? {}),\n display: 'none',\n },\n },\n children,\n )\n }\n >\n {h(config.tag, { ref: mergedRef, ...htmlProps }, children)}\n </Show>\n )\n}\n\nexport default TransitionRenderer\n","import type { VNode } from '@pyreon/core'\nimport type { CSSProperties, TransitionCallbacks } from '../types'\nimport CollapseRenderer from './CollapseRenderer'\nimport GroupRenderer from './GroupRenderer'\nimport StaggerRenderer from './StaggerRenderer'\nimport TransitionRenderer from './TransitionRenderer'\nimport type { ClassConfig, KineticComponent, KineticConfig, KineticMode } from './types'\n\n/** Keys that are kinetic-specific and should not be forwarded as HTML attrs. */\nconst KINETIC_KEYS = new Set([\n 'show',\n 'appear',\n 'unmount',\n 'timeout',\n 'transition',\n 'interval',\n 'reverseLeave',\n 'onEnter',\n 'onAfterEnter',\n 'onLeave',\n 'onAfterLeave',\n])\n\n/**\n * Core factory. Creates a component that delegates to the appropriate\n * renderer based on config.mode, then attaches immutable chain methods\n * via Object.assign.\n */\nconst createKineticComponent = <Tag extends string, Mode extends KineticMode = 'transition'>(\n config: KineticConfig,\n): KineticComponent<Tag, Mode> => {\n const Component = (props: Record<string, unknown>): VNode | null => {\n // Separate kinetic-specific props from HTML pass-through props\n const htmlProps: Record<string, unknown> = {}\n const kineticProps: Record<string, unknown> = {}\n\n for (const key in props) {\n if (KINETIC_KEYS.has(key)) {\n kineticProps[key] = props[key]\n } else {\n htmlProps[key] = props[key]\n }\n }\n\n const {\n show,\n appear,\n unmount,\n timeout,\n transition,\n interval,\n reverseLeave,\n onEnter,\n onAfterEnter,\n onLeave,\n onAfterLeave,\n } = kineticProps as {\n show?: () => boolean\n appear?: boolean\n unmount?: boolean\n timeout?: number\n transition?: string\n interval?: number\n reverseLeave?: boolean\n } & Partial<TransitionCallbacks>\n\n const callbacks: Partial<TransitionCallbacks> = {\n onEnter: onEnter ?? config.onEnter,\n onAfterEnter: onAfterEnter ?? config.onAfterEnter,\n onLeave: onLeave ?? config.onLeave,\n onAfterLeave: onAfterLeave ?? config.onAfterLeave,\n }\n\n // Extract children from htmlProps (it's not an HTML attribute)\n const { children, ...restHtml } = htmlProps\n\n if (config.mode === 'collapse') {\n return (\n <CollapseRenderer\n config={config}\n htmlProps={restHtml}\n show={show as () => boolean}\n appear={appear}\n timeout={timeout}\n transition={transition}\n callbacks={callbacks}\n >\n {children as VNode | VNode[]}\n </CollapseRenderer>\n )\n }\n\n if (config.mode === 'stagger') {\n return (\n <StaggerRenderer\n config={config}\n htmlProps={restHtml}\n show={show as () => boolean}\n appear={appear}\n timeout={timeout}\n interval={interval}\n reverseLeave={reverseLeave}\n callbacks={callbacks}\n >\n {children as VNode[]}\n </StaggerRenderer>\n )\n }\n\n if (config.mode === 'group') {\n return (\n <GroupRenderer\n config={config}\n htmlProps={restHtml}\n appear={appear}\n timeout={timeout}\n callbacks={callbacks}\n >\n {children as VNode[]}\n </GroupRenderer>\n )\n }\n\n // Default: transition mode\n return (\n <TransitionRenderer\n config={config}\n htmlProps={restHtml}\n show={show as () => boolean}\n appear={appear}\n unmount={unmount}\n timeout={timeout}\n callbacks={callbacks}\n >\n {children as VNode | VNode[]}\n </TransitionRenderer>\n )\n }\n\n Component.displayName = `kinetic(${config.tag})`\n\n // Immutable chain methods — each returns a new component with merged config.\n return Object.assign(Component, {\n preset: (preset: Record<string, unknown>) =>\n createKineticComponent<Tag, Mode>({\n ...config,\n ...preset,\n } as KineticConfig),\n\n enter: (styles: CSSProperties) =>\n createKineticComponent<Tag, Mode>({ ...config, enterStyle: styles }),\n\n enterTo: (styles: CSSProperties) =>\n createKineticComponent<Tag, Mode>({ ...config, enterToStyle: styles }),\n\n enterTransition: (value: string) =>\n createKineticComponent<Tag, Mode>({ ...config, enterTransition: value }),\n\n leave: (styles: CSSProperties) =>\n createKineticComponent<Tag, Mode>({ ...config, leaveStyle: styles }),\n\n leaveTo: (styles: CSSProperties) =>\n createKineticComponent<Tag, Mode>({ ...config, leaveToStyle: styles }),\n\n leaveTransition: (value: string) =>\n createKineticComponent<Tag, Mode>({ ...config, leaveTransition: value }),\n\n enterClass: ({ active, from, to }: ClassConfig) =>\n createKineticComponent<Tag, Mode>({\n ...config,\n enter: active,\n enterFrom: from,\n enterTo: to,\n }),\n\n leaveClass: ({ active, from, to }: ClassConfig) =>\n createKineticComponent<Tag, Mode>({\n ...config,\n leave: active,\n leaveFrom: from,\n leaveTo: to,\n }),\n\n config: (opts: Record<string, unknown>) =>\n createKineticComponent<Tag, Mode>({\n ...config,\n ...opts,\n } as KineticConfig),\n\n on: (cbs: Partial<TransitionCallbacks>) =>\n createKineticComponent<Tag, Mode>({ ...config, ...cbs }),\n\n collapse: (opts?: { transition?: string }) =>\n createKineticComponent<Tag, 'collapse'>({\n ...config,\n mode: 'collapse',\n ...opts,\n }),\n\n stagger: (opts?: { interval?: number; reverseLeave?: boolean }) =>\n createKineticComponent<Tag, 'stagger'>({\n ...config,\n mode: 'stagger',\n ...opts,\n }),\n\n group: () => createKineticComponent<Tag, 'group'>({ ...config, mode: 'group' }),\n }) as unknown as KineticComponent<Tag, Mode>\n}\n\nexport default createKineticComponent\n","import createKineticComponent from './kinetic/createKineticComponent'\nimport type { KineticComponent } from './kinetic/types'\n\n/**\n * Creates a reusable animated component via immutable chaining.\n *\n * @example\n * ```tsx\n * // Transition (default)\n * const FadeDiv = kinetic('div').preset(fade)\n *\n * // Collapse\n * const Accordion = kinetic('div').collapse()\n *\n * // Stagger\n * const StaggerList = kinetic('ul').preset(slideUp).stagger({ interval: 50 })\n *\n * // Group (key-based enter/exit)\n * const AnimatedList = kinetic('ul').preset(fade).group()\n * ```\n */\nconst kinetic = <Tag extends string>(tag: Tag): KineticComponent<Tag, 'transition'> =>\n createKineticComponent<Tag, 'transition'>({ tag, mode: 'transition' })\n\nexport default kinetic\n","import type { ClassTransitionProps, StyleTransitionProps } from './types'\n\nexport type Preset = StyleTransitionProps & ClassTransitionProps\n\nexport const fade: Preset = {\n enterStyle: { opacity: 0 },\n enterToStyle: { opacity: 1 },\n enterTransition: 'opacity 300ms ease-out',\n leaveStyle: { opacity: 1 },\n leaveToStyle: { opacity: 0 },\n leaveTransition: 'opacity 200ms ease-in',\n}\n\nexport const scaleIn: Preset = {\n enterStyle: { opacity: 0, transform: 'scale(0.95)' },\n enterToStyle: { opacity: 1, transform: 'scale(1)' },\n enterTransition: 'opacity 300ms ease-out, transform 300ms ease-out',\n leaveStyle: { opacity: 1, transform: 'scale(1)' },\n leaveToStyle: { opacity: 0, transform: 'scale(0.95)' },\n leaveTransition: 'opacity 200ms ease-in, transform 200ms ease-in',\n}\n\nexport const slideUp: Preset = {\n enterStyle: { opacity: 0, transform: 'translateY(16px)' },\n enterToStyle: { opacity: 1, transform: 'translateY(0)' },\n enterTransition: 'opacity 300ms ease-out, transform 300ms ease-out',\n leaveStyle: { opacity: 1, transform: 'translateY(0)' },\n leaveToStyle: { opacity: 0, transform: 'translateY(16px)' },\n leaveTransition: 'opacity 200ms ease-in, transform 200ms ease-in',\n}\n\nexport const slideDown: Preset = {\n enterStyle: { opacity: 0, transform: 'translateY(-16px)' },\n enterToStyle: { opacity: 1, transform: 'translateY(0)' },\n enterTransition: 'opacity 300ms ease-out, transform 300ms ease-out',\n leaveStyle: { opacity: 1, transform: 'translateY(0)' },\n leaveToStyle: { opacity: 0, transform: 'translateY(-16px)' },\n leaveTransition: 'opacity 200ms ease-in, transform 200ms ease-in',\n}\n\nexport const slideLeft: Preset = {\n enterStyle: { opacity: 0, transform: 'translateX(16px)' },\n enterToStyle: { opacity: 1, transform: 'translateX(0)' },\n enterTransition: 'opacity 300ms ease-out, transform 300ms ease-out',\n leaveStyle: { opacity: 1, transform: 'translateX(0)' },\n leaveToStyle: { opacity: 0, transform: 'translateX(16px)' },\n leaveTransition: 'opacity 200ms ease-in, transform 200ms ease-in',\n}\n\nexport const slideRight: Preset = {\n enterStyle: { opacity: 0, transform: 'translateX(-16px)' },\n enterToStyle: { opacity: 1, transform: 'translateX(0)' },\n enterTransition: 'opacity 300ms ease-out, transform 300ms ease-out',\n leaveStyle: { opacity: 1, transform: 'translateX(0)' },\n leaveToStyle: { opacity: 0, transform: 'translateX(-16px)' },\n leaveTransition: 'opacity 200ms ease-in, transform 200ms ease-in',\n}\n\nexport const presets = {\n fade,\n scaleIn,\n slideUp,\n slideDown,\n slideLeft,\n slideRight,\n} as const\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/kinetic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "CSS-transition-based animation components for Pyreon",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"lib",
|
|
13
|
-
"!lib/**/*.map",
|
|
14
13
|
"!lib/analysis",
|
|
15
14
|
"README.md",
|
|
16
15
|
"LICENSE",
|
|
@@ -41,12 +40,12 @@
|
|
|
41
40
|
"typecheck": "tsc --noEmit"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
|
-
"@pyreon/typescript": "^0.
|
|
43
|
+
"@pyreon/typescript": "^0.12.1",
|
|
45
44
|
"@vitus-labs/tools-rolldown": "^1.15.3"
|
|
46
45
|
},
|
|
47
46
|
"peerDependencies": {
|
|
48
|
-
"@pyreon/core": "^0.
|
|
49
|
-
"@pyreon/reactivity": "^0.
|
|
47
|
+
"@pyreon/core": "^0.12.1",
|
|
48
|
+
"@pyreon/reactivity": "^0.12.1"
|
|
50
49
|
},
|
|
51
50
|
"engines": {
|
|
52
51
|
"node": ">= 22"
|
package/src/Collapse.tsx
CHANGED
|
@@ -5,29 +5,23 @@ import type { CollapseProps, TransitionStage } from './types'
|
|
|
5
5
|
import useAnimationEnd from './useAnimationEnd'
|
|
6
6
|
import { useReducedMotion } from './useReducedMotion'
|
|
7
7
|
|
|
8
|
-
const Collapse = ({
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
onEnter,
|
|
14
|
-
onAfterEnter,
|
|
15
|
-
onLeave,
|
|
16
|
-
onAfterLeave,
|
|
17
|
-
children,
|
|
18
|
-
}: CollapseProps): VNode | null => {
|
|
8
|
+
const Collapse = (props: CollapseProps): VNode | null => {
|
|
9
|
+
const transition = props.transition ?? 'height 300ms ease'
|
|
10
|
+
const appear = props.appear ?? false
|
|
11
|
+
const timeout = props.timeout ?? 5000
|
|
12
|
+
|
|
19
13
|
const reducedMotion = useReducedMotion()
|
|
20
14
|
let wrapperRef: { current: HTMLDivElement | null } = createRef<HTMLDivElement>()
|
|
21
15
|
const contentRef = createRef<HTMLDivElement>()
|
|
22
16
|
|
|
23
17
|
const callbacks = {
|
|
24
|
-
onEnter,
|
|
25
|
-
onAfterEnter,
|
|
26
|
-
onLeave,
|
|
27
|
-
onAfterLeave,
|
|
18
|
+
onEnter: props.onEnter,
|
|
19
|
+
onAfterEnter: props.onAfterEnter,
|
|
20
|
+
onLeave: props.onLeave,
|
|
21
|
+
onAfterLeave: props.onAfterLeave,
|
|
28
22
|
}
|
|
29
23
|
|
|
30
|
-
const initialShow = show()
|
|
24
|
+
const initialShow = props.show()
|
|
31
25
|
// When appear=true and show starts true, mount but defer animation until ref is wired
|
|
32
26
|
const needsAppear = appear && initialShow
|
|
33
27
|
const stage = signal<TransitionStage>(initialShow ? 'entered' : 'hidden')
|
|
@@ -56,7 +50,7 @@ const Collapse = ({
|
|
|
56
50
|
|
|
57
51
|
// State machine transitions
|
|
58
52
|
watch(
|
|
59
|
-
show,
|
|
53
|
+
props.show,
|
|
60
54
|
(showVal) => {
|
|
61
55
|
if (isInitialMount) {
|
|
62
56
|
isInitialMount = false
|
|
@@ -163,7 +157,7 @@ const Collapse = ({
|
|
|
163
157
|
}}
|
|
164
158
|
>
|
|
165
159
|
<Show when={shouldRender}>
|
|
166
|
-
<div ref={contentRef}>{children}</div>
|
|
160
|
+
<div ref={contentRef}>{props.children}</div>
|
|
167
161
|
</Show>
|
|
168
162
|
</div>
|
|
169
163
|
)
|
package/src/Stagger.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { VNode } from '@pyreon/core'
|
|
2
|
+
import { splitProps } from '@pyreon/core'
|
|
2
3
|
import Transition from './Transition'
|
|
3
4
|
import type { CSSProperties, StaggerProps } from './types'
|
|
4
5
|
import { cloneVNode } from './utils'
|
|
@@ -6,33 +7,38 @@ import { cloneVNode } from './utils'
|
|
|
6
7
|
const isVNode = (child: unknown): child is VNode =>
|
|
7
8
|
child != null && typeof child === 'object' && 'type' in (child as object)
|
|
8
9
|
|
|
9
|
-
const Stagger = ({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
10
|
+
const Stagger = (props: StaggerProps): VNode | null => {
|
|
11
|
+
const [own, transitionProps] = splitProps(props, [
|
|
12
|
+
'show',
|
|
13
|
+
'interval',
|
|
14
|
+
'reverseLeave',
|
|
15
|
+
'appear',
|
|
16
|
+
'timeout',
|
|
17
|
+
'children',
|
|
18
|
+
'onAfterLeave',
|
|
19
|
+
])
|
|
20
|
+
const interval = own.interval ?? 50
|
|
21
|
+
const reverseLeave = own.reverseLeave ?? false
|
|
22
|
+
const appear = own.appear ?? false
|
|
23
|
+
const timeout = own.timeout ?? 5000
|
|
24
|
+
|
|
25
|
+
const childArray = (Array.isArray(own.children) ? own.children : [own.children]).filter(isVNode)
|
|
20
26
|
const count = childArray.length
|
|
21
27
|
|
|
22
28
|
return (
|
|
23
29
|
<>
|
|
24
30
|
{childArray.map((child, index) => {
|
|
25
|
-
const staggerIndex = !show() && reverseLeave ? count - 1 - index : index
|
|
31
|
+
const staggerIndex = !own.show() && reverseLeave ? count - 1 - index : index
|
|
26
32
|
const delay = staggerIndex * interval
|
|
27
33
|
|
|
28
34
|
return (
|
|
29
35
|
<Transition
|
|
30
36
|
key={(child as VNode & { key?: string | number }).key ?? index}
|
|
31
|
-
show={show}
|
|
37
|
+
show={own.show}
|
|
32
38
|
appear={appear}
|
|
33
39
|
timeout={timeout + delay}
|
|
34
40
|
{...transitionProps}
|
|
35
|
-
onAfterLeave={index === (reverseLeave ? 0 : count - 1) ? onAfterLeave : undefined}
|
|
41
|
+
onAfterLeave={index === (reverseLeave ? 0 : count - 1) ? own.onAfterLeave : undefined}
|
|
36
42
|
>
|
|
37
43
|
{cloneVNode(child, {
|
|
38
44
|
style: {
|
package/src/Transition.tsx
CHANGED
|
@@ -79,29 +79,11 @@ const applyReducedMotion = (
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
const Transition = ({
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
enter,
|
|
88
|
-
enterFrom,
|
|
89
|
-
enterTo,
|
|
90
|
-
leave,
|
|
91
|
-
leaveFrom,
|
|
92
|
-
leaveTo,
|
|
93
|
-
enterStyle,
|
|
94
|
-
enterToStyle,
|
|
95
|
-
enterTransition,
|
|
96
|
-
leaveStyle,
|
|
97
|
-
leaveToStyle,
|
|
98
|
-
leaveTransition,
|
|
99
|
-
onEnter,
|
|
100
|
-
onAfterEnter,
|
|
101
|
-
onLeave,
|
|
102
|
-
onAfterLeave,
|
|
103
|
-
children,
|
|
104
|
-
}: TransitionProps): VNode | null => {
|
|
82
|
+
const Transition = (props: TransitionProps): VNode | null => {
|
|
83
|
+
const appear = props.appear ?? false
|
|
84
|
+
const unmount = props.unmount ?? true
|
|
85
|
+
const timeout = props.timeout ?? 5000
|
|
86
|
+
|
|
105
87
|
const reducedMotion = useReducedMotion()
|
|
106
88
|
const {
|
|
107
89
|
stage,
|
|
@@ -109,12 +91,12 @@ const Transition = ({
|
|
|
109
91
|
shouldMount,
|
|
110
92
|
complete,
|
|
111
93
|
} = useTransitionState({
|
|
112
|
-
show,
|
|
94
|
+
show: props.show,
|
|
113
95
|
appear,
|
|
114
96
|
})
|
|
115
97
|
|
|
116
98
|
const elementRef = createRef<HTMLElement>()
|
|
117
|
-
const childProps = (children.props ?? {}) as Record<string, unknown>
|
|
99
|
+
const childProps = (props.children.props ?? {}) as Record<string, unknown>
|
|
118
100
|
const mergedRef = mergeRefs(
|
|
119
101
|
elementRef,
|
|
120
102
|
stateRef,
|
|
@@ -122,25 +104,25 @@ const Transition = ({
|
|
|
122
104
|
)
|
|
123
105
|
|
|
124
106
|
const callbacks = {
|
|
125
|
-
onEnter,
|
|
126
|
-
onAfterEnter,
|
|
127
|
-
onLeave,
|
|
128
|
-
onAfterLeave,
|
|
107
|
+
onEnter: props.onEnter,
|
|
108
|
+
onAfterEnter: props.onAfterEnter,
|
|
109
|
+
onLeave: props.onLeave,
|
|
110
|
+
onAfterLeave: props.onAfterLeave,
|
|
129
111
|
}
|
|
130
112
|
|
|
131
113
|
const transitionConfig = {
|
|
132
|
-
enter,
|
|
133
|
-
enterFrom,
|
|
134
|
-
enterTo,
|
|
135
|
-
leave,
|
|
136
|
-
leaveFrom,
|
|
137
|
-
leaveTo,
|
|
138
|
-
enterStyle,
|
|
139
|
-
enterToStyle,
|
|
140
|
-
enterTransition,
|
|
141
|
-
leaveStyle,
|
|
142
|
-
leaveToStyle,
|
|
143
|
-
leaveTransition,
|
|
114
|
+
enter: props.enter,
|
|
115
|
+
enterFrom: props.enterFrom,
|
|
116
|
+
enterTo: props.enterTo,
|
|
117
|
+
leave: props.leave,
|
|
118
|
+
leaveFrom: props.leaveFrom,
|
|
119
|
+
leaveTo: props.leaveTo,
|
|
120
|
+
enterStyle: props.enterStyle,
|
|
121
|
+
enterToStyle: props.enterToStyle,
|
|
122
|
+
enterTransition: props.enterTransition,
|
|
123
|
+
leaveStyle: props.leaveStyle,
|
|
124
|
+
leaveToStyle: props.leaveToStyle,
|
|
125
|
+
leaveTransition: props.leaveTransition,
|
|
144
126
|
}
|
|
145
127
|
|
|
146
128
|
useAnimationEnd({
|
|
@@ -181,7 +163,7 @@ const Transition = ({
|
|
|
181
163
|
}
|
|
182
164
|
|
|
183
165
|
if (currentStage === 'entered') {
|
|
184
|
-
removeClasses(el, enter)
|
|
166
|
+
removeClasses(el, props.enter)
|
|
185
167
|
el.style.transition = ''
|
|
186
168
|
}
|
|
187
169
|
},
|
|
@@ -194,7 +176,7 @@ const Transition = ({
|
|
|
194
176
|
fallback={
|
|
195
177
|
unmount
|
|
196
178
|
? null
|
|
197
|
-
: cloneVNode(children, {
|
|
179
|
+
: cloneVNode(props.children, {
|
|
198
180
|
ref: mergedRef,
|
|
199
181
|
style: mergeStyles(
|
|
200
182
|
childProps.style as Record<string, string | number | undefined> | undefined,
|
|
@@ -203,7 +185,7 @@ const Transition = ({
|
|
|
203
185
|
})
|
|
204
186
|
}
|
|
205
187
|
>
|
|
206
|
-
{cloneVNode(children, { ref: mergedRef })}
|
|
188
|
+
{cloneVNode(props.children, { ref: mergedRef })}
|
|
207
189
|
</Show>
|
|
208
190
|
)
|
|
209
191
|
}
|
package/src/TransitionGroup.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { VNode } from '@pyreon/core'
|
|
2
|
+
import { splitProps } from '@pyreon/core'
|
|
2
3
|
import { signal } from '@pyreon/reactivity'
|
|
3
4
|
import Transition from './Transition'
|
|
4
5
|
import type { ClassTransitionProps, StyleTransitionProps, TransitionCallbacks } from './types'
|
|
@@ -42,19 +43,23 @@ const getKeyedChildren = (children: VNode[]): KeyedChild[] => {
|
|
|
42
43
|
* The component uses a reactive accessor internally to diff previous vs
|
|
43
44
|
* current children and animate entries/exits.
|
|
44
45
|
*/
|
|
45
|
-
const TransitionGroup = ({
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
const TransitionGroup = (props: TransitionGroupProps): VNode | null => {
|
|
47
|
+
const [own, transitionProps] = splitProps(props, [
|
|
48
|
+
'children',
|
|
49
|
+
'appear',
|
|
50
|
+
'timeout',
|
|
51
|
+
'onAfterLeave',
|
|
52
|
+
])
|
|
53
|
+
const appear = own.appear ?? false
|
|
52
54
|
const prevMap = new Map<string | number, VNode>()
|
|
53
55
|
const leavingMap = new Map<string | number, VNode>()
|
|
54
56
|
const forceUpdate = signal(0)
|
|
55
57
|
|
|
56
58
|
// Normalize children to an accessor for uniform handling
|
|
57
|
-
const getChildren =
|
|
59
|
+
const getChildren =
|
|
60
|
+
typeof own.children === 'function'
|
|
61
|
+
? (own.children as () => VNode[])
|
|
62
|
+
: () => own.children as VNode[]
|
|
58
63
|
|
|
59
64
|
// Track initial keys for appear animation logic
|
|
60
65
|
const initialKeyed = getKeyedChildren(getChildren())
|
|
@@ -65,7 +70,7 @@ const TransitionGroup = ({
|
|
|
65
70
|
|
|
66
71
|
const handleAfterLeave = (key: string | number) => {
|
|
67
72
|
leavingMap.delete(key)
|
|
68
|
-
onAfterLeave?.()
|
|
73
|
+
own.onAfterLeave?.()
|
|
69
74
|
forceUpdate.update((c) => c + 1)
|
|
70
75
|
}
|
|
71
76
|
|
|
@@ -118,7 +123,7 @@ const TransitionGroup = ({
|
|
|
118
123
|
key={key}
|
|
119
124
|
show={() => isShowing}
|
|
120
125
|
appear={isInitial ? appear : true}
|
|
121
|
-
timeout={timeout}
|
|
126
|
+
timeout={own.timeout}
|
|
122
127
|
{...transitionProps}
|
|
123
128
|
onAfterLeave={() => handleAfterLeave(key)}
|
|
124
129
|
>
|