@lightningtv/solid
Advanced tools
Comparing version 1.0.3 to 1.1.0
@@ -0,13 +1,19 @@ | ||
import { ElementNode } from '@lightningtv/solid'; | ||
import { type Accessor } from 'solid-js'; | ||
import { ElementNode } from '@lightningtv/solid'; | ||
export type KeyNameOrKeyCode = string | number; | ||
export interface DefaultKeyMap { | ||
Left: string | number | (string | number)[]; | ||
Right: string | number | (string | number)[]; | ||
Up: string | number | (string | number)[]; | ||
Down: string | number | (string | number)[]; | ||
Enter: string | number | (string | number)[]; | ||
Last: string | number | (string | number)[]; | ||
Left: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
Right: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
Up: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
Down: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
Enter: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
Last: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
} | ||
export interface DefaultKeyHoldMap { | ||
EnterHold: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
} | ||
export interface KeyMap extends DefaultKeyMap { | ||
} | ||
export interface KeyHoldMap extends DefaultKeyHoldMap { | ||
} | ||
export type KeyHandlerReturn = boolean | void; | ||
@@ -21,2 +27,5 @@ export type KeyHandler = (this: ElementNode, e: KeyboardEvent, target: ElementNode, handlerElm: ElementNode) => KeyHandlerReturn; | ||
}; | ||
type KeyHoldMapEventHandlers = { | ||
[K in keyof KeyHoldMap as `on${Capitalize<K>}`]?: KeyHandler; | ||
}; | ||
declare module '@lightningtv/solid' { | ||
@@ -27,3 +36,3 @@ /** | ||
*/ | ||
interface IntrinsicCommonProps extends KeyMapEventHandlers { | ||
interface IntrinsicCommonProps extends KeyMapEventHandlers, KeyHoldMapEventHandlers { | ||
onFocus?: (currentFocusedElm: ElementNode | undefined, prevFocusedElm: ElementNode | undefined) => void; | ||
@@ -48,4 +57,11 @@ onFocusChanged?: (hasFocus: boolean, currentFocusedElm: ElementNode | undefined, prevFocusedElm: ElementNode | undefined) => void; | ||
} | ||
/** | ||
* holdThreshold is in milliseconds. | ||
*/ | ||
export type KeyHoldOptions = { | ||
userKeyHoldMap: Partial<KeyHoldMap>; | ||
holdThreshold?: number; | ||
}; | ||
declare const focusPath: Accessor<ElementNode[]>; | ||
export { focusPath }; | ||
export declare const useFocusManager: (userKeyMap?: Partial<KeyMap>) => Accessor<ElementNode[]>; | ||
export declare const useFocusManager: (userKeyMap?: Partial<KeyMap>, keyHoldOptions?: KeyHoldOptions) => Accessor<ElementNode[]>; |
@@ -1,4 +0,6 @@ | ||
import { createEffect, on, createSignal, untrack, } from 'solid-js'; | ||
import { activeElement, isFunc, isArray, } from '@lightningtv/solid'; | ||
import { createEffect, createSignal, on, onCleanup, untrack } from 'solid-js'; | ||
import { makeEventListener } from '@solid-primitives/event-listener'; | ||
import { useKeyDownEvent } from '@solid-primitives/keyboard'; | ||
import { activeElement, isFunc, isArray, } from '@lightningtv/solid'; | ||
import { createSingletonRoot } from '@solid-primitives/rootless'; | ||
const keyMapEntries = { | ||
@@ -15,6 +17,28 @@ ArrowLeft: 'Left', | ||
}; | ||
const keyHoldMapEntries = { | ||
Enter: 'EnterHold', | ||
}; | ||
const DEFAULT_KEY_HOLD_THRESHOLD = 150; // ms | ||
const [focusPath, setFocusPath] = createSignal([]); | ||
export { focusPath }; | ||
export const useFocusManager = (userKeyMap) => { | ||
// copy of useKeyDownEvent but for keyup | ||
const useKeyUpEvent = /*#__PURE__*/ createSingletonRoot(() => { | ||
const [event, setEvent] = createSignal(null); | ||
makeEventListener(window, 'keyup', (e) => { | ||
setEvent(e); | ||
setTimeout(() => setEvent(null)); | ||
}); | ||
return event; | ||
}); | ||
export const useFocusManager = (userKeyMap, keyHoldOptions) => { | ||
const keypressEvent = useKeyDownEvent(); | ||
const keyupEvent = useKeyUpEvent(); | ||
const keyHoldTimeouts = {}; | ||
// clear out any leftover timeouts | ||
onCleanup(() => { | ||
for (const [_, timeout] of Object.entries(keyHoldTimeouts)) { | ||
if (timeout) | ||
clearTimeout(timeout); | ||
} | ||
}); | ||
if (userKeyMap) { | ||
@@ -33,2 +57,18 @@ // Flatten the userKeyMap to a hash | ||
} | ||
if (keyHoldOptions?.userKeyHoldMap) { | ||
// same as above | ||
for (const [key, value] of Object.entries(keyHoldOptions?.userKeyHoldMap)) { | ||
if (value === undefined || value === null) { | ||
continue; | ||
} | ||
if (isArray(value)) { | ||
for (const v of value) { | ||
keyHoldMapEntries[v] = key; | ||
} | ||
} | ||
else { | ||
keyHoldMapEntries[value] = key; | ||
} | ||
} | ||
} | ||
createEffect(on(activeElement, (currentFocusedElm, prevFocusedElm, prevFocusPath = []) => { | ||
@@ -62,25 +102,12 @@ let current = currentFocusedElm; | ||
}, { defer: true })); | ||
createEffect(() => { | ||
const e = keypressEvent(); | ||
if (e) { | ||
// Search keyMap for the value of the pressed key or keyCode if value undefined | ||
const mappedKeyEvent = keyMapEntries[e.key] || keyMapEntries[e.keyCode]; | ||
untrack(() => { | ||
const fp = focusPath(); | ||
let finalFocusElm = undefined; | ||
for (const elm of fp) { | ||
finalFocusElm = finalFocusElm || elm; | ||
if (mappedKeyEvent) { | ||
const onKeyHandler = elm[`on${mappedKeyEvent}`]; | ||
if (isFunc(onKeyHandler)) { | ||
if (onKeyHandler.call(elm, e, elm, finalFocusElm) === true) { | ||
break; | ||
} | ||
} | ||
} | ||
else { | ||
console.log(`Unhandled key event: ${e.key || e.keyCode}`); | ||
} | ||
if (isFunc(elm.onKeyPress)) { | ||
if (elm.onKeyPress.call(elm, e, mappedKeyEvent, elm, finalFocusElm) === true) { | ||
const propagateKeyDown = (e, mappedEvent, isHold = false) => { | ||
untrack(() => { | ||
const fp = focusPath(); | ||
let finalFocusElm = undefined; | ||
for (const elm of fp) { | ||
finalFocusElm = finalFocusElm || elm; | ||
if (mappedEvent) { | ||
const onKeyHandler = elm[`on${mappedEvent}`]; | ||
if (isFunc(onKeyHandler)) { | ||
if (onKeyHandler.call(elm, e, elm, finalFocusElm) === true) { | ||
break; | ||
@@ -90,5 +117,48 @@ } | ||
} | ||
return false; | ||
}); | ||
else { | ||
console.log(`Unhandled key event: ${e.key || e.keyCode}`); | ||
} | ||
const fallbackFunction = isHold ? elm.onKeyPress : elm.onKeyHold; | ||
if (isFunc(fallbackFunction)) { | ||
if (fallbackFunction.call(elm, e, mappedEvent, elm, finalFocusElm) === true) { | ||
break; | ||
} | ||
} | ||
} | ||
return false; | ||
}); | ||
}; | ||
const keyHoldCallback = (e, mappedKeyHoldEvent) => { | ||
delete keyHoldTimeouts[e.key || e.keyCode]; | ||
propagateKeyDown(e, mappedKeyHoldEvent, true); | ||
}; | ||
createEffect(() => { | ||
const keypress = keypressEvent(); | ||
const keyup = keyupEvent(); | ||
if (keypress) { | ||
const key = keypress.key || keypress.keyCode; | ||
const mappedKeyHoldEvent = keyHoldMapEntries[key]; | ||
const mappedKeyEvent = keyMapEntries[key]; | ||
if (!mappedKeyHoldEvent) { | ||
// just a regular key press | ||
propagateKeyDown(keypress, mappedKeyEvent, false); | ||
} | ||
else { | ||
const delay = keyHoldOptions?.holdThreshold || DEFAULT_KEY_HOLD_THRESHOLD; | ||
if (keyHoldTimeouts[key]) { | ||
// recieved two keydown events without a keyup in between | ||
clearTimeout(keyHoldTimeouts[key]); | ||
} | ||
keyHoldTimeouts[key] = setTimeout(() => keyHoldCallback(keypress, mappedKeyHoldEvent), delay); | ||
} | ||
} | ||
if (keyup) { | ||
const key = keyup.key || keyup.keyCode; | ||
const mappedKeyEvent = keyMapEntries[key]; | ||
if (keyHoldTimeouts[key]) { | ||
clearTimeout(keyHoldTimeouts[key]); | ||
delete keyHoldTimeouts[key]; | ||
propagateKeyDown(keyup, mappedKeyEvent, false); | ||
} | ||
} | ||
}); | ||
@@ -95,0 +165,0 @@ return focusPath; |
@@ -6,4 +6,4 @@ import { activeElement, setActiveElement, rootNode, Config, } from '@lightningtv/solid'; | ||
import { createEffect } from 'solid-js'; | ||
function createKeyboardEvent(key, keyCode) { | ||
return new KeyboardEvent('keydown', { | ||
function createKeyboardEvent(key, keyCode, eventName = 'keydown') { | ||
return new KeyboardEvent(eventName, { | ||
key, | ||
@@ -22,6 +22,6 @@ keyCode, | ||
if (deltaY < 0) { | ||
document.dispatchEvent(createKeyboardEvent('ArrowUp', 38)); | ||
document.body.dispatchEvent(createKeyboardEvent('ArrowUp', 38)); | ||
} | ||
else if (deltaY > 0) { | ||
document.dispatchEvent(createKeyboardEvent('ArrowDown', 40)); | ||
document.body.dispatchEvent(createKeyboardEvent('ArrowDown', 40)); | ||
} | ||
@@ -35,2 +35,3 @@ }, 250); | ||
document.dispatchEvent(createKeyboardEvent('Enter', 13)); | ||
setTimeout(() => document.body.dispatchEvent(createKeyboardEvent('Enter', 13, 'keyup')), 1); | ||
} | ||
@@ -37,0 +38,0 @@ }; |
import { type IntrinsicNodeProps, type IntrinsicTextProps } from '@lightningtv/core'; | ||
import { type JSXElement, type ValidComponent } from 'solid-js'; | ||
import type { RendererMain, RendererMainSettings } from '@lightningjs/renderer'; | ||
import { SolidNode } from './types.js'; | ||
import type { SolidNode } from './types.js'; | ||
export declare const rootNode: import("@lightningtv/core").ElementNode; | ||
@@ -6,0 +6,0 @@ export declare function createRenderer(rendererOptions?: RendererMainSettings | undefined, node?: HTMLElement | string): { |
@@ -1,3 +0,3 @@ | ||
import { ElementNode, ElementText } from '@lightningtv/core'; | ||
import { SolidNode } from './types.js'; | ||
import { ElementNode, type ElementText } from '@lightningtv/core'; | ||
import type { SolidNode } from './types.js'; | ||
declare const _default: { | ||
@@ -4,0 +4,0 @@ createElement(name: string): ElementNode; |
@@ -1,3 +0,3 @@ | ||
import { ElementNode, Styles, ElementText } from '@lightningtv/core'; | ||
import { JSXElement } from 'solid-js'; | ||
import { ElementNode, type Styles, type ElementText } from '@lightningtv/core'; | ||
import type { JSXElement } from 'solid-js'; | ||
import { createRenderer } from 'solid-js/universal'; | ||
@@ -4,0 +4,0 @@ export type SolidRendererOptions = Parameters<typeof createRenderer<SolidNode>>[0]; |
{ | ||
"name": "@lightningtv/solid", | ||
"version": "1.0.3", | ||
"version": "1.1.0", | ||
"description": "Lightning Renderer for Solid Universal", | ||
@@ -45,6 +45,7 @@ "type": "module", | ||
"dependencies": { | ||
"@lightningtv/core": "^1.0.3", | ||
"@lightningtv/core": "^1.0.4", | ||
"@solid-primitives/event-listener": "^2.3.3", | ||
"@solid-primitives/keyboard": "^1.2.8", | ||
"@solid-primitives/mouse": "^2.0.19", | ||
"@solid-primitives/rootless": "^1.4.5", | ||
"@solid-primitives/scheduled": "^1.4.3" | ||
@@ -51,0 +52,0 @@ }, |
import { | ||
createEffect, | ||
on, | ||
createSignal, | ||
untrack, | ||
type Accessor, | ||
} from 'solid-js'; | ||
import { useKeyDownEvent } from '@solid-primitives/keyboard'; | ||
import { | ||
activeElement, | ||
@@ -15,14 +7,27 @@ ElementNode, | ||
} from '@lightningtv/solid'; | ||
import { createEffect, createSignal, on, onCleanup, untrack } from 'solid-js'; | ||
import { type Accessor } from 'solid-js'; | ||
import { makeEventListener } from '@solid-primitives/event-listener'; | ||
import { useKeyDownEvent } from '@solid-primitives/keyboard'; | ||
import { createSingletonRoot } from '@solid-primitives/rootless'; | ||
export type KeyNameOrKeyCode = string | number; | ||
export interface DefaultKeyMap { | ||
Left: string | number | (string | number)[]; | ||
Right: string | number | (string | number)[]; | ||
Up: string | number | (string | number)[]; | ||
Down: string | number | (string | number)[]; | ||
Enter: string | number | (string | number)[]; | ||
Last: string | number | (string | number)[]; | ||
Left: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
Right: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
Up: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
Down: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
Enter: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
Last: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
} | ||
export interface DefaultKeyHoldMap { | ||
EnterHold: KeyNameOrKeyCode | KeyNameOrKeyCode[]; | ||
} | ||
export interface KeyMap extends DefaultKeyMap {} | ||
export interface KeyHoldMap extends DefaultKeyHoldMap {} | ||
export type KeyHandlerReturn = boolean | void; | ||
@@ -43,2 +48,5 @@ | ||
}; | ||
type KeyHoldMapEventHandlers = { | ||
[K in keyof KeyHoldMap as `on${Capitalize<K>}`]?: KeyHandler; | ||
}; | ||
@@ -50,3 +58,5 @@ declare module '@lightningtv/solid' { | ||
*/ | ||
interface IntrinsicCommonProps extends KeyMapEventHandlers { | ||
interface IntrinsicCommonProps | ||
extends KeyMapEventHandlers, | ||
KeyHoldMapEventHandlers { | ||
onFocus?: ( | ||
@@ -98,3 +108,3 @@ currentFocusedElm: ElementNode | undefined, | ||
const keyMapEntries: Record<string | number, string> = { | ||
const keyMapEntries: Record<KeyNameOrKeyCode, string> = { | ||
ArrowLeft: 'Left', | ||
@@ -111,6 +121,48 @@ ArrowRight: 'Right', | ||
const keyHoldMapEntries: Record<KeyNameOrKeyCode, string> = { | ||
Enter: 'EnterHold', | ||
}; | ||
const DEFAULT_KEY_HOLD_THRESHOLD = 150; // ms | ||
/** | ||
* holdThreshold is in milliseconds. | ||
*/ | ||
export type KeyHoldOptions = { | ||
userKeyHoldMap: Partial<KeyHoldMap>; | ||
holdThreshold?: number; | ||
}; | ||
const [focusPath, setFocusPath] = createSignal<ElementNode[]>([]); | ||
export { focusPath }; | ||
export const useFocusManager = (userKeyMap?: Partial<KeyMap>) => { | ||
// copy of useKeyDownEvent but for keyup | ||
const useKeyUpEvent = /*#__PURE__*/ createSingletonRoot< | ||
Accessor<KeyboardEvent | null> | ||
>(() => { | ||
const [event, setEvent] = createSignal<KeyboardEvent | null>(null); | ||
makeEventListener(window, 'keyup', (e) => { | ||
setEvent(e); | ||
setTimeout(() => setEvent(null)); | ||
}); | ||
return event; | ||
}); | ||
export const useFocusManager = ( | ||
userKeyMap?: Partial<KeyMap>, | ||
keyHoldOptions?: KeyHoldOptions, | ||
) => { | ||
const keypressEvent = useKeyDownEvent(); | ||
const keyupEvent = useKeyUpEvent(); | ||
const keyHoldTimeouts: { [key: KeyNameOrKeyCode]: number } = {}; | ||
// clear out any leftover timeouts | ||
onCleanup(() => { | ||
for (const [_, timeout] of Object.entries(keyHoldTimeouts)) { | ||
if (timeout) clearTimeout(timeout); | ||
} | ||
}); | ||
if (userKeyMap) { | ||
@@ -128,2 +180,17 @@ // Flatten the userKeyMap to a hash | ||
} | ||
if (keyHoldOptions?.userKeyHoldMap) { | ||
// same as above | ||
for (const [key, value] of Object.entries(keyHoldOptions?.userKeyHoldMap)) { | ||
if (value === undefined || value === null) { | ||
continue; | ||
} | ||
if (isArray(value)) { | ||
for (const v of value) { | ||
keyHoldMapEntries[v] = key; | ||
} | ||
} else { | ||
keyHoldMapEntries[value] = key; | ||
} | ||
} | ||
} | ||
createEffect( | ||
@@ -181,42 +248,83 @@ on( | ||
createEffect(() => { | ||
const e = keypressEvent(); | ||
if (e) { | ||
// Search keyMap for the value of the pressed key or keyCode if value undefined | ||
const mappedKeyEvent = keyMapEntries[e.key] || keyMapEntries[e.keyCode]; | ||
untrack(() => { | ||
const fp = focusPath(); | ||
let finalFocusElm: ElementNode | undefined = undefined; | ||
for (const elm of fp) { | ||
finalFocusElm = finalFocusElm || elm; | ||
if (mappedKeyEvent) { | ||
const onKeyHandler = | ||
elm[`on${mappedKeyEvent}` as keyof KeyMapEventHandlers]; | ||
if (isFunc(onKeyHandler)) { | ||
if (onKeyHandler.call(elm, e, elm, finalFocusElm) === true) { | ||
break; | ||
} | ||
} | ||
} else { | ||
console.log(`Unhandled key event: ${e.key || e.keyCode}`); | ||
} | ||
if (isFunc(elm.onKeyPress)) { | ||
if ( | ||
elm.onKeyPress.call( | ||
elm, | ||
e, | ||
mappedKeyEvent, | ||
elm, | ||
finalFocusElm, | ||
) === true | ||
) { | ||
const propagateKeyDown = ( | ||
e: KeyboardEvent, | ||
mappedEvent: string | undefined, | ||
isHold = false, | ||
) => { | ||
untrack(() => { | ||
const fp = focusPath(); | ||
let finalFocusElm: ElementNode | undefined = undefined; | ||
for (const elm of fp) { | ||
finalFocusElm = finalFocusElm || elm; | ||
if (mappedEvent) { | ||
const onKeyHandler = | ||
elm[`on${mappedEvent}` as keyof KeyMapEventHandlers]; | ||
if (isFunc(onKeyHandler)) { | ||
if (onKeyHandler.call(elm, e, elm, finalFocusElm) === true) { | ||
break; | ||
} | ||
} | ||
} else { | ||
console.log(`Unhandled key event: ${e.key || e.keyCode}`); | ||
} | ||
return false; | ||
}); | ||
const fallbackFunction = isHold ? elm.onKeyPress : elm.onKeyHold; | ||
if (isFunc(fallbackFunction)) { | ||
if ( | ||
(fallbackFunction as any).call( | ||
elm, | ||
e, | ||
mappedEvent, | ||
elm, | ||
finalFocusElm, | ||
) === true | ||
) { | ||
break; | ||
} | ||
} | ||
} | ||
return false; | ||
}); | ||
}; | ||
const keyHoldCallback = ( | ||
e: KeyboardEvent, | ||
mappedKeyHoldEvent: string | undefined, | ||
) => { | ||
delete keyHoldTimeouts[e.key || e.keyCode]; | ||
propagateKeyDown(e, mappedKeyHoldEvent, true); | ||
}; | ||
createEffect(() => { | ||
const keypress = keypressEvent(); | ||
const keyup = keyupEvent(); | ||
if (keypress) { | ||
const key: KeyNameOrKeyCode = keypress.key || keypress.keyCode; | ||
const mappedKeyHoldEvent = keyHoldMapEntries[key]; | ||
const mappedKeyEvent = keyMapEntries[key]; | ||
if (!mappedKeyHoldEvent) { | ||
// just a regular key press | ||
propagateKeyDown(keypress, mappedKeyEvent, false); | ||
} else { | ||
const delay = | ||
keyHoldOptions?.holdThreshold || DEFAULT_KEY_HOLD_THRESHOLD; | ||
if (keyHoldTimeouts[key]) { | ||
// recieved two keydown events without a keyup in between | ||
clearTimeout(keyHoldTimeouts[key]); | ||
} | ||
keyHoldTimeouts[key] = setTimeout( | ||
() => keyHoldCallback(keypress, mappedKeyHoldEvent), | ||
delay, | ||
); | ||
} | ||
} | ||
if (keyup) { | ||
const key: KeyNameOrKeyCode = keyup.key || keyup.keyCode; | ||
const mappedKeyEvent = keyMapEntries[key]; | ||
if (keyHoldTimeouts[key]) { | ||
clearTimeout(keyHoldTimeouts[key]); | ||
delete keyHoldTimeouts[key]; | ||
propagateKeyDown(keyup, mappedKeyEvent, false); | ||
} | ||
} | ||
}); | ||
@@ -223,0 +331,0 @@ |
@@ -14,4 +14,8 @@ import type { INode } from '@lightningjs/renderer'; | ||
function createKeyboardEvent(key: string, keyCode: number): KeyboardEvent { | ||
return new KeyboardEvent('keydown', { | ||
function createKeyboardEvent( | ||
key: string, | ||
keyCode: number, | ||
eventName: string = 'keydown', | ||
): KeyboardEvent { | ||
return new KeyboardEvent(eventName, { | ||
key, | ||
@@ -31,5 +35,5 @@ keyCode, | ||
if (deltaY < 0) { | ||
document.dispatchEvent(createKeyboardEvent('ArrowUp', 38)); | ||
document.body.dispatchEvent(createKeyboardEvent('ArrowUp', 38)); | ||
} else if (deltaY > 0) { | ||
document.dispatchEvent(createKeyboardEvent('ArrowDown', 40)); | ||
document.body.dispatchEvent(createKeyboardEvent('ArrowDown', 40)); | ||
} | ||
@@ -53,2 +57,7 @@ }, 250); | ||
document.dispatchEvent(createKeyboardEvent('Enter', 13)); | ||
setTimeout( | ||
() => | ||
document.body.dispatchEvent(createKeyboardEvent('Enter', 13, 'keyup')), | ||
1, | ||
); | ||
} | ||
@@ -55,0 +64,0 @@ }; |
@@ -17,3 +17,3 @@ import { createRenderer as solidCreateRenderer } from 'solid-js/universal'; | ||
import type { RendererMain, RendererMainSettings } from '@lightningjs/renderer'; | ||
import { SolidNode } from './types.js'; | ||
import type { SolidNode } from './types.js'; | ||
@@ -20,0 +20,0 @@ const solidRenderer = solidCreateRenderer<SolidNode>(nodeOpts); |
import { assertTruthy } from '@lightningjs/renderer/utils'; | ||
import { ElementNode, NodeType, log, ElementText } from '@lightningtv/core'; | ||
import { SolidNode, SolidRendererOptions } from './types.js'; | ||
import { ElementNode, NodeType, log, type ElementText } from '@lightningtv/core'; | ||
import type { SolidNode, SolidRendererOptions } from './types.js'; | ||
@@ -5,0 +5,0 @@ export default { |
@@ -1,3 +0,3 @@ | ||
import { ElementNode, Styles, ElementText } from '@lightningtv/core'; | ||
import { JSXElement } from 'solid-js'; | ||
import { ElementNode, type Styles, type ElementText } from '@lightningtv/core'; | ||
import type { JSXElement } from 'solid-js'; | ||
import { createRenderer } from 'solid-js/universal'; | ||
@@ -4,0 +4,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
166239
2166
8