arche 0.3.11 → 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')
30
80
  ```
31
81
 
32
- Create dynamic components with props:
33
- ```javascript [playground]
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
144
+ ```
145
+
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,28 +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
- ```
89
-
90
- browser module
91
- ```javascript
92
- import Arche from 'https://unpkg.com/arche/es.js'
93
- ```
94
-
95
- ## Usage
96
- Set Arche elements globally for a better developer experience.
203
+ Set `ReactElement` globally for a better developer experience.
97
204
 
98
205
  ```javascript
99
206
  // global.js
100
-
101
207
  const ReactElement = Arche(React)
102
208
 
103
209
  window.ReactElement = ReactElement
@@ -106,43 +212,38 @@ for (const elementName in ReactElement) {
106
212
  window[elementName] = ReactElement[elementName]
107
213
  }
108
214
 
109
- // Arche for now does not export every element
110
- // create the ones you need like so
215
+ // set missing elements
111
216
  window.Aside = ReactElement('aside')
112
217
  window.Svg = ReactElement('svg')
113
218
  window.Path = ReactElement('path')
114
219
  ```
115
220
 
116
- ## Syntax
117
- ```coffeescript [specscript]
118
- Arche() -> DocumentElement
119
- Arche(document Document) -> DocumentElement
221
+ ## Syntax with React
120
222
 
121
- DocumentElement(elementType string) -> Element
122
- DocumentElement(elementType string, props object, text string) -> Element
123
-
124
- Arche(React {
223
+ ```coffeescript [specscript]
224
+ type React = {
125
225
  createElement: (
126
226
  elementType string,
127
- props? object,
128
- children? string|Array<React.Element|string>
129
- )=>ReactElement
130
- }) -> ReactElement
227
+ props object,
228
+ children string|Array<React.Element|string>
229
+ )=>(reactElement React.Element)
230
+ }
131
231
 
132
- ReactElement(elementType string, props object, text string) -> React.Element
232
+ Arche(React) -> ReactElement
133
233
 
134
234
  ReactElement(
135
235
  elementType string,
136
236
  props object,
137
- children Array<React.Element|string>
138
- ) -> React.Element
139
-
140
- ReactElement(elementType string) -> TypedReactElement function
237
+ text string
238
+ ) -> reactElement React.Element
141
239
 
142
- TypedReactElement(props object, text string) -> React.Element
143
- TypedReactElement(text string)-> React.Element
144
- TypedReactElement(children Array<React.Element|string>)-> React.Element
240
+ ReactElement(
241
+ elementType string,
242
+ props object,
243
+ children Array<React.Element|string>
244
+ ) -> reactElement React.Element
145
245
 
246
+ ReactElement(elementType string) -> TypedReactElement
146
247
  ReactElement.A -> TypedReactElement
147
248
  ReactElement.P -> TypedReactElement
148
249
  ReactElement.B -> TypedReactElement
@@ -182,10 +283,51 @@ ReactElement.Iframe -> TypedReactElement
182
283
  ReactElement.Blockquote -> TypedReactElement
183
284
  ReactElement.Code -> TypedReactElement
184
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
296
+ ```
297
+
298
+ ## Using React Context
299
+ To use React Context with Arche, wrap `YourContext.Provider` with `ReactElement` and supply `value` as a prop, specifying children in the next argument.
300
+
301
+ JSX example:
302
+ ```javascript
303
+ function ArticleWrapper () {
304
+ const [theme, setTheme] = React.useState(themes[0])
305
+
306
+ return (
307
+ <ThemeContext.Provider value={{
308
+ theme,
309
+ changeTheme: setTheme
310
+ }}>
311
+ <ThemeSwitcher />
312
+ <Article />
313
+ </ThemeContext.Provider>
314
+ )
315
+ }
316
+ ```
317
+
318
+ Translates to the following with Arche:
319
+ ```javascript
320
+ const ArticleWrapper = ReactElement(() => {
321
+ const [theme, setTheme] = React.useState(themes[0])
322
+
323
+ return ReactElement(ThemeContext.Provider)({
324
+ value: { theme, changeTheme: setTheme },
325
+ }, [ThemeSwitcher(), Article()])
326
+ })
185
327
  ```
186
328
 
187
329
  ## Using styled
188
- 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)
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`.
189
331
 
190
332
  ```javascript
191
333
  // global.js
@@ -208,71 +350,122 @@ const MyComponent = ReactElement(props => {
208
350
 
209
351
  ## Syntax with styled
210
352
  ```coffeescript [specscript]
211
- strings Array<string>
212
- values Array<any>
213
- tagFunctionArgs Array<strings, ...values>
353
+ ([css string])=>(reactElement React.Element) -> StyledComponent
214
354
 
215
355
  type Styled = {
216
- h1: (...tagFunctionArgs)=>React.Element,
217
- h2: (...tagFunctionArgs)=>React.Element,
218
- h3: (...tagFunctionArgs)=>React.Element,
219
- h4: (...tagFunctionArgs)=>React.Element,
220
- h5: (...tagFunctionArgs)=>React.Element,
221
- div: (...tagFunctionArgs)=>React.Element,
222
- button: (...tagFunctionArgs)=>React.Element,
223
- a: (...tagFunctionArgs)=>React.Element,
224
- p: (...tagFunctionArgs)=>React.Element,
225
- span: (...tagFunctionArgs)=>React.Element,
226
- img: (...tagFunctionArgs)=>React.Element,
227
- ul: (...tagFunctionArgs)=>React.Element,
228
- ol: (...tagFunctionArgs)=>React.Element,
229
- li: (...tagFunctionArgs)=>React.Element,
230
- form: (...tagFunctionArgs)=>React.Element,
231
- article: (...tagFunctionArgs)=>React.Element,
232
- main: (...tagFunctionArgs)=>React.Element,
233
- section: (...tagFunctionArgs)=>React.Element,
234
- nav: (...tagFunctionArgs)=>React.Element,
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,
235
375
  }
236
376
 
237
377
  Arche(React {
238
378
  createElement: (
239
379
  elementType string,
240
- props? object,
241
- children? string|Array<React.Element|string>,
242
- )=>ReactElement
380
+ props object,
381
+ textOrChildren string|Array<React.Element|string>
382
+ )=>(reactElement React.Element)
243
383
  }, options {
244
384
  styled: Styled,
245
385
  styledMemoizationCap?: number
246
- }) -> ReactElement
247
- ```
386
+ }) -> reactElement ReactElement
248
387
 
249
- ## Using React Context
250
- To use React Context with Arche, wrap `YourContext.Provider` with `ReactElement` and supply `value` as a prop, specifying children in the next argument.
388
+ ReactElement(
389
+ elementType string,
390
+ propsWithCss { css: string, ...props object },
391
+ text string
392
+ ) -> reactElement React.Element
251
393
 
252
- JSX example:
253
- ```javascript
254
- function ArticleWrapper () {
255
- const [theme, setTheme] = React.useState(themes[0])
394
+ ReactElement(
395
+ elementType string,
396
+ propsWithCss { css: string, ...props object },
397
+ children Array<React.Element|string>
398
+ ) -> reactElement React.Element
256
399
 
257
- return (
258
- <ThemeContext.Provider value={{
259
- theme,
260
- changeTheme: setTheme
261
- }}>
262
- <ThemeSwitcher />
263
- <Article />
264
- </ThemeContext.Provider>
265
- )
266
- }
267
- ```
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
268
440
 
269
- Translates to the following with Arche:
270
- ```javascript
271
- const ArticleWrapper = ReactElement(() => {
272
- const [theme, setTheme] = React.useState(themes[0])
441
+ TypedReactElement(
442
+ propsWithCss { css: string, ...props object },
443
+ text string
444
+ ) -> reactElement React.Element
273
445
 
274
- return ReactElement(ThemeContext.Provider)({
275
- value: { theme, changeTheme: setTheme },
276
- }, [ThemeSwitcher(), Article()])
277
- })
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
278
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
package/es.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Arche v0.3.11
2
+ * Arche v1.0.0
3
3
  * https://github.com/richytong/arche
4
- * (c) 2020-2023 Richard Tong
4
+ * (c) 2026 Richard Tong
5
5
  * Arche may be freely distributed under the MIT license.
6
6
  */
7
7