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 +1 -1
- package/src/bindable.ripple +27 -42
- package/src/machine.ripple +53 -52
- package/src/refs.ripple +1 -3
- package/src/track.ripple +6 -6
package/package.json
CHANGED
package/src/bindable.ripple
CHANGED
|
@@ -1,63 +1,48 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { track, effect
|
|
1
|
+
import { isFunction } from "@zag-js/utils"
|
|
2
|
+
import { track, effect } from "ripple"
|
|
3
3
|
|
|
4
|
-
export function
|
|
4
|
+
export function bindable(props) {
|
|
5
5
|
const initial = props().defaultValue ?? props().value
|
|
6
6
|
const eq = props().isEqual ?? Object.is
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
44
|
-
const exec = props().sync ? flushSync : identity
|
|
45
|
-
exec(() => setValueFn(val))
|
|
15
|
+
get() {
|
|
16
|
+
return (@controlled ? props().value : @v)
|
|
46
17
|
},
|
|
47
|
-
|
|
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
|
|
34
|
+
hash(value) {
|
|
51
35
|
return props().hash?.(value) ?? String(value)
|
|
52
36
|
},
|
|
53
37
|
}
|
|
38
|
+
|
|
54
39
|
}
|
|
55
40
|
|
|
56
|
-
|
|
57
|
-
effect(() => fn()
|
|
41
|
+
bindable.cleanup = (fn: VoidFunction) => {
|
|
42
|
+
effect(() => fn())
|
|
58
43
|
}
|
|
59
44
|
|
|
60
|
-
|
|
45
|
+
bindable.ref = (defaultValue: any) => {
|
|
61
46
|
let value = defaultValue
|
|
62
47
|
return {
|
|
63
48
|
get: () => value,
|
package/src/machine.ripple
CHANGED
|
@@ -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 {
|
|
15
|
-
import { track, trackSplit,
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
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
|
|
32
|
+
filtered[key] = compact(@value)
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
return filtered
|
|
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:
|
|
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
|
|
118
|
-
return !!machine.states[
|
|
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 =
|
|
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 =
|
|
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
|
|
210
|
+
if (prevState) {
|
|
243
211
|
action(machine.states[prevState]?.exit)
|
|
244
212
|
}
|
|
245
213
|
|
|
246
214
|
// transition actions
|
|
247
|
-
|
|
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
package/src/track.ripple
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { isEqual
|
|
2
|
-
import { effect
|
|
1
|
+
import { isEqual } from "@zag-js/utils";
|
|
2
|
+
import { effect } from "ripple";
|
|
3
3
|
|
|
4
|
-
const access = (
|
|
5
|
-
if (
|
|
6
|
-
return
|
|
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[] = [];
|