zag-ripple 0.0.8 → 0.0.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zag-ripple",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "RippleJS Adapter for Zag JS",
5
5
  "keywords": [
6
6
  "js",
@@ -1,63 +1,48 @@
1
- import { identity, isFunction } from "@zag-js/utils"
2
- import { track, effect, flushSync, untrack } from "ripple"
1
+ import { isFunction } from "@zag-js/utils"
2
+ import { track, effect } from "ripple"
3
3
 
4
- export function createBindable(props) {
4
+ export function bindable(props) {
5
5
  const initial = props().defaultValue ?? props().value
6
6
  const eq = props().isEqual ?? Object.is
7
7
 
8
- let value = track(initial)
9
- let controlled = track(() => props().value !== undefined)
10
-
11
- let valueRef = { current: untrack(() => @value) }
12
- let prevValue = { current: undefined }
13
-
14
- effect(() => {
15
- const v = @controlled ? props().value : @value
16
- valueRef = { current: v }
17
- prevValue = { current: v }
18
- })
19
-
20
- const setValueFn = (v) => {
21
- const next = isFunction(v) ? v(valueRef.current) : v
22
- const prev = prevValue.current
23
- if (props().debug) {
24
- console.log(`[bindable > ${props().debug}] setValue`, { next, prev })
25
- }
26
-
27
- if (!@controlled) {
28
- @value = next;
29
- }
30
- if (!eq(next, prev)) {
31
- props().onChange?.(next, prev)
32
- }
33
- }
34
-
35
- function get(): T {
36
- return @controlled ? props().value : @value
37
- }
8
+ const v = track(initial)
9
+ const controlled = track(() => props().value !== undefined)
10
+ const valueRef = track(@controlled ? props().value : @v)
38
11
 
39
12
  return {
40
13
  initial,
41
14
  ref: valueRef,
42
- get,
43
- set(val) {
44
- const exec = props().sync ? flushSync : identity
45
- exec(() => setValueFn(val))
15
+ get() {
16
+ return (@controlled ? props().value : @v)
46
17
  },
47
- invoke: (nextValue, prevValue) => {
18
+ set(val){
19
+ const prev = @controlled ? props().value : @v
20
+ const next = isFunction(val) ? val(prev) : val
21
+ if (props().debug) {
22
+ console.log(`[bindable > ${props().debug}] setValue`, { next, prev })
23
+ }
24
+
25
+ if (!@controlled) @v = next
26
+
27
+ if (!eq(next, prev)) {
28
+ props().onChange?.(next, prev)
29
+ }
30
+ },
31
+ invoke(nextValue, prevValue) {
48
32
  props().onChange?.(nextValue, prevValue)
49
33
  },
50
- hash: (value) => {
34
+ hash(value) {
51
35
  return props().hash?.(value) ?? String(value)
52
36
  },
53
37
  }
38
+
54
39
  }
55
40
 
56
- createBindable.cleanup = (fn: VoidFunction) => {
57
- effect(() => fn(), [])
41
+ bindable.cleanup = (fn: VoidFunction) => {
42
+ effect(() => fn())
58
43
  }
59
44
 
60
- createBindable.ref = (defaultValue: any) => {
45
+ bindable.ref = (defaultValue: any) => {
61
46
  let value = defaultValue
62
47
  return {
63
48
  get: () => value,
@@ -11,10 +11,10 @@ import type {
11
11
  Service,
12
12
  } from "@zag-js/core"
13
13
  import { createScope, INIT_STATE, MachineStatus } from "@zag-js/core"
14
- import { ensure, isFunction, isPlainObject, isString, toArray, warn } from "@zag-js/utils"
15
- import { track, trackSplit, untrack, effect, flushSync } from "ripple"
16
- import { createBindable } from "./bindable.ripple"
17
- import { createRefs } from "./refs.ripple"
14
+ import { ensure, isFunction, isPlainObject, isString, toArray, warn } from "@zag-js/utils"
15
+ import { track, trackSplit, effect, flushSync } from "ripple"
16
+ import { bindable } from "./bindable.ripple"
17
+ import { useRefs } from "./refs.ripple"
18
18
  import { createTrack } from "./track.ripple"
19
19
 
20
20
  function access(userProps) {
@@ -29,10 +29,10 @@ function compact(obj) {
29
29
  for (const key of keys) {
30
30
  const value = (obj)[key]
31
31
  if (@value !== undefined) {
32
- filtered[key as keyof T] = compact(@value)
32
+ filtered[key] = compact(@value)
33
33
  }
34
34
  }
35
- return filtered as T
35
+ return filtered
36
36
  }
37
37
 
38
38
  export function useMachine(
@@ -43,6 +43,7 @@ export function useMachine(
43
43
  let scope = track(() => {
44
44
  return createScope({ id: @id, ids: @ids, getRootNode: @getRootNode })
45
45
  })
46
+
46
47
  const debug = (...args: any[]) => {
47
48
  if (machine.debug) console.log(...args)
48
49
  }
@@ -56,7 +57,7 @@ export function useMachine(
56
57
 
57
58
  const context = machine.context?.({
58
59
  prop,
59
- bindable: createBindable,
60
+ bindable: bindable,
60
61
  get scope() {
61
62
  return @scope
62
63
  },
@@ -109,51 +110,18 @@ export function useMachine(
109
110
 
110
111
  const getState = () => ({
111
112
  ...state,
112
- matches(...values) {
113
- const current = state.get()
114
- return values.includes(current)
115
- },
116
113
  hasTag(tag) {
117
- const current = state.get()
118
- return !!machine.states[current]?.tags?.includes(tag)
114
+ const currentState = state.get()
115
+ return !!machine.states[currentState]?.tags?.includes(tag)
116
+ },
117
+ matches(...values) {
118
+ const currentState = state.get()
119
+ return values.includes(currentState)
119
120
  },
120
121
  })
121
122
 
122
- const refs = createRefs(machine.refs?.({ prop, context: ctx }) ?? {})
123
-
124
- const send = (event) => {
125
- if (status !== MachineStatus.Started) return
126
-
127
- previousEventRef.current = eventRef.current
128
- eventRef.current = event
129
-
130
- let currentState = state.get()
131
-
132
- const transitions =
133
- machine.states[currentState]?.on?.[event.type] ??
134
- machine.on?.[event.type]
123
+ const refs = useRefs(machine.refs?.({ prop, context: ctx }) ?? {})
135
124
 
136
- const transition = choose(transitions)
137
- if (!transition) return
138
-
139
- // save current transition
140
- transitionRef.current = transition
141
- const target = transition.target ?? currentState
142
-
143
- debug("transition", event.type, transition.target || currentState, `(${transition.actions})`)
144
-
145
- const changed = target !== currentState
146
- if (changed) {
147
- state.set(target)
148
- } else if (transition.reenter && !changed) {
149
- // reenter will re-invoke the current state
150
- state.invoke?.(currentState, currentState)
151
- } else {
152
- // call transition actions
153
- action(transition.actions ?? [])
154
- }
155
- }
156
-
157
125
  const getParams = () => ({
158
126
  state: getState(),
159
127
  context: ctx,
@@ -226,7 +194,7 @@ export function useMachine(
226
194
  })
227
195
  }
228
196
 
229
- const state = createBindable(() => ({
197
+ const state = bindable(() => ({
230
198
  defaultValue: machine.initialState({ prop }),
231
199
  onChange(nextState: string, prevState: string | undefined) {
232
200
  // compute effects: exit -> transition -> enter
@@ -239,14 +207,12 @@ export function useMachine(
239
207
  }
240
208
 
241
209
  // exit actions
242
- if (prevState && prevState !== INIT_STATE) {
210
+ if (prevState) {
243
211
  action(machine.states[prevState]?.exit)
244
212
  }
245
213
 
246
214
  // transition actions
247
- if (transitionRef.current?.actions) {
248
- action(transitionRef.current.actions)
249
- }
215
+ action(transitionRef.current?.actions)
250
216
 
251
217
  // enter effects
252
218
  const cleanup = effectFn( machine.states[nextState]?.effects)
@@ -277,9 +243,11 @@ export function useMachine(
277
243
  return () => {
278
244
  debug("unmounting...")
279
245
  status = MachineStatus.Stopped
246
+
280
247
  effects.forEach((fn) => fn?.())
281
248
  effects = new Map()
282
249
  transitionRef.current = null
250
+
283
251
  queueMicrotask(() => {
284
252
  action(machine.exit)
285
253
  })
@@ -287,6 +255,39 @@ export function useMachine(
287
255
  })
288
256
 
289
257
 
258
+ const send = (event) => {
259
+ if (status !== MachineStatus.Started) return
260
+
261
+ previousEventRef.current = eventRef.current
262
+ eventRef.current = event
263
+
264
+ let currentState = state.get()
265
+
266
+ const transitions = machine.states[currentState].on?.[event.type] ?? machine.on?.[event.type]
267
+
268
+ const transition = choose(transitions)
269
+ if (!transition) return
270
+
271
+ // save current transition
272
+ transitionRef.current = transition
273
+ const target = transition.target ?? currentState
274
+
275
+ debug("transition", event.type, transition.target || currentState, `(${transition.actions})`)
276
+
277
+ const changed = target !== currentState
278
+ if (changed) {
279
+ // state change is high priority
280
+ state.set(target)
281
+ } else if (transition.reenter && !changed) {
282
+ // reenter will re-invoke the current state
283
+ state.invoke?.(currentState, currentState)
284
+ } else {
285
+ // call transition actions
286
+ action(transition.actions ?? [])
287
+ }
288
+ }
289
+
290
+
290
291
  machine.watch?.(getParams())
291
292
 
292
293
  return {
package/src/refs.ripple CHANGED
@@ -1,6 +1,4 @@
1
- import { track } from "ripple";
2
-
3
- export function createRefs(refs) {
1
+ export function useRefs(refs) {
4
2
  const ref = { current: refs }
5
3
  return {
6
4
  get(key) {
package/src/track.ripple CHANGED
@@ -1,10 +1,10 @@
1
- import { isEqual, isFunction } from "@zag-js/utils";
2
- import { effect, track } from "ripple";
1
+ import { isEqual } from "@zag-js/utils";
2
+ import { effect } from "ripple";
3
3
 
4
- const access = (v) => {
5
- if (isFunction(v)) return v()
6
- return v;
7
- };
4
+ const access = (value: any) => {
5
+ if (typeof value === "function") return value()
6
+ return value
7
+ }
8
8
 
9
9
  export const createTrack = (deps: any[], effectCallback: VoidFunction ) => {
10
10
  let prevDeps: any[] = [];