UNPKG

verstak

Version:
119 lines (118 loc) 5.12 kB
import { ReactiveTreeNode, Mode } from "reactronic"; import { Division, JustText, OnFocus, rowBreak, Fragment, KeyboardModifiers, Horizontal, Vertical } from "verstak"; import { triggeringModel } from "./common/Utils.js"; import { Theme } from "./Theme.js"; import { Icon } from "./Icon.v.js"; export function Input(declaration) { return (Division(ReactiveTreeNode.withBasis(declaration, { mode: Mode.autonomous, preparation: el => { var _a; (_a = el.model) !== null && _a !== void 0 ? _a : (el.model = composeInputModel()); el.native.dataForSensor.focus = el.model; }, script: el => { const m = el.model; const theme = Theme.current.input; el.useStylingPreset(theme.main); if (m.icon) Icon(m.icon, { script: (el, base) => { base(); el.useStylingPreset(theme.icon); }, }); InputField(m, theme); InputPopup(m, theme); }, }))); } export function composeInputModel(props) { var _a, _b, _c, _d, _e, _f, _g, _h; return triggeringModel({ icon: props === null || props === void 0 ? void 0 : props.icon, text: (_a = props === null || props === void 0 ? void 0 : props.text) !== null && _a !== void 0 ? _a : "", options: (_b = props === null || props === void 0 ? void 0 : props.options) !== null && _b !== void 0 ? _b : [], selected: props === null || props === void 0 ? void 0 : props.selected, multiSelected: (_c = props === null || props === void 0 ? void 0 : props.multiSelected) !== null && _c !== void 0 ? _c : new Set(), position: (_d = props === null || props === void 0 ? void 0 : props.position) !== null && _d !== void 0 ? _d : 0, isMultiLineText: (_e = props === null || props === void 0 ? void 0 : props.isMultiLineText) !== null && _e !== void 0 ? _e : false, isEditMode: (_f = props === null || props === void 0 ? void 0 : props.isEditMode) !== null && _f !== void 0 ? _f : false, isHotText: (_g = props === null || props === void 0 ? void 0 : props.isHotText) !== null && _g !== void 0 ? _g : false, inputStyle: (_h = props === null || props === void 0 ? void 0 : props.inputStyle) !== null && _h !== void 0 ? _h : "", }); } function InputField(model, styling) { return (JustText(model.text, false, { key: InputField.name, preparation: (el, base) => { const e = el.native; el.useStylingPreset(styling.field); el.horizontally = Horizontal.stretch; el.vertically = Vertical.stretch; e.tabIndex = 0; e.contentEditable = "true"; e.dataForSensor.focus = model; base(); }, script: el => { const e = el.native; if (!model.isEditMode) e.innerText = model.text; Fragment(() => { const keyboard = e.sensors.keyboard; if (keyboard.down) { if (isApplyKey(model, keyboard)) selectAllAndPreventDefault(e, keyboard); } if (keyboard.up) { if (isApplyKey(model, keyboard)) { selectAllAndPreventDefault(e, keyboard); model.text = e.innerText; } else if (model.isHotText) model.text = e.innerText; } }); OnFocus(e, model); }, })); } function InputPopup(model, styling) { return (Division({ key: InputPopup.name, script: el => { el.useStylingPreset(styling.popup); Fragment(() => model.position = el.native.sensors.scroll.y); const visible = el.overlayVisible = model.isEditMode; if (visible) { const options = model.options; if (options.length > 0) { for (const x of model.options) { rowBreak(); JustText(x, false, { key: x, preparation: el => { el.contentWrapping = false; }, }); } } else JustText("(nothing)", false, { key: "(nothing)" }); } }, })); } function isApplyKey(m, keyboard) { const modifiers = keyboard.modifiers; return keyboard.down === "Enter" && (!m.isMultiLineText || (modifiers & KeyboardModifiers.ctrlShiftMeta) > 0); } function selectAllAndPreventDefault(e, keyboard) { const range = document.createRange(); range.selectNodeContents(e); const sel = window.getSelection(); sel === null || sel === void 0 ? void 0 : sel.removeAllRanges(); sel === null || sel === void 0 ? void 0 : sel.addRange(range); keyboard.preventDefault = true; }