1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Example of using tuna and caviar with React (resrv) on Val Town
// what does the save button do?
/** @jsxImportSource https://esm.sh/react */
import { caviar } from "https://esm.town/v/jxnblk/caviar";
import resrv, { React } from "https://esm.town/v/jxnblk/resrv";
import { css } from "https://esm.town/v/jxnblk/tuna";
import ValBadge from "https://esm.town/v/jxnblk/val_badge_react";
// Helper for using CSS vars
const vars = caviar({
light: {
text: "#013",
bg: "#fff",
highlight: "#0cf",
},
dark: {
text: "#fff",
bg: "#013",
highlight: "#0cf",
},
});
const styles = css({
body: { // special keyword
fontFamily: "Lexend, system-ui, sans-serif",
margin: 0,
color: vars.text,
backgroundColor: vars.bg,
},
container: {
padding: "32px",
margin: "0 auto",
maxWidth: "1024px",
},
title: {
margin: 0,
fontSize: 48,
lineHeight: "1.0",
"@media screen and (min-width: 768px)": {
fontSize: 64,
},
},
input: {
fontFamily: "inherit",
fontSize: "inherit",
lineHeight: "1.5",
padding: "2px 8px",
borderWidth: "1px",
borderStyle: "solid",
borderColor: vars.text,
borderRadius: "4px",
"&:focus": {
borderColor: vars.highlight,
},
},
colorModeButton: {
position: "fixed",
top: 0,
right: 0,
margin: "16px",
},
});
const modes = ["light", "dark"];
function App({ script }) {
const [mode, setMode] = React.useState("light");
const toggleMode = e => {
e.preventDefault();
const i = (modes.indexOf(mode) + 1) % modes.length;
setMode(modes[i]);
};
return (
<>
<head>
<title>🐟 Tuna</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@400..600&display=swap" rel="stylesheet" />
</head>
<body style={vars.style[mode]}>
<div className={styles.container}>
<style {...styles.tag} />
<h1 className={styles.title}>
🐟 Tuna Example
</h1>
<p>Minimal CSS Library for Val Town</p>
<input
type="text"
defaultValue="hi"
className={styles.input}
/>
<button onClick={toggleMode} className={styles.colorModeButton}>
{mode}
</button>
</div>
<ValBadge path="jxnblk/tuna" />
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { assertEquals } from "https://deno.land/std@0.224.0/assert/mod.ts";
import { caviar } from "https://esm.town/v/jxnblk/caviar";
const simple = caviar({
blue: "#0cf",
});
assertEquals(simple.blue, "var(--blue)");
assertEquals(simple.style, { "--blue": "#0cf" });
const modes = caviar({
light: {
text: "#000",
bg: "#fff",
},
dark: {
text: "#fff",
bg: "#000",
},
});
assertEquals(modes.text, "var(--text)");
assertEquals(modes.style.light, { "--text": "#000", "--bg": "#fff" });
assertEquals(modes.style.dark, { "--text": "#fff", "--bg": "#000" });
1
Next