UNPKG

solid-tweakpane

Version:

Solid components for Tweakpane library

204 lines (197 loc) 6.02 kB
'use strict'; var solidJs = require('solid-js'); var tweakpane = require('tweakpane'); const TWPRootContext = solidJs.createContext(); const useTWPRoot = () => solidJs.useContext(TWPRootContext); function TWPGroup(props) { return solidJs.createComponent(TWPRootContext.Provider, { get value() { return props.root; }, get children() { return props.children; } }); } function Tweakpane(props) { const [compProps, paneProps] = solidJs.splitProps(props, ["children"]); const pane = new tweakpane.Pane(paneProps); solidJs.onCleanup(() => pane.dispose()); return solidJs.createComponent(TWPGroup, { root: pane, get children() { return compProps.children; } }); } const TWPBindGroupContext = solidJs.createContext(); const useTWPBingGroup = () => solidJs.useContext(TWPBindGroupContext); function TWPBindGroup(props) { return solidJs.createComponent(TWPBindGroupContext.Provider, { get value() { return props.target; }, get children() { return props.children; } }); } function createTWPUI(initFn) { return function (props) { const root = useTWPRoot(); if (!root) throw new Error(`Use tweakpane controls within <${"Tweakpane"}>`); const [comp, element] = initFn(root, props); solidJs.onCleanup(() => { if (!comp) return; comp.dispose(); root.remove(comp); }); props.ref?.(comp); if (element) return element; }; } const TWPFolder = createTWPUI((root, props) => { const [compProps, folderProps] = solidJs.splitProps(props, ["children"]); const folder = root.addFolder(folderProps); return [folder, solidJs.createComponent(TWPGroup, { root: folder, get children() { return compProps.children; } })]; }); const TWPButton = createTWPUI((root, props) => { const button = root.addButton(props); props.onClick && button.on("click", props.onClick); solidJs.createEffect(() => { button.title = props.title; }); return [button]; }); const TWPSeparator = createTWPUI((root, props) => { const separator = root.addSeparator(props); return [separator]; }); const TabContext = solidJs.createContext(); const useTab = () => solidJs.useContext(TabContext); const TWPTab = createTWPUI((root, props) => { const [compProps, tabProps] = solidJs.splitProps(props, ["children"]); const tab = root.addTab({ ...tabProps, pages: [{ title: "mock" }] }); solidJs.onMount(() => tab.removePage(0)); return [tab, solidJs.createComponent(TabContext.Provider, { value: tab, get children() { return compProps.children; } })]; }); function TWPTabPage(props) { const root = useTab(); if (!root) throw new Error(`Parent for <${"TWPTabPage"}> should be <${"TWPTab"}>`); const [compProps, pageProps] = solidJs.splitProps(props, ["children"]); const page = root.addPage(pageProps); solidJs.createEffect(() => page.title = props.title); solidJs.onCleanup(() => { root.removePage(root.pages.indexOf(page)); }); return solidJs.createComponent(TWPGroup, { root: page, get children() { return compProps.children; } }); } function createTWPControl(initFn) { return function (props) { const root = useTWPRoot(); if (!root) throw new Error(`Use tweakpane controls within <${"Tweakpane"}>`); let binding = props.target ?? useTWPBingGroup(); if (!binding && props.key) { throw new Error(`In case of usage <TWPControl> with key, place it within <${"TWPBindGroup"}> and provide taget`); } if (binding && !Object.hasOwn(binding, props.key)) { throw new Error(`There is no key ${props.key} in binding ${binding}`); } if (!binding && !props.key) { if (!props.initialValue) { throw new Error(`In case of usage <TWPControl> without target and key, provide ${"initialValue"} prop`); } binding = { value: props.initialValue }; props.key = "value"; } const [comp, element] = initFn(root, binding, props); solidJs.createEffect(solidJs.on(() => binding[props.key], () => comp.refresh(), { defer: true })); solidJs.onCleanup(() => { if (!comp) return; root.remove(comp); comp.dispose(); }); props.ref?.(comp); if (element) return element; }; } const TWPInput = createTWPControl((root, binding, props) => { const input = root.addInput(binding, props.key, props.params); props.onChange && input.on("change", props.onChange); return [input]; }); const TWPMonitor = createTWPControl((root, binding, props) => { const monitor = root.addMonitor(binding, props.key, props.params); props.onUpdate && monitor.on("update", props.onUpdate); return [monitor]; }); function TWPAutoMutable(props) { return solidJs.createComponent(solidJs.For, { get each() { return Object.keys(props.target); }, children: key => solidJs.createComponent(solidJs.Switch, { get fallback() { return solidJs.createComponent(TWPInput, { key: key, get target() { return props.target; } }); }, get children() { return solidJs.createComponent(solidJs.Match, { get when() { return props.target[key].constructor === Object; }, get children() { return solidJs.createComponent(TWPFolder, { title: key, get children() { return solidJs.createComponent(TWPAutoMutable, { get target() { return props.target[key]; } }); } }); } }); } }) }); } exports.TWPAutoMutable = TWPAutoMutable; exports.TWPBindGroup = TWPBindGroup; exports.TWPButton = TWPButton; exports.TWPFolder = TWPFolder; exports.TWPInput = TWPInput; exports.TWPMonitor = TWPMonitor; exports.TWPSeparator = TWPSeparator; exports.TWPTab = TWPTab; exports.TWPTabPage = TWPTabPage; exports.Tweakpane = Tweakpane;