Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pickle-ts

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pickle-ts - npm Package Compare versions

Comparing version 0.9.8 to 1.0.0

9

dist/component.d.ts
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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc