@wrnrlr/prelude 0.2.15 → 0.2.17

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/deno.jsonc CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrnrlr/prelude",
3
- "version": "0.2.15",
3
+ "version": "0.2.17",
4
4
  "exports": {
5
5
  ".": "./src/mod.ts",
6
6
  "./style.css": "./src/style.css"
@@ -1,11 +1,22 @@
1
1
  <!DOCTYPE html>
2
- <title>Examples</title>
2
+ <head>
3
+ <title>Examples</title>
4
+ <script type="importmap">{"imports": {"prelude": "../src/mod.ts"}}</script>
5
+ <link rel="stylesheet" href="./style.css"/>
6
+ </head>
3
7
 
4
- <a href="checkbox.html">Checkboxes</a>
5
- <a href="todo.html">Todo</a>
8
+ <h2>Examples</h2>
9
+ <ul>
10
+ <li><a href="checkbox.html">Checkboxes</a></li>
11
+ <li><a href="todo.html">Todo</a></li>
12
+ <li><a href="widget.html">Widget</a></li>
13
+ <li><a href="table.html">Table</a></li>
14
+ </ul>
15
+ <!-- <a href="router.html">Router</a> -->
16
+ <!-- <a href="context.html">Context</a> -->
17
+ <!-- <a href="table.html">Table</a> -->
6
18
 
7
19
  <style>
8
- html {background-color:lightgray}
9
20
  ul {margin:0;padding:0}
10
21
  /* ul,li {list-style-type: none} */
11
22
  input {border-width: 0 0 1px 0; margin:0.25em}
@@ -0,0 +1,505 @@
1
+ *, ::before, ::after {box-sizing: border-box; margin: 0; min-width: 0}
2
+ html {
3
+ height: 100%;
4
+ hanging-punctuation: first last;
5
+ font-family:system-ui,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji';
6
+ line-height: 1.15; -webkit-text-size-adjust: 100%;
7
+ -moz-tab-size: 4;
8
+ tab-size: 4;
9
+ font-size: 18px;
10
+ color: black;
11
+ background-color: white;
12
+ }
13
+ /* body {height: 100%} */
14
+ hr {height: 0;color: inherit;}
15
+ abbr[title] {text-decoration: underline dotted}
16
+ b,strong,i,em {font-weight: normal; text-decoration: none; font-style: normal;}
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; margin: 0; font-size: 1rem; line-height: 1.5rem; font-weight: normal;}
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
+ a {text-decoration: none; color: inherit;}
43
+ /* a:visited{color;} */
44
+ ul {padding:0; list-style:none; text-indent:0; list-style-type:none}
45
+ iframe {border: none}
46
+
47
+ :root {
48
+ --slate-50: #f8fafc;
49
+ --slate-100: #f1f5f9;
50
+ --slate-200: #e2e8f0;
51
+ --slate-300: #cbd5e1;
52
+ --slate-400: #94a3b8;
53
+ --slate-500: #64748b;
54
+ --slate-600: #475569;
55
+ --slate-700: #334155;
56
+ --slate-800: #1e293b;
57
+ --slate-900: #0f172a;
58
+ --slate-950: #020617;
59
+
60
+ --gray-50: #f9fafb;
61
+ --gray-100: #f3f4f6;
62
+ --gray-200: #e5e7eb;
63
+ --gray-300: #d1d5db;
64
+ --gray-400: #9ca3af;
65
+ --gray-500: #6b7280;
66
+ --gray-600: #4b5563;
67
+ --gray-700: #374151;
68
+ --gray-800: #1f2937;
69
+ --gray-900: #111827;
70
+ --gray-950: #030712;
71
+
72
+ --zinc-50: #fafafa;
73
+ --zinc-100: #f4f4f5;
74
+ --zinc-200: #e4e4e7;
75
+ --zinc-300: #d4d4d8;
76
+ --zinc-400: #a1a1aa;
77
+ --zinc-500: #71717a;
78
+ --zinc-600: #52525b;
79
+ --zinc-700: #3f3f46;
80
+ --zinc-800: #27272a;
81
+ --zinc-900: #18181b;
82
+ --zinc-950: #09090b;
83
+
84
+ --neutral-50: #fafafa;
85
+ --neutral-100: #f5f5f5;
86
+ --neutral-200: #e5e5e5;
87
+ --neutral-300: #d4d4d4;
88
+ --neutral-400: #a3a3a3;
89
+ --neutral-500: #737373;
90
+ --neutral-600: #525252;
91
+ --neutral-700: #404040;
92
+ --neutral-800: #262626;
93
+ --neutral-900: #171717;
94
+ --neutral-950: #0a0a0a;
95
+
96
+ --stone-50: #fafaf9;
97
+ --stone-100: #f5f5f4;
98
+ --stone-200: #e7e5e4;
99
+ --stone-300: #d6d3d1;
100
+ --stone-400: #a8a29e;
101
+ --stone-500: #78716c;
102
+ --stone-600: #57534e;
103
+ --stone-700: #44403c;
104
+ --stone-800: #292524;
105
+ --stone-900: #1c1917;
106
+ --stone-950: #0c0a09;
107
+
108
+ --red-50: #fef2f2;
109
+ --red-100: #fee2e2;
110
+ --red-200: #fecaca;
111
+ --red-300: #fca5a5;
112
+ --red-400: #f87171;
113
+ --red-500: #ef4444;
114
+ --red-600: #dc2626;
115
+ --red-700: #b91c1c;
116
+ --red-800: #991b1b;
117
+ --red-900: #7f1d1d;
118
+ --red-950: #450a0a;
119
+
120
+ --orange-50: #fff7ed;
121
+ --orange-100: #ffedd5;
122
+ --orange-200: #fed7aa;
123
+ --orange-300: #fdba74;
124
+ --orange-400: #fb923c;
125
+ --orange-500: #f97316;
126
+ --orange-600: #ea580c;
127
+ --orange-700: #c2410c;
128
+ --orange-800: #9a3412;
129
+ --orange-900: #7c2d12;
130
+ --orange-950: #431407;
131
+
132
+ --yellow-50: #fefce8;
133
+ --yellow-100: #fef9c3;
134
+ --yellow-200: #fef08a;
135
+ --yellow-300: #fde047;
136
+ --yellow-400: #facc15;
137
+ --yellow-500: #eab308;
138
+ --yellow-600: #ca8a04;
139
+ --yellow-700: #a16207;
140
+ --yellow-800: #854d0e;
141
+ --yellow-900: #713f12;
142
+ --yellow-950: #422006;
143
+
144
+ --lime-50: #f7fee7;
145
+ --lime-100: #ecfccb;
146
+ --lime-200: #d9f99d;
147
+ --lime-300: #bef264;
148
+ --lime-400: #a3e635;
149
+ --lime-500: #84cc16;
150
+ --lime-600: #65a30d;
151
+ --lime-700: #4d7c0f;
152
+ --lime-800: #3f6212;
153
+ --lime-900: #365314;
154
+ --lime-950: #1a2e05;
155
+
156
+ --green-50: #f0fdf4;
157
+ --green-100: #dcfce7;
158
+ --green-200: #bbf7d0;
159
+ --green-300: #86efac;
160
+ --green-400: #4ade80;
161
+ --green-500: #22c55e;
162
+ --green-600: #16a34a;
163
+ --green-700: #15803d;
164
+ --green-800: #166534;
165
+ --green-900: #14532d;
166
+ --green-950: #052e16;
167
+
168
+ --emrald-50: #ecfdf5;
169
+ --emrald-100: #d1fae5;
170
+ --emrald-200: #a7f3d0;
171
+ --emrald-300: #6ee7b7;
172
+ --emrald-400: #34d399;
173
+ --emrald-500: #10b981;
174
+ --emrald-600: #059669;
175
+ --emrald-700: #047857;
176
+ --emrald-800: #065f46;
177
+ --emrald-900: #064e3b;
178
+ --emrald-950: #022c22;
179
+
180
+ --teal-50: #f0fdfa;
181
+ --teal-100: #ccfbf1;
182
+ --teal-200: #99f6e4;
183
+ --teal-300: #5eead4;
184
+ --teal-400: #2dd4bf;
185
+ --teal-500: #14b8a6;
186
+ --teal-600: #0d9488;
187
+ --teal-700: #0f766e;
188
+ --teal-800: #115e59;
189
+ --teal-900: #134e4a;
190
+ --teal-950: #042f2e;
191
+
192
+ --cyan-50: #ecfeff;
193
+ --cyan-100: #cffafe;
194
+ --cyan-200: #a5f3fc;
195
+ --cyan-300: #67e8f9;
196
+ --cyan-400: #22d3ee;
197
+ --cyan-500: #06b6d4;
198
+ --cyan-600: #0891b2;
199
+ --cyan-700: #0e7490;
200
+ --cyan-800: #155e75;
201
+ --cyan-900: #164e63;
202
+ --cyan-950: #083344;
203
+
204
+ --sky-50: #f0f9ff;
205
+ --sky-100: #e0f2fe;
206
+ --sky-200: #bae6fd;
207
+ --sky-300: #7dd3fc;
208
+ --sky-400: #38bdf8;
209
+ --sky-500: #0ea5e9;
210
+ --sky-600: #0284c7;
211
+ --sky-700: #0369a1;
212
+ --sky-800: #075985;
213
+ --sky-900: #0c4a6e;
214
+ --sky-950: #082f49;
215
+
216
+ --blue-50: #eff6ff;
217
+ --blue-100: #dbeafe;
218
+ --blue-200: #bfdbfe;
219
+ --blue-300: #93c5fd;
220
+ --blue-400: #60a5fa;
221
+ --blue-500: #3b82f6;
222
+ --blue-600: #2563eb;
223
+ --blue-700: #1d4ed8;
224
+ --blue-800: #1e40af;
225
+ --blue-900: #1e3a8a;
226
+ --blue-950: #172554;
227
+
228
+ --indigo-50: #eef2ff;
229
+ --indigo-100: #e0e7ff;
230
+ --indigo-200: #c7d2fe;
231
+ --indigo-300: #a5b4fc;
232
+ --indigo-400: #818cf8;
233
+ --indigo-500: #6366f1;
234
+ --indigo-600: #4f46e5;
235
+ --indigo-700: #4338ca;
236
+ --indigo-800: #3730a3;
237
+ --indigo-900: #312e81;
238
+ --indigo-950: #1e1b4b;
239
+
240
+ --violet-50: #f5f3ff;
241
+ --violet-100: #ede9fe;
242
+ --violet-200: #ddd6fe;
243
+ --violet-300: #c4b5fd;
244
+ --violet-400: #a78bfa;
245
+ --violet-500: #8b5cf6;
246
+ --violet-600: #7c3aed;
247
+ --violet-700: #6d28d9;
248
+ --violet-800: #5b21b6;
249
+ --violet-900: #4c1d95;
250
+ --violet-950: #2e1065;
251
+
252
+ --purple-50: #faf5ff;
253
+ --purple-100: #f3e8ff;
254
+ --purple-200: #e9d5ff;
255
+ --purple-300: #d8b4fe;
256
+ --purple-400: #c084fc;
257
+ --purple-500: #a855f7;
258
+ --purple-600: #9333ea;
259
+ --purple-700: #7e22ce;
260
+ --purple-800: #6b21a8;
261
+ --purple-900: #581c87;
262
+ --purple-950: #3b0764;
263
+
264
+ --fuchsia-50: #fdf4ff;
265
+ --fuchsia-100: #fae8ff;
266
+ --fuchsia-200: #f5d0fe;
267
+ --fuchsia-300: #f0abfc;
268
+ --fuchsia-400: #e879f9;
269
+ --fuchsia-500: #d946ef;
270
+ --fuchsia-600: #c026d3;
271
+ --fuchsia-700: #a21caf;
272
+ --fuchsia-800: #86198f;
273
+ --fuchsia-900: #701a75;
274
+ --fuchsia-950: #4a044e;
275
+
276
+ --pink-50: #fdf2f8;
277
+ --pink-100: #fce7f3;
278
+ --pink-200: #fbcfe8;
279
+ --pink-300: #f9a8d4;
280
+ --pink-400: #f472b6;
281
+ --pink-500: #ec4899;
282
+ --pink-600: #db2777;
283
+ --pink-700: #be185d;
284
+ --pink-800: #9d174d;
285
+ --pink-900: #831843;
286
+ --pink-950: #500724;
287
+
288
+ --rose-50: #fff1f2;
289
+ --rose-100: #ffe4e6;
290
+ --rose-200: #fecdd3;
291
+ --rose-300: #fda4af;
292
+ --rose-400: #fb7185;
293
+ --rose-500: #f43f5e;
294
+ --rose-600: #e11d48;
295
+ --rose-700: #be123c;
296
+ --rose-800: #9f1239;
297
+ --rose-900: #881337;
298
+ --rose-950: #4c0519;
299
+ }
300
+
301
+ /* Tailwind */
302
+
303
+ .center {text-align: center;}
304
+
305
+ .absolute {position: absolute}
306
+
307
+ .hidden {display: none}
308
+
309
+ .h-full {height:100%}
310
+ .w-full {width:100%}
311
+ .h-half {height:50%}
312
+ .w-half {width:50%}
313
+
314
+ .flex {display: flex}
315
+ .block {display: block}
316
+ .column {flex-direction: column}
317
+ .column-reverse {flex-direction: column-reverse}
318
+ .row {flex-direction: row}
319
+ .row {flex-direction: row-reverse}
320
+ .inline-flex {display: inline-flex}
321
+
322
+ .flex-1 {flex: 1 1 0}
323
+ .flex-auto {flex: 1 1 auto}
324
+ .flex-initial {flex: 0 1 auto}
325
+ .flex-none {flex: none}
326
+
327
+ .flex-wrap {flex-wrap: wrap}
328
+ .flex-wrap-reverse {flex-wrap: wrap-reverse}
329
+ .flex-nowrap {flex-wrap: nowrap}
330
+
331
+ .justify-start {justify-content: flex-start}
332
+ .justify-center {justify-content: center}
333
+ .justify-end {justify-content: flex-end}
334
+ .justify-between {justify-content: space-between}
335
+ .justify-around {justify-content: space-around}
336
+ .justify-evenly {justify-content: space-evenly}
337
+
338
+ .content-start {align-content: flex-start}
339
+ .content-center {align-content: center}
340
+ .content-end {align-content: flex-end}
341
+ .content-between {align-content: space-between}
342
+ .content-around {align-content: space-around}
343
+ .content-evenly {align-content: space-evenly}
344
+
345
+ .items-start {align-items: flex-start}
346
+ .items-center {align-items: center}
347
+ .items-end {align-items: flex-end}
348
+ .items-stretch {align-items: stretch}
349
+ .items-baseline {align-items: baseline}
350
+
351
+ .self-auto {align-self:auto}
352
+ .self-start {align-self:start}
353
+ .self-center {align-self:center}
354
+ .self-end {align-self:end}
355
+ .self-stretch{align-self:stretch}
356
+ .self-baseline {align-self:baseline}
357
+
358
+ .grow {flex-grow: 1}
359
+ .grow-0 {flex-grow: 0}
360
+ .shrink {flex-shrink: 1}
361
+ .shrink-0 {flex-shrink: 0}
362
+
363
+ .w-full {width: 100%}
364
+ .h-full {height: 100%}
365
+
366
+ .p-0 {padding: 0}
367
+ .p-1 {padding: 0.25rem}
368
+ .p-2 {padding: 0.5rem}
369
+ .p-3 {padding: 0.75rem}
370
+ .p-4 {padding: 1rem}
371
+ .p-5 {padding: 1.25rem}
372
+ .p-6 {padding: 1.5rem}
373
+ .p-7 {padding: 1.75rem}
374
+ .p-8 {padding: 2rem}
375
+ .p-9 {padding: 2.25rem}
376
+ .p-10 {padding: 2.5rem}
377
+
378
+ .px-0 {padding-left: 0;padding-right: 0}
379
+ .px-1 {padding-left: 0.25rem;padding-right: 0.25rem}
380
+ .px-2 {padding-left: 0.5rem;padding-right: 0.5rem}
381
+ .px-3 {padding-left: 0.75rem;padding-right: 0.75rem}
382
+ .px-4 {padding-left: 1rem;padding-right: 1rem}
383
+ .px-5 {padding-left: 1.25rem;padding-right: 1.25rem}
384
+ .px-6 {padding-left: 1.5rem;padding-right: 1.5rem}
385
+ .px-7 {padding-left: 1.75rem;padding-right: 1.75rem}
386
+ .px-8 {padding-left: 2rem;padding-right: 2rem}
387
+
388
+ .py-0 {padding-top: 0;padding-bottom: 0}
389
+ .py-1 {padding-top: 0.25rem;padding-bottom: 0.25rem}
390
+ .py-2 {padding-top: 0.5rem;padding-bottom: 0.5rem}
391
+ .py-3 {padding-top: 0.75rem;padding-bottom: 0.75rem}
392
+ .py-4 {padding-top: 1rem;padding-bottom: 1rem}
393
+ .py-5 {padding-top: 1.25rem;padding-bottom: 1.25rem}
394
+ .py-6 {padding-top: 1.5rem;padding-bottom: 1.5rem}
395
+ .py-7 {padding-top: 1.75rem;padding-bottom: 1.75rem}
396
+ .py-8 {padding-top: 2rem;padding-bottom: 2rem}
397
+
398
+ .pl-0 {padding-left: 0}
399
+ .pl-1 {padding-left: 0.25rem}
400
+ .pl-2 {padding-left: 0.5rem}
401
+ .pl-3 {padding-left: 0.75rem}
402
+ .pl-4 {padding-left: 1rem}
403
+ .pl-5 {padding-left: 1.25rem}
404
+ .pl-6 {padding-left: 1.5rem}
405
+ .pl-7 {padding-left: 1.75rem}
406
+ .pl-8 {padding-left: 2rem}
407
+ .pl-9 {padding-left: 2.25rem}
408
+ .pl-10 {padding-left: 2.5rem}
409
+
410
+ .pt-0 {padding-top: 0}
411
+ .pt-1 {padding-top: 0.25rem}
412
+ .pt-2 {padding-top: 0.5rem}
413
+ .pt-3 {padding-top: 0.75rem}
414
+ .pt-4 {padding-top: 1rem}
415
+ .pt-5 {padding-top: 1.25rem}
416
+ .pt-6 {padding-top: 1.5rem}
417
+ .pt-7 {padding-top: 1.75rem}
418
+ .pt-8 {padding-top: 2rem}
419
+ .pt-9 {padding-top: 2.25rem}
420
+ .pt-10 {padding-top: 2.5rem}
421
+
422
+ .pr-0 {padding-right: 0}
423
+ .pr-1 {padding-right: 0.25rem}
424
+ .pr-2 {padding-right: 0.5rem}
425
+ .pr-3 {padding-right: 0.75rem}
426
+ .pr-4 {padding-right: 1rem}
427
+ .pr-5 {padding-right: 1.25rem}
428
+ .pr-6 {padding-right: 1.5rem}
429
+ .pr-7 {padding-right: 1.75rem}
430
+ .pr-8 {padding-right: 2rem}
431
+ .pr-9 {padding-right: 2.25rem}
432
+ .pr-10 {padding-right: 2.5rem}
433
+
434
+ .pb-0 {padding-bottom: 0}
435
+ .pb-1 {padding-bottom: 0.25rem}
436
+ .pb-2 {padding-bottom: 0.5rem}
437
+ .pb-3 {padding-bottom: 0.75rem}
438
+ .pb-4 {padding-bottom: 1rem}
439
+ .pb-5 {padding-bottom: 1.25rem}
440
+ .pb-6 {padding-bottom: 1.5rem}
441
+ .pb-7 {padding-bottom: 1.75rem}
442
+ .pb-8 {padding-bottom: 2rem}
443
+ .pb-9 {padding-bottom: 2.25rem}
444
+ .pb-10 {padding-bottom: 2.5rem}
445
+
446
+ .gap-0 {gap: 0}
447
+ .gap-1 {gap: 0.25rem}
448
+ .gap-2 {gap: 0.5rem}
449
+ .gap-3 {gap: 0.75rem}
450
+ .gap-4 {gap: 1rem}
451
+ .gap-5 {gap: 1.25rem}
452
+ .gap-6 {gap: 1.5rem}
453
+ .gap-7 {gap: 1.75rem}
454
+ .gap-8 {gap: 2rem}
455
+ .gap-9 {gap: 2.25rem}
456
+ .gap-10 {gap: 2.5rem}
457
+ .gap-10 {gap: 2.75rem}
458
+ .gap-11 {gap: 3rem}
459
+ .gap-12 {gap: 3.25rem}
460
+ .gap-13 {gap: 3.5rem}
461
+ .gap-14 {gap: 3.75rem}
462
+ .gap-15 {gap: 4rem}
463
+
464
+ .text-xs {font-size: 0.75rem; line-height: 1rem}
465
+ .text-sm {font-size: 0.875rem; line-height: 1.25rem}
466
+ .text-base {font-size: 1.25rem; line-height: 1.5rem}
467
+ .text-lg {font-size: 1.5rem; line-height: 1.75rem}
468
+ .text-xl {font-size: 1.25rem; line-height: 1.75rem}
469
+ .text-2xl {font-size: 1.5rem; line-height: 2rem}
470
+ .text-3xl {font-size: 1.875rem; line-height: 2.25rem}
471
+ .text-4xl {font-size: 2.25rem; line-height: 2.5rem}
472
+ .text-5xl {font-size: 3rem; line-height: 1}
473
+ .text-6xl {font-size: 3.75rem; line-height: 1}
474
+ .text-7xl {font-size: 4.5rem; line-height: 1}
475
+ .text-8xl {font-size: 6rem; line-height: 1}
476
+ .text-9xl {font-size: 8rem; line-height: 1}
477
+
478
+ .font-weight-100 {font-weight: 100}
479
+ .font-weight-200 {font-weight: 200}
480
+ .font-weight-300 {font-weight: 300}
481
+ .font-weight-400 {font-weight: 400}
482
+ .font-weight-500 {font-weight: 500}
483
+ .font-weight-600 {font-weight: 600}
484
+ .font-weight-700 {font-weight: 700}
485
+ .font-weight-800 {font-weight: 800}
486
+ .font-weight-900 {font-weight: 900}
487
+
488
+ .border-radius {border-radius: 1}
489
+
490
+ .cursor-pointer {cursor:pointer}
491
+
492
+ .rounded-none{border-radius: 0}
493
+ .rounded-sm {border-radius: 0.125rem}
494
+ .rounded {border-radius: 0.25rem}
495
+ .rounded-md {border-radius: 0.375rem}
496
+ .rounded-lg {border-radius: 0.5rem}
497
+ .rounded-xl {border-radius: 0.75rem}
498
+ .rounded-2xl {border-radius: 1rem}
499
+ .rounded-3xl {border-radius: 1.5rem}
500
+ .rounded-full {border-radius: 9999px}
501
+
502
+ .w-min {width: min-content}
503
+ .w-max {width: max-content}
504
+ .min-w-min {min-width: min-content}
505
+ .max-w-max {max-width: max-content}
@@ -0,0 +1,29 @@
1
+ @import('./reset.css')
2
+
3
+ .select {}
4
+
5
+ .option {
6
+ cursor: pointer;
7
+ background-color: var(--bg, white);
8
+ }
9
+
10
+ .multiselect {}
11
+
12
+ :root {
13
+ font-family: sans-serif;
14
+ }
15
+ .example {
16
+ display: flex;
17
+ padding: 2rem;
18
+ }
19
+
20
+ details {
21
+ & > script {
22
+ display: block;
23
+ }
24
+ }
25
+ script {
26
+ display: block;
27
+ }
28
+
29
+ .select {}
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <title>Widget</title>
4
+ <script type="importmap">{"imports": {"prelude": "../src/mod.ts"}}</script>
5
+ <link rel="stylesheet" href="./style.css"/>
6
+ </head>
7
+
8
+ <a href="/index.html">Home</a>
9
+
10
+ <h1>Table</h1>
11
+ <ul>
12
+ <li><a href="#dialog">Simple</a></li>
13
+ <li><a href="#input">Input</a></li>
14
+ </ul>
15
+
16
+ <details>
17
+ <summary>Code</summary>
18
+ <script>Hello</script>
19
+ </details>
20
+
21
+ <style>
22
+ script {
23
+ display: block;
24
+ }
25
+ </style>
@@ -0,0 +1,17 @@
1
+ import { defineConfig } from 'vite'
2
+ import path from 'node:path'
3
+
4
+ export default defineConfig({
5
+ root: path.resolve(__dirname),
6
+ plugins: [],
7
+ resolve: {
8
+ alias: {
9
+ '@src': path.resolve(__dirname, '../src')
10
+ },
11
+ },
12
+ server: {
13
+ fs: {
14
+ allow: ['..'] // Allow Vite to access parent directories
15
+ }
16
+ }
17
+ })
@@ -0,0 +1,112 @@
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <title>Widget</title>
4
+ <script type="importmap">{"imports": {"prelude": "../src/mod.ts"}}</script>
5
+ <link rel="stylesheet" href="./style.css"/>
6
+ </head>
7
+ <style>
8
+ script,script[type="module"] {
9
+ display: block;
10
+ }
11
+ </style>
12
+
13
+ <a href="/index.html">Home</a>
14
+
15
+ <h1>Widgets</h1>
16
+ <ul>
17
+ <li><a href="#dialog">Dialog</a></li>
18
+ <li><a href="#input">Input</a></li>
19
+ <li><a href="#checkbox">Checkbox</a></li>
20
+ <li><a href="#select">Select</a></li>
21
+ </ul>
22
+
23
+ <h2 id="dialog">Dialog</h2>
24
+ <div class="example" id="dialog_example"></div>
25
+ <details>
26
+ <summary>Code</summary>
27
+ <script type="module">
28
+ import { h, signal, render, Dialog, useDialog } from '../src/mod.ts'
29
+
30
+ function HelloDialog(props) {
31
+ let dialog
32
+ return h('', {ref(e){dialog=e}}, [
33
+ 'Hello',
34
+ h('button', {onClick:_=>dialog.close()}, 'Close')
35
+ ])
36
+ }
37
+
38
+ function MenuDialog(props) {
39
+ let dialog
40
+ return h('', {ref(e){dialog=e}}, [
41
+ 'Hello',
42
+ h('button', {onClick:_=>dialog.close()}, 'Close')
43
+ ])
44
+ }
45
+
46
+ function DialogExample() {
47
+ const showModal = signal(false)
48
+ const showDialog = signal(false)
49
+ return h('', {style:'display: flex; gap: 0.25rem'}, [
50
+ h('button', {onClick:e=>showModal(true)}, 'Modal'),
51
+ h(Dialog, {show:()=>showModal, modal: true}, h(HelloDialog)),
52
+ h('button', {onClick:e=>showDialog(true)}, 'Dialog'),
53
+ h(Dialog, {show:()=>showDialog}, h(MenuDialog)),
54
+ ])
55
+ }
56
+
57
+ render(DialogExample, document.getElementById('dialog_example'))
58
+ </script>
59
+ </details>
60
+
61
+ <h2 id="input">Input</h2>
62
+ <div class="example" id="input_example"></div>
63
+
64
+ <h2>Input autosize</h2>
65
+ <div class="example" id="input_autosize"></div>
66
+ <script type="module">
67
+ import { h, signal, render, Input } from '../src/mod.ts'
68
+
69
+ function InputExample() {
70
+ const name = signal('Bob')
71
+ return h(Input, {value:()=>name})
72
+ }
73
+
74
+ render(InputExample, document.getElementById('input_autosize'))
75
+ </script>
76
+
77
+ <h2 id="checkbox">Checkbox</h2>
78
+ <div class="example" id="checkbox_example"></div>
79
+ <script type="module">
80
+ import { h, signal, render, Checkbox } from "../src/mod.ts"
81
+
82
+ function CheckboxExample() {
83
+ const valid = signal(false)
84
+ return h(Checkbox, {value:()=>valid})
85
+ }
86
+
87
+ render(CheckboxExample, document.getElementById('checkbox_example'))
88
+ </script>
89
+
90
+ <h2 id="select">Select</h2>
91
+ <div class="example " id="select_car"></div>
92
+ <script type="module">
93
+ import { h, signal, memo, render, Select } from "../src/mod.ts"
94
+
95
+ function SelectCar() {
96
+ const cars = { 'Audi': ['A1','A6'], 'BMW': ['B5', 'BX'] }
97
+ const companies = Object.keys(cars)
98
+ const company = signal()
99
+ const model = signal('')
100
+ const models = memo(() => cars[company()] || null)
101
+ return [
102
+ '', h(Select, {options:companies, value:()=>company}),
103
+ '', h(Select, {options:models, value:()=>model})
104
+ ]
105
+ }
106
+
107
+ render(SelectCar, document.getElementById('select_car'))
108
+ </script>
109
+
110
+ <style>
111
+
112
+ </style>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wrnrlr/prelude",
3
3
  "type": "module",
4
- "version": "0.2.15",
4
+ "version": "0.2.17",
5
5
  "author": "Werner Laurensse",
6
6
  "description": "A signal based frontend library with fine-grained reactivity",
7
7
  "main": "./src/mod.ts",
package/readme.md CHANGED
@@ -157,7 +157,7 @@ const useCounter = () => useContext(CounterCtx)
157
157
  function CounterProvider(props) {
158
158
  const count = signal(0)
159
159
  const increment = () => count(i=>i+1)
160
- return h(CounterCtx.Provider, {value:[count,increment]}, props.children)
160
+ return h(CounterCtx, {value:[count,increment]}, props.children)
161
161
  }
162
162
 
163
163
  function Counter() {
package/src/canvas.js CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- function Canvas(props) {
2
+ export function Canvas(props) {
3
3
 
4
4
  }
5
5
 
package/src/form.js CHANGED
@@ -1,20 +1,93 @@
1
- import {signal, context, useContext} from './reactive.ts'
1
+ import { signal, memo, effect, context, useContext, renderEffect } from './reactive.ts'
2
+ import { Show } from './show.ts'
3
+ import { List } from './list.ts'
4
+ import { h } from './hyperscript.ts'
5
+ import { nbsp } from './constants.ts'
2
6
 
3
7
  const Ctx = context()
4
8
  const useForm = () => useContext(Ctx)
5
9
 
6
- function Form(props) {
10
+ export function Form(props) {
7
11
  return h('form', h(Ctx.Provider, {value:[props.value]}, props.children))
8
12
  }
9
13
 
10
- function Input(props) {
11
- if (props.name) {
12
- const [form] = useForm()
13
- props.value = wrap(form, props.name)
14
- }
14
+ export function Input(props) {
15
+ props.onInput = ((e) => props.value((e?.target)?.value))
16
+ props.autocomplete = props.autocomplete || 'off'
17
+ // const onInput = ((e) => props.value((e?.target)?.value))
18
+ if (props.autosize) props.ref = (r) => props.autosize(r, props)
15
19
  return h('input', props)
16
20
  }
17
21
 
22
+ export function autosize(r, props) {
23
+ const style = globalThis.getComputedStyle(r)
24
+ renderEffect(() => {
25
+ const font = style.getPropertyValue('font')
26
+ const metrics = fontMetrics(font, props.value().toString())
27
+ r.style.width = metrics.width + 'px'
28
+ })
29
+ }
30
+
31
+ let _fontMetricsCtx
32
+
33
+ function fontMetrics(font, text) {
34
+ if (!_fontMetricsCtx) _fontMetricsCtx = document.createElement('canvas').getContext('2d')
35
+ _fontMetricsCtx.font = font;
36
+ return _fontMetricsCtx.measureText(text)
37
+ }
38
+
39
+ export function Checkbox(props) {
40
+ return h('input',{
41
+ ...props,
42
+ type:'checkbox',
43
+ checked:props.value,
44
+ onInput:e => props.value(e.target.checked)
45
+ })
46
+ }
47
+
48
+ export function Select(props) {
49
+ // const description = wrap(props.value,'description')
50
+ const show = signal(false)
51
+ const selected = memo(()=>{
52
+ const options = typeof props.options === 'function' ? props.options() : props.options || []
53
+ return {options}
54
+ })
55
+ const fallback = props.placeholder ? h('span', props.placeholder) : 'nbsp'
56
+ return h('.select', [
57
+ h('button', {onClick:e=>show(s=>!s)}, h(Show, {when:()=>props.value, fallback}, ()=>props.value() || nbsp)),
58
+ h(Show, {when: show}, h('.options', {style:'position:absolute'}, h(List, {each:()=>selected().options},
59
+ (option) => h('.option', {
60
+ onClick: (_) => { props.value(option()); show(false) },
61
+ style: 'cursor: pointer'
62
+ }, option)
63
+ )))
64
+ ])
65
+ }
66
+
67
+ const DialogCtx = context(null)
68
+ export const useDialog = () => useContext(DialogCtx)
69
+
70
+ export function Dialog(props) {
71
+ let dialog
72
+ const close = () => dialog.close()
73
+ const show = props.modal ? () => dialog.showModal() : () => dialog.show()
74
+ return h('dialog', {
75
+ ref(dia) {
76
+ dialog = dia
77
+ const closeHandler = (_) => props.show(false)
78
+ effect(() => props.show() && show())
79
+ dialog.addEventListener('close', closeHandler)
80
+ if (props.ref) props.ref(dialog)
81
+ return () => dialog.removeEventListener('close', closeHandler)
82
+ }
83
+ }, h(DialogCtx, {value:()=>[{close:close}]}, props.children))
84
+ }
85
+
18
86
  function CurrencyInput(props) {
19
87
  return h(Input, props)
20
88
  }
89
+
90
+ export function Button(props) {
91
+ let checked
92
+ return h('button', {}, props.children)
93
+ }
package/src/mod.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type {Getter,Setter,Signal} from './reactive.ts'
2
- export {signal,effect,untrack,batch,memo,root,context,useContext,wrap,fuse,onMount,onCleanup} from './reactive.ts'
2
+ export {signal,effect,untrack,batch,memo,root,context,useContext,wrap,fuse,onMount,onCleanup,renderEffect} from './reactive.ts'
3
3
  export {nbsp} from './constants.ts'
4
4
  export {List} from './list.ts'
5
5
  export {Show} from './show.ts'
@@ -8,6 +8,9 @@ export type * from './hyperscript.ts'
8
8
  export {hyperscript, h} from './hyperscript.ts'
9
9
  export {HashRouter} from './router.js'
10
10
  export {resource,makeAbortable,abortable} from './resource.js'
11
+ import {r} from './runtime.ts'
12
+ export const render = r.render
13
+ export {Dialog,useDialog,Input,Checkbox,Select} from './form.js'
11
14
 
12
15
  // const r:Runtime = /*#__PURE__*/ (typeof window === 'object') ? runtime(window) : undefined as unknown as Runtime
13
16
 
package/src/reactive.ts CHANGED
@@ -301,14 +301,32 @@ export function context<T>(): Context<T | undefined>;
301
301
  export function context<T>(defaultValue: T): Context<T>;
302
302
  export function context<T>(defaultValue?: T) {
303
303
  const id = Symbol()
304
- const get = (): T | undefined => OBSERVER?.get ( id ) ?? defaultValue
305
- const set = ( value: T ): void => OBSERVER?.set ( id, value )
304
+ const get = (): T | undefined => OBSERVER?.get(id) ?? defaultValue
305
+ const set = ( value: T ): void => OBSERVER?.set(id, value)
306
+ // const Provider = createProvider(id)
306
307
  const s = {id, defaultValue, get, set}
307
308
  const f = Object.assign((props:any) => {
308
309
  set(props.value)
309
310
  return () => props.children.call ? props.children() : props.children
310
311
  }, s)
311
312
  return f as unknown as Context<T>
313
+ // return {id, Provider, defaultValue} as unknown as Context<T>
314
+ }
315
+
316
+ function createProvider(id: symbol): any {
317
+ return function provider(props) {
318
+ let res;
319
+ renderEffect(() => (res = untrack(() => {
320
+ console.log('observer', OBSERVER, props)
321
+ OBSERVER!.context = { ...OBSERVER!.context, [id]: props.value };
322
+ return children(() => props.children);
323
+ })))
324
+ return res;
325
+ };
326
+ }
327
+
328
+ export function renderEffect(fn:()=>void) {
329
+ return globalThis.requestAnimationFrame(()=>effect(fn))
312
330
  }
313
331
 
314
332
  export function useContext<T>(context: Context<T>): T {
package/src/select.js DELETED
@@ -1 +0,0 @@
1
-
File without changes