@wrnrlr/prelude 0.0.1

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/presets.css ADDED
@@ -0,0 +1,284 @@
1
+ @font-face {font-family:BasicIcons;src:url(/static/fa.woff2) format('woff2');}
2
+ *, ::before, ::after {box-sizing: border-box; margin: 0; min-width: 0}
3
+ html {
4
+ height: 100%;
5
+ hanging-punctuation: first last;
6
+ font-family:system-ui,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji';
7
+ line-height: 1.15; -webkit-text-size-adjust: 100%;
8
+ -moz-tab-size: 4; tab-size: 4;
9
+ font-size: 18px;
10
+ color: var(--neutral-950);
11
+ background-color: var(--neutral-50);
12
+ }
13
+ body {height: 100%}
14
+ hr {height: 0;color: inherit;}
15
+ abbr[title] {text-decoration: underline dotted}
16
+ b,strong {font-weight: bolder}
17
+ code,kbd,samp,pre {font-family:ui-monospace,SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace;font-size: 1em;}
18
+ small {font-size: 80%;}
19
+ sub,sup {font-size: 75%;line-height: 0;position: relative;vertical-align: baseline;}
20
+ sub {bottom: -0.25em}
21
+ sup {top: -0.5em}
22
+ table {border-collapse: collapse; text-indent: 0; border-color: inherit;}
23
+ button,input,optgroup,select,textarea {font-family:inherit;font-size:100%;line-height:1.15;}
24
+ button, select {text-transform: none}
25
+ button, [type='button'], [type='reset'], [type='submit'] {-webkit-appearance: button}
26
+ ::-moz-focus-inner {border-style: none;padding: 0;}
27
+ :-moz-focusring {outline: 1px dotted ButtonText;}
28
+ :-moz-ui-invalid {box-shadow: none;}
29
+ legend {padding: 0}
30
+ progress {vertical-align: baseline}
31
+ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {height: auto;margin: 0}
32
+ [type='search'] {-webkit-appearance: textfield; outline-offset: -2px;}
33
+ ::-webkit-search-decoration {-webkit-appearance: none;}
34
+ ::-webkit-file-upload-button {-webkit-appearance: button;font: inherit;}
35
+
36
+ h1,h2,h3,h4,h5,h6 {text-wrap:balance}
37
+ p {max-width:62ch;text-wrap:pretty}
38
+ dialog {padding:0;border-width:0}
39
+ button,input {padding:0;border-width:0;background-color:transparent}
40
+ input:focus,button:focus {outline:none}
41
+ summary {display: list-item;}
42
+
43
+ :root {
44
+ --slate-50: #f8fafc;
45
+ --slate-100: #f1f5f9;
46
+ --slate-200: #e2e8f0;
47
+ --slate-300: #cbd5e1;
48
+ --slate-400: #94a3b8;
49
+ --slate-500: #64748b;
50
+ --slate-600: #475569;
51
+ --slate-700: #334155;
52
+ --slate-800: #1e293b;
53
+ --slate-900: #0f172a;
54
+ --slate-950: #020617;
55
+
56
+ --gray-50: #f9fafb;
57
+ --gray-100: #f3f4f6;
58
+ --gray-200: #e5e7eb;
59
+ --gray-300: #d1d5db;
60
+ --gray-400: #9ca3af;
61
+ --gray-500: #6b7280;
62
+ --gray-600: #4b5563;
63
+ --gray-700: #374151;
64
+ --gray-800: #1f2937;
65
+ --gray-900: #111827;
66
+ --gray-950: #030712;
67
+
68
+ --red-50: #f9fafb;
69
+ --red-100: #f3f4f6;
70
+ --red-200: #e5e7eb;
71
+ --red-300: #d1d5db;
72
+ --red-400: #9ca3af;
73
+ --red-500: #6b7280;
74
+ --red-600: #4b5563;
75
+ --red-700: #374151;
76
+ --red-800: #1f2937;
77
+ --red-900: #111827;
78
+ --red-950: #030712;
79
+
80
+ /* red */
81
+ --red-50: #fef2f2;
82
+ --red-100: #fee2e2;
83
+ --red-200: #fecaca;
84
+ --red-300: #fca5a5;
85
+ --red-400: #f87171;
86
+ --red-500: #ef4444;
87
+ --red-600: #dc2626;
88
+ --red-700: #b91c1c;
89
+ --red-800: #991b1b;
90
+ --red-900: #7f1d1d;
91
+ --red-950: #450a0a;
92
+
93
+ --orange-50: #fff7ed;
94
+ --orange-100: #ffedd5;
95
+ --orange-200: #fed7aa;
96
+ --orange-300: #fdba74;
97
+ --orange-400: #fb923c;
98
+ --orange-500: #f97316;
99
+ --orange-600: #ea580c;
100
+ --orange-700: #c2410c;
101
+ --orange-800: #9a3412;
102
+ --orange-900: #7c2d12;
103
+ --orange-950: #431407;
104
+
105
+ --yellow-50: #fefce8;
106
+ --yellow-100: #fef9c3;
107
+ --yellow-200: #fef08a;
108
+ --yellow-300: #fde047;
109
+ --yellow-400: #facc15;
110
+ --yellow-500: #eab308;
111
+ --yellow-600: #ca8a04;
112
+ --yellow-700: #a16207;
113
+ --yellow-800: #854d0e;
114
+ --yellow-900: #713f12;
115
+ --yellow-950: #422006;
116
+
117
+ --lime-50: #f7fee7;
118
+ --lime-100: #ecfccb;
119
+ --lime-200: #d9f99d;
120
+ --lime-300: #bef264;
121
+ --lime-400: #a3e635;
122
+ --lime-500: #84cc16;
123
+ --lime-600: #65a30d;
124
+ --lime-700: #4d7c0f;
125
+ --lime-800: #3f6212;
126
+ --lime-900: #365314;
127
+ --lime-950: #1a2e05;
128
+
129
+ --green-50: #f0fdf4;
130
+ --green-100: #dcfce7;
131
+ --green-200: #bbf7d0;
132
+ --green-300: #86efac;
133
+ --green-400: #4ade80;
134
+ --green-500: #22c55e;
135
+ --green-600: #16a34a;
136
+ --green-700: #15803d;
137
+ --green-800: #166534;
138
+ --green-900: #14532d;
139
+ --green-950: #052e16;
140
+
141
+ --emrald-50: #ecfdf5;
142
+ --emrald-100: #d1fae5;
143
+ --emrald-200: #a7f3d0;
144
+ --emrald-300: #6ee7b7;
145
+ --emrald-400: #34d399;
146
+ --emrald-500: #10b981;
147
+ --emrald-600: #059669;
148
+ --emrald-700: #047857;
149
+ --emrald-800: #065f46;
150
+ --emrald-900: #064e3b;
151
+ --emrald-950: #022c22;
152
+
153
+ --teal-50: #f0fdfa;
154
+ --teal-100: #ccfbf1;
155
+ --teal-200: #99f6e4;
156
+ --teal-300: #5eead4;
157
+ --teal-400: #2dd4bf;
158
+ --teal-500: #14b8a6;
159
+ --teal-600: #0d9488;
160
+ --teal-700: #0f766e;
161
+ --teal-800: #115e59;
162
+ --teal-900: #134e4a;
163
+ --teal-950: #042f2e;
164
+
165
+ --cyan-50: #ecfeff;
166
+ --cyan-100: #cffafe;
167
+ --cyan-200: #a5f3fc;
168
+ --cyan-300: #67e8f9;
169
+ --cyan-400: #22d3ee;
170
+ --cyan-500: #06b6d4;
171
+ --cyan-600: #0891b2;
172
+ --cyan-700: #0e7490;
173
+ --cyan-800: #155e75;
174
+ --cyan-900: #164e63;
175
+ --cyan-950: #083344;
176
+
177
+ --sky-50: #f0f9ff;
178
+ --sky-100: #e0f2fe;
179
+ --sky-200: #bae6fd;
180
+ --sky-300: #7dd3fc;
181
+ --sky-400: #38bdf8;
182
+ --sky-500: #0ea5e9;
183
+ --sky-600: #0284c7;
184
+ --sky-700: #0369a1;
185
+ --sky-800: #075985;
186
+ --sky-900: #0c4a6e;
187
+ --sky-950: #082f49;
188
+
189
+ --blue-50: #eff6ff;
190
+ --blue-100: #dbeafe;
191
+ --blue-200: #bfdbfe;
192
+ --blue-300: #93c5fd;
193
+ --blue-400: #60a5fa;
194
+ --blue-500: #3b82f6;
195
+ --blue-600: #2563eb;
196
+ --blue-700: #1d4ed8;
197
+ --blue-800: #1e40af;
198
+ --blue-900: #1e3a8a;
199
+ --blue-950: #172554;
200
+
201
+ --indigo-50: #eef2ff;
202
+ --indigo-100: #e0e7ff;
203
+ --indigo-200: #c7d2fe;
204
+ --indigo-300: #a5b4fc;
205
+ --indigo-400: #818cf8;
206
+ --indigo-500: #6366f1;
207
+ --indigo-600: #4f46e5;
208
+ --indigo-700: #4338ca;
209
+ --indigo-800: #3730a3;
210
+ --indigo-900: #312e81;
211
+ --indigo-950: #1e1b4b;
212
+
213
+ --violet-50: #f5f3ff;
214
+ --violet-100: #ede9fe;
215
+ --violet-200: #ddd6fe;
216
+ --violet-300: #c4b5fd;
217
+ --violet-400: #a78bfa;
218
+ --violet-500: #8b5cf6;
219
+ --violet-600: #7c3aed;
220
+ --violet-700: #6d28d9;
221
+ --violet-800: #5b21b6;
222
+ --violet-900: #4c1d95;
223
+ --violet-950: #2e1065;
224
+
225
+ --purple-50: #faf5ff;
226
+ --purple-100: #f3e8ff;
227
+ --purple-200: #e9d5ff;
228
+ --purple-300: #d8b4fe;
229
+ --purple-400: #c084fc;
230
+ --purple-500: #a855f7;
231
+ --purple-600: #9333ea;
232
+ --purple-700: #7e22ce;
233
+ --purple-800: #6b21a8;
234
+ --purple-900: #581c87;
235
+ --purple-950: #3b0764;
236
+
237
+ --fuchsia-50: #fdf4ff;
238
+ --fuchsia-100: #fae8ff;
239
+ --fuchsia-200: #f5d0fe;
240
+ --fuchsia-300: #f0abfc;
241
+ --fuchsia-400: #e879f9;
242
+ --fuchsia-500: #d946ef;
243
+ --fuchsia-600: #c026d3;
244
+ --fuchsia-700: #a21caf;
245
+ --fuchsia-800: #86198f;
246
+ --fuchsia-900: #701a75;
247
+ --fuchsia-950: #4a044e;
248
+
249
+ --pink-50: #fdf2f8;
250
+ --pink-100: #fce7f3;
251
+ --pink-200: #fbcfe8;
252
+ --pink-300: #f9a8d4;
253
+ --pink-400: #f472b6;
254
+ --pink-500: #ec4899;
255
+ --pink-600: #db2777;
256
+ --pink-700: #be185d;
257
+ --pink-800: #9d174d;
258
+ --pink-900: #831843;
259
+ --pink-950: #500724;
260
+
261
+ --rose-50: #fff1f2;
262
+ --rose-100: #ffe4e6;
263
+ --rose-200: #fecdd3;
264
+ --rose-300: #fda4af;
265
+ --rose-400: #fb7185;
266
+ --rose-500: #f43f5e;
267
+ --rose-600: #e11d48;
268
+ --rose-700: #be123c;
269
+ --rose-800: #9f1239;
270
+ --rose-900: #881337;
271
+ --rose-950: #4c0519;
272
+
273
+ --neutral-50: #fafafa;
274
+ --neutral-100: #f5f5f5;
275
+ --neutral-200: #e5e5e5;
276
+ --neutral-300: #d4d4d4;
277
+ --neutral-400: #a3a3a3;
278
+ --neutral-500: #737373;
279
+ --neutral-600: #525252;
280
+ --neutral-700: #404040;
281
+ --neutral-800: #262626;
282
+ --neutral-900: #171717;
283
+ --neutral-950: #0a0a0a;
284
+ }
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- Generated by Pixelmator Pro 3.2.3 -->
3
+ <svg width="1984" height="709" viewBox="0 0 1984 709" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
4
+ <text id="Prelude" xml:space="preserve" x="765" y="492" font-family="Noto Serif" font-size="320" fill="#000000">Prelude</text>
5
+ <path id="Rectangle" fill="none" stroke="#000000" stroke-width="32" stroke-linecap="round" stroke-linejoin="round" d="M 201 548 L 613 548 L 613 159.754944 C 613 159.754944 146.066666 449.268463 410.340546 449.268463 C 670.90271 449.268463 201 159.754944 201 159.754944 L 201 548 Z"/>
6
+ </svg>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- Generated by Pixelmator Pro 3.2.3 -->
3
+ <svg width="709" height="709" viewBox="0 0 709 709" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
4
+ <path id="Rectangle" fill="none" stroke="#444444" stroke-width="40" stroke-linecap="round" stroke-linejoin="round" d="M 76 617 L 631 617 L 631 94 C 631 94 26 450 358 450 C 682 450 76 94 76 94 L 76 617 Z"/>
5
+ </svg>
package/readme.md ADDED
@@ -0,0 +1,86 @@
1
+ # PreludeJS
2
+
3
+ ## Get Started
4
+
5
+ Run directly in the browser using ESM
6
+ ```js
7
+ import {h, signal, render} from 'https://esm.sh/@wrnrlr/prelude'
8
+ ```
9
+
10
+ Install from NPM to run with Node or Bun
11
+ ```js
12
+ import {h, signal, render} from 'wrnrlr/prelude'
13
+ ```
14
+
15
+ Use Deno's JSR
16
+ ```js
17
+ import {h, signal, render} from 'jsr:wrnrlr/prelude'
18
+ ```
19
+
20
+ A simple js frontend library
21
+
22
+ ```js
23
+ import {h,signal,render} from 'https://jsr.org/wrnrlr/prelude.ts'
24
+
25
+ function Counter() {
26
+ const n = signal(1)
27
+ return [n,h('button',{onclick(e){n(n=>n+1)}},'+')]
28
+ }
29
+
30
+ render(Counter, document.body)
31
+ ```
32
+
33
+ ## Signals
34
+
35
+ ```js
36
+ const a = signal(1)
37
+ const b = signal(2)
38
+ effect(() => console.log('a+b', a()+b()))
39
+ const c = () => a()+b()
40
+ effect(() => console.log('c', c()))
41
+ a(i => i+1)
42
+ ```
43
+
44
+ ## Hyperscript
45
+
46
+ The `h` function allows one to write html in javascript with a DSL specifically designed
47
+
48
+ ```js
49
+ h('div',{},[
50
+ h('label','Name'),h('input',{})
51
+ ])
52
+ ```
53
+
54
+ ## Event Handler
55
+
56
+ An event handler MUST have an argument even if this is not being used,
57
+ otherwise hyperscript will confuse it for a signal.
58
+
59
+ ```js
60
+ // Ok
61
+ h('button', {onClick: e => console.log('Ok')}, 'Hi')
62
+ h('button', {onClick: _ => console.log('Ok')}, 'Hi')
63
+ // This event handler will be ignored
64
+ h('button', {onClick: () => console.log('Wrong')}, '')
65
+ ```
66
+
67
+ ## Conditional Rendering
68
+
69
+ ```js
70
+ h(Show, {when:show}, 'Hi')
71
+ ```
72
+
73
+ ## Rendering Lists
74
+
75
+ ```js
76
+ h(List, {each:show}, 'Hi')
77
+ ```
78
+
79
+ ## Inversion of Control
80
+ Prelude supports dependency injection with the `contect` and `useContext` APIs.
81
+
82
+ ## Advanced DataTable
83
+
84
+ ```js
85
+ h(Table)
86
+ ```
package/src/canvas.js ADDED
@@ -0,0 +1,114 @@
1
+ import {signal,effect,memo,context,useContext, onMount} from './reactive.ts'
2
+ import {$RUNTIME} from './runtime.ts'
3
+ import {h} from './mod.ts'
4
+
5
+ function CanvasRuntime() {
6
+ let render,insert,spread,assign,element,text,isChild
7
+ return {render,insert,spread,assign,element,text,isChild}
8
+ }
9
+
10
+ const CountCtx = context()
11
+
12
+ const useCount = () => useContext(CountCtx)
13
+
14
+ function CountProvider(props) {
15
+ const count = signal(0)
16
+ return h(CountCtx, {value:[count]}, props.children)
17
+ }
18
+
19
+ const Ctx = context()
20
+ const useCanvas = () => useContext(Ctx)
21
+
22
+ function Canvas(props) {
23
+ const canvas = signal()
24
+ const ctx = signal()
25
+ effect(() => ctx(canvas()?.getContext('2d')))
26
+ return h(Ctx, {value:[canvas,ctx]},
27
+ h('canvas', {ref:canvas}, props.children))
28
+ }
29
+
30
+ function toCanvas(fn) {
31
+ // fn[$RUNTIME] = CanvasRuntime
32
+ return fn
33
+ }
34
+
35
+ const Path = context()
36
+ const usePath = () => useContext(Path)
37
+
38
+ const Stroke = props => {
39
+ const ref = signal()
40
+ const [_,ctx] = useCanvas()
41
+ const path = signal(null)
42
+ let children
43
+ onMount(()=>path(new Path2D()))
44
+ effect(()=>console.log('Stroke',ref))
45
+ effect(() => {
46
+ if (!children) {
47
+ children = signal()
48
+ }
49
+ const kids = children()
50
+ if (kids) return
51
+ })
52
+ return h(Path, {ref, value:[path]}, props?.children)
53
+ }
54
+
55
+ const Fill = toCanvas(() => {
56
+ const ctx = useCanvas()
57
+ })
58
+
59
+ const Line = props => {
60
+ let value, path, path2d
61
+ // if (props.value) value = memo(() => [l.x0, l.y0, l.x1, l.y1])
62
+ if (props.children) value = props.children.call ? props.children : () => props.children
63
+ if (props.fill || props.stroke) {
64
+ path2d = new Path2D()
65
+ // ctx =
66
+ }
67
+ if (!value) value = props.value
68
+ let ctx = path2d ?? usePath()
69
+ if (!path2d&&ctx) { path = ctx[0] }
70
+ let render = path2d ?
71
+ () => {
72
+ path2d.moveTo(v[0],v[1])
73
+ path2d.lineTo(v[2],v[3])
74
+ } : () => {
75
+ const p = path()
76
+ p.moveTo(v[0],v[1])
77
+ p.lineTo(v[2],v[3])
78
+ }
79
+ // effect(()=>console.log('Line',path(), value()))
80
+ // effect(()=>{path().lineTo(...value())})
81
+ return ops => {
82
+ console.log('render line')
83
+ // ops.push()
84
+ return {
85
+ shape() {return path2d},
86
+ render,
87
+ hit() {},
88
+ size() {},
89
+ }
90
+ }
91
+ }
92
+
93
+ const Quadratic = toCanvas(q => {
94
+ const path = usePath()
95
+ return () => path.quadraticCurveTo(q.x0,q.y0,q.x1,q.y1,q.x2,q.y2)
96
+ })
97
+
98
+ const Bezier = toCanvas(b => {
99
+ const path = usePath()
100
+ return () => path.bezierCurveTo(b.x0,b.y0,b.x1,b.y1,b.x2,b.y2,b.x3,b.y3)
101
+ })
102
+
103
+ const Arc = toCanvas(a => {
104
+ const path = usePath()
105
+ return () => path.arc(a.x, a.y, a.radius, a.startAngle, a.endAngle, a.counterclockwise)
106
+ })
107
+
108
+ export const Group = {}
109
+ export const Pattern = {}
110
+ export const Text = {}
111
+ export const Rectangle = {}
112
+ export const Image = {}
113
+
114
+ export {CanvasRuntime,Canvas,Stroke,Fill,Line,Quadratic,Bezier,Arc}
@@ -0,0 +1,20 @@
1
+ /**
2
+ TODO
3
+ @group Components
4
+ */
5
+ export function Input(props) {
6
+ }
7
+
8
+ /**
9
+ TODO
10
+ @group Components
11
+ */
12
+ export function Table(props) {
13
+ }
14
+
15
+ /**
16
+ TODO
17
+ @group Components
18
+ */
19
+ export function Canvas(props) {
20
+ }