@wardic/solid 1.0.0-rc.6 → 1.0.0-rc.8

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 (65) hide show
  1. package/dist/browser/animation-controls.js +1 -1
  2. package/dist/browser/animation-controls.js.map +1 -1
  3. package/dist/browser/imperative.js +16 -5
  4. package/dist/browser/imperative.js.map +1 -1
  5. package/dist/browser/index.js +1 -1
  6. package/dist/browser/presence-controller.js +12 -1
  7. package/dist/browser/presence-controller.js.map +1 -1
  8. package/dist/browser/retarget-legs.js +6 -3
  9. package/dist/browser/retarget-legs.js.map +1 -1
  10. package/dist/browser/spine.js +37 -13
  11. package/dist/browser/spine.js.map +1 -1
  12. package/dist/browser/unstable/v2/ward.js +8 -1
  13. package/dist/browser/unstable/v2/ward.js.map +1 -1
  14. package/dist/browser/variant-target.js +6 -1
  15. package/dist/browser/variant-target.js.map +1 -1
  16. package/dist/server/animation-controls.js +1 -1
  17. package/dist/server/animation-controls.js.map +1 -1
  18. package/dist/server/imperative.js +16 -5
  19. package/dist/server/imperative.js.map +1 -1
  20. package/dist/server/index.js +1 -1
  21. package/dist/server/presence-controller.js +12 -1
  22. package/dist/server/presence-controller.js.map +1 -1
  23. package/dist/server/retarget-legs.js +6 -3
  24. package/dist/server/retarget-legs.js.map +1 -1
  25. package/dist/server/spine.js +37 -13
  26. package/dist/server/spine.js.map +1 -1
  27. package/dist/server/unstable/v2/ward.js +8 -1
  28. package/dist/server/unstable/v2/ward.js.map +1 -1
  29. package/dist/server/variant-target.js +6 -1
  30. package/dist/server/variant-target.js.map +1 -1
  31. package/dist/solid/animation-controls.d.ts +3 -4
  32. package/dist/solid/animation-controls.d.ts.map +1 -1
  33. package/dist/solid/animation-controls.js +1 -1
  34. package/dist/solid/animation-controls.js.map +1 -1
  35. package/dist/solid/imperative.d.ts.map +1 -1
  36. package/dist/solid/imperative.js +17 -5
  37. package/dist/solid/imperative.js.map +1 -1
  38. package/dist/solid/index.d.ts +1 -1
  39. package/dist/solid/index.js +1 -1
  40. package/dist/solid/presence-controller.d.ts.map +1 -1
  41. package/dist/solid/presence-controller.js +12 -1
  42. package/dist/solid/presence-controller.js.map +1 -1
  43. package/dist/solid/retarget-legs.d.ts.map +1 -1
  44. package/dist/solid/retarget-legs.js +4 -3
  45. package/dist/solid/retarget-legs.js.map +1 -1
  46. package/dist/solid/spine.d.ts +12 -2
  47. package/dist/solid/spine.d.ts.map +1 -1
  48. package/dist/solid/spine.js +38 -6
  49. package/dist/solid/spine.js.map +1 -1
  50. package/dist/solid/unstable/v2/ward.d.ts.map +1 -1
  51. package/dist/solid/unstable/v2/ward.jsx +8 -1
  52. package/dist/solid/unstable/v2/ward.jsx.map +1 -1
  53. package/dist/solid/variant-target.d.ts +2 -0
  54. package/dist/solid/variant-target.d.ts.map +1 -1
  55. package/dist/solid/variant-target.js +3 -1
  56. package/dist/solid/variant-target.js.map +1 -1
  57. package/package.json +4 -4
  58. package/src/animation-controls.ts +4 -2
  59. package/src/imperative.ts +16 -5
  60. package/src/index.ts +1 -1
  61. package/src/presence-controller.ts +13 -2
  62. package/src/retarget-legs.ts +4 -3
  63. package/src/spine.ts +47 -9
  64. package/src/unstable/v2/ward.tsx +8 -1
  65. package/src/variant-target.ts +7 -1
package/src/spine.ts CHANGED
@@ -16,7 +16,7 @@
16
16
  */
17
17
  import * as BaseValue from "@wardic/core/BaseValue"
18
18
  import type * as DefaultTransition from "@wardic/core/DefaultTransition"
19
- import type * as Frame from "@wardic/core/Frame"
19
+ import * as Frame from "@wardic/core/Frame"
20
20
  import type * as FrameLoop from "@wardic/core/FrameLoop"
21
21
  import * as InterpolatorRegistry from "@wardic/core/InterpolatorRegistry"
22
22
  import * as Machine from "@wardic/core/Machine"
@@ -534,8 +534,6 @@ interface Running extends Machine.RunOptions {
534
534
  count: number
535
535
  /** A frame's values for the keys it still draws: the frame's own while it draws all of them. */
536
536
  values: (value: Values.Values) => Values.Values
537
- /** The same, for a frame's velocities. */
538
- velocities: (velocity: Readonly<Record<string, number>>) => Readonly<Record<string, number>>
539
537
  /** It drew its last frame: its keys landed. */
540
538
  done: boolean
541
539
  /** It gave up a key in this Retarget: what it still draws is worked out at the Retarget's end. */
@@ -555,6 +553,11 @@ interface Running extends Machine.RunOptions {
555
553
  last: Values.Values | undefined
556
554
  before: Values.Values | undefined
557
555
  beforeAt: number
556
+ /**
557
+ * A Numbers leg's last Frame (#663): its keys' velocities are read from it when one is asked for, as
558
+ * a Blend leg's are from its frames, by index from a spring's. None before its first frame.
559
+ */
560
+ physics: Frame.MultiPhysics | undefined
558
561
  }
559
562
 
560
563
  /** No running legs. */
@@ -741,7 +744,6 @@ const runningOf = (to: Values.Values, resolution: Resolution, landing: Landing,
741
744
  resolution,
742
745
  count: 0,
743
746
  values: identity,
744
- velocities: identity,
745
747
  done: false,
746
748
  losing: false,
747
749
  fiber: undefined,
@@ -755,6 +757,7 @@ const runningOf = (to: Values.Values, resolution: Resolution, landing: Landing,
755
757
  last: undefined,
756
758
  before: undefined,
757
759
  beforeAt: Number.NEGATIVE_INFINITY,
760
+ physics: undefined,
758
761
  })
759
762
 
760
763
  /**
@@ -1647,13 +1650,19 @@ export interface Snapshot {
1647
1650
  owners: ReadonlyMap<string, Running | undefined> | undefined
1648
1651
  /** The time now, its provider's Clock's once its spine runs (#460, Q7), {@link frameNow} before. */
1649
1652
  now: () => number
1653
+ /**
1654
+ * Every numeric key's velocity now (#663), given the Snapshot: {@link velocitiesNowOf}, one function
1655
+ * every Snapshot shares. A resolver and Animation controls read these: `velocities` doesn't hold a
1656
+ * spring leg's. A method, so a Snapshot is a resolver's `VariantState`.
1657
+ */
1658
+ velocitiesNow(snapshot: Snapshot): Readonly<Record<string, number>>
1650
1659
  }
1651
1660
 
1652
1661
  /** A Snapshot seeded from the Starting values, velocities 0, so frame 1 flows out of the seed (no snap). */
1653
1662
  export const snapshotOf = (start: Start): Snapshot => emptySnapshotOf({ ...start.initialValues })
1654
1663
 
1655
1664
  /** A Snapshot of `values`, nothing moving: read as it is until a spine reads it. */
1656
- export const emptySnapshotOf = (values: Values.Values): Snapshot => ({ values, velocities: {}, drawnAt: {}, owners: undefined, now: frameNow })
1665
+ export const emptySnapshotOf = (values: Values.Values): Snapshot => ({ values, velocities: {}, drawnAt: {}, owners: undefined, now: frameNow, velocitiesNow: velocitiesNowOf })
1657
1666
 
1658
1667
  // --- Velocities (#464) ---------------------------------------------------------------------------
1659
1668
 
@@ -1661,9 +1670,28 @@ export const emptySnapshotOf = (values: Values.Values): Snapshot => ({ values, v
1661
1670
  const legVelocityOf = (snapshot: Snapshot, running: Running, key: string): number => {
1662
1671
  if (running.kind === "Blend") return blendVelocityOf(running, key)
1663
1672
  if (running.kind === "Snap") return 0
1673
+ if (running.kind === "Numbers") return numbersVelocityOf(snapshot, running, key)
1664
1674
  return velocityOf(snapshot, key)
1665
1675
  }
1666
1676
 
1677
+ /**
1678
+ * A Numbers leg's velocity for `key` (#663): its last Frame's, as it drew it, by index from a spring's
1679
+ * (whose velocity record it doesn't write), from the record of an inertia's; the Snapshot's before its
1680
+ * first frame, or for a key its Frame doesn't have. Per key, per Retarget: guards.
1681
+ */
1682
+ const numbersVelocityOf = (snapshot: Snapshot, running: Running, key: string): number => {
1683
+ const last = running.physics
1684
+ if (Predicate.isUndefined(last)) return velocityOf(snapshot, key)
1685
+ if (Frame.isSpringValues(last)) {
1686
+ const at = last.keys.indexOf(key)
1687
+ if (at < 0) return velocityOf(snapshot, key)
1688
+ return UndefinedOr.getOrThrow(last.velocities[at])
1689
+ }
1690
+ const velocity = last.velocity[key]
1691
+ if (Predicate.isUndefined(velocity)) return velocityOf(snapshot, key)
1692
+ return velocity
1693
+ }
1694
+
1667
1695
  /**
1668
1696
  * `key`'s velocity at `now` (#464, Motion's `getVelocity`): the leg drawing it, once it has drawn a
1669
1697
  * frame, else what the Snapshot holds for it (the last leg to let it go left it, a drag or a seed set
@@ -2155,7 +2183,6 @@ export const makeElementSpine = (options: ElementSpineOptions): ElementSpine =>
2155
2183
  if (running.count === 0) return
2156
2184
  const kept = Arr.filter(Rec.keys(running.targets), (key) => owners.get(key) === running)
2157
2185
  running.values = keepingOnly(kept)
2158
- running.velocities = keepingOnly(kept)
2159
2186
  })
2160
2187
  losing.length = 0
2161
2188
  }
@@ -2223,13 +2250,24 @@ export const makeElementSpine = (options: ElementSpineOptions): ElementSpine =>
2223
2250
  // rather than replacing it, so the drag's direct-set x/y survive alongside the
2224
2251
  // spring's keys (drag owns x/y, spring owns the rest) and the post-drag
2225
2252
  // handoff continues from the rested position. Only the keys it still draws (#325).
2253
+ // In place, as the Follow sink writes (#659): a spread made two records per element per
2254
+ // frame. The Snapshot's records are always its own (`snapshotOf`, `emptySnapshotOf`), and
2255
+ // whatever keeps one copies it or reads it at once.
2226
2256
  const value = running.values(frame.value)
2227
- snapshot.values = { ...snapshot.values, ...value }
2228
- snapshot.velocities = { ...snapshot.velocities, ...running.velocities(frame.velocity) }
2257
+ Object.assign(snapshot.values, value)
2258
+ // Its velocities stay on its Frame (#663), read by index when one is asked for: copied into
2259
+ // the Snapshot each frame, they cost a boxed number a key a frame that only a Retarget read.
2260
+ running.physics = frame
2229
2261
  gate.write(id, value)
2230
2262
  recordFrame(value)
2231
2263
  drew(running, frame.done, snapshot.now())
2232
- if (frame.done) landEndsOf(waiting)
2264
+ if (frame.done) {
2265
+ // Landed, its keys are at rest: the Snapshot says so for whatever reads it after it's gone.
2266
+ Arr.forEach(Rec.keys(value), (key) => {
2267
+ snapshot.velocities[key] = 0
2268
+ })
2269
+ landEndsOf(waiting)
2270
+ }
2233
2271
  return undefined
2234
2272
  }, running)
2235
2273
  )
@@ -1103,6 +1103,13 @@ export function wardWith(config: WardConfig, internal: WardInternals): Ward {
1103
1103
  // The Override stack, compared by value: a change that resolves the same target doesn't Retarget.
1104
1104
  // A keyboard lift turns `whileDrag` on, as a drag does (ADR-0037).
1105
1105
  const lifted = UndefinedOr.match(internal.lifted, { onUndefined: () => constFalse, onDefined: identity })
1106
+ // The target reads the lift through a boundary (#666): an item with no `whileDrag` of its own
1107
+ // resolves the same lifted or not (a dragged parent's name hands down with its own drag on), so
1108
+ // every lift and drop re-ran its target for nothing. A Reorder item's alone: no other ward lifts.
1109
+ const liftedLayer = UndefinedOr.match(internal.lifted, {
1110
+ onUndefined: () => constFalse,
1111
+ onDefined: (isLifted) => createMemo(() => Predicate.isNotUndefined(cfg().whileDrag) && isLifted(), CLIENT_ONLY),
1112
+ })
1106
1113
  const target = createMemo<Resolution>(
1107
1114
  () => {
1108
1115
  const g = gestures()
@@ -1115,7 +1122,7 @@ export function wardWith(config: WardConfig, internal: WardInternals): Ward {
1115
1122
  focused: g.focused,
1116
1123
  hovered: g.hovered,
1117
1124
  pressed: g.pressed,
1118
- dragged: Bool.or(g.dragging, lifted()),
1125
+ dragged: Bool.or(g.dragging, liftedLayer()),
1119
1126
  dragging: g.dragging,
1120
1127
  },
1121
1128
  snapshot,
@@ -23,6 +23,8 @@ import type { WardicTransition, WardicVariant, WardicVariantLabels, WardicVarian
23
23
  export interface VariantState {
24
24
  readonly values: Readonly<Record<string, number | string>>
25
25
  readonly velocities: Readonly<Record<string, number>>
26
+ /** The velocities now, worked out when read (#663): a Snapshot's, whose spring legs' aren't in `velocities`. */
27
+ velocitiesNow?(state: VariantState): Readonly<Record<string, number>>
26
28
  }
27
29
 
28
30
  /** No values yet: a server render's, and the Starting style's. */
@@ -87,9 +89,13 @@ export interface NamedTarget extends Target {
87
89
  /** What a variant name, a variants entry or a resolver's result can be. */
88
90
  type Definition = WardicVariant | WardicVariantResolver | string | undefined
89
91
 
92
+ /** A state's velocities now (#663): worked out where it can, else as it holds them. Per resolver call. */
93
+ const velocitiesOf = (state: VariantState): Readonly<Record<string, number>> =>
94
+ UndefinedOr.match(state.velocitiesNow, { onUndefined: () => state.velocities, onDefined: (now) => now(state) })
95
+
90
96
  /** A resolver called with what it reads, as Motion calls it; anything else as it is. */
91
97
  const calledOf = (definition: Definition, custom: unknown, state: VariantState): Definition => {
92
- if (Predicate.isFunction(definition)) return definition(custom, { ...state.values }, { ...state.velocities })
98
+ if (Predicate.isFunction(definition)) return definition(custom, { ...state.values }, { ...velocitiesOf(state) })
93
99
  return definition
94
100
  }
95
101