diff --git a/src/uix/eidos/components/badge/badge.svelte b/src/uix/eidos/components/badge/badge.svelte index 8df4518ae..f9279c3ed 100644 --- a/src/uix/eidos/components/badge/badge.svelte +++ b/src/uix/eidos/components/badge/badge.svelte @@ -12,7 +12,7 @@ * Optional Dot / Icon / Remove sub-parts compose inside. */ import './badge.css'; - import { ActiveEidos } from '$uix/eidos'; + import { ActiveEidos, motionAttrs } from '$uix/eidos'; import { BADGE_LANGS } from './langs'; import type { BadgeProps } from './types'; @@ -27,6 +27,7 @@ onRemove, removeLabel, icon, + motion, children, ...rest }: BadgeProps = $props(); @@ -49,6 +50,7 @@ data-shape={shape} data-dot={dot ? '' : undefined} data-removable={removable ? '' : undefined} + {...motionAttrs(motion)} {...rest} > {#if dot} diff --git a/src/uix/eidos/components/badge/types.ts b/src/uix/eidos/components/badge/types.ts index 25dfd9a85..ba55e9956 100644 --- a/src/uix/eidos/components/badge/types.ts +++ b/src/uix/eidos/components/badge/types.ts @@ -1,5 +1,6 @@ import type { Snippet } from 'svelte'; import type { ChipVariant, ColorRole, ResponsiveProp, ShapeFamily, Size } from '$uix/eidos/lib/types'; +import type { MotionPresetName } from '$uix/eidos/lib/motion/registry'; import type { BoxProps } from '../box/types'; /** @@ -78,4 +79,11 @@ export type BadgeProps = Omit & { icon?: Snippet; /** Badge label. */ children?: Snippet; + /** + * Entrance animation — any registered motion preset (`fade` / `scale-fade` / + * `slide-fade` / …). The badge plays the preset's enter on mount (content + * domain — RFC §D.12; routed via `motionAttrs`). `undefined` (default) = no + * animation. A common use: a notification badge that pops in. + */ + motion?: MotionPresetName; }; diff --git a/web/routes/uix/components/badge/+page.svelte b/web/routes/uix/components/badge/+page.svelte index df39b81d9..6ba6101f8 100644 --- a/web/routes/uix/components/badge/+page.svelte +++ b/web/routes/uix/components/badge/+page.svelte @@ -30,6 +30,8 @@ let withIcon = $state(false); let removable = $state(false); let removeCount = $state(0); + // Remount key so the on-mount entrance animation can be replayed on demand. + let motionReplay = $state(0); const variants: BadgeVariant[] = ['soft', 'solid', 'outline', 'ghost']; const sizes: BadgeSize[] = ['xs', 'sm', 'md', 'lg']; @@ -770,6 +772,31 @@ dot + remove + +
Motion · entrance animation (content domain · RFC §D.12)
+ +

+ Any component can opt into a registered motion preset via the motion prop — + the badge plays its enter on mount (routed through motionAttrs, reusing the + existing preset, no per-component machinery). undefined = no animation. +

+ + {#key motionReplay} + + motion="fade" + motion="scale-fade" + motion="slide-fade" + + {/key} +
{/if}