arche 0.3.10 → 1.0.0

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/.eslintrc.js CHANGED
@@ -75,10 +75,7 @@ module.exports = {
75
75
  'func-call-spacing': 'error',
76
76
  'func-name-matching': 'off',
77
77
  'func-names': 'off',
78
- 'func-style': [
79
- 'error',
80
- 'expression'
81
- ],
78
+ 'func-style': 'off',
82
79
  'function-call-argument-newline': [
83
80
  'error',
84
81
  'consistent'
@@ -0,0 +1,24 @@
1
+ # Contributing
2
+
3
+ ## Steps to release
4
+
5
+ 1. Bump the repo version
6
+
7
+ ```
8
+ npm version patch|minor|major
9
+ ```
10
+
11
+ 2. Copy everything in the scope starting with 'use strict' in `index.js` to `es.js` and `index.mjs`
12
+
13
+ 3. Manually update the code versions and year
14
+
15
+ 4. Commit the changes
16
+
17
+ ```
18
+ git commit -m "distribute"
19
+ ```
20
+
21
+ 5. Publish the new version
22
+ ```
23
+ npm publish
24
+ ```
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020 Richard Tong
3
+ Copyright (c) 2025 Richard Tong
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -5,33 +5,156 @@
5
5
  ![Node.js CI](https://github.com/richytong/arche/actions/workflows/nodejs.yml/badge.svg)
6
6
  [![codecov](https://codecov.io/gh/richytong/arche/branch/master/graph/badge.svg)](https://codecov.io/gh/richytong/arche)
7
7
 
8
- HTML as JavaScript.
8
+ Simplified DOM interface / React in pure JavaScript.
9
9
 
10
- ```javascript [playground]
11
- const ReactElement = Arche(React)
12
- // supply the React library
13
-
14
- const { Div, H1, P } = ReactElement
15
- // some common building blocks are provided on ReactElement
16
- // as property functions.
10
+ ```javascript
11
+ const DocumentElement = Arche(document)
12
+ const { Div, H1, P } = DocumentElement
17
13
 
18
- const myElement = Div([
14
+ const myElement = Div({ id: 'my-element' }, [
19
15
  H1('I am a heading'),
20
16
  P('paragraph'),
21
17
  P('lorem ipsum'),
22
18
  ])
23
19
 
24
- render(myElement)
25
- // <div>
26
- // <h1>I am a heading</h1>
27
- // <p>paragraph</p>
28
- // <p>lorem ipsum</p>
20
+ document.getElementById('#my-container').appendChild(myElement)
21
+ // <div id="my-container">
22
+ // <div id="my-element">
23
+ // <h1>I am a heading</h1>
24
+ // <p>paragraph</p>
25
+ // <p>lorem ipsum</p>
26
+ // </div>
29
27
  // </div>
28
+
29
+ const ReactElement = Arche(React)
30
+ const { Div, H1, P, Button, Img } = ReactElement
31
+
32
+ const UserCard = ReactElement(({
33
+ firstName, lastName, age,
34
+ }) => Div([
35
+ H1(`${firstName} ${lastName}`),
36
+ Img({ src: 'https://via.placeholder.com/150x150', alt: 'placeholder' }),
37
+ P({ style: { color: 'lightgrey' } }, `age: ${age}`),
38
+ ]))
39
+
40
+ ReactDOM.render(
41
+ UserCard({ firstName: 'Example', lastName: 'Name', age: 32 }),
42
+ document.getElementById('react-root')
43
+ )
44
+ ```
45
+
46
+ ## Installation
47
+ with `npm`
48
+
49
+ ```bash
50
+ npm i arche
51
+ ```
52
+
53
+ with browser script, sets `window.Arche`
54
+
55
+ ```html
56
+ <script src="https://unpkg.com/arche"></script>
57
+ ```
58
+
59
+ with [ES Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
60
+ ```javascript
61
+ import Arche from 'https://unpkg.com/arche/es.js'
62
+ ```
63
+
64
+ Set `DocumentElement` globally for a better developer experience.
65
+
66
+ ```javascript
67
+ // global.js
68
+ const DocumentElement = Arche()
69
+
70
+ window.DocumentElement = DocumentElement
71
+
72
+ for (const elementName in DocumentElement) {
73
+ window[elementName] = DocumentElement[elementName]
74
+ }
75
+
76
+ // set missing elements
77
+ window.Aside = DocumentElement('aside')
78
+ window.Svg = DocumentElement('svg')
79
+ window.Path = DocumentElement('path')
80
+ ```
81
+
82
+ ## Syntax
83
+ ```coffeescript [specscript]
84
+ Arche() -> DocumentElement
85
+ Arche(document Document) -> DocumentElement
86
+
87
+ DocumentElement(
88
+ elementType string,
89
+ props object,
90
+ text string
91
+ ) -> element Element
92
+
93
+ DocumentElement(
94
+ elementType string,
95
+ props object,
96
+ children Array<Element|string>
97
+ ) -> element Element
98
+
99
+ DocumentElement(elementType string) -> TypedDocumentElement
100
+ DocumentElement.A -> TypedDocumentElement
101
+ DocumentElement.P -> TypedDocumentElement
102
+ DocumentElement.B -> TypedDocumentElement
103
+ DocumentElement.Q -> TypedDocumentElement
104
+ DocumentElement.I -> TypedDocumentElement
105
+ DocumentElement.Ul -> TypedDocumentElement
106
+ DocumentElement.Ol -> TypedDocumentElement
107
+ DocumentElement.Li -> TypedDocumentElement
108
+ DocumentElement.H1 -> TypedDocumentElement
109
+ DocumentElement.H2 -> TypedDocumentElement
110
+ DocumentElement.H3 -> TypedDocumentElement
111
+ DocumentElement.H4 -> TypedDocumentElement
112
+ DocumentElement.H5 -> TypedDocumentElement
113
+ DocumentElement.H6 -> TypedDocumentElement
114
+ DocumentElement.Hr -> TypedDocumentElement
115
+ DocumentElement.Br -> TypedDocumentElement
116
+ DocumentElement.Script -> TypedDocumentElement
117
+ DocumentElement.Html -> TypedDocumentElement
118
+ DocumentElement.Body -> TypedDocumentElement
119
+ DocumentElement.Nav -> TypedDocumentElement
120
+ DocumentElement.Section -> TypedDocumentElement
121
+ DocumentElement.Article -> TypedDocumentElement
122
+ DocumentElement.Footer -> TypedDocumentElement
123
+ DocumentElement.Span -> TypedDocumentElement
124
+ DocumentElement.Div -> TypedDocumentElement
125
+ DocumentElement.Img -> TypedDocumentElement
126
+ DocumentElement.Video -> TypedDocumentElement
127
+ DocumentElement.Form -> TypedDocumentElement
128
+ DocumentElement.Fieldset -> TypedDocumentElement
129
+ DocumentElement.Input -> TypedDocumentElement
130
+ DocumentElement.Label -> TypedDocumentElement
131
+ DocumentElement.Textarea -> TypedDocumentElement
132
+ DocumentElement.Select -> TypedDocumentElement
133
+ DocumentElement.Option -> TypedDocumentElement
134
+ DocumentElement.Button -> TypedDocumentElement
135
+ DocumentElement.Iframe -> TypedDocumentElement
136
+ DocumentElement.Blockquote -> TypedDocumentElement
137
+ DocumentElement.Code -> TypedDocumentElement
138
+ DocumentElement.Pre -> TypedDocumentElement
139
+
140
+ TypedDocumentElement(props object, text string) -> element Element
141
+ TypedDocumentElement(text string) -> element Element
142
+ TypedDocumentElement(props object, children Array<Element|string>) -> element Element
143
+ TypedDocumentElement(children Array<Element|string>) -> element Element
30
144
  ```
31
145
 
32
- Create dynamic components with props:
33
- ```javascript [playground]
146
+ ## Using React
147
+ To use Arche with [React](https://react.dev/), simply provide the React library.
148
+
149
+ ```javascript
34
150
  const ReactElement = Arche(React)
151
+ ```
152
+
153
+ Create dynamic components with props.
154
+
155
+ ```javascript
156
+ const ReactElement = Arche(React)
157
+
35
158
  const { Div, H1, P, Button, Img } = ReactElement
36
159
 
37
160
  const UserCard = ReactElement(({
@@ -42,16 +165,17 @@ const UserCard = ReactElement(({
42
165
  P({ style: { color: 'lightgrey' } }, `age: ${age}`),
43
166
  ]))
44
167
 
45
- render(UserCard({ firstName: 'George', lastName: 'Henry', age: 32 }))
168
+ render(UserCard({ firstName: 'Example', lastName: 'Name', age: 32 }))
46
169
  // <div>
47
- // <h1>George Henry</h1>
170
+ // <h1>Example Name</h1>
48
171
  // <img src="https://via.placeholder.com/150x150" alt="placeholder">
49
172
  // <p style="color: lightgrey">age: 32</p>
50
173
  // </div>
51
174
  ```
52
175
 
53
- Complete interoperability with React hooks (converted from [this example](https://reactjs.org/docs/hooks-intro.html)):
54
- ```javascript [playground]
176
+ Complete interoperability with React hooks (converted from [this example](https://reactjs.org/docs/hooks-intro.html)).
177
+
178
+ ```javascript
55
179
  const ReactElement = Arche(React)
56
180
  const { Div, P, Button } = ReactElement
57
181
  const { useState } = React
@@ -76,44 +200,10 @@ render(Example())
76
200
  // </div>
77
201
  ```
78
202
 
79
- # Installation
80
- with `npm`
81
- ```bash
82
- npm i arche
83
- ```
84
-
85
- browser script, global `Arche`
86
- ```html
87
- <script src="https://unpkg.com/arche"></script>
88
- ```
203
+ Set `ReactElement` globally for a better developer experience.
89
204
 
90
- browser module
91
- ```javascript
92
- import Arche from 'https://unpkg.com/arche/es.js'
93
- ```
94
-
95
- # Syntax
96
- ```coffeescript [specscript]
97
- Arche() -> DocumentElement
98
- Arche(document Document) -> DocumentElement
99
- Arche(React {
100
- createElement: (type, props?, children?)=>ReactElement,
101
- }, options? {
102
- styled?: {
103
- div: function,
104
- p: funcion,
105
- span: function,
106
- // etc
107
- },
108
- styledMemoizationCap?: number, // defaults to 1000
109
- }) -> ReactElement
110
- ```
111
-
112
- # Usage
113
- Set Arche elements globally for a great developer experience.
114
205
  ```javascript
115
206
  // global.js
116
-
117
207
  const ReactElement = Arche(React)
118
208
 
119
209
  window.ReactElement = ReactElement
@@ -122,33 +212,87 @@ for (const elementName in ReactElement) {
122
212
  window[elementName] = ReactElement[elementName]
123
213
  }
124
214
 
125
- // Arche for now does not export every element
126
- // create the ones you need like so
215
+ // set missing elements
127
216
  window.Aside = ReactElement('aside')
128
217
  window.Svg = ReactElement('svg')
129
218
  window.Path = ReactElement('path')
130
219
  ```
131
220
 
132
- ## Using styled
133
- Arche accepts a `styled` option from css-in-js libraries like [Styled Components](https://styled-components.com/) to enable a `css` prop on the base elements. This does not apply to composite components (those created with `ReactElement(props => {...})` syntax)
221
+ ## Syntax with React
134
222
 
135
- ```javascript
136
- // global.js
137
- const ReactElement = Arche(React, { styled })
138
- ```
223
+ ```coffeescript [specscript]
224
+ type React = {
225
+ createElement: (
226
+ elementType string,
227
+ props object,
228
+ children string|Array<React.Element|string>
229
+ )=>(reactElement React.Element)
230
+ }
139
231
 
140
- Elements can now specify a `css` prop to use css-in-js.
232
+ Arche(React) -> ReactElement
141
233
 
142
- ```javascript
143
- // MyComponent.js
144
- const MyComponent = ReactElement(props => {
145
- return Div({
146
- css: `
147
- width: 500px;
148
- background-color: pink;
149
- `,
150
- })
151
- })
234
+ ReactElement(
235
+ elementType string,
236
+ props object,
237
+ text string
238
+ ) -> reactElement React.Element
239
+
240
+ ReactElement(
241
+ elementType string,
242
+ props object,
243
+ children Array<React.Element|string>
244
+ ) -> reactElement React.Element
245
+
246
+ ReactElement(elementType string) -> TypedReactElement
247
+ ReactElement.A -> TypedReactElement
248
+ ReactElement.P -> TypedReactElement
249
+ ReactElement.B -> TypedReactElement
250
+ ReactElement.Q -> TypedReactElement
251
+ ReactElement.I -> TypedReactElement
252
+ ReactElement.Ul -> TypedReactElement
253
+ ReactElement.Ol -> TypedReactElement
254
+ ReactElement.Li -> TypedReactElement
255
+ ReactElement.H1 -> TypedReactElement
256
+ ReactElement.H2 -> TypedReactElement
257
+ ReactElement.H3 -> TypedReactElement
258
+ ReactElement.H4 -> TypedReactElement
259
+ ReactElement.H5 -> TypedReactElement
260
+ ReactElement.H6 -> TypedReactElement
261
+ ReactElement.Hr -> TypedReactElement
262
+ ReactElement.Br -> TypedReactElement
263
+ ReactElement.Script -> TypedReactElement
264
+ ReactElement.Html -> TypedReactElement
265
+ ReactElement.Body -> TypedReactElement
266
+ ReactElement.Nav -> TypedReactElement
267
+ ReactElement.Section -> TypedReactElement
268
+ ReactElement.Article -> TypedReactElement
269
+ ReactElement.Footer -> TypedReactElement
270
+ ReactElement.Span -> TypedReactElement
271
+ ReactElement.Div -> TypedReactElement
272
+ ReactElement.Img -> TypedReactElement
273
+ ReactElement.Video -> TypedReactElement
274
+ ReactElement.Form -> TypedReactElement
275
+ ReactElement.Fieldset -> TypedReactElement
276
+ ReactElement.Input -> TypedReactElement
277
+ ReactElement.Label -> TypedReactElement
278
+ ReactElement.Textarea -> TypedReactElement
279
+ ReactElement.Select -> TypedReactElement
280
+ ReactElement.Option -> TypedReactElement
281
+ ReactElement.Button -> TypedReactElement
282
+ ReactElement.Iframe -> TypedReactElement
283
+ ReactElement.Blockquote -> TypedReactElement
284
+ ReactElement.Code -> TypedReactElement
285
+ ReactElement.Pre -> TypedReactElement
286
+
287
+ TypedReactElement(props object, text string) -> reactElement React.Element
288
+ TypedReactElement(text string) -> reactElement React.Element
289
+
290
+ TypedReactElement(
291
+ props object,
292
+ children Array<React.Element|string>
293
+ ) -> reactElement React.Element
294
+
295
+ TypedReactElement(children Array<React.Element|string>) -> reactElement React.Element
152
296
  ```
153
297
 
154
298
  ## Using React Context
@@ -181,3 +325,147 @@ const ArticleWrapper = ReactElement(() => {
181
325
  }, [ThemeSwitcher(), Article()])
182
326
  })
183
327
  ```
328
+
329
+ ## Using styled
330
+ Arche accepts a `styled` option from css-in-js libraries like [Styled Components](https://styled-components.com/) to enable a `css` prop on `ReactElement` and `TypedReactElement`.
331
+
332
+ ```javascript
333
+ // global.js
334
+ const ReactElement = Arche(React, { styled })
335
+ ```
336
+
337
+ Elements can now specify a `css` prop to use css-in-js.
338
+
339
+ ```javascript
340
+ // MyComponent.js
341
+ const MyComponent = ReactElement(props => {
342
+ return Div({
343
+ css: `
344
+ width: 500px;
345
+ background-color: pink;
346
+ `,
347
+ })
348
+ })
349
+ ```
350
+
351
+ ## Syntax with styled
352
+ ```coffeescript [specscript]
353
+ ([css string])=>(reactElement React.Element) -> StyledComponent
354
+
355
+ type Styled = {
356
+ h1: StyledComponent,
357
+ h2: StyledComponent,
358
+ h3: StyledComponent,
359
+ h4: StyledComponent,
360
+ h5: StyledComponent,
361
+ div: StyledComponent,
362
+ button: StyledComponent,
363
+ a: StyledComponent,
364
+ p: StyledComponent,
365
+ span: StyledComponent,
366
+ img: StyledComponent,
367
+ ul: StyledComponent,
368
+ ol: StyledComponent,
369
+ li: StyledComponent,
370
+ form: StyledComponent,
371
+ article: StyledComponent,
372
+ main: StyledComponent,
373
+ section: StyledComponent,
374
+ nav: StyledComponent,
375
+ }
376
+
377
+ Arche(React {
378
+ createElement: (
379
+ elementType string,
380
+ props object,
381
+ textOrChildren string|Array<React.Element|string>
382
+ )=>(reactElement React.Element)
383
+ }, options {
384
+ styled: Styled,
385
+ styledMemoizationCap?: number
386
+ }) -> reactElement ReactElement
387
+
388
+ ReactElement(
389
+ elementType string,
390
+ propsWithCss { css: string, ...props object },
391
+ text string
392
+ ) -> reactElement React.Element
393
+
394
+ ReactElement(
395
+ elementType string,
396
+ propsWithCss { css: string, ...props object },
397
+ children Array<React.Element|string>
398
+ ) -> reactElement React.Element
399
+
400
+ ReactElement(elementType string) -> TypedReactElement
401
+ ReactElement.A -> TypedReactElement
402
+ ReactElement.P -> TypedReactElement
403
+ ReactElement.B -> TypedReactElement
404
+ ReactElement.Q -> TypedReactElement
405
+ ReactElement.I -> TypedReactElement
406
+ ReactElement.Ul -> TypedReactElement
407
+ ReactElement.Ol -> TypedReactElement
408
+ ReactElement.Li -> TypedReactElement
409
+ ReactElement.H1 -> TypedReactElement
410
+ ReactElement.H2 -> TypedReactElement
411
+ ReactElement.H3 -> TypedReactElement
412
+ ReactElement.H4 -> TypedReactElement
413
+ ReactElement.H5 -> TypedReactElement
414
+ ReactElement.H6 -> TypedReactElement
415
+ ReactElement.Hr -> TypedReactElement
416
+ ReactElement.Br -> TypedReactElement
417
+ ReactElement.Script -> TypedReactElement
418
+ ReactElement.Html -> TypedReactElement
419
+ ReactElement.Body -> TypedReactElement
420
+ ReactElement.Nav -> TypedReactElement
421
+ ReactElement.Section -> TypedReactElement
422
+ ReactElement.Article -> TypedReactElement
423
+ ReactElement.Footer -> TypedReactElement
424
+ ReactElement.Span -> TypedReactElement
425
+ ReactElement.Div -> TypedReactElement
426
+ ReactElement.Img -> TypedReactElement
427
+ ReactElement.Video -> TypedReactElement
428
+ ReactElement.Form -> TypedReactElement
429
+ ReactElement.Fieldset -> TypedReactElement
430
+ ReactElement.Input -> TypedReactElement
431
+ ReactElement.Label -> TypedReactElement
432
+ ReactElement.Textarea -> TypedReactElement
433
+ ReactElement.Select -> TypedReactElement
434
+ ReactElement.Option -> TypedReactElement
435
+ ReactElement.Button -> TypedReactElement
436
+ ReactElement.Iframe -> TypedReactElement
437
+ ReactElement.Blockquote -> TypedReactElement
438
+ ReactElement.Code -> TypedReactElement
439
+ ReactElement.Pre -> TypedReactElement
440
+
441
+ TypedReactElement(
442
+ propsWithCss { css: string, ...props object },
443
+ text string
444
+ ) -> reactElement React.Element
445
+
446
+ TypedReactElement(text string) -> reactElement React.Element
447
+
448
+ TypedReactElement(
449
+ propsWithCss { css: string, ...props object },
450
+ children Array<React.Element|string>
451
+ ) -> reactElement React.Element
452
+
453
+ TypedReactElement(children Array<React.Element|string>) -> reactElement React.Element
454
+ ```
455
+
456
+ # Contributing
457
+ Your feedback and contributions are welcome. If you have a suggestion, please raise an issue. Prior to that, please search through the issues first in case your suggestion has been made already. If you decide to work on an issue, please create a pull request.
458
+
459
+ Pull requests should provide some basic context and link the relevant issue. Here is an [example pull request](https://github.com/a-synchronous/rubico/pull/12). If you are interested in contributing, the [help wanted](https://github.com/richytong/arche/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) tag is a good place to start.
460
+
461
+ For more information please see [CONTRIBUTING.md](/CONTRIBUTING.md)
462
+
463
+ # License
464
+ Arche is [MIT Licensed](https://github.com/a-synchronous/rubico/blob/master/LICENSE).
465
+
466
+ # Support
467
+ * minimum Node.js version: 14
468
+ * minimum Chrome version: 63
469
+ * minimum Firefox version: 57
470
+ * minimum Edge version: 79
471
+ * minimum Safari version: 11.1