Skip to content

Commit ef544cf

Browse files
authored
Size directive. (#795)
1 parent 5d643aa commit ef544cf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+950
-196
lines changed

core/tests/tests/Context.mint

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
type Test.Context {
22
name : String
3-
}
3+
} context { name: "NAME" }
44

55
component Test.NestedConsumer {
66
fun render {
@@ -30,4 +30,10 @@ suite "Context" {
3030
|> Test.Html.start()
3131
|> Test.Html.assertTextOf("div", "Joe")
3232
}
33+
34+
test "Test.Consumer" {
35+
<Test.Consumer/>
36+
|> Test.Html.start()
37+
|> Test.Html.assertTextOf("div", "NAME")
38+
}
3339
}

runtime/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export { createElement, Fragment as fragment, createContext } from "preact";
2-
export { useEffect, useMemo, useRef, useContext } from "preact/hooks";
2+
export { useEffect, useMemo, useContext } from "preact/hooks";
33
export { signal, batch } from "@preact/signals";
44

55
export * from "./src/pattern_matching";

runtime/src/utilities.js

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { useEffect, useRef, useMemo } from "preact/hooks";
2-
import { signal } from "@preact/signals";
1+
import { signal, useSignalEffect, useSignal as useSignalOriginal } from "@preact/signals";
2+
import { useEffect, useRef, useMemo, useCallback } from "preact/hooks";
33

44
import {
55
createRef as createRefOriginal,
@@ -31,16 +31,32 @@ export const bracketAccess = (array, index, just, nothing) => {
3131
}
3232
};
3333

34-
// This sets the references to an element or component. The current
34+
// These set the references to an element or component. The current
3535
// value is always a `Maybe`
36-
export const setRef = (value, just, nothing) => (element) => {
36+
export const setTestRef = (signal, just, nothing) => (element) => {
37+
let current;
3738
if (element === null) {
38-
value.current = new nothing();
39+
current = new nothing();
3940
} else {
40-
value.current = new just(element);
41+
current = new just(element);
4142
}
43+
44+
if (signal) {
45+
if (!compare(signal.peek(), current)) {
46+
signal.value = current
47+
}
48+
}
49+
}
50+
51+
export const setRef = (signal, just, nothing) => {
52+
return useCallback((element) => {
53+
setTestRef(signal, just, nothing)(element)
54+
}, [])
4255
};
4356

57+
// The normal useSignal.
58+
export const useRefSignal = useSignalOriginal;
59+
4460
// A version of `useSignal` which subscribes to the signal by default (like a
4561
// state) since we want to re-render every time the signal changes.
4662
export const useSignal = (value) => {
@@ -49,13 +65,6 @@ export const useSignal = (value) => {
4965
return item;
5066
};
5167

52-
// A version of `createRef` with a default value.
53-
export const createRef = (value) => {
54-
const ref = createRefOriginal();
55-
ref.current = value;
56-
return ref;
57-
};
58-
5968
// A hook to replace the `componentDidUpdate` function.
6069
export const useDidUpdate = (callback) => {
6170
const hasMount = useRef(false);
@@ -131,3 +140,26 @@ export const load = async (path) => {
131140
export const isThruthy = (value, just, ok) => {
132141
return value instanceof ok || value instanceof just
133142
};
143+
144+
// Returns a signal for tracking the size of an entity.
145+
export const useDimensions = (ref, get, empty) => {
146+
const signal = useSignal(empty());
147+
148+
// Initial setup...
149+
useSignalEffect(() => {
150+
const observer = new ResizeObserver(() => {
151+
signal.value = ref.value && ref.value._0 ? get(ref.value._0) : empty();
152+
});
153+
154+
if (ref.value && ref.value._0) {
155+
observer.observe(ref.value._0);
156+
}
157+
158+
return () => {
159+
signal.value = empty();
160+
observer.disconnect();
161+
};
162+
});
163+
164+
return signal;
165+
}

spec/compilers/component_instance_access

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ component Main {
3131
import {
3232
patternVariable as G,
3333
createElement as C,
34+
useRefSignal as D,
3435
pattern as F,
3536
useMemo as B,
3637
variant as A,
3738
setRef as H,
38-
useRef as D,
3939
match as E
4040
} from "./runtime.js";
4141

@@ -60,7 +60,7 @@ export const
6060
const
6161
c = D(new J()),
6262
d = () => {
63-
return E(c.current, [
63+
return E(c.value, [
6464
[
6565
F(I, [G]),
6666
(e) => {

spec/compilers/component_instance_access_2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ global component Global {
1717
--------------------------------------------------------------------------------
1818
import {
1919
createElement as B,
20-
createRef as C,
2120
variant as A,
22-
setRef as D
21+
setRef as D,
22+
signal as C
2323
} from "./runtime.js";
2424

2525
export const

spec/compilers/component_instance_access_ref

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ component Main {
2727
import {
2828
patternVariable as H,
2929
createElement as D,
30+
useRefSignal as B,
3031
pattern as G,
3132
useMemo as C,
3233
variant as A,
3334
setRef as E,
34-
useRef as B,
3535
match as F
3636
} from "./runtime.js";
3737

@@ -56,11 +56,11 @@ export const
5656
const
5757
c = B(new J()),
5858
d = () => {
59-
return F(c.current, [
59+
return F(c.value, [
6060
[
6161
G(I, [H]),
6262
(e) => {
63-
return e.a.current
63+
return e.a.value
6464
}
6565
],
6666
[

spec/compilers/context

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
type Form {
22
set: Function(String, String, Promise(Void)),
33
get: Function(String, String)
4+
} context {
5+
set: (a: String, b: String) { await void },
6+
get: (a: String) { "" }
47
}
58

69
type Maybe(a) {
@@ -46,12 +49,12 @@ component Main {
4649
--------------------------------------------------------------------------------
4750
import {
4851
createElement as E,
49-
createContext as B,
52+
createContext as C,
5053
useContext as D,
5154
mapAccess as H,
5255
useSignal as F,
5356
variant as A,
54-
record as C,
57+
record as B,
5558
or as G
5659
} from "./runtime.js";
5760

@@ -60,40 +63,47 @@ export const
6063
J = A(1, `Maybe.Just`),
6164
K = A(1, `Result.Ok`),
6265
L = A(1, `Result.Err`),
63-
M = B(),
64-
a = C(`Form`),
66+
a = B(`Form`),
67+
M = C(a({
68+
set: async (b, c) => {
69+
return await null
70+
},
71+
get: (d) => {
72+
return ``
73+
}
74+
})),
6575
N = ({
66-
b
76+
e
6777
}) => {
6878
const
69-
c = () => {
70-
return d.set(b, d.get(b) + `1`)
79+
f = () => {
80+
return g.set(e, g.get(e) + `1`)
7181
},
72-
d = D(M);
82+
g = D(M);
7383
return E(`button`, {
74-
"onClick": c
84+
"onClick": f
7585
}, [`Change!`])
7686
},
7787
O = () => {
78-
const e = F([]);
88+
const h = F([]);
7989
return E(M.Provider, {
8090
value: a({
81-
set: (f, g) => {
91+
set: (i, j) => {
8292
return (() => {
83-
e.value = e.value
93+
h.value = h.value
8494
})()
8595
},
86-
get: (h) => {
87-
return G(I, L, H(e.value, h, J, I), ``)
96+
get: (k) => {
97+
return G(I, L, H(h.value, k, J, I), ``)
8898
}
8999
})
90100
}, (() => {
91101
return E(`div`, {}, [
92102
E(N, {
93-
b: `firstname`
103+
e: `firstname`
94104
}),
95105
E(N, {
96-
b: `lastname`
106+
e: `lastname`
97107
})
98108
])
99109
})())

spec/compilers/context_with_defer

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
type Form {
2+
set: Function(String, String, Promise(Void)),
3+
get: Function(String, String)
4+
} context {
5+
set: (a: String, b: String) { await void },
6+
get: (a: String) { "" }
7+
}
8+
9+
type Maybe(a) {
10+
Nothing
11+
Just(a)
12+
}
13+
14+
type Result(err, value) {
15+
Ok(value)
16+
Err(err)
17+
}
18+
19+
async component Input {
20+
property name : String
21+
context form : Form
22+
23+
fun handleClick {
24+
form.set(name, form.get(name) + "1")
25+
}
26+
27+
fun render {
28+
<button onClick={handleClick}>
29+
"Change!"
30+
</button>
31+
}
32+
}
33+
34+
component Main {
35+
state form : Map(String, String) = {} of String => String
36+
37+
provide Form {
38+
set: (name : String, value : String) { next { form: form } },
39+
get: (name : String) { form[name] or "" }
40+
}
41+
42+
fun render {
43+
<div>
44+
<Input name="firstname"/>
45+
<Input name="lastname"/>
46+
</div>
47+
}
48+
}
49+
--------------------------------------------------------------------------------
50+
---=== /__mint__/index.js ===---
51+
import {
52+
lazyComponent as I,
53+
createElement as F,
54+
createContext as C,
55+
mapAccess as H,
56+
useSignal as E,
57+
variant as A,
58+
record as B,
59+
lazy as D,
60+
or as G
61+
} from "./runtime.js";
62+
63+
export const
64+
J = A(0, `Maybe.Nothing`),
65+
K = A(1, `Maybe.Just`),
66+
L = A(1, `Result.Ok`),
67+
M = A(1, `Result.Err`),
68+
a = B(`Form`),
69+
N = C(a({
70+
set: async (b, c) => {
71+
return await null
72+
},
73+
get: (d) => {
74+
return ``
75+
}
76+
})),
77+
O = D(`./1.js`),
78+
P = () => {
79+
const e = E([]);
80+
return F(N.Provider, {
81+
value: a({
82+
set: (f, g) => {
83+
return (() => {
84+
e.value = e.value
85+
})()
86+
},
87+
get: (h) => {
88+
return G(J, M, H(e.value, h, K, J), ``)
89+
}
90+
})
91+
}, (() => {
92+
return F(`div`, {}, [
93+
F(I, {
94+
c: [],
95+
key: `Input`,
96+
p: {
97+
a: `firstname`
98+
},
99+
x: O
100+
}),
101+
F(I, {
102+
c: [],
103+
key: `Input`,
104+
p: {
105+
a: `lastname`
106+
},
107+
x: O
108+
})
109+
])
110+
})())
111+
};
112+
113+
---=== /__mint__/1.js ===---
114+
import {
115+
createElement as C,
116+
useContext as B
117+
} from "./runtime.js";
118+
119+
import { N as A } from "./index.js";
120+
121+
export const D = ({
122+
a
123+
}) => {
124+
const
125+
b = () => {
126+
return c.set(a, c.get(a) + `1`)
127+
},
128+
c = B(A);
129+
return C(`button`, {
130+
"onClick": b
131+
}, [`Change!`])
132+
};
133+
134+
export default D;

0 commit comments

Comments
 (0)