Comparing version 0.9.8 to 1.0.0
import { App } from './app'; | ||
import { VElement } from './dom'; | ||
import { KeyValue } from './util'; | ||
export declare abstract class Component { | ||
@@ -24,4 +23,2 @@ /** The app associated with the component; undefined if not yet attached - use judiciously - main purpose is internal use by update method */ | ||
update(updater: () => void, payload?: any): void; | ||
/** A convenient shortcut to update a component property; wraps property change in update */ | ||
updateProperty(payload: KeyValue): void; | ||
root(): Component; | ||
@@ -44,4 +41,6 @@ /** Returns the branch, inclusively from this component to the root component */ | ||
initDecorators(): void; | ||
/** Returns properties not marked with the `isSystemProperty()` decorator. */ | ||
properties(): string[]; | ||
/** Returns properties not marked with the `@NonData()` decorator. Think of it like a customizable Object.getKeys method, | ||
* where you can black-list properties that aren't part of your domain. The properties on the Component base class are | ||
* marked with @NonData(). @NonData() is often used in conjuction with @Exclude() */ | ||
dataKeys(): string[]; | ||
} |
@@ -66,9 +66,2 @@ "use strict"; | ||
}; | ||
/** A convenient shortcut to update a component property; wraps property change in update */ | ||
Component.prototype.updateProperty = function (payload) { | ||
var _this = this; | ||
this.update(function () { | ||
return _this[payload.key] = util_1.parseTyped(payload.value, _this[payload.key]); | ||
}, payload); | ||
}; | ||
/* Returns the root component by recursively walking through each parent */ | ||
@@ -123,6 +116,4 @@ Component.prototype.root = function () { | ||
} | ||
if (detached) { | ||
util_1.ensureFieldsNums(this); | ||
if (detached) | ||
this.attached(deserialize); | ||
} | ||
}; | ||
@@ -155,9 +146,11 @@ /** internal use only */ | ||
}; | ||
/** Returns properties not marked with the `isSystemProperty()` decorator. */ | ||
Component.prototype.properties = function () { | ||
/** Returns properties not marked with the `@NonData()` decorator. Think of it like a customizable Object.getKeys method, | ||
* where you can black-list properties that aren't part of your domain. The properties on the Component base class are | ||
* marked with @NonData(). @NonData() is often used in conjuction with @Exclude() */ | ||
Component.prototype.dataKeys = function () { | ||
var _this = this; | ||
return Object.keys(this).filter(function (k) { return !util_1.isSystemProperty(_this, k); }); | ||
return Object.keys(this).filter(function (k) { return !util_1.isNonData(_this, k); }); | ||
}; | ||
__decorate([ | ||
util_1.IsSystemProperty(), class_transformer_1.Exclude(), | ||
util_1.NonData(), class_transformer_1.Exclude(), | ||
__metadata("design:type", app_1.App | ||
@@ -168,7 +161,7 @@ /** The parent component; undefined if the root component - use judiciously - main purpose is internal use by update method */ | ||
__decorate([ | ||
util_1.IsSystemProperty(), class_transformer_1.Exclude(), | ||
util_1.NonData(), class_transformer_1.Exclude(), | ||
__metadata("design:type", Component) | ||
], Component.prototype, "parent", void 0); | ||
__decorate([ | ||
util_1.IsSystemProperty(), class_transformer_1.Exclude(), | ||
util_1.NonData(), class_transformer_1.Exclude(), | ||
__metadata("design:type", Array) | ||
@@ -175,0 +168,0 @@ ], Component.prototype, "refreshQueue", void 0); |
@@ -8,4 +8,4 @@ export { Component } from './component'; | ||
export { VElement, VNode, VAttributes, VLifecycle, isVElement, createVElement, merge } from './dom'; | ||
export { literal, KeyValue, isNullOrEmpty, key, Let, Num, equalsIgnoreCase } from './util'; | ||
export { commandButton, commandLink, inputText, inputValue, slider, radioGroup, selector } from './widgets'; | ||
export { literal, isNullOrEmpty, key, Let, equalsIgnoreCase, isNonData, NonData, parseFloatDeNaN, fuzzyEquals, humanizeIdentifier, Label, getLabel } from './util'; | ||
export { commandLink, inputText, inputNumber, inputValue, inputRange, radioGroup, RadioGroupProps, selector, getPropertyKey, getPropertyValue, PropertyRef, SelectorProps, SelectOption, numberToInputString, inputStringToNumber, InputProps, setPropertyValue, BasicBindableType, checkbox, CheckProps, inputTextArea, getFriendlyName } from './widgets'; | ||
export { h, HValue, HAttributes, HProps, a, abbr, address, area, article, aside, audio, b, bdi, bdo, blockquote, br, button, canvas, caption, cite, code, col, colgroup, data, datalist, dd, del, details, dfn, dialog, div, dl, dt, em, embed, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hr, i, iframe, img, input, ins, kbd, label, legend, li, main, map, mark, menu, menuitem, meter, nav, object, ol, optgroup, option, output, p, param, pre, progress, q, rp, rt, rtc, ruby, s, samp, section, select, small, source, span, strong, sub, summary, sup, svg, table, tbody, td, textarea, tfoot, th, thead, time, tr, track, u, ul, video, vvar, wbr } from './html'; |
@@ -27,12 +27,26 @@ "use strict"; | ||
exports.Let = util_1.Let; | ||
exports.Num = util_1.Num; | ||
exports.equalsIgnoreCase = util_1.equalsIgnoreCase; | ||
exports.isNonData = util_1.isNonData; | ||
exports.NonData = util_1.NonData; | ||
exports.parseFloatDeNaN = util_1.parseFloatDeNaN; | ||
exports.fuzzyEquals = util_1.fuzzyEquals; | ||
exports.humanizeIdentifier = util_1.humanizeIdentifier; | ||
exports.Label = util_1.Label; | ||
exports.getLabel = util_1.getLabel; | ||
var widgets_1 = require("./widgets"); | ||
exports.commandButton = widgets_1.commandButton; | ||
exports.commandLink = widgets_1.commandLink; | ||
exports.inputText = widgets_1.inputText; | ||
exports.inputNumber = widgets_1.inputNumber; | ||
exports.inputValue = widgets_1.inputValue; | ||
exports.slider = widgets_1.slider; | ||
exports.inputRange = widgets_1.inputRange; | ||
exports.radioGroup = widgets_1.radioGroup; | ||
exports.selector = widgets_1.selector; | ||
exports.getPropertyKey = widgets_1.getPropertyKey; | ||
exports.getPropertyValue = widgets_1.getPropertyValue; | ||
exports.numberToInputString = widgets_1.numberToInputString; | ||
exports.inputStringToNumber = widgets_1.inputStringToNumber; | ||
exports.setPropertyValue = widgets_1.setPropertyValue; | ||
exports.checkbox = widgets_1.checkbox; | ||
exports.inputTextArea = widgets_1.inputTextArea; | ||
exports.getFriendlyName = widgets_1.getFriendlyName; | ||
var html_1 = require("./html"); | ||
@@ -39,0 +53,0 @@ exports.h = html_1.h; |
import 'reflect-metadata'; | ||
export declare type KeyValue = { | ||
key: string; | ||
value?: string; | ||
}; | ||
export declare type PropertyName = string | (() => any); | ||
export declare function propertyName(name: PropertyName): string; | ||
export declare function key(propertyAccess: () => any): string; | ||
export declare function equalsIgnoreCase(a: string, b: string): boolean; | ||
export declare function fuzzyEquals(x: any, y: any): boolean; | ||
export declare const parseFloatDeNaN: (s: string) => number | undefined; | ||
export declare function literal(html: string): (element: Element) => void; | ||
export declare function parseTyped(s: string | undefined, guideValue: any): string | number | boolean | undefined; | ||
export declare function Let<T, U>(obj: T, op: (x: T) => U): U; | ||
export declare function isNullOrEmpty(s?: string | null): boolean; | ||
export declare function guessPrimitiveType(value: any): "string" | "number" | "undefined" | "null" | "boolean"; | ||
export declare function Num(): { | ||
export declare function NonData(): { | ||
(target: Function): void; | ||
(target: Object, propertyKey: string | symbol): void; | ||
}; | ||
export declare function getNum(target: any, propertyKey: string): any; | ||
export declare function ensureFieldsNums(obj: object): void; | ||
export declare function IsSystemProperty(): { | ||
export declare function isNonData(target: any, propertyKey: string): any; | ||
export declare function Label(s: string): { | ||
(target: Function): void; | ||
(target: Object, propertyKey: string | symbol): void; | ||
}; | ||
export declare function isSystemProperty(target: any, propertyKey: string): any; | ||
export declare function getLabel(target: any, propertyKey: string): string | undefined; | ||
export declare const humanizeIdentifier: (str: string) => string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
require("reflect-metadata"); | ||
function propertyName(name) { | ||
return typeof (name) == "string" ? name : key(name); | ||
} | ||
exports.propertyName = propertyName; | ||
function key(propertyAccess) { | ||
@@ -26,2 +22,5 @@ return ("" + propertyAccess).match(/\.([a-zA-Z_$][0-9a-zA-Z_$]*)[^\.]*$/)[1]; | ||
exports.fuzzyEquals = fuzzyEquals; | ||
exports.parseFloatDeNaN = function (s) { | ||
return Let(parseFloat(s), function (n) { return isNaN(n) ? undefined : n; }); | ||
}; | ||
function literal(html) { | ||
@@ -31,13 +30,2 @@ return function (element) { element.innerHTML = html; }; | ||
exports.literal = literal; | ||
function parseTyped(s, guideValue) { | ||
if (s == null || guideValue == null) | ||
return s; | ||
var type = guessPrimitiveType(guideValue); | ||
if (type == "number") | ||
return parseFloat(s); | ||
if (type == "boolean") | ||
return s == "true"; | ||
return s; | ||
} | ||
exports.parseTyped = parseTyped; | ||
function Let(obj, op) { | ||
@@ -51,42 +39,24 @@ return op(obj); | ||
exports.isNullOrEmpty = isNullOrEmpty; | ||
// needed to work on ie | ||
function guessPrimitiveType(value) { | ||
if (value === undefined) | ||
return "undefined"; | ||
if (value === null) | ||
return "null"; | ||
var type = value.constructor.toString(); | ||
if (type.indexOf("Number") != -1) | ||
return "number"; | ||
if (type.indexOf("Boolean") != -1) | ||
return "boolean"; | ||
return "string"; | ||
function NonData() { | ||
return Reflect.metadata("nonData", true); | ||
} | ||
exports.guessPrimitiveType = guessPrimitiveType; | ||
function Num() { | ||
return Reflect.metadata("num", true); | ||
exports.NonData = NonData; | ||
function isNonData(target, propertyKey) { | ||
return Reflect.getMetadata("nonData", target, propertyKey); | ||
} | ||
exports.Num = Num; | ||
function getNum(target, propertyKey) { | ||
return Reflect.getMetadata("num", target, propertyKey); | ||
exports.isNonData = isNonData; | ||
function Label(s) { | ||
return Reflect.metadata("label", s); | ||
} | ||
exports.getNum = getNum; | ||
function ensureFieldsNums(obj) { | ||
for (var _i = 0, _a = Object.keys(obj); _i < _a.length; _i++) { | ||
var x = _a[_i]; | ||
if (getNum(obj, x)) { | ||
var n = obj[x]; | ||
obj[x] = n == null ? NaN : parseFloat(n); | ||
} | ||
} | ||
exports.Label = Label; | ||
function getLabel(target, propertyKey) { | ||
return Reflect.getMetadata("label", target, propertyKey); | ||
} | ||
exports.ensureFieldsNums = ensureFieldsNums; | ||
function IsSystemProperty() { | ||
return Reflect.metadata("isSystemProperty", true); | ||
} | ||
exports.IsSystemProperty = IsSystemProperty; | ||
function isSystemProperty(target, propertyKey) { | ||
return Reflect.getMetadata("isSystemProperty", target, propertyKey); | ||
} | ||
exports.isSystemProperty = isSystemProperty; | ||
exports.getLabel = getLabel; | ||
exports.humanizeIdentifier = function (str) { | ||
return str | ||
.replace(/[a-z][A-Z]/g, function (x) { return "" + x[0] + " " + x[1]; }) | ||
.replace(/_[a-z]/g, function (x) { return " " + x.slice(1).toUpperCase(); }) | ||
.replace(/^./, function (x) { return x.toUpperCase(); }); | ||
}; | ||
//# sourceMappingURL=util.js.map |
import { Component } from "./component"; | ||
import { ValidationError } from "class-validator"; | ||
import { PropertyRef } from "./widgets"; | ||
export interface IValidated { | ||
@@ -17,4 +18,4 @@ validator: Validator; | ||
validateThenUpdate(payload?: any): Promise<boolean>; | ||
validationError(prop: () => any): ValidationError | undefined; | ||
validationError<T>(prop: PropertyRef<T>): ValidationError | undefined; | ||
} | ||
export declare function isValidated(form: any): form is IValidated; |
@@ -47,5 +47,5 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var util_1 = require("./util"); | ||
var class_validator_1 = require("class-validator"); | ||
var class_transformer_1 = require("class-transformer"); | ||
var widgets_1 = require("./widgets"); | ||
var Validator = /** @class */ (function () { | ||
@@ -131,3 +131,3 @@ function Validator(form) { | ||
return undefined; | ||
var error = this.validationErrors.filter(function (e) { return e.property == util_1.key(prop); }); | ||
var error = this.validationErrors.filter(function (e) { return e.property == widgets_1.getPropertyKey(prop); }); | ||
return error.length == 0 ? undefined : error[0]; | ||
@@ -134,0 +134,0 @@ }; |
import { VElement } from './dom'; | ||
import { HValue } from './html'; | ||
import { KeyValue } from './util'; | ||
export declare function commandButton(click: () => void, ...values: HValue[]): VElement; | ||
export declare function commandLink(click: () => void, ...values: HValue[]): VElement; | ||
export declare function inputValue<T>(propertyAccess: () => any, inputAction: (propertyChange: KeyValue) => any, inputStringToValue: (s: string, prevValue: T) => T, valueToInputString: (value: T, prevInputString: string) => string, ...values: HValue[]): VElement; | ||
export declare function inputText(propertyAccess: () => any, inputAction: (propertyChange: KeyValue) => any, ...values: HValue[]): VElement; | ||
export declare function inputStringToNumber(s: string, prevNumber: number): number; | ||
export declare function numberToInputString(n: number, prevInputString: string): string; | ||
export declare function handlePropertyChange(propertyAccess: () => any, action: (propertyChange: KeyValue) => void): (e: Event) => void; | ||
export declare function slider(propertyAccess: () => any, min: number, max: number, step: number, slideAction: (propertyChange: KeyValue) => any, ...values: HValue[]): VElement; | ||
export declare function selector(propertyAccess: () => any, options: string[][] | undefined, hasEmpty: boolean | undefined, selectAction: (propertyChange: KeyValue) => any, ...values: HValue[]): VElement; | ||
export declare function radioGroup(propertyAccess: () => any, options: string[][] | undefined, checkedAction: (propertyChange: KeyValue) => any): VElement[]; | ||
import { HValue, HProps } from './html'; | ||
import { Component } from './component'; | ||
export declare type PropertyRef<T> = string | (() => T); | ||
export declare type BasicBindableType = string | number | undefined; | ||
export declare function commandLink(...values: HValue[]): VElement; | ||
export declare type InputValueProps<T> = { | ||
inputStringToModel: (inputString: string, prevModel: T) => T; | ||
modelToInputString: (model: T, prevInputString: string) => string; | ||
}; | ||
export declare const getPropertyKey: <T>(prop: PropertyRef<T>) => string; | ||
export declare const getPropertyValue: <T>(component: Component, prop: PropertyRef<T>) => any; | ||
export declare const setPropertyValue: <T>(component: Component, prop: PropertyRef<T>, value: T) => void; | ||
export declare const typeify: <T extends BasicBindableType>(guideValue: any, strValue: string) => T; | ||
export declare const getFriendlyName: <T>(obj: any, prop: PropertyRef<T>) => string; | ||
export declare function inputValue<T extends BasicBindableType>(component: Component, prop: PropertyRef<T>, props: InputValueProps<T>, ...values: HValue[]): VElement; | ||
/** Currently empty but here for future proofing */ | ||
export declare type InputProps = {}; | ||
export declare function inputText(component: Component, prop: PropertyRef<string | undefined>, options: InputProps, ...values: HValue[]): VElement; | ||
export declare function inputNumber(component: Component, prop: PropertyRef<number | undefined>, options: InputProps, ...values: HValue[]): VElement; | ||
export declare function inputStringToNumber(s: string, prevNumber: number | undefined): number | undefined; | ||
export declare function numberToInputString(n: number | undefined, prevInputString: string): string; | ||
/** Currently empty but here for future proofing */ | ||
export declare type InputRangeProps = {}; | ||
export declare function inputRange(component: Component, prop: PropertyRef<number>, props: InputRangeProps, ...values: HValue[]): VElement; | ||
export declare type SelectorProps = { | ||
attrs?: HProps; | ||
hasEmpty?: boolean; | ||
}; | ||
export interface SelectOption<T> { | ||
value: T; | ||
label: HValue; | ||
disabled?: boolean; | ||
} | ||
export declare function selector<T extends BasicBindableType>(component: Component, prop: PropertyRef<T>, options: SelectOption<T>[] | undefined, props: SelectorProps): VElement; | ||
export interface RadioOption<T> extends SelectOption<T> { | ||
extraItem?: HValue; | ||
} | ||
export declare type RadioGroupProps = { | ||
attrs?: HProps; | ||
optionAttrs?: HProps; | ||
inputAttrs?: HProps; | ||
labelAttrs?: HProps; | ||
prefix?: string; | ||
}; | ||
export declare function radioGroup<T extends BasicBindableType>(component: Component, prop: PropertyRef<T>, options?: RadioOption<T>[], props?: RadioGroupProps): VElement; | ||
export declare function checkbox(component: Component, prop: PropertyRef<boolean | undefined>, props?: CheckProps): VElement; | ||
export declare type CheckProps = { | ||
attrs?: HProps; | ||
labelAttrs?: HProps; | ||
inputAttrs?: HProps; | ||
label?: HValue; | ||
groupName?: string; | ||
}; | ||
export declare function inputTextArea(component: Component, prop: PropertyRef<string>, props: InputProps, ...values: HValue[]): VElement; |
@@ -5,71 +5,77 @@ "use strict"; | ||
var util_1 = require("./util"); | ||
function commandButton(click) { | ||
function commandLink() { | ||
var values = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
values[_i - 1] = arguments[_i]; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
values[_i] = arguments[_i]; | ||
} | ||
return html_1.button.apply(void 0, [{ | ||
onclick: function (e) { return click(); } | ||
}].concat(values)); | ||
return html_1.a.apply(void 0, [{ href: "javascript:;" }].concat(values)); | ||
} | ||
exports.commandButton = commandButton; | ||
function commandLink(click) { | ||
var values = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
values[_i - 1] = arguments[_i]; | ||
} | ||
return html_1.a.apply(void 0, [{ | ||
onclick: function (e) { return click(); }, | ||
href: "javascript:;" | ||
}].concat(values)); | ||
} | ||
exports.commandLink = commandLink; | ||
function inputValue(propertyAccess, inputAction, inputStringToValue, valueToInputString) { | ||
exports.getPropertyKey = function (prop) { | ||
return typeof (prop) == "string" ? prop : util_1.key(prop); | ||
}; | ||
exports.getPropertyValue = function (component, prop) { | ||
return component[exports.getPropertyKey(prop)]; | ||
}; | ||
exports.setPropertyValue = function (component, prop, value) { | ||
var key = exports.getPropertyKey(prop); | ||
component.update(function () { | ||
component[key] = value; | ||
}, { key: key, value: value }); | ||
}; | ||
exports.typeify = function (guideValue, strValue) { | ||
return (typeof (guideValue) == "number" ? util_1.parseFloatDeNaN(strValue) : strValue); | ||
}; | ||
exports.getFriendlyName = function (obj, prop) { | ||
var k = exports.getPropertyKey(prop); | ||
return util_1.getLabel(obj, k) || util_1.humanizeIdentifier(k); | ||
}; | ||
function inputValue(component, prop, props) { | ||
var values = []; | ||
for (var _i = 4; _i < arguments.length; _i++) { | ||
values[_i - 4] = arguments[_i]; | ||
for (var _i = 3; _i < arguments.length; _i++) { | ||
values[_i - 3] = arguments[_i]; | ||
} | ||
var handler = handlePropertyChange(propertyAccess, function (e) { | ||
return inputAction({ | ||
key: e.key, | ||
value: "" + inputStringToValue(e.value || "", propertyAccess()) | ||
}); | ||
}); | ||
return html_1.input.apply(void 0, [{ | ||
value: valueToInputString(propertyAccess(), ""), | ||
oninput: handler, | ||
onchange: handler, | ||
onUpdated: function (el) { return el.value = valueToInputString(propertyAccess(), el.value); } | ||
value: props.modelToInputString(exports.getPropertyValue(component, prop), ""), | ||
oninput: function (e) { | ||
return exports.setPropertyValue(component, prop, props.inputStringToModel(e.target.value, exports.getPropertyValue(component, prop))); | ||
}, | ||
onUpdated: function (el) { | ||
return el.value = props.modelToInputString(exports.getPropertyValue(component, prop), el.value); | ||
} | ||
}].concat(values)); | ||
} | ||
exports.inputValue = inputValue; | ||
function inputText(propertyAccess, inputAction) { | ||
function inputText(component, prop, options) { | ||
var values = []; | ||
for (var _i = 2; _i < arguments.length; _i++) { | ||
values[_i - 2] = arguments[_i]; | ||
for (var _i = 3; _i < arguments.length; _i++) { | ||
values[_i - 3] = arguments[_i]; | ||
} | ||
if (util_1.guessPrimitiveType(propertyAccess()) == "number") | ||
return inputNumber.apply(void 0, [propertyAccess, inputAction].concat(values)); | ||
return inputValue.apply(void 0, [propertyAccess, | ||
inputAction, | ||
function (s) { return s; }, | ||
function (s, prevS) { return s || ""; }].concat(values)); | ||
return inputValue.apply(void 0, [component, | ||
prop, | ||
{ | ||
inputStringToModel: function (s) { return s; }, | ||
modelToInputString: function (s, prevS) { return s || ""; }, | ||
}].concat(values)); | ||
} | ||
exports.inputText = inputText; | ||
function inputNumber(propertyAccess, inputAction) { | ||
function inputNumber(component, prop, options) { | ||
var values = []; | ||
for (var _i = 2; _i < arguments.length; _i++) { | ||
values[_i - 2] = arguments[_i]; | ||
for (var _i = 3; _i < arguments.length; _i++) { | ||
values[_i - 3] = arguments[_i]; | ||
} | ||
return inputValue.apply(void 0, [propertyAccess, | ||
inputAction, | ||
inputStringToNumber, | ||
numberToInputString].concat(values)); | ||
return inputValue.apply(void 0, [component, | ||
prop, | ||
{ | ||
inputStringToModel: inputStringToNumber, | ||
modelToInputString: numberToInputString | ||
}].concat(values)); | ||
} | ||
exports.inputNumber = inputNumber; | ||
function inputStringToNumber(s, prevNumber) { | ||
return parseFloat(s); | ||
return util_1.parseFloatDeNaN(s); | ||
} | ||
exports.inputStringToNumber = inputStringToNumber; | ||
function numberToInputString(n, prevInputString) { | ||
if ("" + n == "NaN") { | ||
if ("" + n == "NaN" || n == null) { | ||
if (new RegExp("^[+-.]$").test(prevInputString)) | ||
@@ -84,36 +90,23 @@ return prevInputString; | ||
exports.numberToInputString = numberToInputString; | ||
function handlePropertyChange(propertyAccess, action) { | ||
return function (e) { return action({ | ||
key: util_1.key(propertyAccess), | ||
value: e.target.value | ||
}); }; | ||
} | ||
exports.handlePropertyChange = handlePropertyChange; | ||
function slider(propertyAccess, min, max, step, slideAction) { | ||
function inputRange(component, prop, props) { | ||
var values = []; | ||
for (var _i = 5; _i < arguments.length; _i++) { | ||
values[_i - 5] = arguments[_i]; | ||
for (var _i = 3; _i < arguments.length; _i++) { | ||
values[_i - 3] = arguments[_i]; | ||
} | ||
var handler = handlePropertyChange(propertyAccess, slideAction); | ||
var onchange = function (e) { return exports.setPropertyValue(component, prop, util_1.parseFloatDeNaN(e.target.value)); }; | ||
return html_1.input.apply(void 0, [{ | ||
type: "range", | ||
min: min, | ||
max: max, | ||
value: propertyAccess(), | ||
oninput: handler, | ||
onchange: handler, | ||
step: step | ||
value: exports.getPropertyValue(component, prop), | ||
oninput: onchange, | ||
onchange: onchange, | ||
onUpdated: function (el) { el.value = exports.getPropertyValue(component, prop); } | ||
}].concat(values)); | ||
} | ||
exports.slider = slider; | ||
function selector(propertyAccess, options, hasEmpty, selectAction) { | ||
exports.inputRange = inputRange; | ||
function selector(component, prop, options, props) { | ||
if (options === void 0) { options = []; } | ||
if (hasEmpty === void 0) { hasEmpty = false; } | ||
var values = []; | ||
for (var _i = 4; _i < arguments.length; _i++) { | ||
values[_i - 4] = arguments[_i]; | ||
} | ||
var value = propertyAccess(); | ||
var allOptions = !hasEmpty ? options : [["", ""]].concat(options); | ||
var id = util_1.key(propertyAccess); | ||
var value = exports.getPropertyValue(component, prop); | ||
var allOptions = !props.hasEmpty ? options : [{ value: undefined, label: "", disabled: false }].concat(options); | ||
var id = exports.getPropertyKey(prop); | ||
var guideValue = !options.length ? undefined : options[options.length - 1].value; | ||
return (html_1.select.apply(void 0, [{ | ||
@@ -123,27 +116,62 @@ type: "select", | ||
id: id, | ||
onchange: handlePropertyChange(propertyAccess, selectAction) | ||
}].concat(values, allOptions.map(function (pair) { | ||
onchange: function (e) { return exports.setPropertyValue(component, prop, exports.typeify(guideValue, e.target.value)); } | ||
}, | ||
props.attrs].concat(allOptions.map(function (so) { | ||
return html_1.option({ | ||
value: pair[0], | ||
selected: util_1.fuzzyEquals(pair[0], value) ? "selected" : undefined | ||
}, pair[1]); | ||
value: so.value, | ||
selected: util_1.fuzzyEquals(so.value, value) ? "selected" : undefined, | ||
disabled: so.disabled ? "disabled" : undefined | ||
}, so.label); | ||
})))); | ||
} | ||
exports.selector = selector; | ||
function radioGroup(propertyAccess, options, checkedAction) { | ||
function radioGroup(component, prop, options, props) { | ||
if (options === void 0) { options = []; } | ||
return options.map(function (pair) { | ||
return html_1.label(html_1.input({ | ||
value: pair[0], | ||
name: util_1.key(propertyAccess), | ||
if (props === void 0) { props = {}; } | ||
var id = (props.prefix || "") + exports.getPropertyKey(prop); | ||
return (html_1.div({ id: id }, props.attrs, options.map(function (option) { | ||
var checked = util_1.fuzzyEquals(option.value, exports.getPropertyValue(component, prop)); | ||
var optionId = id + "-" + option.value; | ||
return html_1.div(props.optionAttrs, html_1.input({ | ||
id: optionId, | ||
value: "" + option.value, | ||
name: id, | ||
type: "radio", | ||
checked: util_1.fuzzyEquals(pair[0], propertyAccess()) ? "checked" : undefined, | ||
onchange: handlePropertyChange(propertyAccess, checkedAction), | ||
onUpdated: function (element, attributes) { | ||
element.checked = element.getAttribute("checked") == "checked"; | ||
checked: checked ? "checked" : undefined, | ||
onchange: function (e) { return exports.setPropertyValue(component, prop, exports.typeify(options[0].value, e.target.value)); }, | ||
onUpdated: function (el) { | ||
el.checked = el.getAttribute("checked") == "checked"; | ||
} | ||
}), pair[1], html_1.br()); | ||
}); | ||
}, props.inputAttrs), html_1.label({ for: optionId }, props.labelAttrs, option.label), option.extraItem); | ||
}))); | ||
} | ||
exports.radioGroup = radioGroup; | ||
function checkbox(component, prop, props) { | ||
if (props === void 0) { props = {}; } | ||
return (html_1.div(props.attrs, html_1.input({ | ||
id: exports.getPropertyKey(prop), | ||
value: "" + exports.getPropertyValue(component, prop), | ||
type: "checkbox", | ||
name: props.groupName || exports.getPropertyKey(prop), | ||
checked: exports.getPropertyValue(component, prop) ? "checked" : undefined, | ||
onchange: function () { | ||
exports.setPropertyValue(component, prop, !exports.getPropertyValue(component, prop)); | ||
}, | ||
onUpdated: function (el) { | ||
el.checked = el.getAttribute("checked") == "checked"; | ||
} | ||
}, props.inputAttrs), html_1.label({ for: exports.getPropertyKey(prop) }, props.labelAttrs, props.label || exports.getFriendlyName(component, prop)))); | ||
} | ||
exports.checkbox = checkbox; | ||
function inputTextArea(component, prop, props) { | ||
var values = []; | ||
for (var _i = 3; _i < arguments.length; _i++) { | ||
values[_i - 3] = arguments[_i]; | ||
} | ||
return html_1.textarea.apply(void 0, [{ | ||
oninput: function (e) { return exports.setPropertyValue(component, prop, (e.target.value)); }, | ||
onUpdated: function (el) { return el.value = exports.getPropertyValue(component, prop); } | ||
}].concat(values, [exports.getPropertyValue(component, prop)])); | ||
} | ||
exports.inputTextArea = inputTextArea; | ||
//# sourceMappingURL=widgets.js.map |
{ | ||
"name": "pickle-ts", | ||
"version": "0.9.8", | ||
"version": "1.0.0", | ||
"author": "pickle", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
import { App } from './app'; | ||
import { div } from './html' | ||
import { VElement } from './dom' | ||
import { parseTyped, KeyValue, ensureFieldsNums, IsSystemProperty, isSystemProperty } from './util' | ||
import { NonData, isNonData } from './util' | ||
import { Exclude, Type } from 'class-transformer' | ||
@@ -10,8 +10,8 @@ | ||
/** The app associated with the component; undefined if not yet attached - use judiciously - main purpose is internal use by update method */ | ||
@IsSystemProperty() @Exclude() app?: App | ||
@NonData() @Exclude() app?: App | ||
/** The parent component; undefined if the root component - use judiciously - main purpose is internal use by update method */ | ||
@IsSystemProperty() @Exclude() parent?: Component | ||
@NonData() @Exclude() parent?: Component | ||
@IsSystemProperty() @Exclude() private refreshQueue: Function[] = [] | ||
@NonData() @Exclude() private refreshQueue: Function[] = [] | ||
@@ -68,10 +68,2 @@ /** Called after construction, with a flag indicating if deserialization occured */ | ||
/** A convenient shortcut to update a component property; wraps property change in update */ | ||
updateProperty (payload: KeyValue) { | ||
this.update (() => | ||
this[payload.key] = parseTyped (payload.value, this[payload.key]), | ||
payload | ||
) | ||
} | ||
/* Returns the root component by recursively walking through each parent */ | ||
@@ -127,6 +119,4 @@ root() : Component { | ||
if (detached) { | ||
ensureFieldsNums (this) | ||
this.attached (deserialize) | ||
} | ||
if (detached) | ||
this.attached (deserialize) | ||
} | ||
@@ -156,6 +146,8 @@ | ||
/** Returns properties not marked with the `isSystemProperty()` decorator. */ | ||
properties() { | ||
return Object.keys (this).filter(k => ! isSystemProperty (this, k)) | ||
/** Returns properties not marked with the `@NonData()` decorator. Think of it like a customizable Object.getKeys method, | ||
* where you can black-list properties that aren't part of your domain. The properties on the Component base class are | ||
* marked with @NonData(). @NonData() is often used in conjuction with @Exclude() */ | ||
dataKeys() { | ||
return Object.keys (this).filter(k => ! isNonData (this, k)) | ||
} | ||
} |
@@ -8,4 +8,6 @@ export { Component } from './component' | ||
export { VElement, VNode, VAttributes, VLifecycle, isVElement, createVElement, merge } from './dom' | ||
export { literal, KeyValue, isNullOrEmpty, key, Let, Num, equalsIgnoreCase } from './util' | ||
export { commandButton, commandLink, inputText, inputValue, slider, radioGroup, selector } from './widgets' | ||
export { literal, isNullOrEmpty, key, Let, equalsIgnoreCase, isNonData, NonData, parseFloatDeNaN, fuzzyEquals, humanizeIdentifier, Label, getLabel } from './util' | ||
export { commandLink, inputText, inputNumber, inputValue, inputRange, radioGroup, RadioGroupProps, selector, | ||
getPropertyKey, getPropertyValue, PropertyRef, SelectorProps, SelectOption, numberToInputString, inputStringToNumber, | ||
InputProps, setPropertyValue, BasicBindableType, checkbox, CheckProps, inputTextArea, getFriendlyName } from './widgets' | ||
export { | ||
@@ -12,0 +14,0 @@ h, HValue, HAttributes, HProps, |
import 'reflect-metadata' | ||
import { PropertyRef } from '.'; | ||
import { getPropertyKey } from './widgets'; | ||
export type KeyValue = { | ||
key: string | ||
value?: string | ||
} | ||
export type PropertyName = string | (() => any) | ||
export function propertyName(name: PropertyName) { | ||
return typeof(name) == "string" ? name : key (name) | ||
} | ||
export function key (propertyAccess: () => any) { | ||
@@ -32,2 +23,5 @@ return (""+propertyAccess).match (/\.([a-zA-Z_$][0-9a-zA-Z_$]*)[^\.]*$/)![1] | ||
export const parseFloatDeNaN = (s: string) => | ||
Let (parseFloat (s), n => isNaN (n) ? undefined : n) | ||
export function literal (html: string) { | ||
@@ -37,13 +31,2 @@ return (element: Element) => {element.innerHTML = html} | ||
export function parseTyped (s: string|undefined, guideValue: any) { | ||
if (s == null || guideValue == null) | ||
return s | ||
var type = guessPrimitiveType (guideValue) | ||
if (type == "number") | ||
return parseFloat (s) | ||
if (type == "boolean") | ||
return s == "true" | ||
return s | ||
} | ||
export function Let<T, U>(obj: T, op: (x: T) => U) { | ||
@@ -57,39 +40,22 @@ return op(obj) | ||
// needed to work on ie | ||
export function guessPrimitiveType (value: any) | ||
{ | ||
if (value === undefined) | ||
return "undefined" | ||
if (value === null) | ||
return "null" | ||
var type = value.constructor.toString() | ||
if (type.indexOf ("Number") != -1) | ||
return "number" | ||
if (type.indexOf ("Boolean") != -1) | ||
return "boolean" | ||
return "string" | ||
export function NonData() { | ||
return Reflect.metadata("nonData", true); | ||
} | ||
export function Num() { | ||
return Reflect.metadata("num", true); | ||
export function isNonData(target: any, propertyKey: string) { | ||
return Reflect.getMetadata("nonData", target, propertyKey); | ||
} | ||
export function getNum(target: any, propertyKey: string) { | ||
return Reflect.getMetadata("num", target, propertyKey); | ||
export function Label (s: string) { | ||
return Reflect.metadata("label", s); | ||
} | ||
export function ensureFieldsNums (obj: object) { | ||
for (var x of Object.keys(obj)) | ||
if (getNum(obj, x)) { | ||
const n = obj[x] | ||
obj[x] = n == null ? NaN : parseFloat (n) | ||
} | ||
export function getLabel(target: any, propertyKey: string) { | ||
return Reflect.getMetadata("label", target, propertyKey) as string|undefined | ||
} | ||
export function IsSystemProperty() { | ||
return Reflect.metadata("isSystemProperty", true); | ||
} | ||
export function isSystemProperty(target: any, propertyKey: string) { | ||
return Reflect.getMetadata("isSystemProperty", target, propertyKey); | ||
} | ||
export const humanizeIdentifier = (str: string) => | ||
str | ||
.replace (/[a-z][A-Z]/g, x => "" + x[0] + " " + x[1]) | ||
.replace (/_[a-z]/g, x => " " + x.slice(1).toUpperCase()) | ||
.replace (/^./, x => x.toUpperCase()) |
@@ -5,2 +5,3 @@ import { Component } from "./component" | ||
import { Exclude } from "class-transformer" | ||
import { getPropertyKey, PropertyRef } from "./widgets"; | ||
@@ -65,7 +66,7 @@ export interface IValidated | ||
validationError (prop: () => any) { | ||
validationError<T> (prop: PropertyRef<T>) { | ||
if (! this.validationErrors) | ||
return undefined | ||
const error = this.validationErrors.filter (e => e.property == key(prop)) | ||
const error = this.validationErrors.filter (e => e.property == getPropertyKey(prop)) | ||
return error.length == 0 ? undefined : error[0] | ||
@@ -72,0 +73,0 @@ } |
import { VElement, VAttributes } from './dom' | ||
import { HValue, button, input, select, option, div, label, span, br, a } from './html' | ||
import { KeyValue, key, PropertyName, propertyName, Let, fuzzyEquals, guessPrimitiveType } from './util' | ||
import { HValue, button, input, select, option, div, label, span, br, a, HProps, textarea } from './html' | ||
import { key, Let, fuzzyEquals, parseFloatDeNaN, getLabel, humanizeIdentifier } from './util' | ||
import { Component } from './component' | ||
export function commandButton(click: () => void, ...values: HValue[]) { | ||
return button ( | ||
{ | ||
onclick: (e: Event) => click() | ||
}, | ||
...values | ||
) | ||
export type PropertyRef<T> = string | (() => T) | ||
export type BasicBindableType = string | number | undefined | ||
export function commandLink (...values: HValue[]) { | ||
return a ({ href: "javascript:;"}, ...values) | ||
} | ||
export function commandLink(click: () => void, ...values: HValue[]) { | ||
return a ( | ||
{ | ||
onclick: (e: Event) => click(), | ||
href: "javascript:;" | ||
export type InputValueProps<T> = | ||
{ | ||
inputStringToModel : (inputString: string, prevModel: T) => T, | ||
modelToInputString : (model: T, prevInputString: string) => string, | ||
} | ||
export const getPropertyKey = <T> (prop: PropertyRef<T>) => | ||
typeof (prop) == "string" ? prop: key (prop) | ||
export const getPropertyValue = <T> (component: Component, prop: PropertyRef<T>) => | ||
component [getPropertyKey (prop)] | ||
export const setPropertyValue = <T> (component: Component, prop: PropertyRef<T>, value: T) => | ||
{ | ||
const key = getPropertyKey (prop) | ||
component.update (() => | ||
{ | ||
component [key] = value | ||
}, | ||
...values | ||
{key: key, value: value} | ||
) | ||
} | ||
export function inputValue<T> | ||
export const typeify = <T extends BasicBindableType> (guideValue: any, strValue: string) => | ||
<T><any> (typeof(guideValue) == "number" ? parseFloatDeNaN (strValue) : strValue) | ||
export const getFriendlyName = <T>(obj: any, prop: PropertyRef<T>) => { | ||
const k = getPropertyKey (prop) | ||
return getLabel (obj, k) || humanizeIdentifier (k) | ||
} | ||
export function inputValue<T extends BasicBindableType> | ||
( | ||
propertyAccess: () => any, | ||
inputAction: (propertyChange: KeyValue) => any, | ||
inputStringToValue : (s: string, prevValue: T) => T, | ||
valueToInputString : (value: T, prevInputString: string) => string, | ||
component: Component, | ||
prop: PropertyRef<T>, | ||
props: InputValueProps<T>, | ||
...values: HValue[] | ||
) | ||
{ | ||
var handler = handlePropertyChange(propertyAccess, e => | ||
inputAction ( | ||
return input ( | ||
{ | ||
key : e.key, | ||
value : "" + inputStringToValue (e.value || "", propertyAccess()) | ||
})) | ||
return input( | ||
{ | ||
value: valueToInputString (propertyAccess(), ""), | ||
oninput: handler, | ||
onchange: handler, | ||
onUpdated: (el: HTMLInputElement) => el.value = valueToInputString (propertyAccess(), el.value) | ||
value: props.modelToInputString (getPropertyValue (component, prop), ""), | ||
oninput: e => | ||
setPropertyValue (component, prop, | ||
props.inputStringToModel ( | ||
(<HTMLInputElement>e.target).value, | ||
getPropertyValue (component, prop) | ||
) | ||
), | ||
onUpdated: (el: HTMLInputElement) => | ||
el.value = props.modelToInputString (getPropertyValue (component, prop), el.value) | ||
}, | ||
@@ -51,12 +70,14 @@ ...values | ||
export function inputText (propertyAccess: () => any, inputAction: (propertyChange: KeyValue) => any, ...values: HValue[]) | ||
/** Currently empty but here for future proofing */ | ||
export type InputProps = {} | ||
export function inputText (component: Component, prop: PropertyRef<string|undefined>, options: InputProps, ...values: HValue[]) | ||
{ | ||
if (guessPrimitiveType (propertyAccess()) == "number") | ||
return inputNumber(propertyAccess, inputAction, ...values) | ||
return inputValue<string>( | ||
propertyAccess, | ||
inputAction, | ||
s => s, | ||
(s, prevS) => s || "", | ||
return inputValue<string|undefined>( | ||
component, | ||
prop, | ||
{ | ||
inputStringToModel: s => s, | ||
modelToInputString: (s, prevS) => s || "", | ||
}, | ||
...values | ||
@@ -66,9 +87,11 @@ ) | ||
function inputNumber (propertyAccess: () => any, inputAction: (propertyChange: KeyValue) => any, ...values: HValue[]) | ||
export function inputNumber (component: Component, prop: PropertyRef<number|undefined>, options: InputProps, ...values: HValue[]) | ||
{ | ||
return inputValue<number>( | ||
propertyAccess, | ||
inputAction, | ||
inputStringToNumber, | ||
numberToInputString, | ||
return inputValue<number|undefined>( | ||
component, | ||
prop, | ||
{ | ||
inputStringToModel: inputStringToNumber, | ||
modelToInputString: numberToInputString | ||
}, | ||
...values | ||
@@ -78,8 +101,8 @@ ) | ||
export function inputStringToNumber (s: string, prevNumber: number) : number { | ||
return parseFloat (s) | ||
export function inputStringToNumber (s: string, prevNumber: number|undefined) : number|undefined { | ||
return parseFloatDeNaN (s) | ||
} | ||
export function numberToInputString (n: number, prevInputString: string) : string { | ||
if ("" + n == "NaN") { | ||
export function numberToInputString (n: number|undefined, prevInputString: string) : string { | ||
if ("" + n == "NaN" || n == null) { | ||
if (new RegExp ("^[+-.]$").test (prevInputString)) | ||
@@ -94,21 +117,17 @@ return prevInputString | ||
export function handlePropertyChange (propertyAccess: () => any, action: (propertyChange: KeyValue) => void) { | ||
return (e: Event) => action({ | ||
key : key (propertyAccess), | ||
value: (<HTMLInputElement|HTMLSelectElement>e.target).value | ||
}) | ||
/** Currently empty but here for future proofing */ | ||
export type InputRangeProps = { | ||
} | ||
export function slider (propertyAccess: () => any, min: number, max: number, step: number, slideAction: (propertyChange: KeyValue) => any, ...values: HValue[]) | ||
export function inputRange (component: Component, prop: PropertyRef<number>, props: InputRangeProps, ...values: HValue[]) | ||
{ | ||
var handler = handlePropertyChange (propertyAccess, slideAction) | ||
const onchange = (e: Event) => setPropertyValue (component, prop, parseFloatDeNaN ((<HTMLInputElement>e.target).value)) | ||
return input ( | ||
{ | ||
type: "range", | ||
min: min, | ||
max: max, | ||
value: propertyAccess(), | ||
oninput: handler, | ||
onchange: handler, | ||
step: step | ||
value: getPropertyValue (component, prop), | ||
oninput: onchange, | ||
onchange: onchange, | ||
onUpdated: (el: HTMLInputElement) => { el.value = getPropertyValue (component, prop) } | ||
}, | ||
@@ -119,30 +138,43 @@ ...values | ||
export function selector | ||
export type SelectorProps = { | ||
attrs?: HProps | ||
hasEmpty?: boolean | ||
} | ||
export interface SelectOption<T> { | ||
value: T | ||
label: HValue, | ||
disabled? : boolean | ||
} | ||
export function selector<T extends BasicBindableType> | ||
( | ||
propertyAccess: () => any, | ||
options: string[][] = [], | ||
hasEmpty: boolean = false, | ||
selectAction: (propertyChange: KeyValue) => any, | ||
...values: HValue[] | ||
component: Component, | ||
prop: PropertyRef<T>, | ||
options: SelectOption<T>[] = [], | ||
props: SelectorProps | ||
) | ||
{ | ||
const value = propertyAccess() | ||
const allOptions = ! hasEmpty ? options : [["", ""], ...options] | ||
const id = key (propertyAccess) | ||
const value = getPropertyValue (component, prop) | ||
const allOptions = ! props.hasEmpty ? options : [{value: undefined, label: "", disabled:false}, ...options] | ||
const id = getPropertyKey (prop) | ||
const guideValue = ! options.length ? undefined : options[options.length-1].value | ||
return ( | ||
select ( | ||
{ | ||
select ({ | ||
type: "select", | ||
name : id, | ||
id : id, | ||
onchange: handlePropertyChange (propertyAccess, selectAction) | ||
onchange: e => setPropertyValue (component, prop, | ||
typeify<T> (guideValue, (<any>e.target).value) | ||
) | ||
}, | ||
...values, | ||
...allOptions.map (pair => | ||
props.attrs, | ||
...allOptions.map (so => | ||
option ({ | ||
value: pair[0], | ||
selected: fuzzyEquals (pair[0], value) ? "selected" : undefined | ||
value: so.value, | ||
selected: fuzzyEquals (so.value, value) ? "selected" : undefined, | ||
disabled: so.disabled ? "disabled" : undefined | ||
}, | ||
pair[1] | ||
so.label | ||
) | ||
@@ -154,25 +186,107 @@ ) | ||
export function radioGroup | ||
export interface RadioOption<T> extends SelectOption<T> { | ||
extraItem?: HValue | ||
} | ||
export type RadioGroupProps = | ||
{ | ||
attrs?: HProps, | ||
optionAttrs?: HProps, | ||
inputAttrs?: HProps, | ||
labelAttrs?: HProps, | ||
prefix?: string | ||
} | ||
export function radioGroup<T extends BasicBindableType> | ||
( | ||
propertyAccess: () => any, | ||
options: string[][] = [], | ||
checkedAction: (propertyChange: KeyValue) => any | ||
component: Component, | ||
prop: PropertyRef<T>, | ||
options: RadioOption<T>[] = [], | ||
props: RadioGroupProps = {} | ||
) | ||
{ | ||
return options.map (pair => | ||
label ( | ||
input({ | ||
value: pair[0], | ||
name: key (propertyAccess), | ||
type: "radio", | ||
checked: fuzzyEquals(pair[0], propertyAccess()) ? "checked" : undefined, | ||
onchange: handlePropertyChange (propertyAccess, checkedAction), | ||
onUpdated: (element: HTMLInputElement, attributes?: VAttributes) => { | ||
element.checked = element.getAttribute ("checked") == "checked" | ||
} | ||
}), | ||
pair[1], | ||
br() | ||
const id = (props.prefix || "") + getPropertyKey(prop) | ||
return ( | ||
div ({ id: id }, props.attrs, | ||
options.map(option => { | ||
const checked = fuzzyEquals (option.value, getPropertyValue (component, prop)) | ||
const optionId = id+"-"+option.value | ||
return div ( props.optionAttrs, | ||
input({ | ||
id: optionId, | ||
value: "" + option.value, | ||
name: id, | ||
type: "radio", | ||
checked: checked ? "checked" : undefined, | ||
onchange: e => setPropertyValue (component, prop, | ||
typeify<T> (options[0].value, (<any>e.target).value) | ||
), | ||
onUpdated: el => { | ||
(<HTMLInputElement>el).checked = el.getAttribute ("checked") == "checked" | ||
} | ||
}, | ||
props.inputAttrs | ||
), | ||
label ({ for: optionId }, props.labelAttrs, option.label), | ||
option.extraItem | ||
) | ||
}) | ||
) | ||
) | ||
} | ||
} | ||
export function checkbox | ||
( | ||
component: Component, | ||
prop: PropertyRef<boolean | undefined>, | ||
props: CheckProps = {} | ||
) | ||
{ | ||
return ( | ||
div (props.attrs, | ||
input ( | ||
{ | ||
id: getPropertyKey (prop), | ||
value: "" + getPropertyValue (component, prop), | ||
type: "checkbox", | ||
name: props.groupName || getPropertyKey (prop), | ||
checked: getPropertyValue (component, prop) ? "checked" : undefined, | ||
onchange: () => { | ||
setPropertyValue (component, prop, ! getPropertyValue (component, prop)) | ||
}, | ||
onUpdated: el => { | ||
(<HTMLInputElement>el).checked = el.getAttribute ("checked") == "checked" | ||
} | ||
}, | ||
props.inputAttrs, | ||
), | ||
label ({ for: getPropertyKey (prop) }, props.labelAttrs, props.label || getFriendlyName (component, prop)) | ||
) | ||
) | ||
} | ||
export type CheckProps = { | ||
attrs?: HProps, | ||
labelAttrs?: HProps, | ||
inputAttrs?: HProps, | ||
label?: HValue, | ||
groupName?: string, | ||
} | ||
export function inputTextArea | ||
( | ||
component: Component, | ||
prop: PropertyRef<string>, | ||
props: InputProps, | ||
...values: HValue[] | ||
) | ||
{ | ||
return textarea ( | ||
{ | ||
oninput: e => setPropertyValue (component, prop, ((<HTMLTextAreaElement>e.target).value)), | ||
onUpdated: (el: HTMLInputElement) => el.value = getPropertyValue (component, prop) | ||
}, | ||
...values, | ||
getPropertyValue (component, prop) | ||
) | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
253400
5128
1