Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion core/tests/tests/Context.mint
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
type Test.Context {
name : String
}
} context { name: "NAME" }

component Test.NestedConsumer {
fun render {
Expand Down Expand Up @@ -30,4 +30,10 @@ suite "Context" {
|> Test.Html.start()
|> Test.Html.assertTextOf("div", "Joe")
}

test "Test.Consumer" {
<Test.Consumer/>
|> Test.Html.start()
|> Test.Html.assertTextOf("div", "NAME")
}
}
2 changes: 1 addition & 1 deletion runtime/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { createElement, Fragment as fragment, createContext } from "preact";
export { useEffect, useMemo, useRef, useContext } from "preact/hooks";
export { useEffect, useMemo, useContext } from "preact/hooks";
export { signal, batch } from "@preact/signals";

export * from "./src/pattern_matching";
Expand Down
58 changes: 45 additions & 13 deletions runtime/src/utilities.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useRef, useMemo } from "preact/hooks";
import { signal } from "@preact/signals";
import { signal, useSignalEffect, useSignal as useSignalOriginal } from "@preact/signals";
import { useEffect, useRef, useMemo, useCallback } from "preact/hooks";

import {
createRef as createRefOriginal,
Expand Down Expand Up @@ -31,16 +31,32 @@ export const bracketAccess = (array, index, just, nothing) => {
}
};

// This sets the references to an element or component. The current
// These set the references to an element or component. The current
// value is always a `Maybe`
export const setRef = (value, just, nothing) => (element) => {
export const setTestRef = (signal, just, nothing) => (element) => {
let current;
if (element === null) {
value.current = new nothing();
current = new nothing();
} else {
value.current = new just(element);
current = new just(element);
}

if (signal) {
if (!compare(signal.peek(), current)) {
signal.value = current
}
}
}

export const setRef = (signal, just, nothing) => {
return useCallback((element) => {
setTestRef(signal, just, nothing)(element)
}, [])
};

// The normal useSignal.
export const useRefSignal = useSignalOriginal;

// A version of `useSignal` which subscribes to the signal by default (like a
// state) since we want to re-render every time the signal changes.
export const useSignal = (value) => {
Expand All @@ -49,13 +65,6 @@ export const useSignal = (value) => {
return item;
};

// A version of `createRef` with a default value.
export const createRef = (value) => {
const ref = createRefOriginal();
ref.current = value;
return ref;
};

// A hook to replace the `componentDidUpdate` function.
export const useDidUpdate = (callback) => {
const hasMount = useRef(false);
Expand Down Expand Up @@ -131,3 +140,26 @@ export const load = async (path) => {
export const isThruthy = (value, just, ok) => {
return value instanceof ok || value instanceof just
};

// Returns a signal for tracking the size of an entity.
export const useDimensions = (ref, get, empty) => {
const signal = useSignal(empty());

// Initial setup...
useSignalEffect(() => {
const observer = new ResizeObserver(() => {
signal.value = ref.value && ref.value._0 ? get(ref.value._0) : empty();
});

if (ref.value && ref.value._0) {
observer.observe(ref.value._0);
}

return () => {
signal.value = empty();
observer.disconnect();
};
});

return signal;
}
4 changes: 2 additions & 2 deletions spec/compilers/component_instance_access
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ component Main {
import {
patternVariable as G,
createElement as C,
useRefSignal as D,
pattern as F,
useMemo as B,
variant as A,
setRef as H,
useRef as D,
match as E
} from "./runtime.js";

Expand All @@ -60,7 +60,7 @@ export const
const
c = D(new J()),
d = () => {
return E(c.current, [
return E(c.value, [
[
F(I, [G]),
(e) => {
Expand Down
4 changes: 2 additions & 2 deletions spec/compilers/component_instance_access_2
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ global component Global {
--------------------------------------------------------------------------------
import {
createElement as B,
createRef as C,
variant as A,
setRef as D
setRef as D,
signal as C
} from "./runtime.js";

export const
Expand Down
6 changes: 3 additions & 3 deletions spec/compilers/component_instance_access_ref
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ component Main {
import {
patternVariable as H,
createElement as D,
useRefSignal as B,
pattern as G,
useMemo as C,
variant as A,
setRef as E,
useRef as B,
match as F
} from "./runtime.js";

Expand All @@ -56,11 +56,11 @@ export const
const
c = B(new J()),
d = () => {
return F(c.current, [
return F(c.value, [
[
G(I, [H]),
(e) => {
return e.a.current
return e.a.value
}
],
[
Expand Down
42 changes: 26 additions & 16 deletions spec/compilers/context
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
type Form {
set: Function(String, String, Promise(Void)),
get: Function(String, String)
} context {
set: (a: String, b: String) { await void },
get: (a: String) { "" }
}

type Maybe(a) {
Expand Down Expand Up @@ -46,12 +49,12 @@ component Main {
--------------------------------------------------------------------------------
import {
createElement as E,
createContext as B,
createContext as C,
useContext as D,
mapAccess as H,
useSignal as F,
variant as A,
record as C,
record as B,
or as G
} from "./runtime.js";

Expand All @@ -60,40 +63,47 @@ export const
J = A(1, `Maybe.Just`),
K = A(1, `Result.Ok`),
L = A(1, `Result.Err`),
M = B(),
a = C(`Form`),
a = B(`Form`),
M = C(a({
set: async (b, c) => {
return await null
},
get: (d) => {
return ``
}
})),
N = ({
b
e
}) => {
const
c = () => {
return d.set(b, d.get(b) + `1`)
f = () => {
return g.set(e, g.get(e) + `1`)
},
d = D(M);
g = D(M);
return E(`button`, {
"onClick": c
"onClick": f
}, [`Change!`])
},
O = () => {
const e = F([]);
const h = F([]);
return E(M.Provider, {
value: a({
set: (f, g) => {
set: (i, j) => {
return (() => {
e.value = e.value
h.value = h.value
})()
},
get: (h) => {
return G(I, L, H(e.value, h, J, I), ``)
get: (k) => {
return G(I, L, H(h.value, k, J, I), ``)
}
})
}, (() => {
return E(`div`, {}, [
E(N, {
b: `firstname`
e: `firstname`
}),
E(N, {
b: `lastname`
e: `lastname`
})
])
})())
Expand Down
134 changes: 134 additions & 0 deletions spec/compilers/context_with_defer
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
type Form {
set: Function(String, String, Promise(Void)),
get: Function(String, String)
} context {
set: (a: String, b: String) { await void },
get: (a: String) { "" }
}

type Maybe(a) {
Nothing
Just(a)
}

type Result(err, value) {
Ok(value)
Err(err)
}

async component Input {
property name : String
context form : Form

fun handleClick {
form.set(name, form.get(name) + "1")
}

fun render {
<button onClick={handleClick}>
"Change!"
</button>
}
}

component Main {
state form : Map(String, String) = {} of String => String

provide Form {
set: (name : String, value : String) { next { form: form } },
get: (name : String) { form[name] or "" }
}

fun render {
<div>
<Input name="firstname"/>
<Input name="lastname"/>
</div>
}
}
--------------------------------------------------------------------------------
---=== /__mint__/index.js ===---
import {
lazyComponent as I,
createElement as F,
createContext as C,
mapAccess as H,
useSignal as E,
variant as A,
record as B,
lazy as D,
or as G
} from "./runtime.js";

export const
J = A(0, `Maybe.Nothing`),
K = A(1, `Maybe.Just`),
L = A(1, `Result.Ok`),
M = A(1, `Result.Err`),
a = B(`Form`),
N = C(a({
set: async (b, c) => {
return await null
},
get: (d) => {
return ``
}
})),
O = D(`./1.js`),
P = () => {
const e = E([]);
return F(N.Provider, {
value: a({
set: (f, g) => {
return (() => {
e.value = e.value
})()
},
get: (h) => {
return G(J, M, H(e.value, h, K, J), ``)
}
})
}, (() => {
return F(`div`, {}, [
F(I, {
c: [],
key: `Input`,
p: {
a: `firstname`
},
x: O
}),
F(I, {
c: [],
key: `Input`,
p: {
a: `lastname`
},
x: O
})
])
})())
};

---=== /__mint__/1.js ===---
import {
createElement as C,
useContext as B
} from "./runtime.js";

import { N as A } from "./index.js";

export const D = ({
a
}) => {
const
b = () => {
return c.set(a, c.get(a) + `1`)
},
c = B(A);
return C(`button`, {
"onClick": b
}, [`Change!`])
};

export default D;
Loading