|
| 1 | +import { ElementNode, insertNode, type NodeProps, type NodeStyles } from '@lightningtv/solid'; |
| 2 | +import { createMemo, getOwner, onMount, runWithOwner, type Accessor } from 'solid-js'; |
| 3 | +import { fadeIn, fadeOut } from './FadeInOut.jsx'; |
| 4 | +import { chainFunctions } from '@lightningtv/solid/primitives'; |
| 5 | + |
| 6 | +export const BorderBoxStyle: NodeStyles = { |
| 7 | + alpha: 0, |
| 8 | + borderSpace: 6, |
| 9 | + borderRadius: 20, |
| 10 | + border: { color: 0xffffff, width: 2 }, |
| 11 | +}; |
| 12 | + |
| 13 | +type BorderProps = NodeProps & { borderSpace?: number }; |
| 14 | +const borderComponent = (props: BorderProps) => { |
| 15 | + const space = createMemo(() => props.borderSpace ?? (BorderBoxStyle.borderSpace as number)); |
| 16 | + return ( |
| 17 | + <> |
| 18 | + <view |
| 19 | + skipFocus |
| 20 | + onCreate={(el) => { |
| 21 | + const parent = el.parent!; |
| 22 | + el.width = parent.width + space() * 2; |
| 23 | + el.height = parent.height + space() * 2; |
| 24 | + fadeIn(el); |
| 25 | + }} |
| 26 | + onDestroy={fadeOut} |
| 27 | + style={BorderBoxStyle} |
| 28 | + x={-space()} |
| 29 | + y={-space()} |
| 30 | + {...props} |
| 31 | + /> |
| 32 | + </> |
| 33 | + ); |
| 34 | +}; |
| 35 | + |
| 36 | +// Solid directives can only be used on native root elements `view` and `text` |
| 37 | +export default function borderbox(el: ElementNode, accessor: Accessor<BorderProps | true | undefined>) { |
| 38 | + let border: ElementNode | null; |
| 39 | + const owner = getOwner(); |
| 40 | + |
| 41 | + onMount(() => { |
| 42 | + el.onFocusChanged = chainFunctions((f) => { |
| 43 | + if (f) { |
| 44 | + if (border) return; |
| 45 | + runWithOwner(owner, () => { |
| 46 | + const props = accessor(); |
| 47 | + border = borderComponent( |
| 48 | + props === true || props === undefined ? ({} as NodeProps) : props, |
| 49 | + ) as any as ElementNode; |
| 50 | + insertNode(el, border); |
| 51 | + border.render(); |
| 52 | + }); |
| 53 | + } else if (border) { |
| 54 | + border.destroy(); |
| 55 | + el.removeChild(border!); |
| 56 | + border = null; |
| 57 | + } |
| 58 | + }, el.onFocusChanged); |
| 59 | + }); |
| 60 | +} |
0 commit comments