Add a few type improvements to jscadParams.ts

This commit is contained in:
Kurt Hutten
2021-08-07 15:29:17 +10:00
parent f83d1b395f
commit 2d7df96ad9
6 changed files with 43 additions and 43 deletions

View File

@@ -1,6 +1,6 @@
import { useRender } from 'src/components/IdeWrapper/useRender' import { useRender } from 'src/components/IdeWrapper/useRender'
import { useIdeContext } from 'src/helpers/hooks/useIdeContext' import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
import { genParams, getParams } from 'src/helpers/cadPackages/jscadParams' import { genParams, getParams } from 'src/helpers/cadPackages/jsCad/jscadParams'
const Customizer = () => { const Customizer = () => {
const [open, setOpen] = React.useState(true) const [open, setOpen] = React.useState(true)

View File

@@ -1,9 +1,10 @@
import { makeCodeStoreKey, requestRender } from 'src/helpers/hooks/useIdeState' import { makeCodeStoreKey, requestRender } from 'src/helpers/hooks/useIdeState'
import { useIdeContext } from 'src/helpers/hooks/useIdeContext' import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
import type { RawCustomizerParams } from 'src/helpers/cadPackages/common'
export const useRender = () => { export const useRender = () => {
const { state, thunkDispatch } = useIdeContext() const { state, thunkDispatch } = useIdeContext()
return (parameters) => { return (parameters?: RawCustomizerParams) => {
thunkDispatch((dispatch, getState) => { thunkDispatch((dispatch, getState) => {
const state = getState() const state = getState()
dispatch({ type: 'setLoading' }) dispatch({ type: 'setLoading' })

View File

@@ -35,6 +35,10 @@ export interface HealthyResponse {
lastParameters?: any lastParameters?: any
} }
export interface RawCustomizerParams {
[paramName: string]: number | string | boolean
}
export function createHealthyResponse({ export function createHealthyResponse({
date, date,
data, data,

View File

@@ -3,7 +3,7 @@ import type { CadPackage } from 'src/helpers/hooks/useIdeState'
import openscad from './openScadController' import openscad from './openScadController'
import cadquery from './cadQueryController' import cadquery from './cadQueryController'
import jscad from './jsCadController' import jscad from './jsCad/jsCadController'
export const cadPackages: { [key in CadPackage]: DefaultKernelExport } = { export const cadPackages: { [key in CadPackage]: DefaultKernelExport } = {
openscad, openscad,

View File

@@ -3,7 +3,7 @@ import {
DefaultKernelExport, DefaultKernelExport,
createUnhealthyResponse, createUnhealthyResponse,
createHealthyResponse, createHealthyResponse,
} from './common' } from '../common'
import { import {
MeshPhongMaterial, MeshPhongMaterial,
LineBasicMaterial, LineBasicMaterial,

View File

@@ -1,20 +1,25 @@
import type { RawCustomizerParams } from '../common'
const GROUP_SELECTOR = 'DIV[type="group"]' const GROUP_SELECTOR = 'DIV[type="group"]'
const INPUT_SELECTOR = 'INPUT, SELECT' const INPUT_SELECTOR = 'INPUT, SELECT'
function forEachInput(target, callback) { function forEachInput(
target: HTMLElement,
callback: (e: HTMLInputElement) => void
) {
target.querySelectorAll(INPUT_SELECTOR).forEach(callback) target.querySelectorAll(INPUT_SELECTOR).forEach(callback)
} }
function forEachGroup(target, callback) { function forEachGroup(target: HTMLElement, callback: (e: HTMLElement) => void) {
target.querySelectorAll(GROUP_SELECTOR).forEach(callback) target.querySelectorAll(GROUP_SELECTOR).forEach(callback)
} }
const numeric = { number: 1, float: 1, int: 1, range: 1, slider: 1 } const numeric = { number: 1, float: 1, int: 1, range: 1, slider: 1 }
function applyRange(inp) { function applyRange(inp) {
let label = inp.previousElementSibling const label = inp.previousElementSibling
if (label && label.tagName == 'LABEL') { if (label && label.tagName == 'LABEL') {
let info = label.querySelector('I') const info = label.querySelector('I')
if (info) info.innerHTML = inp.value if (info) info.innerHTML = inp.value
} }
} }
@@ -26,10 +31,8 @@ export function genParams(
callback = undefined, callback = undefined,
buttons = ['reset', 'save', 'load', 'edit', 'link'] buttons = ['reset', 'save', 'load', 'edit', 'link']
) { ) {
let funcs = { const funcs = {
group: function ({ name, type, caption, captions, value, min, max }) { group: () => '',
return ''
},
choice: inputChoice, choice: inputChoice,
radio: inputRadio, radio: inputRadio,
float: inputNumber, float: inputNumber,
@@ -43,17 +46,8 @@ export function genParams(
password: inputNumber, password: inputNumber,
color: inputNumber, color: inputNumber,
// TODO radio similar options as choice // TODO radio similar options as choice
checkbox: function ({ checkbox: function ({ name, value }) {
name, const checkedStr = value === 'checked' || value === true ? 'checked' : ''
type,
caption,
captions,
value,
checked,
min,
max,
}) {
let checkedStr = value === 'checked' || value === true ? 'checked' : ''
return `<input type="checkbox" name="${name}" ${checkedStr}/>` return `<input type="checkbox" name="${name}" ${checkedStr}/>`
}, },
number: inputNumber, number: inputNumber,
@@ -65,7 +59,8 @@ export function genParams(
let ret = '<div type="radio">' let ret = '<div type="radio">'
for (let i = 0; i < values.length; i++) { for (let i = 0; i < values.length; i++) {
let checked = value == values[i] || value == captions[i] ? 'checked' : '' const checked =
value == values[i] || value == captions[i] ? 'checked' : ''
ret += `<label><input type="radio" _type="${type}" name="${name}" numeric="${ ret += `<label><input type="radio" _type="${type}" name="${name}" numeric="${
typeof values[0] == 'number' ? '1' : '0' typeof values[0] == 'number' ? '1' : '0'
}" value="${values[i]}" ${checked}/>${captions[i]}</label>` }" value="${values[i]}" ${checked}/>${captions[i]}</label>`
@@ -81,7 +76,8 @@ export function genParams(
}">` }">`
for (let i = 0; i < values.length; i++) { for (let i = 0; i < values.length; i++) {
let checked = value == values[i] || value == captions[i] ? 'selected' : '' const checked =
value == values[i] || value == captions[i] ? 'selected' : ''
ret += `<option value="${values[i]}" ${checked}>${captions[i]}</option>` ret += `<option value="${values[i]}" ${checked}>${captions[i]}</option>`
} }
return ret + '</select>' return ret + '</select>'
@@ -93,7 +89,7 @@ export function genParams(
let inputType = type let inputType = type
if (type == 'int' || type == 'float') inputType = 'number' if (type == 'int' || type == 'float') inputType = 'number'
if (type == 'range' || type == 'slider') inputType = 'range' if (type == 'range' || type == 'slider') inputType = 'range'
var str = `<input _type="${type}" type="${inputType}" name="${name}"` let str = `<input _type="${type}" type="${inputType}" name="${name}"`
if (step !== undefined) str += ` step="${step || ''}"` if (step !== undefined) str += ` step="${step || ''}"`
if (min !== undefined) str += ` min="${min || ''}"` if (min !== undefined) str += ` min="${min || ''}"`
if (max !== undefined) str += ` max="${max || ''}"` if (max !== undefined) str += ` max="${max || ''}"`
@@ -105,10 +101,10 @@ export function genParams(
let html = '' let html = ''
let closed = false let closed = false
let missing = {} const missing = {}
defs.forEach((def) => { defs.forEach((def) => {
let { type, caption, name } = def const { type, caption, name } = def
if (storedParams[name] !== undefined) { if (storedParams[name] !== undefined) {
def.value = storedParams[name] def.value = storedParams[name]
@@ -140,7 +136,7 @@ export function genParams(
html += '</div>\n' html += '</div>\n'
}) })
let missingKeys = Object.keys(missing) const missingKeys = Object.keys(missing)
if (missingKeys.length) console.log('missing param impl', missingKeys) if (missingKeys.length) console.log('missing param impl', missingKeys)
function _callback(source = 'change') { function _callback(source = 'change') {
@@ -148,9 +144,9 @@ export function genParams(
} }
html += '<div class="jscad-param-buttons"><div>' html += '<div class="jscad-param-buttons"><div>'
buttons.forEach((b) => { buttons.forEach((button) => {
if (typeof b === 'string') b = { id: b, name: b } const { id, name } =
let { id, name } = b typeof button === 'string' ? { id: button, name: button } : button
html += `<button action="${id}"><b>${name}</b></button>` html += `<button action="${id}"><b>${name}</b></button>`
}) })
html += '</div></div>' html += '</div></div>'
@@ -158,7 +154,7 @@ export function genParams(
target.innerHTML = html target.innerHTML = html
forEachInput(target, (inp) => { forEachInput(target, (inp) => {
let type = inp.type const type = inp.type
inp.addEventListener('input', function (evt) { inp.addEventListener('input', function (evt) {
applyRange(inp) applyRange(inp)
if (inp.getAttribute('live') === '1') _callback('live') if (inp.getAttribute('live') === '1') _callback('live')
@@ -168,10 +164,9 @@ export function genParams(
}) })
function groupClick(evt) { function groupClick(evt) {
var groupDiv = evt.target let groupDiv = evt.target
if (groupDiv.tagName === 'LABEL') groupDiv = groupDiv.parentNode if (groupDiv.tagName === 'LABEL') groupDiv = groupDiv.parentNode
var closed = groupDiv.getAttribute('closed') == '1' ? '0' : '1' const closed = groupDiv.getAttribute('closed') == '1' ? '0' : '1'
var name = evt.target.getAttribute('name')
do { do {
groupDiv.setAttribute('closed', closed) groupDiv.setAttribute('closed', closed)
groupDiv = groupDiv.nextElementSibling groupDiv = groupDiv.nextElementSibling
@@ -184,20 +179,20 @@ export function genParams(
}) })
} }
export function getParams(target) { export function getParams(target: HTMLElement): RawCustomizerParams {
let params = {} const params = {}
if (!target) return params if (!target) return params
forEachGroup(target, (elem) => { forEachGroup(target, (elem) => {
let name = elem.getAttribute('name') const name = elem.getAttribute('name')
params[name] = elem.getAttribute('closed') == '1' ? 'closed' : '' params[name] = elem.getAttribute('closed') == '1' ? 'closed' : ''
}) })
forEachInput(target, (elem) => { forEachInput(target, (elem) => {
let name = elem.name const name = elem.name
let value = elem.value let value: RawCustomizerParams[string] = elem.value
if (elem.tagName == 'INPUT') { if (elem.tagName == 'INPUT') {
if (elem.type == 'checkbox') value = elem.checked if (elem.type == 'checkbox') value = elem?.checked
if (elem.type == 'range' || elem.type == 'color') applyRange(elem) if (elem.type == 'range' || elem.type == 'color') applyRange(elem)
} }
@@ -205,7 +200,7 @@ export function getParams(target) {
numeric[elem.getAttribute('type')] || numeric[elem.getAttribute('type')] ||
elem.getAttribute('numeric') == '1' elem.getAttribute('numeric') == '1'
) )
value = parseFloat(value || 0) value = parseFloat(String(value || 0))
if (elem.type == 'radio' && !elem.checked) return // skip if not checked radio button if (elem.type == 'radio' && !elem.checked) return // skip if not checked radio button