arche 0.2.3 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,2 +1,14 @@
1
- ## v0.1.0 - latest
1
+ ## v0.3.0
2
+ * styled option enables the css parameter
3
+
4
+ ## v0.2.5
5
+ * mjs export
6
+
7
+ ## v0.2.2
8
+ * React Context Support
9
+
10
+ ## v0.2.0
11
+ * Element shorthands
12
+
13
+ ## v0.1.0
2
14
  * First release with proof of concept at [rubico.land](https://rubico.land/)
package/es.js CHANGED
@@ -114,7 +114,9 @@ const creatorCreateElement = function (creator, type, props, children) {
114
114
  * Pre: (props, children?)|children)=>element,
115
115
  * }
116
116
  *
117
- * Arche(creator) -> rootElement
117
+ * Arche(creator, options {
118
+ * styled?: Styled,
119
+ * }) -> rootElement
118
120
  * ```
119
121
  *
120
122
  * @description
@@ -184,23 +186,69 @@ const creatorCreateElement = function (creator, type, props, children) {
184
186
  * ```
185
187
  */
186
188
 
187
- const Arche = function (creator) {
188
- const rootElement = type => function creatingElement(arg0, arg1) {
189
+ const Arche = function (creator, options = {}) {
190
+ const { styled } = options
191
+
192
+ const originalRootElement = type => function creatingElement(arg0, arg1) {
189
193
  if (isArray(arg0)) {
190
194
  return creatorCreateElement(creator, type, {}, arg0)
191
195
  }
196
+
192
197
  if (typeof arg0 == 'string') {
193
198
  return creatorCreateElement(creator, type, {}, [arg0])
194
199
  }
200
+
195
201
  if (isArray(arg1)) {
196
202
  return creatorCreateElement(creator, type, arg0, arg1)
197
203
  }
204
+
198
205
  if (arg1 == null) {
199
206
  return creatorCreateElement(creator, type, arg0, [])
200
207
  }
208
+
201
209
  return creatorCreateElement(creator, type, arg0, [arg1])
202
210
  }
203
211
 
212
+ const styledRootElement = type => function creatingStyledElement(arg0, arg1) {
213
+ if (isArray(arg0)) {
214
+ return creatorCreateElement(creator, type, {}, arg0)
215
+ }
216
+
217
+ if (typeof arg0 == 'string') {
218
+ return creatorCreateElement(creator, type, {}, [arg0])
219
+ }
220
+
221
+ if (isArray(arg1)) {
222
+ if (arg0.css == null) {
223
+ return creatorCreateElement(creator, type, arg0, arg1)
224
+ }
225
+ const { css, ...props } = arg0
226
+ return creatorCreateElement(creator, styled[type](css), props, arg1)
227
+ }
228
+
229
+ if (arg1 == null) {
230
+ if (arg0.css == null) {
231
+ return creatorCreateElement(creator, type, arg0, [])
232
+ }
233
+ const { css, ...props } = arg0
234
+ return creatorCreateElement(creator, styled[type](css), props, [])
235
+ }
236
+
237
+ if (arg0.css == null) {
238
+ return creatorCreateElement(creator, type, arg0, [arg1])
239
+ }
240
+ const { css, ...props } = arg0
241
+ return creatorCreateElement(creator, styled[type](css), props, [arg1])
242
+ }
243
+
244
+ const rootElement = (
245
+ styled == null
246
+ ? originalRootElement
247
+ : type => typeof type == 'string'
248
+ ? styledRootElement(type)
249
+ : originalRootElement(type)
250
+ )
251
+
204
252
  rootElement.A = rootElement('a')
205
253
  rootElement.P = rootElement('p')
206
254
  rootElement.B = rootElement('b')
package/index.js CHANGED
@@ -120,7 +120,9 @@ const creatorCreateElement = function (creator, type, props, children) {
120
120
  * Pre: (props, children?)|children)=>element,
121
121
  * }
122
122
  *
123
- * Arche(creator) -> rootElement
123
+ * Arche(creator, options {
124
+ * styled?: Styled,
125
+ * }) -> rootElement
124
126
  * ```
125
127
  *
126
128
  * @description
@@ -190,23 +192,69 @@ const creatorCreateElement = function (creator, type, props, children) {
190
192
  * ```
191
193
  */
192
194
 
193
- const Arche = function (creator) {
194
- const rootElement = type => function creatingElement(arg0, arg1) {
195
+ const Arche = function (creator, options = {}) {
196
+ const { styled } = options
197
+
198
+ const originalRootElement = type => function creatingElement(arg0, arg1) {
195
199
  if (isArray(arg0)) {
196
200
  return creatorCreateElement(creator, type, {}, arg0)
197
201
  }
202
+
198
203
  if (typeof arg0 == 'string') {
199
204
  return creatorCreateElement(creator, type, {}, [arg0])
200
205
  }
206
+
201
207
  if (isArray(arg1)) {
202
208
  return creatorCreateElement(creator, type, arg0, arg1)
203
209
  }
210
+
204
211
  if (arg1 == null) {
205
212
  return creatorCreateElement(creator, type, arg0, [])
206
213
  }
214
+
207
215
  return creatorCreateElement(creator, type, arg0, [arg1])
208
216
  }
209
217
 
218
+ const styledRootElement = type => function creatingStyledElement(arg0, arg1) {
219
+ if (isArray(arg0)) {
220
+ return creatorCreateElement(creator, type, {}, arg0)
221
+ }
222
+
223
+ if (typeof arg0 == 'string') {
224
+ return creatorCreateElement(creator, type, {}, [arg0])
225
+ }
226
+
227
+ if (isArray(arg1)) {
228
+ if (arg0.css == null) {
229
+ return creatorCreateElement(creator, type, arg0, arg1)
230
+ }
231
+ const { css, ...props } = arg0
232
+ return creatorCreateElement(creator, styled[type](css), props, arg1)
233
+ }
234
+
235
+ if (arg1 == null) {
236
+ if (arg0.css == null) {
237
+ return creatorCreateElement(creator, type, arg0, [])
238
+ }
239
+ const { css, ...props } = arg0
240
+ return creatorCreateElement(creator, styled[type](css), props, [])
241
+ }
242
+
243
+ if (arg0.css == null) {
244
+ return creatorCreateElement(creator, type, arg0, [arg1])
245
+ }
246
+ const { css, ...props } = arg0
247
+ return creatorCreateElement(creator, styled[type](css), props, [arg1])
248
+ }
249
+
250
+ const rootElement = (
251
+ styled == null
252
+ ? originalRootElement
253
+ : type => typeof type == 'string'
254
+ ? styledRootElement(type)
255
+ : originalRootElement(type)
256
+ )
257
+
210
258
  rootElement.A = rootElement('a')
211
259
  rootElement.P = rootElement('p')
212
260
  rootElement.B = rootElement('b')
@@ -253,5 +301,6 @@ const Arche = function (creator) {
253
301
 
254
302
  return rootElement
255
303
  }
304
+
256
305
  return Arche
257
306
  }())))
package/index.mjs ADDED
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Arche v0.2.0
3
+ * https://github.com/richytong/arche
4
+ * (c) 2020-2021 Richard Tong
5
+ * Arche may be freely distributed under the MIT license.
6
+ */
7
+
8
+ const isArray = Array.isArray
9
+
10
+ /**
11
+ * @name elementSetAttribute
12
+ *
13
+ * @synopsis
14
+ * ```coffeescript [specscript]
15
+ * Element = Object
16
+ *
17
+ * var element Element,
18
+ * key string,
19
+ * value string|number|Object,
20
+ *
21
+ * elementSetAttribute(element, key, value) -> element
22
+ * ```
23
+ */
24
+ const elementSetAttribute = function (element, key, value) {
25
+ if (value != null && value.constructor == Object) { // style
26
+ for (const subKey in value) {
27
+ element[key][subKey] = value[subKey]
28
+ }
29
+ } else {
30
+ element.setAttribute(key, value)
31
+ }
32
+ return element
33
+ }
34
+
35
+ /**
36
+ * @name creatorCreateElement
37
+ *
38
+ * @synopsis
39
+ * ```coffeescript [specscript]
40
+ * Element = Object
41
+ *
42
+ * var type string|function,
43
+ * props Object,
44
+ * children string|Object|Array<string|Object>,
45
+ * element Element,
46
+ * creator { createElement: (type, props?, children?)=>element },
47
+ *
48
+ * creatorCreateElement(creator, type, props, children) -> element
49
+ * ```
50
+ */
51
+ const creatorCreateElement = function (creator, type, props, children) {
52
+ if (creator.createElement.length == 1) {
53
+ const element = creator.createElement(type) // document.createElement
54
+ for (const key in props) {
55
+ elementSetAttribute(element, key, props[key])
56
+ }
57
+ const childrenLength = children.length
58
+ let childrenIndex = -1
59
+ while (++childrenIndex < childrenLength) {
60
+ const child = children[childrenIndex]
61
+ if (typeof child == 'string') {
62
+ element.appendChild(creator.createTextNode(child))
63
+ } else {
64
+ element.appendChild(child)
65
+ }
66
+ }
67
+ return element
68
+ }
69
+ return creator.createElement(type, props, ...children) // React.createElement
70
+ }
71
+
72
+ /**
73
+ * @name Arche
74
+ *
75
+ * @synopsis
76
+ * ```coffeescript [specscript]
77
+ * Element = Object
78
+ *
79
+ * var type string|function,
80
+ * props Object,
81
+ * children string|Object|Array<string|Object>,
82
+ * element Element,
83
+ * creator { createElement: (type, props?, children?)=>element },
84
+ * rootElement type=>((props, children?)|children)=>element {
85
+ * Script: ((props, children?)|children)=>element,
86
+ * Html: ((props, children?)|children)=>element,
87
+ * Body: (props, children?)|children)=>element,
88
+ * Section: (props, children?)|children)=>element,
89
+ * Article: (props, children?)|children)=>element,
90
+ * Span: (props, children?)|children)=>element,
91
+ * Div: (props, children?)|children)=>element,
92
+ * Img: (props, children?)|children)=>element,
93
+ * H1: (props, children?)|children)=>element,
94
+ * H2: (props, children?)|children)=>element,
95
+ * H3: (props, children?)|children)=>element,
96
+ * H4: (props, children?)|children)=>element,
97
+ * H5: (props, children?)|children)=>element,
98
+ * H6: (props, children?)|children)=>element,
99
+ *
100
+ * A: (props, children?)|children)=>element,
101
+ * P: (props, children?)|children)=>element,
102
+ * B: (props, children?)|children)=>element,
103
+ * Q: (props, children?)|children)=>element,
104
+ * I: (props, children?)|children)=>element,
105
+ * Ul: (props, children?)|children)=>element,
106
+ * Ol: (props, children?)|children)=>element,
107
+ * Li: (props, children?)|children)=>element,
108
+ * Textarea: (props, children?)|children)=>element,
109
+ * Button: (props, children?)|children)=>element,
110
+ * Iframe: (props, children?)|children)=>element,
111
+ * Blockquote: (props, children?)|children)=>element,
112
+ * Br: (props, children?)|children)=>element,
113
+ * Code: (props, children?)|children)=>element,
114
+ * Pre: (props, children?)|children)=>element,
115
+ * }
116
+ *
117
+ * Arche(creator, options {
118
+ * styled?: Styled,
119
+ * }) -> rootElement
120
+ * ```
121
+ *
122
+ * @description
123
+ * > Arche (/ˈɑːrki/; Ancient Greek: ἀρχή) is a Greek word with primary senses "beginning", "origin" or "source of action" (ἐξ' ἀρχῆς: from the beginning, οr ἐξ' ἀρχῆς λόγος: the original argument), and later "first principle" or "element". ([wikipedia](https://en.wikipedia.org/wiki/Arche))
124
+ *
125
+ * HTML as JavaScript.
126
+ *
127
+ * ```javascript [playground]
128
+ * const ReactElement = Arche(React)
129
+ * // supply the React library
130
+ *
131
+ * const { Div, H1, P } = ReactElement
132
+ * // some common building blocks are provided on ReactElement
133
+ * // as property functions.
134
+ *
135
+ * const myElement = Div([
136
+ * H1('I am a heading'),
137
+ * P('heyo'),
138
+ * P('lorem ipsum'),
139
+ * ])
140
+ *
141
+ * console.log(myElement)
142
+ * // {
143
+ * // $$typeof: Symbol(react.element),
144
+ * // type: 'div',
145
+ * // props: {
146
+ * // children: [
147
+ * // { $$typeof: Symbol(react.element), type: 'h1', props: { children: 'I am a heading' } },
148
+ * // { $$typeof: Symbol(react.element), type: 'p', props: { children: 'heyo' } },
149
+ * // { $$typeof: Symbol(react.element), type: 'p', props: { children: 'heyo' } },
150
+ * // ],
151
+ * // },
152
+ * // }
153
+ * ```
154
+ *
155
+ * Create dynamic components with props:
156
+ * ```javascript [playground]
157
+ * const ReactElement = Arche(React)
158
+ * const { Div, P, Button } = ReactElement
159
+ *
160
+ * const UserCard = ReactElement(({
161
+ * firstName, lastName, age,
162
+ * }) => Div([
163
+ * H1(`${firstName} ${lastName}`),
164
+ * P({ style: { color: 'lightgrey' } }, [age]),
165
+ * ]))
166
+ * ```
167
+ *
168
+ * Complete interop with React hooks (converted from [this example](https://reactjs.org/docs/hooks-intro.html)):
169
+ * ```javascript [playground]
170
+ * const ReactElement = Arche(React)
171
+ * const { Div, P, Button } = ReactElement
172
+ * const { useState } = React
173
+ *
174
+ * const Example = ReactElement(() => {
175
+ * const [count, setCount] = useState(0)
176
+ *
177
+ * return Div([
178
+ * P(`You clicked ${count} times`),
179
+ * Button({
180
+ * onClick() {
181
+ * setCount(count + 1)
182
+ * },
183
+ * }, 'Click me'),
184
+ * ])
185
+ * })
186
+ * ```
187
+ */
188
+
189
+ const Arche = function (creator, options = {}) {
190
+ const { styled } = options
191
+
192
+ const originalRootElement = type => function creatingElement(arg0, arg1) {
193
+ if (isArray(arg0)) {
194
+ return creatorCreateElement(creator, type, {}, arg0)
195
+ }
196
+
197
+ if (typeof arg0 == 'string') {
198
+ return creatorCreateElement(creator, type, {}, [arg0])
199
+ }
200
+
201
+ if (isArray(arg1)) {
202
+ return creatorCreateElement(creator, type, arg0, arg1)
203
+ }
204
+
205
+ if (arg1 == null) {
206
+ return creatorCreateElement(creator, type, arg0, [])
207
+ }
208
+
209
+ return creatorCreateElement(creator, type, arg0, [arg1])
210
+ }
211
+
212
+ const styledRootElement = type => function creatingStyledElement(arg0, arg1) {
213
+ if (isArray(arg0)) {
214
+ return creatorCreateElement(creator, type, {}, arg0)
215
+ }
216
+
217
+ if (typeof arg0 == 'string') {
218
+ return creatorCreateElement(creator, type, {}, [arg0])
219
+ }
220
+
221
+ if (isArray(arg1)) {
222
+ if (arg0.css == null) {
223
+ return creatorCreateElement(creator, type, arg0, arg1)
224
+ }
225
+ const { css, ...props } = arg0
226
+ return creatorCreateElement(creator, styled[type](css), props, arg1)
227
+ }
228
+
229
+ if (arg1 == null) {
230
+ if (arg0.css == null) {
231
+ return creatorCreateElement(creator, type, arg0, [])
232
+ }
233
+ const { css, ...props } = arg0
234
+ return creatorCreateElement(creator, styled[type](css), props, [])
235
+ }
236
+
237
+ if (arg0.css == null) {
238
+ return creatorCreateElement(creator, type, arg0, [arg1])
239
+ }
240
+ const { css, ...props } = arg0
241
+ return creatorCreateElement(creator, styled[type](css), props, [arg1])
242
+ }
243
+
244
+ const rootElement = (
245
+ styled == null
246
+ ? originalRootElement
247
+ : type => typeof type == 'string'
248
+ ? styledRootElement(type)
249
+ : originalRootElement(type)
250
+ )
251
+
252
+ rootElement.A = rootElement('a')
253
+ rootElement.P = rootElement('p')
254
+ rootElement.B = rootElement('b')
255
+ rootElement.Q = rootElement('q')
256
+ rootElement.I = rootElement('i')
257
+ rootElement.Ul = rootElement('ul')
258
+ rootElement.Ol = rootElement('ol')
259
+ rootElement.Li = rootElement('li')
260
+
261
+ rootElement.H1 = rootElement('h1')
262
+ rootElement.H2 = rootElement('h2')
263
+ rootElement.H3 = rootElement('h3')
264
+ rootElement.H4 = rootElement('h4')
265
+ rootElement.H5 = rootElement('h5')
266
+ rootElement.H6 = rootElement('h6')
267
+ rootElement.Hr = rootElement('hr')
268
+ rootElement.Br = rootElement('br')
269
+
270
+ rootElement.Script = rootElement('script')
271
+ rootElement.Html = rootElement('html')
272
+ rootElement.Body = rootElement('body')
273
+ rootElement.Nav = rootElement('nav')
274
+ rootElement.Section = rootElement('section')
275
+ rootElement.Article = rootElement('article')
276
+ rootElement.Footer = rootElement('footer')
277
+ rootElement.Span = rootElement('span')
278
+ rootElement.Div = rootElement('div')
279
+ rootElement.Img = rootElement('img')
280
+ rootElement.Video = rootElement('video')
281
+
282
+ rootElement.Form = rootElement('form')
283
+ rootElement.Fieldset = rootElement('fieldset')
284
+ rootElement.Input = rootElement('input')
285
+ rootElement.Label = rootElement('label')
286
+ rootElement.Textarea = rootElement('textarea')
287
+ rootElement.Select = rootElement('select')
288
+ rootElement.Option = rootElement('option')
289
+
290
+ rootElement.Button = rootElement('button')
291
+ rootElement.Iframe = rootElement('iframe')
292
+ rootElement.Blockquote = rootElement('blockquote')
293
+ rootElement.Code = rootElement('code')
294
+ rootElement.Pre = rootElement('pre')
295
+
296
+ return rootElement
297
+ }
298
+
299
+ export default Arche
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arche",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "HTML as JavaScript",
5
5
  "author": "Richard Tong",
6
6
  "license": "MIT",
package/test.js CHANGED
@@ -34,7 +34,7 @@ describe('Arche', () => {
34
34
  Article('yo'),
35
35
  ]),
36
36
  ])
37
- // console.log(JSON.stringify(el))
37
+
38
38
  assert.strictEqual(
39
39
  JSON.stringify(el),
40
40
  '{"type":"div","children":[{"type":"h1","children":[{"type":"text","text":"header"}],"style":{}},{"type":"p","children":[{"type":"text","text":"description"}],"style":{"color":"grey"}},{"type":"span","children":[],"style":{},"id":"hey","excluded":null},{"type":"div","children":[{"type":"article","children":[{"type":"text","text":"yo"}],"style":{}}],"style":{},"id":"nested"}],"style":{}}')
@@ -59,10 +59,63 @@ describe('Arche', () => {
59
59
  Article('yo'),
60
60
  ]),
61
61
  ])
62
- // console.log(JSON.stringify(el))
62
+
63
63
  assert.strictEqual(
64
64
  JSON.stringify(el),
65
65
  '["div",{},[["h1",{},["header"]],["p",{"style":{"color":"grey"}},["description"]],["span",{"id":"hey","excluded":null},[]],["div",{"id":"nested"},[["article",{},["yo"]]]]]]')
66
66
  })
67
67
  })
68
+
69
+ describe('styled 3-ary creator.createElement', () => {
70
+ const mockReact = {
71
+ createElement(type, props, ...children) {
72
+ return [type, props || {}, children || []]
73
+ },
74
+ }
75
+
76
+ const identity = value => value
77
+
78
+ const styled = {
79
+ h1: identity,
80
+ h2: identity,
81
+ div: identity,
82
+ p: identity,
83
+ b: identity,
84
+ span: identity,
85
+ article: identity,
86
+ }
87
+
88
+ const rootElement = Arche(mockReact, { styled })
89
+ const { Div, H1, P, Span, Article } = rootElement
90
+
91
+ it('tree structure 1', () => {
92
+ const el = Div([
93
+ H1({ css: 'h2' }, 'header'), // should swap with h2
94
+ P({ style: { color: 'grey' } }, 'description'),
95
+ Span({ id: 'hey', excluded: null }),
96
+ Div({ id: 'nested' }, [
97
+ Article('yo'),
98
+ ]),
99
+ ])
100
+
101
+ assert.strictEqual(
102
+ JSON.stringify(el),
103
+ '["div",{},[["h2",{},["header"]],["p",{"style":{"color":"grey"}},["description"]],["span",{"id":"hey","excluded":null},[]],["div",{"id":"nested"},[["article",{},["yo"]]]]]]')
104
+ })
105
+
106
+ it('tree structure 2', () => {
107
+ const el = Div([
108
+ H1('header'),
109
+ P({ css: 'h3', style: { color: 'grey' } }, 'description'),
110
+ Span({ css: 'b', id: 'hey', excluded: null }),
111
+ Div({ css: 'article', id: 'nested' }, [
112
+ Article('yo'),
113
+ ]),
114
+ ])
115
+
116
+ assert.strictEqual(
117
+ JSON.stringify(el),
118
+ '["div",{},[["h1",{},["header"]],["h3",{"style":{"color":"grey"}},["description"]],["b",{"id":"hey","excluded":null},[]],["article",{"id":"nested"},[["article",{},["yo"]]]]]]')
119
+ })
120
+ })
68
121
  })