kuinetic 0.1.4 → 0.2.0

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.
Files changed (124) hide show
  1. package/README.md +93 -10
  2. package/dist/esm/advanced/index.mjs +4727 -0
  3. package/dist/esm/chunk-AEQGC2KM.mjs +189 -0
  4. package/dist/esm/chunk-MQSNMYRP.mjs +9332 -0
  5. package/dist/esm/chunk-RVTYN6NZ.mjs +3446 -0
  6. package/dist/esm/chunk-U43BX5O2.mjs +2984 -0
  7. package/dist/esm/core/index.mjs +16 -9
  8. package/dist/esm/effects/index.mjs +19 -4
  9. package/dist/esm/index.mjs +17 -10
  10. package/dist/kuinetic.advanced.js +5070 -0
  11. package/dist/kuinetic.advanced.min.js +749 -0
  12. package/dist/kuinetic.all.js +15147 -6039
  13. package/dist/kuinetic.all.min.js +2 -0
  14. package/dist/kuinetic.css +2801 -318
  15. package/dist/kuinetic.js +15147 -6038
  16. package/dist/kuinetic.min.css +1 -0
  17. package/dist/kuinetic.min.js +7 -0
  18. package/dist/types/3d/angles.d.ts +30 -0
  19. package/dist/types/3d/flattening.d.ts +49 -0
  20. package/dist/types/3d/index.d.ts +36 -0
  21. package/dist/types/3d/model-3d.d.ts +115 -0
  22. package/dist/types/3d/register.d.ts +26 -0
  23. package/dist/types/3d/webgl.d.ts +24 -0
  24. package/dist/types/advanced/audio.d.ts +322 -0
  25. package/dist/types/advanced/base.d.ts +233 -0
  26. package/dist/types/advanced/camera-3d.d.ts +236 -0
  27. package/dist/types/advanced/fluid-cursor.d.ts +149 -0
  28. package/dist/types/advanced/gl-utils.d.ts +52 -0
  29. package/dist/types/advanced/glsl.d.ts +60 -0
  30. package/dist/types/advanced/index.d.ts +23 -0
  31. package/dist/types/advanced/particles.d.ts +108 -0
  32. package/dist/types/advanced/scenes.d.ts +207 -0
  33. package/dist/types/advanced/shaders.d.ts +972 -0
  34. package/dist/types/browser/boot.d.ts +72 -0
  35. package/dist/types/core/activation.d.ts +227 -2
  36. package/dist/types/core/animator.d.ts +446 -11
  37. package/dist/types/core/attrs.d.ts +9 -0
  38. package/dist/types/core/breakpoints.d.ts +260 -0
  39. package/dist/types/core/bundles.d.ts +71 -0
  40. package/dist/types/core/callback.d.ts +64 -0
  41. package/dist/types/core/capabilities.d.ts +47 -0
  42. package/dist/types/core/channels.d.ts +120 -2
  43. package/dist/types/core/cloak-selectors.d.ts +47 -0
  44. package/dist/types/core/compile.d.ts +207 -2
  45. package/dist/types/core/control.d.ts +218 -0
  46. package/dist/types/core/declarations.d.ts +128 -0
  47. package/dist/types/core/derived/aggregate.d.ts +43 -0
  48. package/dist/types/core/derived/book.d.ts +30 -0
  49. package/dist/types/core/derived/diagnostics.d.ts +51 -0
  50. package/dist/types/core/derived/group-gate.d.ts +62 -0
  51. package/dist/types/core/derived/install.d.ts +110 -0
  52. package/dist/types/core/derived/late-matches.d.ts +19 -0
  53. package/dist/types/core/derived/types.d.ts +108 -0
  54. package/dist/types/core/easing.d.ts +57 -0
  55. package/dist/types/core/element-config.d.ts +47 -6
  56. package/dist/types/core/element-size.d.ts +23 -0
  57. package/dist/types/core/event-sources.d.ts +39 -0
  58. package/dist/types/core/flip.d.ts +34 -1
  59. package/dist/types/core/gesture.d.ts +12 -0
  60. package/dist/types/core/host-facts.d.ts +155 -0
  61. package/dist/types/core/index.d.ts +7 -3
  62. package/dist/types/core/owned-styles.d.ts +129 -2
  63. package/dist/types/core/params.d.ts +48 -0
  64. package/dist/types/core/parse.d.ts +28 -1
  65. package/dist/types/core/register-into.d.ts +29 -0
  66. package/dist/types/core/registry.d.ts +10 -3
  67. package/dist/types/core/repeat.d.ts +91 -0
  68. package/dist/types/core/sequence.d.ts +126 -0
  69. package/dist/types/core/stagger-config.d.ts +199 -0
  70. package/dist/types/core/stagger-keys.d.ts +63 -0
  71. package/dist/types/core/stagger.d.ts +187 -6
  72. package/dist/types/core/style-plan.d.ts +21 -16
  73. package/dist/types/core/target.d.ts +128 -0
  74. package/dist/types/core/threshold-reachability.d.ts +45 -0
  75. package/dist/types/core/time-scale.d.ts +9 -0
  76. package/dist/types/core/toggle-actions.d.ts +141 -0
  77. package/dist/types/core/travel.d.ts +59 -0
  78. package/dist/types/core/types.d.ts +699 -13
  79. package/dist/types/core/unquoted-selectors.d.ts +53 -0
  80. package/dist/types/effects/carousel/drag.d.ts +80 -0
  81. package/dist/types/effects/carousel/index.d.ts +149 -0
  82. package/dist/types/effects/catalog/discrete.d.ts +13 -0
  83. package/dist/types/effects/catalog/interaction-proximity.d.ts +24 -0
  84. package/dist/types/effects/catalog/interaction-reveal.d.ts +248 -0
  85. package/dist/types/effects/catalog/interaction-shared.d.ts +42 -0
  86. package/dist/types/effects/catalog/interaction-states.d.ts +68 -0
  87. package/dist/types/effects/catalog/materials.d.ts +67 -0
  88. package/dist/types/effects/catalog/media-shared.d.ts +3 -2
  89. package/dist/types/effects/catalog/numbers-shared.d.ts +8 -5
  90. package/dist/types/effects/catalog/shared.d.ts +1 -1
  91. package/dist/types/effects/catalog/text-shared.d.ts +86 -10
  92. package/dist/types/effects/catalog/transforms.d.ts +13 -0
  93. package/dist/types/effects/catalog/view-transitions.d.ts +13 -0
  94. package/dist/types/effects/forms/primitives.d.ts +15 -4
  95. package/dist/types/effects/gestures/index.d.ts +53 -0
  96. package/dist/types/effects/index.d.ts +5 -0
  97. package/dist/types/effects/layout/presets.d.ts +35 -0
  98. package/dist/types/effects/motion-path/index.d.ts +35 -0
  99. package/dist/types/effects/scroll-mechanics/params.d.ts +23 -0
  100. package/dist/types/effects/scroll-mechanics/presets.d.ts +51 -0
  101. package/dist/types/effects/scroll-mechanics/section-index.d.ts +47 -0
  102. package/dist/types/effects/shared.d.ts +124 -4
  103. package/dist/types/effects/step-index.d.ts +121 -0
  104. package/dist/types/effects/step-marking.d.ts +41 -33
  105. package/dist/types/effects/svg/icon-parts.d.ts +23 -0
  106. package/dist/types/effects/three-d/flip-parts.d.ts +46 -0
  107. package/dist/types/effects/tween/index.d.ts +57 -0
  108. package/dist/types/effects/tween/properties.d.ts +107 -0
  109. package/dist/types/effects/tween/waypoints.d.ts +106 -0
  110. package/dist/types/showcase/compare.d.ts +4 -0
  111. package/dist/types/showcase/device-frame.d.ts +3 -0
  112. package/dist/types/showcase/hotspots.d.ts +3 -0
  113. package/dist/types/showcase/index.d.ts +30 -0
  114. package/dist/types/showcase/lightbox.d.ts +3 -0
  115. package/dist/types/showcase/media-source.d.ts +13 -0
  116. package/dist/types/showcase/modal-shell.d.ts +22 -0
  117. package/dist/types/showcase/scroll-story.d.ts +4 -0
  118. package/dist/types/showcase/shared.d.ts +47 -0
  119. package/dist/types/showcase/slideshow.d.ts +3 -0
  120. package/dist/types/showcase/slow-mo.d.ts +5 -0
  121. package/package.json +14 -7
  122. package/dist/esm/chunk-7WMNPIOZ.mjs +0 -4883
  123. package/dist/esm/chunk-JT4PZL3A.mjs +0 -773
  124. package/dist/esm/chunk-TJDDIQRG.mjs +0 -1290
@@ -0,0 +1,107 @@
1
+ import type { Channel, ParamSpec, ParameterSchema } from '../../core/types.js';
2
+ /**
3
+ * The generic tween's vocabulary: which property names an author may put in a `key:value` slot,
4
+ * what each one means, and which keyframe block renders it.
5
+ *
6
+ * **Why this is an allowlist and not a passthrough.** `tween <name>:<value>` is the one place in
7
+ * the library where an author names a *CSS property* rather than choosing from a primitive's
8
+ * declared parameters, so the obvious implementation — write whatever they typed into whatever
9
+ * they typed — is also the one that breaks two invariants at once. It breaks composition, because
10
+ * `core/channels.ts` decides whether two effects may share an element from their declared channel
11
+ * sets and an open-ended property list has no channel; and it breaks the parameter contract in
12
+ * `core/params.ts`, which exists precisely because author strings end up in a stylesheet. An
13
+ * allowlist keeps every tweenable property on a known channel with a known value grammar, and
14
+ * costs only that a property nobody listed here cannot be tweened until someone adds a row.
15
+ *
16
+ * **Why the rows are grouped.** CSS writes `translate` as one property, not three; a keyframe that
17
+ * sets it sets every axis. So the unit of rendering is the *group* — one `@keyframes` block per
18
+ * group, one animation track per group the author actually touched — and not the individual key.
19
+ * See `src/css/tween.css`, where each group's block is written out, including what the identity
20
+ * fallbacks mean for an axis the author did not name.
21
+ */
22
+ /** One rendering unit: a single CSS property (or filter list) written by one keyframe block. */
23
+ export type TweenGroup = 'translate' | 'rotate' | 'scale' | 'opacity' | 'filter' | 'color' | 'background';
24
+ /**
25
+ * Declared in rendering order rather than derived from `TWEEN_PROPERTIES`'s key order, so
26
+ * `tween opacity:0 x:100` and `tween x:100 opacity:0` compile to the same track order. Two
27
+ * spellings of one animation producing two different `animation-name` lists would make every
28
+ * assertion about a compiled plan depend on the order the author happened to type in.
29
+ */
30
+ export declare const TWEEN_GROUP_ORDER: readonly TweenGroup[];
31
+ /**
32
+ * The channel each group claims — the honest answer to "what does this spec collide with".
33
+ *
34
+ * These are the existing catalog channels, not new ones: a tween writing `translate` must collide
35
+ * with `fade-up` for the same reason two entrances do, and giving the tween a private channel name
36
+ * would let exactly that pair compose into one effect silently overwriting the other.
37
+ */
38
+ export declare const TWEEN_GROUP_CHANNELS: Record<TweenGroup, Channel>;
39
+ interface TweenProperty {
40
+ group: TweenGroup;
41
+ spec: ParamSpec;
42
+ }
43
+ /**
44
+ * Author key → what it animates.
45
+ *
46
+ * Deliberately absent, and each for a reason worth writing down rather than rediscovering:
47
+ *
48
+ * - **`rotate-x` / `rotate-y`.** The CSS `rotate` property takes one axis at a time, so they could
49
+ * not share the rotate group with `rotate` anyway; and rotating a flat box about x or y without a
50
+ * `perspective()` reads as a vertical squash, not a turn. Perspective only exists inside the
51
+ * `transform` shorthand, which is a different channel entirely (`CHANNEL.skew` — see
52
+ * `core/types.ts`) and already has an effect family of its own in `flip-in-x`/`flip-in-y`.
53
+ * - **`width` / `height` / `top` / `left`.** Animatable, and every one of them animates layout.
54
+ * The tween declares `perfClass: 'paint'`; admitting these would make that a lie for the whole
55
+ * effect rather than for the one attribute that used them, and the library has never offered a
56
+ * layout-animating primitive without saying so.
57
+ * - **`skew`.** Same `transform`-shorthand problem as 3D rotation, and skew has no property of its
58
+ * own to write — `CHANNEL.skew` documents exactly this.
59
+ */
60
+ export declare const TWEEN_PROPERTIES: Readonly<Record<string, TweenProperty>>;
61
+ /**
62
+ * The tween's parameter schema, declared statically even though which keys *matter* varies per
63
+ * attribute.
64
+ *
65
+ * Every key is always declared, so an author who mistypes one gets `resolveParams`' ordinary
66
+ * `unknown parameter "opactiy" (known: ...)` warning listing the whole vocabulary, exactly as they
67
+ * would on any other effect. Declaring only the keys a given attribute used would have produced a
68
+ * "known:" list containing nothing but the author's own typo-free keys, which is the least useful
69
+ * form that message could take.
70
+ */
71
+ export declare const TWEEN_SCHEMA: ParameterSchema;
72
+ /**
73
+ * `BARE_NUMBER` and {@link decimalNumber} used to live here. They moved to `core/params.ts` when
74
+ * the `'number|percentage'` union landed and the core needed the same lexical decimal shift to
75
+ * turn `opacity:80%` into `0.8` — one implementation, so the two paths cannot drift into
76
+ * disagreeing about what `50%` means.
77
+ */
78
+ /**
79
+ * Give a bare number the unit its property implies — `x:100` is `100px`, `rotate:45` is `45deg`.
80
+ *
81
+ * `core/params.ts` requires a unit on every `length`, and should keep doing so: a unitless
82
+ * `distance:24` on `fade-up` is a mistake worth naming, because the parameter is ambiguous between
83
+ * `px` and `%` and the author simply left the unit off. `angle` is not in that position and
84
+ * `params.ts` now coerces it there too, which makes this function's angle branch a no-op for
85
+ * anything that reaches validation — it is kept because it runs first and keeps the tween's own
86
+ * `rotate:45` identical to its `x:100`. A tween property is different for `length`. `x:100` is the
87
+ * syntax this feature was specified around, it is what every other animation library accepts, and
88
+ * "100 what" has exactly one sensible answer per property. So the coercion lives here, scoped to
89
+ * the tween's own keys, rather than loosening validation for the other 255 effects.
90
+ *
91
+ * Number-valued properties also accept percentages, expressed as decimal ratios for the core
92
+ * validator. Length percentages retain their units. Other values pass through unchanged: `2rem`
93
+ * and a quoted `calc(...)` still have to earn their acceptance in `params.ts`.
94
+ *
95
+ * @complexity O(n) time in value length; O(1) space.
96
+ * @overallScore 100
97
+ */
98
+ export declare function withImpliedUnit(raw: string, type: ParamSpec['type']): string;
99
+ /**
100
+ * A shared param type is intentionally broader than some CSS slots: percentages are lengths for
101
+ * x/y, but not z or blur, and a negative blur invalidates the entire filter list. Check these
102
+ * slot-specific constraints on scalar values and waypoints alike. CSS-wide keywords are also
103
+ * unsafe here: `--kui-tween-color: inherit` inherits the custom property, not the element's color.
104
+ * All other values still go through the core validator; this never opens a second CSS escape path.
105
+ */
106
+ export declare function tweenValue(key: string, raw: string, warn: (message: string) => void, label?: string): string | undefined;
107
+ export {};
@@ -0,0 +1,106 @@
1
+ import type { ParameterSchema } from '../../core/types.js';
2
+ import type { TweenGroup } from './properties.js';
3
+ /**
4
+ * Multi-waypoint tweening — `tween x:'0,100,40'`, a value list instead of a value.
5
+ *
6
+ * `tween`/`tween-from` animate between exactly two states: wherever the element is, and where the
7
+ * author said. That is `gsap.to()`/`gsap.from()`, and it is where the catalog stopped — nothing in
8
+ * it smooths a property through *several* states, which is the shape of most real choreography (out,
9
+ * over, settle) and of every keyframe array in Motion, GSAP and WAAPI.
10
+ *
11
+ * **The whole feature is still static CSS.** A list of N values selects an N-step `@keyframes` block
12
+ * from `src/css/tween.css`, and each step reads its own custom property. Nothing is generated at
13
+ * runtime, nothing is interpolated in JavaScript, and the result is an ordinary compositor-run CSS
14
+ * animation exactly as the two-point tween already was — see the outline's §2.3, and `tween.css`'s
15
+ * own header for what the blocks look like.
16
+ *
17
+ * **Why a value list rather than a waypoint list.** The alternative shape is per-waypoint objects —
18
+ * `at:'x:0 y:0' at:'x:100 y:-60'` — and the grammar cannot hold it: a `key:value` slot appears once
19
+ * per spec, so repeating one is a duplicate-parameter warning. Property-major is also what Motion
20
+ * and WAAPI use (`animate(el, { x: [0, 100, 40] })`), and it keeps the vocabulary identical to the
21
+ * two-point tween's: an author who knows `x:100` knows `x:'0,100,40'`.
22
+ *
23
+ * **Even spacing across the duration.** Also GSAP's own default for a bare keyframe array. A
24
+ * per-step position would need the *percentage* in the keyframe selector to vary, and a keyframe
25
+ * selector cannot be a `var()` — it is the one part of a keyframe block that has to be literal. An
26
+ * author who wants an uneven rhythm can repeat a value to hold it for a step.
27
+ */
28
+ /**
29
+ * The most waypoints one property may name.
30
+ *
31
+ * A budget rather than a limit of the technique: every count needs its own `@keyframes` block per
32
+ * property group, because the step percentages are literal, so the shipped stylesheet grows with
33
+ * this number. Five states keeps this static vocabulary bounded. Longer choreography needs another keyframe
34
+ * definition; two effects on the same property cannot bypass this budget by composing.
35
+ */
36
+ export declare const MAX_WAYPOINTS = 5;
37
+ /**
38
+ * One property group's waypoint shape, as read off the attribute.
39
+ *
40
+ * `count` is the group's, not the key's: a keyframe block has one step count, so every key in the
41
+ * group renders at the same steps whatever each of them individually wrote.
42
+ */
43
+ export interface GroupWaypoints {
44
+ count: number;
45
+ /** Author key → its values, already padded to `count` and unit-normalised. */
46
+ keys: Map<string, string[]>;
47
+ }
48
+ /**
49
+ * Read one authored value as a waypoint list, or as the single value it is.
50
+ *
51
+ * Commas inside functions and strings are data. Unlike the core tokenizer, this scanner must
52
+ * retain empty items: dropping the middle of `0,,100` changes both the count and the rhythm,
53
+ * while dropping every item of `,,` used to make the first-value lookup throw. Empty values now
54
+ * reach ordinary parameter validation at their authored index and use the CSS fallback.
55
+ *
56
+ * @returns The values in order. One entry means the author wrote a plain value, and every caller
57
+ * treats that as the two-point tween it has always been.
58
+ * @complexity O(n) time and space in the value's length.
59
+ * @overallScore 100
60
+ */
61
+ export declare function readWaypoints(raw: string): string[];
62
+ /**
63
+ * Collect the waypoint lists an attribute wrote, bucketed by the group that renders them.
64
+ *
65
+ * @param authored - Author key → raw value, for tween properties only.
66
+ * @returns One entry per group that named at least one list. Groups whose keys are all plain values
67
+ * are absent, and keep the two-point blocks they have always used.
68
+ * @complexity O(n) time and space in the number of values across the attribute.
69
+ * @overallScore 100
70
+ */
71
+ export declare function collectWaypoints(authored: [string, string[]][], warn: (message: string) => void): Map<TweenGroup, GroupWaypoints>;
72
+ /**
73
+ * Expand a group's lists into one parameter per waypoint, with a spec for each.
74
+ *
75
+ * The key is `x[2]`, not `x-2`, and the brackets are load-bearing: these keys are synthesised by
76
+ * the library and can never be authored, so when one of them appears in a `resolveParams`
77
+ * diagnostic — `parameter "x[2]": expected a length` — the author can see both which key and which
78
+ * waypoint without the message having to explain itself, and can tell at a glance that it is not a
79
+ * name they were supposed to have written.
80
+ *
81
+ * The custom property is `--kui-tween-<key>-<n>`, which is what `tween.css`'s step reads, with the
82
+ * plain `--kui-tween-<key>` as its fallback. That fallback is the whole broadcast rule: a key that
83
+ * wrote a single value (`tween x:'0,100,40' y:20`) sets only the plain property, so every step of
84
+ * the block reads the same `y` and it holds — no JavaScript, no per-step duplication of a value the
85
+ * author wrote once.
86
+ *
87
+ * @param waypoints - One group's padded lists.
88
+ * @param params - Sink for the expanded values, keyed as above.
89
+ * @param schema - Sink for the specs those values are validated against.
90
+ * @complexity O(n) time and space in the group's total number of values.
91
+ * @overallScore 100
92
+ */
93
+ export declare function expandWaypoints(waypoints: GroupWaypoints, params: Record<string, string>, schema: ParameterSchema, warn: (message: string) => void): void;
94
+ /**
95
+ * The keyframe block a group with waypoints renders through.
96
+ *
97
+ * One block per (group, count), all of them fully explicit from 0% to 100% — so unlike the
98
+ * two-point blocks there is no `to`-only and `from`-only pair, and `tween` and `tween-from` share
99
+ * them. That falls out of what a list *is*: an author who writes every state has written the first
100
+ * one too, so there is no implicit half left for the browser to fill from the element's computed
101
+ * style.
102
+ *
103
+ * @complexity O(1) time and space.
104
+ * @overallScore 100
105
+ */
106
+ export declare function waypointKeyframes(group: TweenGroup, count: number): string;
@@ -0,0 +1,4 @@
1
+ import type { Preset, Primitive } from '../core/types.js';
2
+ export declare const COMPARE_AXIS_ATTR = "data-kui-compare-axis";
3
+ export declare const COMPARE_PRIMITIVE: Primitive;
4
+ export declare const COMPARE_PRESETS: Preset[];
@@ -0,0 +1,3 @@
1
+ import type { Preset, Primitive } from '../core/types.js';
2
+ export declare const DEVICE_FRAME_PRIMITIVE: Primitive;
3
+ export declare const DEVICE_FRAME_PRESETS: Preset[];
@@ -0,0 +1,3 @@
1
+ import type { Preset, Primitive } from '../core/types.js';
2
+ export declare const HOTSPOTS_PRIMITIVE: Primitive;
3
+ export declare const HOTSPOTS_PRESETS: Preset[];
@@ -0,0 +1,30 @@
1
+ import type { Animator } from '../core/animator.js';
2
+ import type { Registry } from '../core/registry.js';
3
+ import type { Preset, Primitive } from '../core/types.js';
4
+ /**
5
+ * The showcase module: pre-built presentation widgets — a dialog, an ARIA carousel, image
6
+ * hotspots — the one part of this library that owns UI behaviour rather than only motion.
7
+ * `docs/design.md` §14's amendment is the boundary this module operates under; every widget's own
8
+ * file (`device-frame.ts`, `lightbox.ts`, …) argues its own case for why it needs the exception.
9
+ *
10
+ * This is the *only* file anything outside `src/showcase/` may import from — see
11
+ * `only-effects-barrel-imports-showcase` in `.dependency-cruiser.cjs`. That is what makes the
12
+ * later split into a standalone `kuinetic.showcase.js` a build-config change and not a source
13
+ * change: every showcase file keeps importing from inside `src/showcase/`, and the one line that
14
+ * moves is `src/effects/index.ts`'s call to {@link registerShowcase}.
15
+ */
16
+ export declare const SHOWCASE_PRIMITIVES: Primitive[];
17
+ export declare const SHOWCASE_PRESETS: Preset[];
18
+ /**
19
+ * Register every showcase widget onto a `Registry`, an `Animator`, or anything shaped like either.
20
+ *
21
+ * The shape check — not `instanceof` — is what lets this same function serve as both the in-core
22
+ * call `src/effects/index.ts` makes today and the `boot({ register })` callback a split
23
+ * `kuinetic.showcase.js` tag will hand a page's existing animator tomorrow. See
24
+ * `src/core/register-into.ts`'s docblock for why identity cannot survive that split and shape can.
25
+ *
26
+ * @param target - The registry, the animator, or a host exposing one as `.registry`.
27
+ * @returns `target`, so callers can chain.
28
+ * @complexity O(n) time in showcase primitives plus presets; O(1) extra space.
29
+ */
30
+ export declare function registerShowcase(target: unknown): Registry | Animator;
@@ -0,0 +1,3 @@
1
+ import type { Preset, Primitive } from '../core/types.js';
2
+ export declare const LIGHTBOX_PRIMITIVE: Primitive;
3
+ export declare const LIGHTBOX_PRESETS: Preset[];
@@ -0,0 +1,13 @@
1
+ /** A safe, supported video URL and its preferred frame shape. */
2
+ export interface MediaSource {
3
+ kind: 'youtube' | 'vimeo' | 'file';
4
+ embedUrl: string;
5
+ aspect: 'wide' | 'tall';
6
+ }
7
+ /**
8
+ * Resolve a real link into a supported player source. Unknown hosts and non-web schemes keep
9
+ * their normal link behavior; no attacker-controlled URL is handed to an iframe.
10
+ * @complexity O(n) in the URL length; O(1) extra space.
11
+ * @overallScore 100
12
+ */
13
+ export declare function resolveMediaSource(href: string): MediaSource | null;
@@ -0,0 +1,22 @@
1
+ export interface ModalContent {
2
+ node: HTMLElement;
3
+ label: string;
4
+ duration: number;
5
+ scale: string;
6
+ ease: string;
7
+ reducedMotion: boolean;
8
+ onKey?: (event: KeyboardEvent) => void;
9
+ onClose?: () => void;
10
+ }
11
+ export interface ModalShell {
12
+ open(content: ModalContent): void;
13
+ dismiss(): void;
14
+ release(): void;
15
+ }
16
+ /**
17
+ * Share one lazily built modal per document across image and video widgets. The final live
18
+ * instance removes it, including an in-flight close timer and any scroll lock.
19
+ * @complexity O(1) per operation; O(1) shared DOM per document.
20
+ * @overallScore 100
21
+ */
22
+ export declare function acquireModalShell(doc: Document): ModalShell;
@@ -0,0 +1,4 @@
1
+ import type { Preset, Primitive } from '../core/types.js';
2
+ export declare const STORY_SIDE_ATTR = "data-kui-story-side";
3
+ export declare const SCROLL_STORY_PRIMITIVE: Primitive;
4
+ export declare const SCROLL_STORY_PRESETS: Preset[];
@@ -0,0 +1,47 @@
1
+ import type { Channel, ParameterSchema, PerfClass, Primitive } from '../core/types.js';
2
+ /**
3
+ * The one shape every showcase widget shares.
4
+ *
5
+ * `src/showcase/` builds UI components the effect catalog deliberately stays out of (a dialog, an
6
+ * ARIA carousel, a native popover) — see `docs/design.md` §14's amendment. Every one of them is
7
+ * built the same way for the same reasons, so this bakes the shared answers in once rather than
8
+ * repeating them per widget:
9
+ *
10
+ * - `renderer: 'javascript'` — nothing here compiles to a `@keyframes` block; the DOM the widget
11
+ * builds and the states it toggles are the whole effect.
12
+ * - `supportedTimelines: ['time']` — a widget runs on a clock, never on scroll/view/pointer
13
+ * progress. Narrower than `TIMELINE_AGNOSTIC` (`effects/shared.ts`), which abstains for
14
+ * primitives that never read a `Timeline` at all; a widget primitive *could* be asked for one and
15
+ * the honest answer is "only time makes sense here".
16
+ * - `supportedActivations: ['load']`, `defaultActivation: 'load'` — a widget must be wired up
17
+ * before a keyboard user tabs to it or a crawler indexes it, not when it happens to scroll into
18
+ * view. `on:enter`'s lazy-install story is right for a decorative reveal and wrong for a control.
19
+ * - `reducedMotion: 'shorten'`, never `'disable'` — `'disable'` means the animator never calls
20
+ * `activate()` at all (`src/effects/forms/primitives.ts`'s doc on the same trap), which would
21
+ * leave the widget entirely unbuilt for a reduced-motion visitor. Motion is removed in CSS
22
+ * instead; the widget itself still has to exist.
23
+ * - `perfClass` is the one field every widget answers differently (a dialog's `backdrop-filter`
24
+ * is `'paint'`, a native-popover positioning read is `'layout'`, a synchronous attribute stamp is
25
+ * `'layout'` too), so it is a parameter rather than baked in.
26
+ *
27
+ * `prepare` is taken pre-built — already run through `deferPrepare` and, where the widget has
28
+ * nothing to time, `withTimingContract` — rather than assembled here, because the timing contract
29
+ * (which of `duration`/`delay`/`ease` a widget honours, and why not the rest) genuinely differs per
30
+ * widget and baking one reason in would misdescribe the others. Same division of labour
31
+ * `src/effects/navigation/index.ts`'s `navPrimitive` already uses for its own small family.
32
+ *
33
+ * @param id - Primitive id, also the preset name for every showcase widget shipped so far.
34
+ * @param spec - The three fields every widget answers differently: `channels` (CSS property
35
+ * groups this widget's CSS claims, see `core/channels.ts`), `parameters` (the widget's parameter
36
+ * schema), and `perfClass` (this widget's honest performance-budget class). Grouped into one
37
+ * object rather than three positional params so this factory stays under the four-parameter
38
+ * lint ceiling (`eslint.config.js`'s `max-params`) alongside `prepare`.
39
+ * @param prepare - Fully wrapped setup: `withTimingContract(...)`-and/or-`deferPrepare(...)`.
40
+ * @returns A complete `Primitive`.
41
+ * @complexity O(1) time and space.
42
+ */
43
+ export declare function widgetPrimitive(id: string, spec: {
44
+ channels: Channel[];
45
+ parameters: ParameterSchema;
46
+ perfClass: PerfClass;
47
+ }, prepare: NonNullable<Primitive['prepare']>): Primitive;
@@ -0,0 +1,3 @@
1
+ import type { Preset, Primitive } from '../core/types.js';
2
+ export declare const SLIDESHOW_PRIMITIVE: Primitive;
3
+ export declare const SLIDESHOW_PRESETS: Preset[];
@@ -0,0 +1,5 @@
1
+ import type { Preset, Primitive } from '../core/types.js';
2
+ /** A host-only speed control for Web Animations and CSS motion in its subtree. */
3
+ export declare const SLOW_MO_PRIMITIVE: Primitive;
4
+ /** The showcase name for the speed-control primitive. */
5
+ export declare const SLOW_MO_PRESETS: Preset[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kuinetic",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "Declarative web animation from HTML attributes. Native CSS where possible, JS only where necessary.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -10,8 +10,8 @@
10
10
  "main": "./dist/esm/index.mjs",
11
11
  "module": "./dist/esm/index.mjs",
12
12
  "types": "./dist/types/index.d.ts",
13
- "unpkg": "dist/kuinetic.js",
14
- "jsdelivr": "dist/kuinetic.js",
13
+ "unpkg": "dist/kuinetic.min.js",
14
+ "jsdelivr": "dist/kuinetic.min.js",
15
15
  "files": [
16
16
  "dist"
17
17
  ],
@@ -28,6 +28,10 @@
28
28
  "types": "./dist/types/effects/index.d.ts",
29
29
  "default": "./dist/esm/effects/index.mjs"
30
30
  },
31
+ "./advanced": {
32
+ "types": "./dist/types/advanced/index.d.ts",
33
+ "default": "./dist/esm/advanced/index.mjs"
34
+ },
31
35
  "./css": "./dist/kuinetic.css",
32
36
  "./package.json": "./package.json"
33
37
  },
@@ -39,11 +43,12 @@
39
43
  "lint": "eslint src test scripts",
40
44
  "lint:deps": "depcruise src --config .dependency-cruiser.cjs",
41
45
  "lint:dead": "knip",
42
- "ci": "npm run build:dist && npm run typecheck && npm run lint && npm run lint:deps && npm run lint:dead && npm run check:css-coverage && npm run test:coverage && npm run test:browser",
46
+ "ci": "npm run build:dist && node scripts/verify-tiers.mjs && npm run typecheck && npm run lint && npm run lint:deps && npm run lint:dead && npm run check:css-coverage && npm run test:coverage && npm run test:browser",
43
47
  "size": "npm run build:dist && size-limit",
44
- "build": "npm run generate:css && esbuild src/index.ts --bundle --format=iife --global-name=kuinetic --outfile=demo/kuinetic.js && esbuild src/css/index.css --bundle --outfile=demo/kuinetic.css && npx @tailwindcss/cli -i demo/tailwind-entry.css -o demo/tailwind.css && node scripts/build-standalone.mjs demo",
45
- "build:dist": "npm run clean:dist && npm run generate:css && esbuild src/index.ts src/core/index.ts src/effects/index.ts --bundle --format=esm --splitting --outdir=dist/esm --out-extension:.js=.mjs && esbuild src/index.ts --bundle --format=iife --global-name=kuinetic --outfile=dist/kuinetic.js && esbuild src/css/index.css --bundle --outfile=dist/kuinetic.css && tsc -p tsconfig.build.json && node scripts/build-standalone.mjs",
48
+ "build": "npm run generate:css && esbuild src/index.ts --bundle --format=iife --global-name=kuinetic --minify --sourcemap=linked --outfile=demo/kuinetic.js && esbuild src/css/index.css --bundle --outfile=demo/kuinetic.css && npx @tailwindcss/cli -i demo/tailwind-entry.css -o demo/tailwind.css && node scripts/build-tiers.mjs demo && node scripts/build-standalone.mjs demo && npm run sync:docs",
49
+ "build:dist": "npm run clean:dist && npm run generate:css && esbuild src/index.ts src/core/index.ts src/effects/index.ts src/advanced/index.ts --bundle --format=esm --splitting --outdir=dist/esm --out-extension:.js=.mjs && esbuild src/index.ts --bundle --format=iife --global-name=kuinetic --outfile=dist/kuinetic.js && esbuild src/css/index.css --bundle --outfile=dist/kuinetic.css && esbuild src/index.ts --bundle --format=iife --global-name=kuinetic --minify --outfile=dist/kuinetic.min.js && esbuild src/css/index.css --bundle --minify --outfile=dist/kuinetic.min.css && tsc -p tsconfig.build.json && node scripts/build-tiers.mjs && node scripts/build-standalone.mjs",
46
50
  "verify:standalone": "npm run build:dist && node scripts/verify-standalone.mjs",
51
+ "verify:tiers": "npm run build:dist && node scripts/verify-tiers.mjs",
47
52
  "verify:pack": "npm run build:dist && node scripts/verify-pack.mjs",
48
53
  "clean:dist": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
49
54
  "prepack": "npm run build:dist",
@@ -57,7 +62,8 @@
57
62
  "generate:nav": "node scripts/generate-nav-header.mjs",
58
63
  "record": "npm run build && node scripts/verify-browser.mjs --record",
59
64
  "check:showcase": "npm run build && node scripts/check-showcase.mjs",
60
- "check:css-coverage": "npm run build && node scripts/check-css-coverage.mjs"
65
+ "check:css-coverage": "npm run build && node scripts/check-css-coverage.mjs",
66
+ "sync:docs": "node scripts/sync-demo-docs.mjs"
61
67
  },
62
68
  "devDependencies": {
63
69
  "@eslint/js": "^9.39.5",
@@ -78,6 +84,7 @@
78
84
  "pngjs": "^7.0.0",
79
85
  "size-limit": "^13.0.3",
80
86
  "tailwindcss": "^4.3.3",
87
+ "three": "^0.186.0",
81
88
  "typescript": "^5.9.3",
82
89
  "typescript-eslint": "^8.66.0",
83
90
  "vitest": "^2.1.9"