create-atom.io 0.0.2 → 0.0.4

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.
Files changed (51) hide show
  1. package/dist/{create-atom-DOkiQlT8.js → create-atom-C0gh5ath.js} +3 -3
  2. package/dist/create-atom-C0gh5ath.js.map +1 -0
  3. package/dist/create-atom.d.ts +1 -4
  4. package/dist/create-atom.d.ts.map +1 -1
  5. package/dist/create-atom.js +2 -2
  6. package/dist/create-atom.x.js +1 -1
  7. package/package.json +10 -9
  8. package/src/create-atom.ts +6 -2
  9. package/dist/create-atom-DOkiQlT8.js.map +0 -1
  10. package/templates/preact-svg-editor/_gitignore +0 -24
  11. package/templates/preact-svg-editor/eslint.config.ts +0 -179
  12. package/templates/preact-svg-editor/eslint.d.ts +0 -31
  13. package/templates/preact-svg-editor/index.html +0 -14
  14. package/templates/preact-svg-editor/node_modules/.bin/vite +0 -21
  15. package/templates/preact-svg-editor/package.json +0 -24
  16. package/templates/preact-svg-editor/public/preact.svg +0 -6
  17. package/templates/preact-svg-editor/src/BezierPlayground.tsx +0 -458
  18. package/templates/preact-svg-editor/src/index.tsx +0 -50
  19. package/templates/preact-svg-editor/src/msg.md +0 -105
  20. package/templates/preact-svg-editor/src/style.css +0 -126
  21. package/templates/preact-svg-editor/tsconfig.json +0 -21
  22. package/templates/preact-svg-editor/vite.config.ts +0 -10
  23. package/templates/react-node-backend/.turbo/turbo-build.log +0 -12
  24. package/templates/react-node-backend/README.md +0 -75
  25. package/templates/react-node-backend/_gitignore +0 -24
  26. package/templates/react-node-backend/dist/assets/index-6PkP9syN.js +0 -9
  27. package/templates/react-node-backend/dist/assets/index-By2j7w9s.css +0 -1
  28. package/templates/react-node-backend/dist/index.html +0 -14
  29. package/templates/react-node-backend/dist/react.svg +0 -1
  30. package/templates/react-node-backend/dist/vite.svg +0 -1
  31. package/templates/react-node-backend/eslint.config.ts +0 -176
  32. package/templates/react-node-backend/eslint.d.ts +0 -31
  33. package/templates/react-node-backend/index.html +0 -13
  34. package/templates/react-node-backend/node/authenticator.ts +0 -47
  35. package/templates/react-node-backend/node/server.ts +0 -103
  36. package/templates/react-node-backend/node_modules/.bin/conc +0 -21
  37. package/templates/react-node-backend/node_modules/.bin/concurrently +0 -21
  38. package/templates/react-node-backend/node_modules/.bin/eslint +0 -21
  39. package/templates/react-node-backend/node_modules/.bin/tsc +0 -21
  40. package/templates/react-node-backend/node_modules/.bin/tsserver +0 -21
  41. package/templates/react-node-backend/node_modules/.bin/vite +0 -21
  42. package/templates/react-node-backend/package.json +0 -33
  43. package/templates/react-node-backend/public/react.svg +0 -1
  44. package/templates/react-node-backend/public/vite.svg +0 -1
  45. package/templates/react-node-backend/src/App.tsx +0 -69
  46. package/templates/react-node-backend/src/index.css +0 -145
  47. package/templates/react-node-backend/src/main.tsx +0 -12
  48. package/templates/react-node-backend/tsconfig.app.json +0 -28
  49. package/templates/react-node-backend/tsconfig.json +0 -7
  50. package/templates/react-node-backend/tsconfig.node.json +0 -26
  51. package/templates/react-node-backend/vite.config.ts +0 -13
@@ -1,458 +0,0 @@
1
- import type { Loadable, RegularAtomToken } from "atom.io"
2
- import {
3
- atom,
4
- atomFamily,
5
- getState,
6
- resetState,
7
- runTransaction,
8
- selectorFamily,
9
- setState,
10
- transaction,
11
- } from "atom.io"
12
- import { useO } from "atom.io/react"
13
- import type { PointerEventHandler, TargetedPointerEvent, VNode } from "preact"
14
- import type { MutableRef } from "preact/hooks"
15
- import { useCallback, useEffect, useRef } from "preact/hooks"
16
-
17
- type PointXY = { x: number; y: number }
18
- type EdgeXY = { c?: PointXY; s: PointXY }
19
-
20
- const pathKeysAtom = atom<string[]>({
21
- key: `pathKeys`,
22
- default: [],
23
- })
24
- const subpathKeysAtoms = atomFamily<string[], string>({
25
- key: `subpathKeys`,
26
- default: [],
27
- })
28
- const nodeAtoms = atomFamily<PointXY | null, string>({
29
- key: `nodeAtoms`,
30
- default: null,
31
- })
32
- const edgeAtoms = atomFamily<EdgeXY | boolean, string>({
33
- key: `edgeAtoms`,
34
- default: true,
35
- })
36
- const pathDrawSelectors = selectorFamily<string, string>({
37
- key: `pathDrawSelectors`,
38
- get:
39
- (pathKey) =>
40
- ({ get }) => {
41
- const subpathKeys = get(subpathKeysAtoms, pathKey)
42
- return subpathKeys
43
- .map((subpathKey, idx) => {
44
- const node = get(nodeAtoms, subpathKey)
45
- const edge = get(edgeAtoms, subpathKey)
46
-
47
- if (node === null) {
48
- return `Z`
49
- }
50
- if (idx === 0) {
51
- return `M ${node.x} ${node.y}`
52
- }
53
- if (edge === false) {
54
- return `M ${node.x} ${node.y}`
55
- }
56
- if (edge === true) {
57
- return `L ${node.x} ${node.y}`
58
- }
59
- if (`c` in edge) {
60
- return `C ${edge.c.x} ${edge.c.y} ${edge.s.x} ${edge.s.y} ${node.x} ${node.y}`
61
- }
62
- return `S ${edge.s.x} ${edge.s.y} ${node.x} ${node.y}`
63
- })
64
- .join(` `)
65
- },
66
- })
67
-
68
- export function useAtomicRef<T>(
69
- token: RegularAtomToken<T | null>,
70
- ): MutableRef<T | null> {
71
- const ref = useRef<T | null>(null)
72
- useEffect(() => {
73
- setState(token, ref.current)
74
- }, [token])
75
- return ref
76
- }
77
-
78
- function clamp(n: number, min: number, max: number) {
79
- return Math.max(min, Math.min(max, n))
80
- }
81
-
82
- function Bezier({
83
- at,
84
- subpathKey,
85
- prevSubpathKey,
86
- node: maybeNode,
87
- }: {
88
- at: PointXY
89
- subpathKey: string
90
- prevSubpathKey: string
91
- node?: PointXY
92
- }) {
93
- let node: PointXY | null
94
- // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
95
- switch (typeof maybeNode) {
96
- case `undefined`:
97
- // eslint-disable-next-line react-hooks/rules-of-hooks
98
- node = useO(nodeAtoms, prevSubpathKey)
99
- break
100
- default:
101
- node = maybeNode
102
- }
103
- return node === null ? null : (
104
- <>
105
- <line
106
- class="bezier"
107
- x1={node.x}
108
- y1={node.y}
109
- x2={at.x}
110
- y2={at.y}
111
- stroke="#777"
112
- stroke-width={1}
113
- />
114
- <circle
115
- class="bezier"
116
- fill="#777"
117
- stroke="#aaa"
118
- stroke-width={1}
119
- cx={at.x}
120
- cy={at.y}
121
- r={2}
122
- />
123
- <circle
124
- class="bezier-draggable"
125
- fill="transparent"
126
- cx={at.x}
127
- cy={at.y}
128
- r={6}
129
- onPointerDown={(evt) => {
130
- evt.currentTarget.setPointerCapture(evt.pointerId)
131
- setState(currentlyDraggingAtom, {
132
- key: subpathKey,
133
- by: !maybeNode ? `c` : `s`,
134
- })
135
- }}
136
- />
137
- </>
138
- )
139
- }
140
-
141
- function Node({
142
- subpathKey,
143
- nextSubpathKey,
144
- }: {
145
- subpathKey: string
146
- nextSubpathKey: string
147
- }) {
148
- const node = useO(nodeAtoms, subpathKey)
149
- const edge = useO(edgeAtoms, subpathKey)
150
- return node === null ? null : (
151
- <>
152
- {typeof edge === `boolean` ? (
153
- <rect class="node" x={node.x - 3} y={node.y - 3} width={6} height={6} />
154
- ) : (
155
- <>
156
- <Bezier
157
- at={edge.s}
158
- node={node}
159
- subpathKey={subpathKey}
160
- prevSubpathKey={nextSubpathKey}
161
- />
162
- {edge.c ? (
163
- <Bezier
164
- at={edge.c}
165
- subpathKey={subpathKey}
166
- prevSubpathKey={nextSubpathKey}
167
- />
168
- ) : null}
169
- <circle class="node" cx={node.x} cy={node.y} r={3} />
170
- </>
171
- )}
172
- <circle
173
- class="node-draggable"
174
- fill="transparent"
175
- cx={node.x}
176
- cy={node.y}
177
- r={10}
178
- onPointerDown={(evt) => {
179
- evt.currentTarget.setPointerCapture(evt.pointerId)
180
- setState(currentlyDraggingAtom, { key: subpathKey })
181
- }}
182
- />
183
- </>
184
- )
185
- }
186
-
187
- function RenderedPath({ pathKey }: { pathKey: string }) {
188
- const draw = useO(pathDrawSelectors, pathKey)
189
- return <path d={`${draw} Z`} class="path" style={{ pointerEvents: `none` }} />
190
- }
191
-
192
- function Path({ pathKey }: { pathKey: string }) {
193
- const subpathKeys = useO(subpathKeysAtoms, pathKey)
194
- return (
195
- <>
196
- <RenderedPath pathKey={pathKey} />
197
- {subpathKeys.toReversed().map((spk, idx, arr) => (
198
- <Node
199
- subpathKey={spk}
200
- nextSubpathKey={arr[idx + 1] ?? arr[0]}
201
- key={spk}
202
- />
203
- ))}
204
- </>
205
- )
206
- }
207
-
208
- function PathsDemo() {
209
- const pathKeys = useO(pathKeysAtom)
210
- return (
211
- <>
212
- {pathKeys.map((pathKey) => {
213
- return <Path pathKey={pathKey} key={pathKey} />
214
- })}
215
- </>
216
- )
217
- }
218
-
219
- const svgRefAtom = atom<SVGSVGElement | null>({
220
- key: `svgRef`,
221
- default: null,
222
- })
223
- const currentlyDraggingAtom = atom<{ key: string; by?: `c` | `s` } | null>({
224
- key: `currentlyDragging`,
225
- default: null,
226
- })
227
-
228
- function onPointerMove(evt: TargetedPointerEvent<SVGSVGElement>): void {
229
- evt.preventDefault()
230
- const { key: currentlyDragging, by: draggingBy } =
231
- getState(currentlyDraggingAtom) ?? {}
232
- const svg = getState(svgRefAtom)
233
- if (!svg || !currentlyDragging) {
234
- return
235
- }
236
- const pt = svg.createSVGPoint()
237
- pt.x = evt.clientX
238
- pt.y = evt.clientY
239
- const ctm = svg.getScreenCTM()?.inverse()
240
- const { x, y } = pt.matrixTransform(ctm)
241
-
242
- switch (draggingBy) {
243
- case undefined:
244
- setState(nodeAtoms, currentlyDragging, {
245
- x: clamp(x, -185, WIDTH + 185),
246
- y: clamp(y, -10, HEIGHT + 10),
247
- })
248
- break
249
- case `s`:
250
- setState(edgeAtoms, currentlyDragging, (prev) => ({
251
- ...(prev as EdgeXY),
252
- s: { x: clamp(x, -185, WIDTH + 185), y: clamp(y, -10, HEIGHT + 10) },
253
- }))
254
- break
255
- case `c`:
256
- setState(edgeAtoms, currentlyDragging, (prev) => ({
257
- ...(prev as EdgeXY),
258
- c: { x: clamp(x, -185, WIDTH + 185), y: clamp(y, -10, HEIGHT + 10) },
259
- }))
260
- break
261
- }
262
- }
263
-
264
- const CODES = [`m`, `M`, `l`, `L`, `c`, `C`, `v`, `V`, `z`, `Z`] as const
265
-
266
- const preactLogoAtom = atom<Loadable<string>>({
267
- key: `preactLogo`,
268
- default: () => fetch(`preact.svg`).then((res) => res.text()),
269
- })
270
-
271
- const resetTX = transaction<() => Promise<void>>({
272
- key: `reset`,
273
- do: async () => {
274
- const logo = await getState(preactLogoAtom)
275
- for (const pathKey of getState(pathKeysAtom)) {
276
- resetState(subpathKeysAtoms, pathKey)
277
- }
278
- resetState(pathKeysAtom)
279
-
280
- const shapes = logo
281
- .split(`\n`)
282
- .filter((line) => line.startsWith(`\t<path`))
283
- .map((line) => {
284
- const raw = line.split(`d="`)[1].slice(0, -9)
285
-
286
- type Letter = (typeof CODES)[number]
287
- let letter: Letter | undefined
288
- let number = ``
289
- let numbers: number[] = []
290
-
291
- const instructions: { letter: Letter; numbers: number[] }[] = []
292
- for (const c of raw) {
293
- if (CODES.includes(c as Letter)) {
294
- if (number) {
295
- numbers.push(Number.parseFloat(number))
296
- number = ``
297
- }
298
- if (letter) {
299
- instructions.push({ letter, numbers })
300
- }
301
- letter = c as Letter
302
- numbers = []
303
- continue
304
- }
305
- if (c === ` `) {
306
- numbers.push(Number.parseFloat(number))
307
- number = ``
308
- continue
309
- }
310
- if (c === `-` && number) {
311
- numbers.push(Number.parseFloat(number))
312
- number = `-`
313
- continue
314
- }
315
-
316
- number += c
317
- }
318
-
319
- let prev: PointXY = { x: 0, y: 0 }
320
- const edgeNodes = instructions.map<{
321
- node: PointXY | null
322
- edge: boolean | { c?: PointXY; s: PointXY }
323
- }>(({ letter: l, numbers: ns }) => {
324
- let node: PointXY | null
325
- let edge: boolean | { c?: PointXY; s: PointXY }
326
- switch (l) {
327
- case `m`:
328
- node = { x: prev.x + ns[0], y: prev.y + ns[1] }
329
- edge = false
330
- break
331
- case `M`:
332
- node = { x: ns[0], y: ns[1] }
333
- edge = false
334
- break
335
- case `l`:
336
- node = { x: prev.x + ns[0], y: prev.y + ns[1] }
337
- edge = true
338
- break
339
- case `L`:
340
- node = { x: ns[0], y: ns[1] }
341
- edge = true
342
- break
343
- case `c`:
344
- node = { x: prev.x + ns[4], y: prev.y + ns[5] }
345
- edge = {
346
- c: { x: prev.x + ns[0], y: prev.y + ns[1] },
347
- s: { x: prev.x + ns[2], y: prev.y + ns[3] },
348
- }
349
- break
350
- case `C`:
351
- node = { x: ns[4], y: ns[5] }
352
- edge = {
353
- c: { x: ns[0], y: ns[1] },
354
- s: { x: ns[2], y: ns[3] },
355
- }
356
- break
357
- case `v`:
358
- node = { x: prev.x, y: prev.y + ns[0] }
359
- edge = true
360
- break
361
- case `V`:
362
- node = { x: prev.x, y: ns[0] }
363
- edge = true
364
- break
365
- case `z`:
366
- case `Z`:
367
- node = null
368
- edge = true
369
- }
370
- if (node) {
371
- prev = node
372
- }
373
-
374
- return { node, edge }
375
- })
376
-
377
- return edgeNodes
378
- })
379
-
380
- let i = 0
381
- let j = 0
382
- for (const shape of shapes) {
383
- const jj = j
384
- for (const { node, edge } of shape) {
385
- setState(edgeAtoms, `subpath${j}`, edge)
386
- setState(nodeAtoms, `subpath${j}`, node)
387
- j++
388
- }
389
- const numberOfNodes = j - jj
390
- setState(
391
- subpathKeysAtoms,
392
- `path${i}`,
393
- Array.from(
394
- { length: numberOfNodes },
395
- (_, nodeNum) => `subpath${jj + nodeNum}`,
396
- ),
397
- )
398
- setState(pathKeysAtom, (prev) => [...prev, `path${i}`])
399
- i++
400
- }
401
- },
402
- })
403
- const reset = runTransaction(resetTX)
404
-
405
- const WIDTH = 256
406
- const HEIGHT = 296
407
- export default function BezierPlayground(): VNode {
408
- const svgRef = useAtomicRef(svgRefAtom)
409
- const onPointerUp: PointerEventHandler<SVGSVGElement> = useCallback((evt) => {
410
- evt.currentTarget.releasePointerCapture(evt.pointerId)
411
- setState(currentlyDraggingAtom, null)
412
- }, [])
413
-
414
- useEffect(() => void reset(), [])
415
-
416
- return (
417
- <div
418
- style={{
419
- display: `flex`,
420
- flexFlow: `column`,
421
- position: `relative`,
422
- overflow: `hidden`,
423
- maxWidth: `1280px`,
424
- width: `100vw`,
425
- alignItems: `center`,
426
- }}
427
- >
428
- <svg
429
- ref={svgRef}
430
- viewBox={`-185 -15 ${WIDTH + 370} ${HEIGHT + 30}`}
431
- width={1000}
432
- height={500}
433
- onPointerMove={onPointerMove}
434
- onPointerUp={onPointerUp}
435
- onPointerCancel={onPointerUp}
436
- >
437
- <title>Bezier Playground</title>
438
- <defs>
439
- <pattern id="grid" width="5" height="5" patternUnits="userSpaceOnUse">
440
- <rect x="0" y="0" width=".5" height=".5" fill="none" stroke="#aaa" />
441
- </pattern>
442
- </defs>
443
- <rect x={0} y={0} width={WIDTH} height={HEIGHT} fill="#aaa3" />
444
- <rect
445
- x={-185}
446
- y={-10}
447
- width={WIDTH + 370}
448
- height={HEIGHT + 20}
449
- fill="url(#grid)"
450
- />
451
- <PathsDemo />
452
- </svg>
453
- <button type="button" class="flat" onClick={reset}>
454
- Reset
455
- </button>
456
- </div>
457
- )
458
- }
@@ -1,50 +0,0 @@
1
- import "./style.css"
2
-
3
- import type { VNode } from "preact"
4
- import { render } from "preact"
5
-
6
- import BezierPlayground from "./BezierPlayground.tsx"
7
-
8
- export function App(): VNode {
9
- return (
10
- <>
11
- <h1>Atom.io in Preact on Vite</h1>
12
- <main>
13
- <BezierPlayground />
14
- <article>
15
- <Resource
16
- title="Learn Atom.io"
17
- description="Atom.io is where data lives."
18
- href="https://atom.io.fyi/docs/getting-started"
19
- />
20
- <Resource
21
- title="Learn Preact"
22
- description="If you're new to Preact, try the interactive tutorial to learn important concepts"
23
- href="https://preactjs.com/tutorial"
24
- />
25
- <Resource
26
- title="Learn Vite"
27
- description="To learn more about Vite and how you can customize it to fit your needs, take a look at their excellent documentation"
28
- href="https://vitejs.dev"
29
- />
30
- </article>
31
- </main>
32
- </>
33
- )
34
- }
35
-
36
- type ResourceProps = {
37
- title: string
38
- description: string
39
- href: string
40
- }
41
- function Resource(props: ResourceProps) {
42
- return (
43
- <a href={props.href} target="_blank" class="resource" rel="noreferrer">
44
- <h2>{props.title}</h2>
45
- <p>{props.description}</p>
46
- </a>
47
- )
48
- }
49
-
50
- render(<App />, document.getElementById(`app`)!)
@@ -1,105 +0,0 @@
1
- Great question — the `d` attribute in an SVG `<path>` element is one of the most powerful but also most cryptic parts of SVG. It defines the shape of the path by listing a series of **commands** and **parameters**. Let’s break it down step by step so you can confidently read (and write) it.
2
-
3
- ---
4
-
5
- ## 🧭 1. What the `d` Attribute Is
6
-
7
- The `d` attribute contains **a mini language** consisting of:
8
-
9
- - Single-letter commands (e.g. `M`, `L`, `C`, `Z`)
10
- - A series of numbers following those commands (coordinates or parameters)
11
- - Optional spaces and commas
12
-
13
- For example:
14
-
15
- ```svg
16
- <path d="M10 10 L50 50 L90 10 Z" />
17
- ```
18
-
19
- This draws a triangle:
20
-
21
- 1. Move to `(10,10)`
22
- 2. Draw a line to `(50,50)`
23
- 3. Draw a line to `(90,10)`
24
- 4. Close the shape
25
-
26
- ---
27
-
28
- ## ✍️ 2. Absolute vs Relative Commands
29
-
30
- Each command can be:
31
-
32
- - **Uppercase** → Absolute coordinates
33
- - **Lowercase** → Relative coordinates (relative to the current point)
34
-
35
- Example:
36
-
37
- ```svg
38
- M 100 100 // Move to (100,100)
39
- l 50 0 // Draw line relative +50 in x, +0 in y → ends at (150,100)
40
- ```
41
-
42
- ---
43
-
44
- ## 🧱 3. Common Path Commands
45
-
46
- | Command | Name | Parameters | What it does |
47
- | --------- | ------------------- | --------------------------------------------------- | -------------------------------------------------------- |
48
- | `M` / `m` | moveto | x y | Moves the “pen” to a new position without drawing |
49
- | `L` / `l` | lineto | x y | Draws a straight line from current point to new point |
50
- | `H` / `h` | horizontal lineto | x | Line horizontally (only x changes) |
51
- | `V` / `v` | vertical lineto | y | Line vertically (only y changes) |
52
- | `C` / `c` | cubic Bézier curve | x1 y1 x2 y2 x y | Curve with 2 control points and an endpoint |
53
- | `S` / `s` | smooth cubic Bézier | x2 y2 x y | Like `C` but assumes first control point is a reflection |
54
- | `Q` / `q` | quadratic Bézier | x1 y1 x y | Curve with 1 control point and an endpoint |
55
- | `T` / `t` | smooth quadratic | x y | Like `Q` but auto-control point |
56
- | `A` / `a` | elliptical arc | rx ry x-axis-rotation large-arc-flag sweep-flag x y | Draws an arc |
57
- | `Z` / `z` | closepath | _(none)_ | Closes the path (line back to start) |
58
-
59
- ---
60
-
61
- ## 🧮 4. How to Read a Complex Example
62
-
63
- Here’s a more complex example:
64
-
65
- ```svg
66
- <path d="M 100 100 C 100 50, 200 50, 200 100 S 300 150, 300 100 Z" />
67
- ```
68
-
69
- Let’s break it down:
70
-
71
- 1. `M 100 100` — move to `(100,100)`
72
- 2. `C 100 50, 200 50, 200 100` — draw cubic Bézier curve with control points `(100,50)` and `(200,50)`, endpoint `(200,100)`
73
- 3. `S 300 150, 300 100` — smooth curve, auto control point from previous, second control `(300,150)`, endpoint `(300,100)`
74
- 4. `Z` — close the path (draw a line back to `(100,100)`)
75
-
76
- ---
77
-
78
- ## 🧠 5. Tips for Reading
79
-
80
- - Think of the “pen” moving around.
81
- - Break the path at each command letter.
82
- - Translate relative commands (`l`, `c`, etc.) into absolute positions step by step if needed.
83
- - Visualization tools like [SVG Path Editor](https://yqnn.github.io/svg-path-editor/) can help you see what’s happening interactively.
84
-
85
- ---
86
-
87
- ## 🧰 6. Handy Shortcuts
88
-
89
- - Repeating commands can omit the command letter.
90
-
91
- ```svg
92
- M10 10 L20 20 30 10
93
- ```
94
-
95
- is equivalent to:
96
-
97
- ```svg
98
- M10 10 L20 20 L30 10
99
- ```
100
-
101
- - For curves (`C`, `S`, `Q`, `T`), the number of coordinates tells you how many segments there are.
102
-
103
- ---
104
-
105
- Would you like me to **deconstruct a specific `d` string** you have? (e.g. paste one and I’ll walk through it step by step.)