@lukekaalim/act-web 5.2.0 → 6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @lukekaalim/act-web
2
2
 
3
+ ## 6.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 2ed02cf: Breaking! Change how useRef works, no longer compatible with React-style.
8
+
9
+ New API has `.get` and `.set` properties in order to better type ReadOnlyRef and WriteOnlyRef.
10
+
11
+ Add primitive registry to web, remove old element API and replace with "html" and "svg" element maps
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [2ed02cf]
16
+ - @lukekaalim/act@5.0.0
17
+ - @lukekaalim/act-recon@4.0.1
18
+ - @lukekaalim/act-backstage@3.2.1
19
+
3
20
  ## 5.2.0
4
21
 
5
22
  ### Minor Changes
package/element.ts CHANGED
@@ -1,5 +1,139 @@
1
1
  import * as act from '@lukekaalim/act';
2
- import { HTMLTagName } from "./tags";
2
+ import { createPrimitiveRegistry } from '@lukekaalim/act-backstage';
3
+ import { Object } from 'ts-toolbelt';
4
+
5
+ export interface ExtendedHTMLPrimitives {}
6
+ export interface ExtendedSVGPrimitives {}
7
+
8
+ type HTMLClasses = {
9
+ div: HTMLDivElement,
10
+ span: HTMLSpanElement,
11
+ main: HTMLElement,
12
+ article: HTMLElement,
13
+ section: HTMLElement,
14
+ p: HTMLParagraphElement,
15
+ i: HTMLElement,
16
+ strong: HTMLElement,
17
+ title: HTMLTitleElement,
18
+
19
+ body: HTMLBodyElement,
20
+ head: HTMLHeadElement,
21
+ meta: HTMLMetaElement,
22
+
23
+ ol: HTMLOListElement,
24
+ li: HTMLLIElement,
25
+ ul: HTMLUListElement,
26
+ menu: HTMLMenuElement,
27
+ nav: HTMLOListElement,
28
+
29
+ form: HTMLFormElement,
30
+ input: HTMLInputElement,
31
+ label: HTMLLabelElement,
32
+ button: HTMLButtonElement,
33
+ meter: HTMLMeterElement,
34
+ select: HTMLSelectElement,
35
+ options: HTMLOptionElement,
36
+ progress: HTMLProgressElement,
37
+ time: HTMLTimeElement,
38
+
39
+ table: HTMLTableElement,
40
+ tbody: HTMLTableSectionElement,
41
+ thead: HTMLTableSectionElement,
42
+ tfoot: HTMLTableSectionElement,
43
+ tr: HTMLTableRowElement,
44
+ th: HTMLTableCellElement,
45
+ td: HTMLTableCellElement,
46
+
47
+ a: HTMLAnchorElement,
48
+
49
+ map: HTMLMapElement,
50
+
51
+ audio: HTMLAudioElement,
52
+ video: HTMLVideoElement,
53
+ image: HTMLImageElement,
54
+ canvas: HTMLCanvasElement,
55
+ iframe: HTMLIFrameElement,
56
+ source: HTMLSourceElement,
57
+ };
58
+ type SVGClasses = {
59
+ svg: SVGSVGElement,
60
+ rect: SVGRectElement,
61
+ line: SVGLineElement,
62
+ path: SVGPathElement,
63
+ text: SVGTextElement,
64
+ g: SVGGElement,
65
+ }
66
+ type BuiltinHTMLPrimitives = { [Key in keyof HTMLClasses]: PropsFromClass<HTMLClasses[Key]> } & {
67
+ [act.primitiveNodeTypes.string]: { value: string },
68
+ [act.primitiveNodeTypes.number]: { value: number },
69
+ [act.primitiveNodeTypes.boolean]: { value: boolean },
70
+ }
71
+ type BuiltinSVGPrimitives = { [Key in keyof SVGClasses]: PropsFromClass<SVGClasses[Key]> } & {
72
+
73
+ }
74
+
75
+ type AllHTMLPrimitives = BuiltinHTMLPrimitives & ExtendedHTMLPrimitives;
76
+ type AllSVGPrimitives = BuiltinSVGPrimitives & ExtendedSVGPrimitives;
77
+
78
+
79
+ type HTMLElementProps<T extends HTMLElement> = {
80
+ style?: { [key in keyof CSSStyleDeclaration]?: CSSStyleDeclaration[key] } & { [key in string]?: string },
81
+ classList?: readonly (string | false | null | void)[],
82
+ className?: string | false | null | void,
83
+ attributes?: Record<string, string>,
84
+ };
85
+ type SVGElementProps<T extends SVGElement> = {
86
+ style?: { [key in keyof CSSStyleDeclaration]?: CSSStyleDeclaration[key] } & { [key in string]?: string },
87
+ classList?: readonly (string | false | null | void)[],
88
+ attributes?: Record<string, string>,
89
+ };
90
+
91
+ type WritableProps<T extends {}> = {
92
+ [
93
+ Key
94
+ in Exclude<Object.WritableKeys<T>, 'style' | 'classList'>
95
+ as (T[Key] extends string | number | boolean ? Key : never)
96
+ ]?: T[Key]
97
+ };
98
+ type EventHandlers<T> = {
99
+ [Key in keyof EventMap]?: (this: T, event: GlobalEventHandlersEventMap[EventMap[Key]] & { currentTarget: T }) => unknown
100
+ }
101
+
102
+
103
+ export type PropsFromClass<T extends HTMLElement | SVGElement | Text> = {
104
+ ref?: act.WriteOnlyRef<T>,
105
+ }
106
+ & (T extends HTMLElement ? HTMLElementProps<T> : {})
107
+ & (T extends SVGElement ? SVGElementProps<T> : {})
108
+ & WritableProps<T>
109
+ & EventHandlers<T>
110
+
111
+ export const htmlRegistry = createPrimitiveRegistry<AllHTMLPrimitives, HTMLElement | Text>()
112
+ .registerUnhandledPrimitives([
113
+ 'a', 'audio', 'article',
114
+ 'body', 'button',
115
+ 'canvas',
116
+ 'div', 'form',
117
+ 'head',
118
+ 'i', 'iframe', 'image',
119
+ 'label', 'li', 'main',
120
+ 'map', 'menu', 'meta', 'meter',
121
+ 'nav',
122
+ 'ol', 'options',
123
+ 'p', 'progress',
124
+ 'section', 'select', 'source', 'span', 'strong',
125
+ 'title', 'time', 'table', 'tbody', 'thead', 'tfoot', 'tr', 'th', 'td',
126
+ 'ul',
127
+ 'video',
128
+ ]);
129
+
130
+ export const svgRegistry = createPrimitiveRegistry<AllSVGPrimitives, SVGElement>()
131
+ .registerUnhandledPrimitives([
132
+ 'g', 'line', 'path', 'rect', 'svg', 'text'
133
+ ]);
134
+
135
+ export const html = htmlRegistry.elements;
136
+ export const svg = svgRegistry.elements;
3
137
 
4
138
  type EventMap = {
5
139
  onClick: "click",
@@ -21,35 +155,3 @@ type EventMap = {
21
155
  onInput: "input",
22
156
  onChange: "change",
23
157
  }
24
-
25
- type ElementMap = {
26
- "button": HTMLButtonElement,
27
- "div": HTMLDivElement,
28
- "form": HTMLFormElement,
29
- "input": HTMLInputElement,
30
- "pre": HTMLPreElement,
31
- "canvas": HTMLCanvasElement,
32
- }
33
-
34
- export const createSpiderElement = <Type extends HTMLTagName>(
35
- type: Type,
36
- props?: {
37
- ref?: act.Ref<null | HTMLElement>,
38
- key?: string | number,
39
- style?: { [key in keyof CSSStyleDeclaration]?: number | string },
40
- classList?: readonly (string | boolean | null | void)[],
41
- className?: string,
42
- }
43
- & Record<string, unknown>
44
- & {
45
- //[key in keyof HTMLElement]?: HTMLElement[key] extends Function ? never : HTMLElement[key]
46
- }
47
- & {
48
- [key in keyof EventMap]?: (this: HTMLElement, ev: HTMLElementEventMap[EventMap[key]]) => unknown
49
- },
50
- children?: act.Node,
51
- ): act.Element => {
52
- return act.createElement(type, props, children)
53
- };
54
-
55
- export const hs = createSpiderElement;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukekaalim/act-web",
3
- "version": "5.2.0",
3
+ "version": "6.0.0",
4
4
  "type": "module",
5
5
  "main": "mod.ts",
6
6
  "exports": {
@@ -8,13 +8,14 @@
8
8
  "./node": "./nodejs/index.ts"
9
9
  },
10
10
  "dependencies": {
11
- "@lukekaalim/act": "^4.3.0",
12
- "@lukekaalim/act-backstage": "^3.2.0",
13
- "@lukekaalim/act-recon": "^4.0.0",
11
+ "@lukekaalim/act": "^5.0.0",
12
+ "@lukekaalim/act-backstage": "^3.2.1",
13
+ "@lukekaalim/act-recon": "^4.0.1",
14
14
  "@types/hast": "^3.0.4",
15
15
  "hast-util-to-html": "^9.0.5",
16
16
  "hastscript": "^9.0.1",
17
17
  "rehype": "^13.0.2",
18
- "rehype-stringify": "^10.0.1"
18
+ "rehype-stringify": "^10.0.1",
19
+ "ts-toolbelt": "^9.6.0"
19
20
  }
20
21
  }
package/props.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as act from '@lukekaalim/act';
2
+ import { String } from 'ts-toolbelt';
2
3
 
3
4
  declare global {
4
5
  interface Window {
package/space.ts CHANGED
@@ -2,6 +2,7 @@ import * as act from '@lukekaalim/act';
2
2
 
3
3
  import { setProps } from './props.ts';
4
4
  import { NodeBuilder } from '@lukekaalim/act-backstage';
5
+ import { htmlRegistry, svgRegistry } from './element.ts';
5
6
 
6
7
  export const HTML: act.Component = ({ children }) => act.h(act.renderNodeType, { type: 'web:html' }, children);
7
8
  export const SVG: act.Component = ({ children }) => act.h(act.renderNodeType, { type: 'web:svg' }, children);
@@ -29,10 +30,18 @@ export const createWebNodeBuilder = (
29
30
  }
30
31
  case 'string': {
31
32
  switch (rootType) {
32
- case 'web:html':
33
+ case 'web:html': {
34
+ const prim = htmlRegistry.create(element);
35
+ if (prim)
36
+ return prim;
33
37
  return window.document.createElementNS('http://www.w3.org/1999/xhtml', tag);
34
- case 'web:svg':
38
+ }
39
+ case 'web:svg': {
40
+ const prim = svgRegistry.create(element);
41
+ if (prim)
42
+ return prim;
35
43
  return window.document.createElementNS('http://www.w3.org/2000/svg', tag);
44
+ }
36
45
  }
37
46
  }
38
47
  default:
package/ssr.ts CHANGED
@@ -162,10 +162,10 @@ export const ssr = {
162
162
  }, deps)
163
163
 
164
164
  useEffect(() => {
165
- if (!firstRun.current || ssrData.mode === 'server')
165
+ if (!firstRun.get() || ssrData.mode === 'server')
166
166
  return effect();
167
167
 
168
- firstRun.current = false;
168
+ firstRun.set(false);
169
169
 
170
170
  // for the very first run on a client, check against
171
171
  // the server props to see if we need to re-render
package/tags.ts DELETED
@@ -1,31 +0,0 @@
1
- export const htmlTagNames = new Set([
2
- "div", "span",
3
- "img", "picture", "canvas",
4
- "details", "summary", "section",
5
- "video", "audio",
6
- "h1", "h2", "h3", "h4", "h5", "h6",
7
- "hl",
8
- 'p',
9
- "ol", "ul", "li", "menu",
10
- "table", 'td', 'tr', 'th',
11
- "pre",
12
-
13
- 'article', 'code', 'a',
14
-
15
- "form", "input", "label", "button", "select", "textarea",
16
- ] as const);
17
- export const svgTagName = new Set([
18
- "svg",
19
- "line",
20
- "path",
21
- "polyline",
22
- "circle",
23
- "rect",
24
- "g",
25
- "text",
26
- ] as const);
27
-
28
- type SetValue<T extends Set<string>> = T extends Set<infer X> ? X : never;
29
-
30
- export type HTMLTagName = SetValue<typeof htmlTagNames>;
31
- export type SVGTagName = SetValue<typeof svgTagName>;