summaryrefslogtreecommitdiff
path: root/core/gjs/src/jsx/jsx-runtime.ts
blob: f40dc05831a8d441cbd1a97b629d879e75fc6ca8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { Gtk } from "../imports.js"
import * as Widget from "../widgets.js"

function isArrowFunction(func: any): func is (args: any) => any {
    return !Object.hasOwn(func, "prototype")
}

export function jsx(
    ctor: keyof typeof ctors | typeof Gtk.Widget,
    { children, ...props }: any,
) {
    children ??= []

    if (!Array.isArray(children))
        children = [children]

    children = children.filter(Boolean)

    if (children.length === 1)
        props.child = children[0]
    else if (children.length > 1)
        props.children = children

    if (typeof ctor === "string") {
        return new ctors[ctor](props)
    }

    if (isArrowFunction(ctor))
        return ctor(props)

    // @ts-expect-error can be class or function
    return new ctor(props)
}

const ctors = {
    box: Widget.Box,
    button: Widget.Button,
    centerbox: Widget.CenterBox,
    circularprogress: Widget.CircularProgress,
    drawingarea: Widget.DrawingArea,
    entry: Widget.Entry,
    eventbox: Widget.EventBox,
    // TODO: fixed
    // TODO: flowbox
    icon: Widget.Icon,
    label: Widget.Label,
    levelbar: Widget.LevelBar,
    // TODO: listbox
    overlay: Widget.Overlay,
    revealer: Widget.Revealer,
    scrollable: Widget.Scrollable,
    slider: Widget.Slider,
    stack: Widget.Stack,
    switch: Widget.Switch,
    window: Widget.Window,
}

declare global {
    // eslint-disable-next-line @typescript-eslint/no-namespace
    namespace JSX {
        type Element = Gtk.Widget
        type ElementClass = Gtk.Widget
        interface IntrinsicElements {
            box: Widget.BoxProps
            button: Widget.ButtonProps
            centerbox: Widget.CenterBoxProps
            circularprogress: Widget.CircularProgressProps
            drawingarea: Widget.DrawingAreaProps
            entry: Widget.EntryProps
            eventbox: Widget.EventBoxProps
            // TODO: fixed
            // TODO: flowbox
            icon: Widget.IconProps
            label: Widget.LabelProps
            levelbar: Widget.LevelBarProps
            // TODO: listbox
            overlay: Widget.OverlayProps
            revealer: Widget.RevealerProps
            scrollable: Widget.ScrollableProps
            slider: Widget.SliderProps
            stack: Widget.StackProps
            switch: Widget.SwitchProps
            window: Widget.WindowProps
        }
    }
}

export const jsxs = jsx