@furystack/shades 14.0.0 → 15.0.1

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 (125) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/esm/compile-route.d.ts +5 -0
  3. package/esm/compile-route.d.ts.map +1 -1
  4. package/esm/compile-route.js +5 -0
  5. package/esm/compile-route.js.map +1 -1
  6. package/esm/component-factory.spec.d.ts.map +1 -1
  7. package/esm/component-factory.spec.js +2 -2
  8. package/esm/component-factory.spec.js.map +1 -1
  9. package/esm/components/nested-hooks.js +2 -2
  10. package/esm/components/nested-hooks.js.map +1 -1
  11. package/esm/components/nested-hooks.spec.js +14 -14
  12. package/esm/components/nested-hooks.spec.js.map +1 -1
  13. package/esm/components/nested-navigate.js +1 -1
  14. package/esm/components/nested-navigate.js.map +1 -1
  15. package/esm/components/nested-navigate.spec.js +16 -16
  16. package/esm/components/nested-navigate.spec.js.map +1 -1
  17. package/esm/components/nested-replace.js +1 -1
  18. package/esm/components/nested-replace.js.map +1 -1
  19. package/esm/components/nested-replace.spec.js +6 -6
  20. package/esm/components/nested-replace.spec.js.map +1 -1
  21. package/esm/components/nested-route-link.js +1 -1
  22. package/esm/components/nested-route-link.js.map +1 -1
  23. package/esm/components/nested-route-link.spec.js +8 -8
  24. package/esm/components/nested-route-link.spec.js.map +1 -1
  25. package/esm/components/nested-router.js +3 -3
  26. package/esm/components/nested-router.js.map +1 -1
  27. package/esm/components/nested-router.spec.js +24 -24
  28. package/esm/components/nested-router.spec.js.map +1 -1
  29. package/esm/css-generator.d.ts +9 -26
  30. package/esm/css-generator.d.ts.map +1 -1
  31. package/esm/css-generator.js +9 -26
  32. package/esm/css-generator.js.map +1 -1
  33. package/esm/css-generator.spec.js.map +1 -1
  34. package/esm/models/css-object.d.ts +3 -5
  35. package/esm/models/css-object.d.ts.map +1 -1
  36. package/esm/models/render-options.d.ts +16 -20
  37. package/esm/models/render-options.d.ts.map +1 -1
  38. package/esm/models/shade-component.d.ts +6 -4
  39. package/esm/models/shade-component.d.ts.map +1 -1
  40. package/esm/models/shade-component.js +3 -3
  41. package/esm/models/shade-component.js.map +1 -1
  42. package/esm/services/location-service.d.ts +39 -42
  43. package/esm/services/location-service.d.ts.map +1 -1
  44. package/esm/services/location-service.js +115 -134
  45. package/esm/services/location-service.js.map +1 -1
  46. package/esm/services/location-service.spec.js +32 -30
  47. package/esm/services/location-service.spec.js.map +1 -1
  48. package/esm/services/route-match-service.d.ts +3 -2
  49. package/esm/services/route-match-service.d.ts.map +1 -1
  50. package/esm/services/route-match-service.js +13 -22
  51. package/esm/services/route-match-service.js.map +1 -1
  52. package/esm/services/route-match-service.spec.js +40 -51
  53. package/esm/services/route-match-service.spec.js.map +1 -1
  54. package/esm/services/route-meta-utils.js.map +1 -1
  55. package/esm/services/route-meta-utils.spec.js +3 -3
  56. package/esm/services/route-meta-utils.spec.js.map +1 -1
  57. package/esm/services/screen-service.d.ts +13 -72
  58. package/esm/services/screen-service.d.ts.map +1 -1
  59. package/esm/services/screen-service.js +45 -137
  60. package/esm/services/screen-service.js.map +1 -1
  61. package/esm/services/screen-service.spec.js +19 -18
  62. package/esm/services/screen-service.spec.js.map +1 -1
  63. package/esm/services/spatial-navigation-service.d.ts +17 -39
  64. package/esm/services/spatial-navigation-service.d.ts.map +1 -1
  65. package/esm/services/spatial-navigation-service.js +280 -313
  66. package/esm/services/spatial-navigation-service.js.map +1 -1
  67. package/esm/services/spatial-navigation-service.spec.js +163 -158
  68. package/esm/services/spatial-navigation-service.spec.js.map +1 -1
  69. package/esm/shade-component.d.ts +14 -17
  70. package/esm/shade-component.d.ts.map +1 -1
  71. package/esm/shade-component.js +14 -17
  72. package/esm/shade-component.js.map +1 -1
  73. package/esm/shade.d.ts +18 -15
  74. package/esm/shade.d.ts.map +1 -1
  75. package/esm/shade.js +22 -32
  76. package/esm/shade.js.map +1 -1
  77. package/esm/style-manager.d.ts +8 -22
  78. package/esm/style-manager.d.ts.map +1 -1
  79. package/esm/style-manager.js +8 -22
  80. package/esm/style-manager.js.map +1 -1
  81. package/esm/styled-shade.d.ts +4 -7
  82. package/esm/styled-shade.d.ts.map +1 -1
  83. package/esm/styled-shade.js +4 -4
  84. package/esm/styled-shade.js.map +1 -1
  85. package/esm/view-transition.d.ts +10 -22
  86. package/esm/view-transition.d.ts.map +1 -1
  87. package/esm/view-transition.js +10 -22
  88. package/esm/view-transition.js.map +1 -1
  89. package/esm/vnode.js.map +1 -1
  90. package/esm/vnode.spec.js.map +1 -1
  91. package/package.json +9 -8
  92. package/src/compile-route.ts +5 -0
  93. package/src/component-factory.spec.tsx +3 -2
  94. package/src/components/nested-hooks.spec.ts +14 -14
  95. package/src/components/nested-hooks.ts +2 -2
  96. package/src/components/nested-navigate.spec.ts +17 -16
  97. package/src/components/nested-navigate.ts +1 -1
  98. package/src/components/nested-replace.spec.ts +7 -6
  99. package/src/components/nested-replace.ts +1 -1
  100. package/src/components/nested-route-link.spec.tsx +8 -8
  101. package/src/components/nested-route-link.tsx +1 -1
  102. package/src/components/nested-router.spec.tsx +24 -24
  103. package/src/components/nested-router.tsx +5 -5
  104. package/src/css-generator.spec.ts +1 -1
  105. package/src/css-generator.ts +9 -26
  106. package/src/models/css-object.ts +3 -5
  107. package/src/models/render-options.ts +17 -20
  108. package/src/models/shade-component.ts +6 -4
  109. package/src/services/location-service.spec.ts +35 -31
  110. package/src/services/location-service.tsx +156 -122
  111. package/src/services/route-match-service.spec.ts +41 -32
  112. package/src/services/route-match-service.ts +17 -8
  113. package/src/services/route-meta-utils.spec.ts +3 -3
  114. package/src/services/route-meta-utils.ts +1 -1
  115. package/src/services/screen-service.spec.ts +21 -20
  116. package/src/services/screen-service.ts +65 -110
  117. package/src/services/spatial-navigation-service.spec.ts +165 -160
  118. package/src/services/spatial-navigation-service.ts +299 -287
  119. package/src/shade-component.ts +14 -17
  120. package/src/shade.ts +31 -41
  121. package/src/style-manager.ts +9 -22
  122. package/src/styled-shade.ts +5 -8
  123. package/src/view-transition.ts +10 -22
  124. package/src/vnode.spec.ts +3 -3
  125. package/src/vnode.ts +2 -2
@@ -22,9 +22,9 @@ export const setRenderMode = (mode: boolean): void => {
22
22
  // ---------------------------------------------------------------------------
23
23
 
24
24
  /**
25
- * Appends a list of items to an element
26
- * @param el the root element
27
- * @param children array of items to append
25
+ * Appends `children` to `el`. Strings/numbers are wrapped in text nodes;
26
+ * nested arrays are flattened recursively. Used outside render mode (real
27
+ * DOM); inside render mode the JSX factory builds VNodes instead.
28
28
  */
29
29
  export const appendChild = (el: Element | DocumentFragment, children: ChildrenList) => {
30
30
  for (const child of children) {
@@ -46,10 +46,7 @@ export const hasStyle = (props: unknown): props is { style: Partial<CSSStyleDecl
46
46
  )
47
47
  }
48
48
 
49
- /**
50
- * @param el The Target HTML Element
51
- * @param props The Properties to fetch The Styles Object
52
- */
49
+ /** Copies `props.style` (when present) onto `el.style`. No-op for non-styled props. */
53
50
  export const attachStyles = (el: HTMLElement, props: unknown) => {
54
51
  if (hasStyle(props))
55
52
  for (const key in props.style) {
@@ -70,9 +67,9 @@ export const attachDataAttributes = <TProps extends object>(el: HTMLElement, pro
70
67
  }
71
68
 
72
69
  /**
73
- * Attaches properties to an HTML element
74
- * @param el The Target HTML Element
75
- * @param props The Props to attach
70
+ * Assigns `props` onto `el` as element properties (not attributes). `style`
71
+ * is forwarded to {@link attachStyles}; `data-*` / `aria-*` are forwarded to
72
+ * {@link attachDataAttributes}.
76
73
  */
77
74
  export const attachProps = <TProps extends object>(el: HTMLElement, props: TProps) => {
78
75
  if (!props) {
@@ -90,11 +87,9 @@ export const attachProps = <TProps extends object>(el: HTMLElement, props: TProp
90
87
  }
91
88
 
92
89
  /**
93
- * Attaches properties to an SVG element via setAttribute.
94
- * SVG attributes are XML-based and must be set via setAttribute,
95
- * not via property assignment like HTML elements.
96
- * @param el The target SVG element
97
- * @param props The props to attach
90
+ * SVG counterpart of {@link attachProps}. SVG attributes are XML-based and
91
+ * must be set via `setAttribute` rather than property assignment. Event
92
+ * handlers (`on*`) and `style` are still set as properties.
98
93
  */
99
94
  export const attachSvgProps = <TProps extends object>(el: Element, props: TProps) => {
100
95
  if (!props) {
@@ -122,8 +117,10 @@ type CreateComponentArgs<TProps> = [
122
117
  ]
123
118
 
124
119
  /**
125
- * Factory method that creates a component. This should be configured as a default JSX Factory in tsconfig.
126
- * @returns the created JSX element
120
+ * JSX factory backing both intrinsic elements (`<div>`, `<svg>`, …) and
121
+ * Shade components (`<MyShade>`). Configured as `jsxFactory` in tsconfig.
122
+ * Outside render mode this returns real DOM nodes; the render-mode wrapper
123
+ * {@link createComponent} swaps in VNode descriptors.
127
124
  */
128
125
  export const createComponentInner = <TProps extends object>(
129
126
  ...[elementType, props, ...children]: CreateComponentArgs<TProps>
package/src/shade.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { Constructable } from '@furystack/inject'
2
- import { hasInjectorReference, Injector } from '@furystack/inject'
1
+ import type { Constructable } from '@furystack/core'
2
+ import { Injector } from '@furystack/inject'
3
3
  import { ObservableValue } from '@furystack/utils'
4
4
  import type { ChildrenList, CSSObject, PartialElement, RenderOptions } from './models/index.js'
5
5
  import type { RefObject } from './models/render-options.js'
@@ -19,18 +19,18 @@ export type ShadeOptions<TProps, TElementBase extends HTMLElement> = {
19
19
  */
20
20
  customElementName: string
21
21
 
22
- /**
23
- * Render hook, this method will be executed on each and every render.
24
- */
25
22
  render: (options: RenderOptions<TProps, TElementBase>) => JSX.Element | string | null
26
23
 
27
24
  /**
28
- * Name of the HTML Element's base class. Needs to be defined if the elementBase is set. E.g.: 'div', 'button', 'input'
25
+ * Tag name of the base built-in element when extending one (e.g. `'a'`,
26
+ * `'button'`, `'input'`). Required when {@link ShadeOptions.elementBase}
27
+ * is set; passed to `customElements.define` as `{ extends }`.
29
28
  */
30
29
  elementBaseName?: string
31
30
 
32
31
  /**
33
- * Base class for the custom element. Defaults to HTMLElement. E.g. HTMLButtonElement
32
+ * Constructor of the built-in element to extend (e.g. `HTMLButtonElement`).
33
+ * Defaults to `HTMLElement`. Pair with {@link ShadeOptions.elementBaseName}.
34
34
  */
35
35
  elementBase?: Constructable<TElementBase>
36
36
 
@@ -61,9 +61,14 @@ export type ShadeOptions<TProps, TElementBase extends HTMLElement> = {
61
61
  }
62
62
 
63
63
  /**
64
- * Factory method for creating Shade components
65
- * @param o The options object for component creation
66
- * @returns the JSX element
64
+ * Defines and registers a Shade component as a custom element. Returns a
65
+ * JSX-callable factory `(props, children?) => JSX.Element`. Throws when a
66
+ * component with the same {@link ShadeOptions.customElementName} has
67
+ * already been registered — registration is global and process-wide.
68
+ *
69
+ * The returned factory is the entry point for downstream code. The custom
70
+ * element class itself is installed via `customElements.define` and never
71
+ * directly exposed.
67
72
  */
68
73
  export const Shade = <TProps, TElementBase extends HTMLElement = HTMLElement>(
69
74
  o: ShadeOptions<TProps, TElementBase>,
@@ -84,9 +89,6 @@ export const Shade = <TProps, TElementBase extends HTMLElement = HTMLElement>(
84
89
  class extends (ElementBase as Constructable<HTMLElement>) implements JSX.Element {
85
90
  private _renderCount = 0
86
91
 
87
- /**
88
- * @returns the current render count
89
- */
90
92
  public getRenderCount() {
91
93
  return this._renderCount
92
94
  }
@@ -128,28 +130,15 @@ export const Shade = <TProps, TElementBase extends HTMLElement = HTMLElement>(
128
130
  await this.resourceManager[Symbol.asyncDispose]()
129
131
  }
130
132
 
131
- /**
132
- * Will be triggered when updating the external props object
133
- */
134
133
  public props!: TProps & { children?: JSX.Element[] } & PartialElement<TElementBase>
135
134
 
136
- /**
137
- * Will be updated when on children change
138
- */
139
135
  public shadeChildren?: ChildrenList
140
136
 
141
- /**
142
- * @param options Options for rendering the component
143
- * @returns the JSX element
144
- */
145
137
  public render = (options: RenderOptions<TProps, TElementBase>) => {
146
138
  this._renderCount++
147
139
  return o.render(options)
148
140
  }
149
141
 
150
- /**
151
- * @returns values for the current render options
152
- */
153
142
  private getRenderOptions = (): RenderOptions<TProps, TElementBase> => {
154
143
  const renderOptions: RenderOptions<TProps, TElementBase> = {
155
144
  props: this.props,
@@ -163,19 +152,19 @@ export const Shade = <TProps, TElementBase extends HTMLElement = HTMLElement>(
163
152
  const existingRef = this._refs.get(key) as RefObject<T> | undefined
164
153
  if (existingRef) return existingRef
165
154
  const refObject = { current: null } as { current: T | null }
166
- this._refs.set(key, refObject as unknown as RefObject<Element>)
167
- return refObject as RefObject<T>
155
+ this._refs.set(key, refObject)
156
+ return refObject
168
157
  },
169
- useObservable: (key, obesrvable, options) => {
158
+ useObservable: (key, observable, options) => {
170
159
  const onChange = options?.onChange || (() => this.updateComponent())
171
- return this.resourceManager.useObservable(key, obesrvable, onChange, options)
160
+ return this.resourceManager.useObservable(key, observable, onChange, options)
172
161
  },
173
162
  useState: (key, initialValue) =>
174
163
  this.resourceManager.useState(key, initialValue, this.updateComponent.bind(this)),
175
164
  useSearchState: (key, initialValue) =>
176
165
  this.resourceManager.useObservable(
177
166
  `useSearchState-${key}`,
178
- this.injector.getInstance(LocationService).useSearchParam(key, initialValue),
167
+ this.injector.get(LocationService).useSearchParam(key, initialValue),
179
168
  () => this.updateComponent(),
180
169
  ),
181
170
 
@@ -308,7 +297,7 @@ export const Shade = <TProps, TElementBase extends HTMLElement = HTMLElement>(
308
297
  this.removeAttribute(key)
309
298
  }
310
299
  if (this._prevHostProps.style) {
311
- for (const sk of Object.keys(this._prevHostProps.style as Record<string, string>)) {
300
+ for (const sk of Object.keys(this._prevHostProps.style)) {
312
301
  if (sk.startsWith('--')) {
313
302
  this.style.removeProperty(sk)
314
303
  } else {
@@ -416,8 +405,8 @@ export const Shade = <TProps, TElementBase extends HTMLElement = HTMLElement>(
416
405
  return this._injector
417
406
  }
418
407
 
419
- const fromProps = hasInjectorReference(this.props) && this.props.injector
420
- if (fromProps && fromProps instanceof Injector) {
408
+ const fromProps = (this.props as { injector?: unknown } | undefined)?.injector
409
+ if (fromProps instanceof Injector) {
421
410
  return fromProps
422
411
  }
423
412
 
@@ -426,7 +415,10 @@ export const Shade = <TProps, TElementBase extends HTMLElement = HTMLElement>(
426
415
  this._injector = fromParent
427
416
  return fromParent
428
417
  }
429
- // Injector not set explicitly and not found on parents!
418
+ // Fallback for isolated components (tests and non-DI use cases) that
419
+ // never reach for any services. Components that do resolve tokens
420
+ // will fail loudly at resolution time, since this throwaway injector
421
+ // has no bindings.
430
422
  return new Injector()
431
423
  }
432
424
 
@@ -461,11 +453,9 @@ export const Shade = <TProps, TElementBase extends HTMLElement = HTMLElement>(
461
453
  }
462
454
 
463
455
  /**
464
- * Flushes any pending microtask-based component updates.
465
- * Useful in tests to wait for batched renders to complete before asserting DOM state.
466
- *
467
- * Child component updates during reconciliation are performed synchronously, so a single
468
- * `await flushUpdates()` is sufficient to settle the entire component tree after a state change.
469
- * @returns a promise that resolves after the current microtask queue has been processed
456
+ * Awaits the next microtask tick — long enough for `updateComponent`'s
457
+ * batching microtask to drain. A single `await flushUpdates()` settles the
458
+ * entire component tree because child reconciliation is synchronous within
459
+ * the parent's render. Use in tests before asserting on DOM state.
470
460
  */
471
461
  export const flushUpdates = (): Promise<void> => new Promise<void>((resolve) => queueMicrotask(resolve))
@@ -1,19 +1,16 @@
1
1
  import { generateCSS } from './css-generator.js'
2
2
  import type { CSSObject } from './models/css-object.js'
3
+ import type { Shade } from './shade.js'
3
4
 
4
5
  /**
5
- * Singleton that manages component CSS injection.
6
- * Creates and maintains a shared `<style>` element in the document head,
7
- * and tracks registered component styles to avoid duplicates.
6
+ * Owns a shared `<style data-shades-styles>` element in `document.head`
7
+ * and dedupes component-style registration. Internal — consumers use
8
+ * the {@link StyleManager} singleton.
8
9
  */
9
10
  class StyleManagerClass {
10
11
  private styleElement: HTMLStyleElement | null = null
11
12
  private registeredComponents = new Set<string>()
12
13
 
13
- /**
14
- * Gets or creates the shared style element
15
- * @returns The style element for CSS injection
16
- */
17
14
  private getStyleElement(): HTMLStyleElement {
18
15
  if (!this.styleElement) {
19
16
  this.styleElement = document.createElement('style')
@@ -66,26 +63,16 @@ class StyleManagerClass {
66
63
  return false
67
64
  }
68
65
 
69
- /**
70
- * Checks if a component's styles have already been registered
71
- * @param customElementName - The component identifier to check
72
- * @returns True if styles are already registered
73
- */
74
66
  public isRegistered(customElementName: string): boolean {
75
67
  return this.registeredComponents.has(customElementName)
76
68
  }
77
69
 
78
- /**
79
- * Gets all registered component names (for debugging/testing)
80
- * @returns Set of registered component names
81
- */
70
+ /** Snapshot of registered component names. Intended for diagnostics + tests. */
82
71
  public getRegisteredComponents(): ReadonlySet<string> {
83
72
  return this.registeredComponents
84
73
  }
85
74
 
86
- /**
87
- * Clears all registered styles (useful for testing)
88
- */
75
+ /** Removes the shared style element and clears the registration set. Test-only. */
89
76
  public clear(): void {
90
77
  this.registeredComponents.clear()
91
78
  if (this.styleElement) {
@@ -97,8 +84,8 @@ class StyleManagerClass {
97
84
  }
98
85
 
99
86
  /**
100
- * Singleton instance for managing component CSS styles.
101
- * Use this to register component-level styles that support
102
- * pseudo-selectors and nested selectors.
87
+ * Process-wide CSS injection registry for Shade components. The {@link Shade}
88
+ * factory calls `registerComponentStyles` automatically; direct use is rare
89
+ * (e.g. injecting a third-party stylesheet keyed off a component name).
103
90
  */
104
91
  export const StyleManager = new StyleManagerClass()
@@ -1,17 +1,14 @@
1
1
  import type { ChildrenList } from './models/children-list.js'
2
2
 
3
- /**
4
- * Props constraint for styled components - must have an optional style property
5
- */
6
3
  type StyledProps = {
7
4
  style?: Partial<CSSStyleDeclaration>
8
5
  }
9
6
 
10
7
  /**
11
- * Creates a shortcut for a specific custom Shade element with additional styles
12
- * @param element The element instance
13
- * @param styles The additional styles to add
14
- * @returns The updated element
8
+ * Wraps a Shade factory with a baked-in `style` overlay. Baked-in `styles`
9
+ * win over caller-supplied `style` props (the wrapper merges last). Use to
10
+ * specialise an existing Shade (e.g. theme variants) without registering
11
+ * a new custom element.
15
12
  */
16
13
  export const styledShade = <TProps extends StyledProps>(
17
14
  element: (props: TProps, children?: ChildrenList) => JSX.Element,
@@ -25,7 +22,7 @@ export const styledShade = <TProps extends StyledProps>(
25
22
  ...props.style,
26
23
  ...styles,
27
24
  },
28
- } as TProps,
25
+ },
29
26
  childrenList,
30
27
  )
31
28
  }
@@ -8,16 +8,13 @@ export type ViewTransitionConfig = {
8
8
  }
9
9
 
10
10
  /**
11
- * Wraps a DOM update in `document.startViewTransition()` when the View Transition API
12
- * is available and `config` is truthy. Falls back to calling `update()` directly otherwise.
11
+ * Runs `update` inside `document.startViewTransition()` when the API is
12
+ * available and `config` is truthy; otherwise calls `update` synchronously.
13
13
  *
14
- * Returns the `updateCallbackDone` promise when a transition is started, allowing callers
15
- * that need to wait for the DOM update (e.g. to run lifecycle hooks) to `await` the result.
16
- * Returns `undefined` when no transition is used (the update runs synchronously).
17
- *
18
- * @param config - The view transition configuration (boolean or object with types)
19
- * @param update - The synchronous DOM update callback
20
- * @returns A promise that resolves after the update callback completes inside the transition, or `undefined`
14
+ * The returned promise (when a transition starts) resolves once the update
15
+ * callback completes inside the transition — callers that need to chain
16
+ * lifecycle work after the DOM swap can `await` it. Returns `undefined`
17
+ * when no transition is used.
21
18
  */
22
19
  export const maybeViewTransition = (
23
20
  config: boolean | ViewTransitionConfig | undefined,
@@ -33,19 +30,10 @@ export const maybeViewTransition = (
33
30
  }
34
31
 
35
32
  /**
36
- * Keeps a "displayed" copy of `value` that is updated through a view transition
37
- * whenever the value changes and `shouldTransition` returns true.
38
- *
39
- * When the transition is skipped (config is falsy or `shouldTransition` returns false),
40
- * the displayed value is updated synchronously without an animation.
41
- *
42
- * @param useState - The component's `useState` hook
43
- * @param key - Unique state key for caching the displayed value
44
- * @param value - The latest source value (e.g. from `useObservable` or derived from props)
45
- * @param config - View transition configuration forwarded to `maybeViewTransition`
46
- * @param shouldTransition - Predicate that decides whether a value change warrants a transition.
47
- * Defaults to `() => true` (always transition).
48
- * @returns The currently displayed value
33
+ * Decouples a component's "displayed" value from its source. When `value`
34
+ * changes and `shouldTransition(prev, next)` returns true, the swap is
35
+ * routed through {@link maybeViewTransition}; otherwise the displayed
36
+ * value updates synchronously. `shouldTransition` defaults to always-true.
49
37
  */
50
38
  export const transitionedValue = <T>(
51
39
  useState: <S>(key: string, initialValue: S) => [S, (v: S) => void],
package/src/vnode.spec.ts CHANGED
@@ -545,7 +545,7 @@ describe('vnode', () => {
545
545
  ;(fakeShadeEl as unknown as Record<string, unknown>).props = { count: 1 }
546
546
  ;(fakeShadeEl as unknown as Record<string, unknown>).shadeChildren = undefined
547
547
 
548
- const factory = vi.fn(() => fakeShadeEl as unknown as JSX.Element)
548
+ const factory = vi.fn(() => fakeShadeEl)
549
549
 
550
550
  const old: VChild[] = [{ _brand: 'vnode', type: factory, props: { count: 1 }, children: [], _el: fakeShadeEl }]
551
551
  parent.appendChild(fakeShadeEl)
@@ -566,7 +566,7 @@ describe('vnode', () => {
566
566
  ;(fakeShadeEl as unknown as Record<string, unknown>).props = { elevation: 2 }
567
567
  ;(fakeShadeEl as unknown as Record<string, unknown>).shadeChildren = undefined
568
568
 
569
- const factory = vi.fn(() => fakeShadeEl as unknown as JSX.Element)
569
+ const factory = vi.fn(() => fakeShadeEl)
570
570
 
571
571
  const old: VChild[] = [
572
572
  { _brand: 'vnode', type: factory, props: { elevation: 2 }, children: [], _el: fakeShadeEl },
@@ -591,7 +591,7 @@ describe('vnode', () => {
591
591
  ;(fakeShadeEl as unknown as Record<string, unknown>).props = props
592
592
  ;(fakeShadeEl as unknown as Record<string, unknown>).shadeChildren = undefined
593
593
 
594
- const factory = vi.fn(() => fakeShadeEl as unknown as JSX.Element)
594
+ const factory = vi.fn(() => fakeShadeEl)
595
595
 
596
596
  const old: VChild[] = [{ _brand: 'vnode', type: factory, props: { count: 1 }, children: [], _el: fakeShadeEl }]
597
597
  parent.appendChild(fakeShadeEl)
package/src/vnode.ts CHANGED
@@ -197,9 +197,9 @@ export const toVChildArray = (renderResult: unknown): VChild[] => {
197
197
  // Real DOM element (from async code that ran outside renderMode)
198
198
  if (renderResult instanceof DocumentFragment) {
199
199
  return Array.from(renderResult.childNodes).map((node) => ({
200
- _brand: VNODE_BRAND as typeof VNODE_BRAND,
200
+ _brand: VNODE_BRAND,
201
201
  type: EXISTING_NODE,
202
- props: {} as Record<string, unknown>,
202
+ props: {},
203
203
  children: [] as VChild[],
204
204
  _el: node,
205
205
  }))