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

@uwdata/mosaic-inputs

Package Overview
Dependencies
Maintainers
2
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@uwdata/mosaic-inputs - npm Package Compare versions

Comparing version 0.8.0 to 0.9.0

8

package.json
{
"name": "@uwdata/mosaic-inputs",
"version": "0.8.0",
"version": "0.9.0",
"description": "Mosaic input components.",

@@ -28,7 +28,7 @@ "keywords": [

"dependencies": {
"@uwdata/mosaic-core": "^0.8.0",
"@uwdata/mosaic-sql": "^0.8.0",
"@uwdata/mosaic-core": "^0.9.0",
"@uwdata/mosaic-sql": "^0.9.0",
"isoformat": "^0.2.1"
},
"gitHead": "a24b4c9f7dfa1c38c6af96ec17e075326c1af9b0"
"gitHead": "89bb9b0dfa747aed691eaeba35379525a6764c61"
}

@@ -1,3 +0,3 @@

import { MosaicClient, isParam, isSelection } from '@uwdata/mosaic-core';
import { Query, eq, literal } from '@uwdata/mosaic-sql';
import { MosaicClient, Param, isParam, isSelection, point } from '@uwdata/mosaic-core';
import { Query } from '@uwdata/mosaic-sql';
import { input } from './input.js';

@@ -13,4 +13,27 @@

/**
* Create a new Menu instance.
* @param {object} options Options object
* Create a new menu input.
* @param {object} [options] Options object
* @param {HTMLElement} [options.element] The parent DOM element in which to
* place the menu elements. If undefined, a new `div` element is created.
* @param {Selection} [options.filterBy] A selection to filter the database
* table indicated by the *from* option.
* @param {Param} [options.as] The output param or selection. A selection
* clause is added for the currently selected menu option.
* @param {string} [options.field] The database column name to use within
* generated selection clause predicates. Defaults to the *column* option.
* @param {(any | { value: any, label?: string })[]} [options.options] An
* array of menu options, as literal values or option objects. Option
* objects have a `value` property and an optional `label` property. If no
* label or *format* function is provided, the string-coerced value is used.
* @param {(value: any) => string} [options.format] A format function that
* takes an option value as input and generates a string label. The format
* function is not applied when an explicit label is provided in an option
* object.
* @param {*} [options.value] The initial selected menu value.
* @param {string} [options.from] The name of a database table to use as a data
* source for this widget. Used in conjunction with the *column* option.
* @param {string} [options.column] The name of a database column from which
* to pull menu options. The unique column values are used as menu options.
* Used in conjunction with the *from* option.
* @param {string} [options.label] A text label for this input.
*/

@@ -26,2 +49,3 @@ constructor({

value,
field = column,
as

@@ -32,8 +56,9 @@ } = {}) {

this.column = column;
this.selection = as;
this.format = format;
this.field = field;
const selection = this.selection = as;
this.element = element ?? document.createElement('div');
this.element.setAttribute('class', 'input');
this.element.value = this;
Object.defineProperty(this.element, 'value', { value: this });

@@ -45,15 +70,29 @@ const lab = document.createElement('label');

this.select = document.createElement('select');
this.element.appendChild(this.select);
// if provided, populate menu options
if (options) {
this.data = options.map(value => isObject(value) ? value : { value });
this.selectedValue(value ?? '');
this.update();
}
value = value ?? this.selection?.value ?? this.data?.[0]?.value;
if (this.selection?.value === undefined) this.publish(value);
this.element.appendChild(this.select);
if (this.selection) {
// initialize selection or param bindings
if (selection) {
const isParam = !isSelection(selection);
// publish any initial menu value to the selection/param
// later updates propagate this back to the menu element
// do not publish if using a param that already has a value
if (value != null && (!isParam || selection.value === undefined)) {
this.publish(value);
}
// publish selected value upon menu change
this.select.addEventListener('input', () => {
this.publish(this.selectedValue() ?? null);
});
if (!isSelection(this.selection)) {
// if bound to a scalar param, respond to value updates
if (isParam) {
this.selection.addEventListener('value', value => {

@@ -87,10 +126,7 @@ if (value !== this.select.value) {

publish(value) {
const { selection, column } = this;
const { selection, field } = this;
if (isSelection(selection)) {
selection.update({
source: this,
schema: { type: 'point' },
value,
predicate: (value !== '' && value !== undefined) ? eq(column, literal(value)) : null
});
if (value === '') value = undefined; // 'All' option
const clause = point(field, value, { source: this });
selection.update(clause);
} else if (isParam(selection)) {

@@ -113,2 +149,3 @@ selection.update(value);

queryResult(data) {
// column option values, with an inserted 'All' value
this.data = [{ value: '', label: 'All' }, ...data];

@@ -119,3 +156,5 @@ return this;

update() {
const { data, format, select } = this;
const { data, format, select, selection } = this;
// generate menu item options
select.replaceChildren();

@@ -128,7 +167,13 @@ for (const { value, label } of data) {

}
if (this.selection) {
this.selectedValue(this.selection?.value ?? '');
// update menu value based on param/selection
if (selection) {
const value = isSelection(selection)
? selection.valueFor(this)
: selection.value;
this.selectedValue(value ?? '');
}
return this;
}
}

@@ -1,8 +0,5 @@

import { MosaicClient, isParam, isSelection } from '@uwdata/mosaic-core';
import {
Query, regexp_matches, contains, prefix, suffix, literal
} from '@uwdata/mosaic-sql';
import { MosaicClient, Param, isParam, isSelection, match } from '@uwdata/mosaic-core';
import { Query } from '@uwdata/mosaic-sql';
import { input } from './input.js';
const FUNCTIONS = { contains, prefix, suffix, regexp: regexp_matches };
let _id = 0;

@@ -14,4 +11,25 @@

/**
* Create a new Search instance.
* @param {object} options Options object
* Create a new text search input.
* @param {object} [options] Options object
* @param {HTMLElement} [options.element] The parent DOM element in which to
* place the search elements. If undefined, a new `div` element is created.
* @param {Selection} [options.filterBy] A selection to filter the database
* table indicated by the *from* option.
* @param {Param} [options.as] The output param or selection. A selection
* clause is added based on the current text search query.
* @param {string} [options.field] The database column name to use within
* generated selection clause predicates. Defaults to the *column* option.
* @param {'contains' | 'prefix' | 'suffix' | 'regexp'} [options.type] The
* type of text search query to perform. One of:
* - `"contains"` (default): the query string may appear anywhere in the text
* - `"prefix"`: the query string must appear at the start of the text
* - `"suffix"`: the query string must appear at the end of the text
* - `"regexp"`: the query string is a regular expression the text must match
* @param {string} [options.from] The name of a database table to use as an
* autocomplete data source for this widget. Used in conjunction with the
* *column* option.
* @param {string} [options.column] The name of a database column from which
* to pull valid search results. The unique column values are used as search
* autocomplete values. Used in conjunction with the *from* option.
* @param {string} [options.label] A text label for this input.
*/

@@ -25,2 +43,3 @@ constructor({

type = 'contains',
field = column,
as

@@ -34,6 +53,7 @@ } = {}) {

this.selection = as;
this.field = field;
this.element = element ?? document.createElement('div');
this.element.setAttribute('class', 'input');
this.element.value = this;
Object.defineProperty(this.element, 'value', { value: this });

@@ -72,10 +92,6 @@ if (label) {

publish(value) {
const { selection, column, type } = this;
const { selection, field, type } = this;
if (isSelection(selection)) {
selection.update({
source: this,
schema: { type },
value,
predicate: value ? FUNCTIONS[type](column, literal(value)) : null
});
const clause = match(field, value, { source: this, method: type });
selection.update(clause);
} else if (isParam(selection)) {

@@ -82,0 +98,0 @@ selection.update(value);

@@ -1,3 +0,3 @@

import { MosaicClient, isParam, isSelection } from '@uwdata/mosaic-core';
import { Query, eq, literal, max, min } from '@uwdata/mosaic-sql';
import { MosaicClient, Param, interval, isParam, isSelection, point } from '@uwdata/mosaic-core';
import { Query, max, min } from '@uwdata/mosaic-sql';
import { input } from './input.js';

@@ -11,4 +11,30 @@

/**
* Create a new Slider instance.
* @param {object} options Options object
* Create a new slider input.
* @param {object} [options] Options object
* @param {HTMLElement} [options.element] The parent DOM element in which to
* place the slider elements. If undefined, a new `div` element is created.
* @param {Selection} [options.filterBy] A selection to filter the database
* table indicated by the *from* option.
* @param {Param} [options.as] The output param or selection. A selection
* clause is added based on the currently selected slider option.
* @param {string} [options.field] The database column name to use within
* generated selection clause predicates. Defaults to the *column* option.
* @param {'point' | 'interval'} [options.select] The type of selection clause
* predicate to generate if the **as** option is a Selection. If `'point'`
* (the default), the selection predicate is an equality check for the slider
* value. If `'interval'`, the predicate checks an interval from the minimum
* to the current slider value.
* @param {number} [options.min] The minimum slider value.
* @param {number} [options.max] The maximum slider value.
* @param {number} [options.step] The slider step, the amount to increment
* between consecutive values.
* @param {number} [options.value] The initial slider value.
* @param {string} [options.from] The name of a database table to use as a data
* source for this widget. Used in conjunction with the *column* option.
* The minimum and maximum values of the column determine the slider range.
* @param {string} [options.column] The name of a database column whose values
* determine the slider range. Used in conjunction with the *from* option.
* The minimum and maximum values of the column determine the slider range.
* @param {string} [options.label] A text label for this input.
* @param {number} [options.width] The width of the slider in screen pixels.
*/

@@ -26,2 +52,4 @@ constructor({

value = as?.value,
select = 'point',
field = column,
width

@@ -34,2 +62,4 @@ } = {}) {

this.selection = as;
this.selectionType = select;
this.field = field;
this.min = min;

@@ -41,9 +71,9 @@ this.max = max;

this.element.setAttribute('class', 'input');
this.element.value = this;
Object.defineProperty(this.element, 'value', { value: this });
if (label) {
const lab = document.createElement('label');
lab.setAttribute('for', this.id);
lab.innerText = label;
this.element.appendChild(lab);
const desc = document.createElement('label');
desc.setAttribute('for', this.id);
desc.innerText = label;
this.element.appendChild(desc);
}

@@ -55,22 +85,34 @@

if (width != null) this.slider.style.width = `${+width}px`;
if (min != null) this.slider.setAttribute('min', min);
if (max != null) this.slider.setAttribute('max', max);
if (step != null) this.slider.setAttribute('step', step);
if (min != null) this.slider.setAttribute('min', `${min}`);
if (max != null) this.slider.setAttribute('max', `${max}`);
if (step != null) this.slider.setAttribute('step', `${step}`);
this.element.appendChild(this.slider);
this.curval = document.createElement('label');
this.curval.setAttribute('for', this.id);
this.curval.setAttribute('class', 'value');
this.element.appendChild(this.curval);
// handle initial value
if (value != null) {
this.slider.setAttribute('value', value);
this.slider.setAttribute('value', `${value}`);
if (this.selection?.value === undefined) this.publish(value);
}
this.element.appendChild(this.slider);
this.curval.innerText = this.slider.value;
if (this.selection) {
this.slider.addEventListener('input', () => {
this.publish(+this.slider.value);
// respond to slider input
this.slider.addEventListener('input', () => {
const { value } = this.slider;
this.curval.innerText = value;
if (this.selection) this.publish(+value);
});
// track param updates
if (this.selection && !isSelection(this.selection)) {
this.selection.addEventListener('value', value => {
if (value !== +this.slider.value) {
this.slider.value = value;
this.curval.innerText = value;
}
});
if (!isSelection(this.selection)) {
this.selection.addEventListener('value', value => {
if (value !== +this.slider.value) {
this.slider.value = value;
}
});
}
}

@@ -90,5 +132,14 @@ }

const { min, max } = Array.from(data)[0];
if (this.min == null) this.slider.setAttribute('min', min);
if (this.max == null) this.slider.setAttribute('max', max);
if (this.step == null) this.slider.setAttribute('step', String((max - min) / 500));
if (this.min == null) {
this.min = min;
this.slider.setAttribute('min', `${min}`);
}
if (this.max == null) {
this.max = max;
this.slider.setAttribute('max', `${max}`);
}
if (this.step == null) {
this.step = (max - min) / 500;
this.slider.setAttribute('step', `${this.step}`);
}
return this;

@@ -98,10 +149,16 @@ }

publish(value) {
const { selection, column } = this;
const { field, selectionType, selection } = this;
if (isSelection(selection)) {
selection.update({
source: this,
schema: { type: 'point' },
value,
predicate: eq(column, literal(value))
});
if (selectionType === 'interval') {
/** @type {[number, number]} */
const domain = [this.min ?? 0, value];
selection.update(interval(field, domain, {
source: this,
bin: 'ceil',
scale: { type: 'identity', domain },
pixelSize: this.step
}));
} else {
selection.update(point(field, value, { source: this }));
}
} else if (isParam(this.selection)) {

@@ -108,0 +165,0 @@ selection.update(value);

@@ -45,3 +45,3 @@ import { MosaicClient, coordinator } from '@uwdata/mosaic-core';

this.element.setAttribute('id', this.id);
this.element.value = this;
Object.defineProperty(this.element, 'value', { value: this });
if (typeof width === 'number') this.element.style.width = `${width}px`;

@@ -48,0 +48,0 @@ if (maxWidth) this.element.style.maxWidth = `${maxWidth}px`;

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

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