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

svelte-formula

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svelte-formula - npm Package Compare versions

Comparing version 0.10.0 to 0.11.0

11

CHANGELOG.md

@@ -8,2 +8,13 @@ # Changelog

## [0.11.0] - 2021-04-13
### Changed
- Types for Formula now provide stronger typing
### Fixed
- Formula now won't apply `aria-role` on items that already have a role set
- Better handling of value and validation updates, store update is called less times
## [0.10.0] - 2021-03-12

@@ -10,0 +21,0 @@

10

index.d.ts

@@ -1,2 +0,2 @@

import { Beaker, BeakerOptions, BeakerStores, Formula, FormulaError, FormulaOptions, FormulaStores } from './types';
import { Beaker, BeakerOptions, BeakerStores, Formula, FormulaError, FormulaOptions, FormulaStores, FormulaValue, FormulaValueDefault } from './types';
export { Beaker, BeakerStores, Formula, FormulaError, FormulaOptions, FormulaStores };

@@ -8,4 +8,4 @@ /**

*/
export declare const formulaStores: any;
export declare const beakerStores: any;
export declare const formulaStores: Map<string, FormulaStores<Record<string, unknown>>>;
export declare const beakerStores: Map<string, BeakerStores<Record<string, unknown>>>;
/**

@@ -21,3 +21,3 @@ * The `formula` function returns a form object that can be bound to any HTML

*/
export declare function formula<T extends Record<string, unknown | unknown[]>>(options?: FormulaOptions): Formula<T>;
export declare function formula<T extends FormulaValue = FormulaValueDefault>(options?: FormulaOptions): Formula<T>;
/**

@@ -31,2 +31,2 @@ * The beaker function returns an instance of a group of elements and their stores, it also provides methods

*/
export declare function beaker<T extends Record<string, unknown | unknown[]>>(options?: BeakerOptions): Beaker<T>;
export declare function beaker<T extends FormulaValue = FormulaValueDefault>(options?: BeakerOptions): Beaker<T>;

@@ -15,6 +15,6 @@ import { FormEl } from '../../types';

* Sets ARIA attributes based on the current value
* @param el
* @param element
* @param elGroup
*/
export declare function setAriaValue(el: FormEl, elGroup: FormEl[]): void;
export declare function setAriaValue(element: FormEl, elGroup: FormEl[]): void;
/**

@@ -26,2 +26,6 @@ * Set the container

export declare function setAriaContainer(container: HTMLElement, isGroup: boolean): void;
/**
* Add the ARIA button role to all buttons contained in the form that don't already have an ARIA role
* @param container
*/
export declare function setAriaButtons(container: HTMLElement): void;

@@ -14,2 +14,2 @@ import { FormEl, FormulaStores } from '../../types';

*/
export declare function createDirtyHandler<T extends Record<string, unknown | unknown[]>>(name: string, elements: FormEl[], stores: FormulaStores<T>): () => void;
export declare function createDirtyHandler(name: string, elements: FormEl[], stores: FormulaStores): () => void;

@@ -1,8 +0,7 @@

import { FormulaOptions } from '../../types';
import { FormulaOptions, FormulaValue, FormulaValueDefault } from '../../types';
/**
* Create an enrichment object for the field
* Creates an enrichment object for the named group,
* @param name
* @param options
*/
export declare function createEnrichField(name: string, options: FormulaOptions): (value: unknown | unknown[]) => Record<string, unknown | unknown[]>;
export declare function createEnrichField<T extends FormulaValue = FormulaValueDefault>(name: string, options: FormulaOptions): (value: unknown) => T;

@@ -1,2 +0,2 @@

import { FormEl, FormulaField, FormulaOptions, FormulaStores } from '../../types';
import { FormEl, FormulaField, FormulaOptions, FormulaStores, FormulaValue, FormulaValueDefault } from '../../types';
/**

@@ -10,3 +10,3 @@ * Update the value and error stores, also update form validity

*/
export declare function valueUpdate<T extends Record<string, unknown | unknown[]>>(details: FormulaField, stores: FormulaStores<T>, options: FormulaOptions, hiddenFields: Map<string, HTMLInputElement[]>, enrich?: (value: unknown | unknown[]) => Record<string, unknown>): void;
export declare function valueUpdate(details: FormulaField, stores: FormulaStores, options: FormulaOptions, hiddenFields: Map<string, HTMLInputElement[]>, enrich?: (value: unknown | unknown[]) => Record<string, unknown>): void;
/**

@@ -22,3 +22,3 @@ * Create a handler for the passed element

*/
export declare function createHandler<T extends Record<string, unknown | unknown[]>>(name: string, eventName: string, element: FormEl, groupElements: FormEl[], stores: FormulaStores<T>, options: FormulaOptions, hiddenGroups: Map<string, HTMLInputElement[]>): () => void;
export declare function createHandler<T extends FormulaValue = FormulaValueDefault>(name: string, eventName: string, element: FormEl, groupElements: FormEl[], stores: FormulaStores<T>, options: FormulaOptions, hiddenGroups: Map<string, HTMLInputElement[]>): () => void;
/**

@@ -30,2 +30,2 @@ * Create a handler for a form element submission, when called it copies the contents

*/
export declare function createSubmitHandler<T extends Record<string, unknown | unknown[]>>(stores: FormulaStores<T>, form: HTMLFormElement): (event: Event) => void;
export declare function createSubmitHandler<T extends FormulaValue = FormulaValueDefault>(stores: FormulaStores<T>, form: HTMLFormElement): (event: Event) => void;

@@ -9,2 +9,2 @@ import { FormEl, FormulaField, FormulaOptions, FormulaStores } from '../../types';

*/
export declare function createFieldExtract<T extends Record<string, unknown | unknown[]>>(name: string, elementGroup: FormEl[], options: FormulaOptions, stores: FormulaStores<T>): (element: FormEl, isInit?: boolean, isReset?: boolean) => FormulaField;
export declare function createFieldExtract(name: string, elementGroup: FormEl[], options: FormulaOptions, stores: FormulaStores): (element: FormEl, isInit?: boolean, isReset?: boolean) => FormulaField;

@@ -1,2 +0,2 @@

import { Formula, FormulaOptions, FormulaStores } from '../../types';
import { Formula, FormulaOptions, FormulaStores, FormulaValue, FormulaValueDefault } from '../../types';
/**

@@ -9,2 +9,2 @@ * Creates the form action

*/
export declare function createForm<T extends Record<string, unknown | unknown[]>>(options: FormulaOptions, globalStore?: Map<string, FormulaStores<T>>, groupName?: string, initialData?: T): Formula<T>;
export declare function createForm<T extends FormulaValue = FormulaValueDefault>(options: FormulaOptions, globalStore?: Map<string, FormulaStores>, groupName?: string, initialData?: T): Formula<T>;

@@ -6,2 +6,2 @@ import { FormEl, FormulaOptions, FormulaStores } from '../../types';

*/
export declare function createReset<T extends Record<string, unknown | unknown[]>>(node: HTMLElement, allGroups: [string, FormEl[]][], stores: FormulaStores<T>, options: FormulaOptions): () => void;
export declare function createReset(node: HTMLElement, allGroups: [string, FormEl[]][], stores: FormulaStores, options: FormulaOptions): () => void;

@@ -14,2 +14,2 @@ import { FormEl, FormulaStores } from '../../types';

*/
export declare function createTouchHandlers<T extends Record<string, unknown | unknown[]>>(name: string, elements: FormEl[], stores: FormulaStores<T>): () => void;
export declare function createTouchHandlers(name: string, elements: FormEl[], stores: FormulaStores): () => void;

@@ -1,2 +0,2 @@

import { Beaker, BeakerOptions, BeakerStores } from '../../types';
import { Beaker, BeakerOptions, BeakerStores, FormulaValue, FormulaValueDefault } from '../../types';
/**

@@ -7,2 +7,2 @@ * Creates a group, which is really just a collection of forms for row data

*/
export declare function createGroup<T extends Record<string, unknown | unknown[]>>(options: BeakerOptions, beakerStores: Map<string, BeakerStores<T>>): Beaker<T>;
export declare function createGroup<T extends FormulaValue = FormulaValueDefault>(options: BeakerOptions, beakerStores: Map<string, BeakerStores>): Beaker<T>;

@@ -1,2 +0,2 @@

import { BeakerOptions, BeakerStores, FormulaOptions, FormulaStores } from '../../types';
import { BeakerOptions, BeakerStores, FormulaOptions, FormulaStores, FormulaValue, FormulaValueDefault } from '../../types';
/**

@@ -10,6 +10,6 @@ * Create the stores for the the form instance, these can be set using the `defaultValue` property

*/
export declare function createFormStores<T extends Record<string, unknown | unknown[]>>(options?: FormulaOptions, initialData?: T): FormulaStores<T>;
export declare function createFormStores<T extends FormulaValue = FormulaValueDefault>(options?: FormulaOptions, initialData?: T): FormulaStores<T>;
/**
* Create a group store which contains arrays of form store values
*/
export declare function createGroupStores<T extends Record<string, unknown | unknown[]>>(options?: BeakerOptions): BeakerStores<T>;
export declare function createGroupStores<T extends FormulaValue = FormulaValueDefault>(options?: BeakerOptions): BeakerStores<T>;
{
"name": "svelte-formula",
"description": "Reactive Forms for Svelte",
"version": "0.10.0",
"version": "0.11.0",
"keywords": [

@@ -6,0 +6,0 @@ "svelte",

@@ -247,8 +247,17 @@ import { get, writable } from 'svelte/store';

*/
function getRadioGroupParent(el) {
var _a, _b;
if (!el) {
return undefined;
}
var isContainer = Array.from(el.querySelectorAll(':scope input[type=radio]')).length > 1;
if (!isContainer) {
if (!el.parentElement) {
return undefined;
}
if (((_a = el.parentElement.dataset) === null || _a === void 0 ? void 0 : _a.beakerGroup) || ((_b = el.parentElement.dataset) === null || _b === void 0 ? void 0 : _b.formulaForm)) {

@@ -258,3 +267,3 @@ return undefined;

return getRadioGroupParent(el.parentElement);
return getRadioGroupParent(el === null || el === void 0 ? void 0 : el.parentElement);
}

@@ -272,2 +281,6 @@

function setAriaRole(el, elements) {
if (el.hasAttribute('aria-role')) {
return;
}
if (el.type === 'radio') {

@@ -320,17 +333,32 @@ if (elements.length < 2) {

* Sets ARIA attributes based on the current value
* @param el
* @param element
* @param elGroup
*/
function setAriaValue(el, elGroup) {
if (el.type === 'radio') {
elGroup.forEach(function (el) {
return el.removeAttribute('aria-checked');
});
function setAriaValue(element, elGroup) {
var e_1, _a;
if (element.type === 'radio') {
try {
for (var elGroup_1 = __values(elGroup), elGroup_1_1 = elGroup_1.next(); !elGroup_1_1.done; elGroup_1_1 = elGroup_1.next()) {
var el = elGroup_1_1.value;
el.removeAttribute('aria-checked');
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (elGroup_1_1 && !elGroup_1_1.done && (_a = elGroup_1["return"])) _a.call(elGroup_1);
} finally {
if (e_1) throw e_1.error;
}
}
}
if (el.checked) {
el.setAttribute('aria-checked', 'checked');
if (element.checked) {
element.setAttribute('aria-checked', 'checked');
} else {
el.removeAttribute('aria-checked');
element.removeAttribute('aria-checked');
}

@@ -345,8 +373,32 @@ }

function setAriaContainer(container, isGroup) {
container.setAttribute('aria-role', isGroup ? 'row' : 'form');
if (!container.hasAttribute('aria-role')) {
container.setAttribute('aria-role', isGroup ? 'row' : 'form');
}
}
/**
* Add the ARIA button role to all buttons contained in the form that don't already have an ARIA role
* @param container
*/
function setAriaButtons(container) {
Array.from(container.querySelectorAll('button')).forEach(function (el) {
return el.setAttribute('aria-role', 'button');
});
var e_2, _a;
var nonAriaButtons = Array.from(container.querySelectorAll('button:not([aria-role])'));
try {
for (var nonAriaButtons_1 = __values(nonAriaButtons), nonAriaButtons_1_1 = nonAriaButtons_1.next(); !nonAriaButtons_1_1.done; nonAriaButtons_1_1 = nonAriaButtons_1.next()) {
var el = nonAriaButtons_1_1.value;
el.setAttribute('aria-role', 'button');
}
} catch (e_2_1) {
e_2 = {
error: e_2_1
};
} finally {
try {
if (nonAriaButtons_1_1 && !nonAriaButtons_1_1.done && (_a = nonAriaButtons_1["return"])) _a.call(nonAriaButtons_1);
} finally {
if (e_2) throw e_2.error;
}
}
}

@@ -486,7 +538,3 @@

var isMultiValue = function () {
if (elementGroup[0].type === 'radio') {
return false;
}
return !elementGroup[0].multiple;
return elementGroup[0].type === 'radio' ? false : !elementGroup[0].multiple;
}() && elementGroup.length > 1;

@@ -543,6 +591,5 @@ /**

/**
* Create an enrichment object for the field
* Creates an enrichment object for the named group,
* @param name
* @param options
*/

@@ -552,30 +599,43 @@

return function (value) {
var e_1, _a;
return Object.entries(options.enrich[name]).reduce(function (a, _a) {
var _b = __read(_a, 2),
key = _b[0],
fn = _b[1];
var results = {};
a[key] = fn(value);
return a;
}, {});
};
}
try {
for (var _b = __values(Object.entries(options.enrich[name])), _c = _b.next(); !_c.done; _c = _b.next()) {
var _d = __read(_c.value, 2),
key = _d[0],
fn = _d[1];
/**
* Do validation on the form and set the form validity state and set the form to invalid if there
* are any form validations
* @param formValidators
* @param stores
*/
results[key] = fn(value);
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
} finally {
if (e_1) throw e_1.error;
}
function formValidation(formValidators, stores) {
var currentValues = get(stores.formValues);
stores.formValidity.set({});
var validators = Object.entries(formValidators);
var invalidStates = {};
for (var i = 0; i < validators.length; i++) {
var _a = __read(validators[i], 2),
name_1 = _a[0],
validator = _a[1];
var invalid = validator(currentValues);
if (invalid !== null) {
invalidStates[name_1] = invalid;
}
}
return results;
};
if (Object.keys(invalidStates).length > 0) {
stores.formValidity.set(invalidStates);
stores.isFormValid.set(false);
}
}
/**

@@ -590,2 +650,3 @@ * Update the value and error stores, also update form validity

function valueUpdate(details, stores, options, hiddenFields, enrich) {

@@ -596,54 +657,35 @@ var _a;

value = details.value,
validity = __rest(details, ["name", "value"]); // Update form values and if onChanges passed run it
validity = __rest(details, ["name", "value"]);
stores.formValues.update(function (state) {
var _a;
var result = __assign(__assign({}, state), (_a = {}, _a[name] = value, _a));
return __assign(__assign({}, state), (_a = {}, _a[name] = value, _a));
});
hiddenFields.forEach(function (group, name) {
return result[name] = group.length > 1 ? group.map(function (e) {
return e.value;
}) : group[0].value;
if (hiddenFields.size) {
stores.formValues.update(function (state) {
hiddenFields.forEach(function (group, name) {
return state[name] = group.length > 1 ? group.map(function (e) {
return e.value;
}) : group[0].value;
});
return state;
});
return result;
});
var currentValues = get(stores.formValues); // Update validity and form validity
} // Update validity and form validity
stores.validity.update(function (state) {
var _a;
var result = __assign(__assign({}, state), (_a = {}, _a[name] = validity, _a));
return __assign(__assign({}, state), (_a = {}, _a[name] = validity, _a));
});
stores.isFormValid.set(Object.values(get(stores.validity)).every(function (v) {
return v.valid;
}));
stores.isFormValid.set(Object.values(result).every(function (v) {
return v.valid;
}));
if (options === null || options === void 0 ? void 0 : options.formValidators) {
formValidation(options.formValidators, stores);
}
if (options === null || options === void 0 ? void 0 : options.formValidators) {
stores.formValidity.set({});
var validators = Object.entries(options === null || options === void 0 ? void 0 : options.formValidators);
var invalidStates = {};
for (var i = 0; i < validators.length; i++) {
var _b = __read(validators[i], 2),
name_1 = _b[0],
validator = _b[1];
var invalid = validator(currentValues);
if (invalid !== null) {
invalidStates[name_1] = invalid;
}
}
if (Object.keys(invalidStates).length > 0) {
stores.formValidity.set(invalidStates);
stores.isFormValid.set(false);
}
}
return result;
});
if (enrich) {

@@ -653,3 +695,5 @@ stores.enrichment.set((_a = {}, _a[name] = enrich(value), _a));

if (options === null || options === void 0 ? void 0 : options.postChanges) options === null || options === void 0 ? void 0 : options.postChanges(currentValues);
if (typeof (options === null || options === void 0 ? void 0 : options.postChanges) === 'function') {
options === null || options === void 0 ? void 0 : options.postChanges(get(stores.formValues));
}
}

@@ -667,3 +711,3 @@ /**

return function (event) {
if (options === null || options === void 0 ? void 0 : options.preChanges) options === null || options === void 0 ? void 0 : options.preChanges(); // Allow elements to update by letting the browser do a tick
if (typeof (options === null || options === void 0 ? void 0 : options.preChanges) === 'function') options.preChanges(); // Allow elements to update by letting the browser do a tick

@@ -693,11 +737,7 @@ setTimeout(function () {

var enrich;
if ((_a = options === null || options === void 0 ? void 0 : options.enrich) === null || _a === void 0 ? void 0 : _a[name]) {
enrich = createEnrichField(name, options);
}
if ((_a = options === null || options === void 0 ? void 0 : options.enrich) === null || _a === void 0 ? void 0 : _a[name]) enrich = createEnrichField(name, options);
var handler = createHandlerForData(extract, stores, options, hiddenGroups, enrich);
element.addEventListener(eventName, handler);
return function () {
element.removeEventListener(eventName, handler);
return element.removeEventListener(eventName, handler);
};

@@ -714,6 +754,3 @@ }

return function () {
if (!form.noValidate) {
form.reportValidity();
}
if (!form.noValidate) form.reportValidity();
stores.formValues.subscribe(function (v) {

@@ -946,7 +983,7 @@ return stores.submitValues.set(v);

function matchingArrays(array1, array2) {
var matchingArrays = function matchingArrays(array1, array2) {
return array1.every(function (e) {
return array2.includes(e);
});
}
};
/**

@@ -980,3 +1017,3 @@ * Creates the handler for a group of elements for the dirty event on the group name, once an

var destroy = function destroy() {
var setDirtyAndStopListening = function setDirtyAndStopListening() {
var e_2, _a;

@@ -1020,15 +1057,7 @@

return function () {
var startValue = initialValues.get(groupName); // Take the current form values and check if the user has changed it
var startValue = initialValues.get(groupName);
var currentValues = get(stores.formValues);
stores.formValues.subscribe(function (v) {
if (Array.isArray(v[groupName])) {
if (!matchingArrays(v[groupName], startValue)) {
stores.dirty.update(function (state) {
var _a;
return __assign(__assign({}, state), (_a = {}, _a[groupName] = true, _a));
});
destroy();
}
} else if (v[groupName] !== startValue) {
if (Array.isArray(currentValues[groupName])) {
if (!matchingArrays(currentValues[groupName], startValue)) {
stores.dirty.update(function (state) {

@@ -1039,5 +1068,12 @@ var _a;

});
destroy();
setDirtyAndStopListening();
}
})();
} else if (currentValues[groupName] !== startValue) {
stores.dirty.update(function (state) {
var _a;
return __assign(__assign({}, state), (_a = {}, _a[groupName] = true, _a));
});
setDirtyAndStopListening();
}
};

@@ -1065,3 +1101,3 @@ }

return destroy;
return setDirtyAndStopListening;
}

@@ -1278,3 +1314,3 @@

customBindings.split('|').forEach(function (event) {
eventHandlers.set(el, createHandler(name, event, el, elements, stores, innerOpt, hiddenGroups));
return eventHandlers.set(el, createHandler(name, event, el, elements, stores, innerOpt, hiddenGroups));
});

@@ -1318,7 +1354,4 @@ } else if (el instanceof HTMLSelectElement) {

if (node.id && globalStore) {
globalStore.set(node.id, stores);
} // If the HTML element attached is a form, also listen for the submit event
if (node.id && globalStore) globalStore.set(node.id, stores); // If the HTML element attached is a form, also listen for the submit event
if (node instanceof HTMLFormElement) {

@@ -1357,6 +1390,3 @@ submitHandler = createSubmitHandler(stores, node);

});
if (submitHandler) {
currentNode.removeEventListener('submit', submitHandler);
}
if (submitHandler) currentNode.removeEventListener('submit', submitHandler);
}

@@ -1375,3 +1405,3 @@

cleanupSubscriptions();
currentNode.id && globalStore && globalStore["delete"](name);
currentNode.id && globalStore && globalStore["delete"](currentNode.id);
}

@@ -1398,3 +1428,3 @@ };

cleanupSubscriptions();
currentNode.id && globalStore && globalStore["delete"](name);
currentNode.id && globalStore && globalStore["delete"](currentNode.id);
},

@@ -1466,8 +1496,23 @@

function cleanupStores(rows) {
Object.keys(groupStores).forEach(function (key) {
if (['formValues', 'initialValues', 'submitValues'].includes(key)) return;
groupStores[key].update(function (state) {
return Array.isArray(state) ? state.slice(0, rows.length) : state;
});
});
var e_1, _a;
try {
for (var _b = __values(Object.keys(groupStores)), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
if (['formValues', 'initialValues', 'submitValues'].includes(key)) return;
groupStores[key].update(function (state) {
return Array.isArray(state) ? state.slice(0, rows.length) : state;
});
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
} finally {
if (e_1) throw e_1.error;
}
}
}

@@ -1482,10 +1527,10 @@ /**

function setupSubscriptions(form, index) {
var e_2, _a;
var initial = true;
Object.entries(form.stores).forEach(function (_a) {
var _b = __read(_a, 2),
key = _b[0],
store = _b[1];
var formStores = Object.entries(form.stores);
var _loop_1 = function _loop_1(key, store) {
var unsub = store.subscribe(function (value) {
if (initial && key === 'formValues') return; //Don't emit the form values when there is a form value change from the group
if (initial && key === 'formValues') return; // Don't emit the initial change

@@ -1502,3 +1547,24 @@ groupStores[key].update(function (state) {

subscriptions.add(unsub);
});
};
try {
for (var formStores_1 = __values(formStores), formStores_1_1 = formStores_1.next(); !formStores_1_1.done; formStores_1_1 = formStores_1.next()) {
var _b = __read(formStores_1_1.value, 2),
key = _b[0],
store = _b[1];
_loop_1(key, store);
}
} catch (e_2_1) {
e_2 = {
error: e_2_1
};
} finally {
try {
if (formStores_1_1 && !formStores_1_1.done && (_a = formStores_1["return"])) _a.call(formStores_1);
} finally {
if (e_2) throw e_2.error;
}
}
initial = false;

@@ -1521,3 +1587,5 @@ }

row.setAttribute('data-beaker-index', "" + i);
var form = createForm(formulaOptions, undefined, groupName, currentVals[i]);
var form = createForm(__assign(__assign({}, formulaOptions), {
defaultValues: defaultValues[i] || {}
}), undefined, groupName, currentVals[i]);
var instance = form.form(row);

@@ -1538,3 +1606,3 @@ formulaInstances.set(row, form);

function setupGroupContainer(node) {
globalObserver = new MutationObserver(function (mutations) {
globalObserver = new MutationObserver(function () {
var rows = node.querySelectorAll(':scope > *');

@@ -1561,3 +1629,7 @@ groupHasChanged(Array.from(rows));

node.setAttribute('data-beaker-group', 'true');
node.setAttribute('aria-role', 'group');
if (!node.hasAttribute('aria-role')) {
node.setAttribute('aria-role', 'group');
}
setupGroupContainer(node);

@@ -1564,0 +1636,0 @@ return {

@@ -251,8 +251,17 @@ (function (global, factory) {

*/
function getRadioGroupParent(el) {
var _a, _b;
if (!el) {
return undefined;
}
var isContainer = Array.from(el.querySelectorAll(':scope input[type=radio]')).length > 1;
if (!isContainer) {
if (!el.parentElement) {
return undefined;
}
if (((_a = el.parentElement.dataset) === null || _a === void 0 ? void 0 : _a.beakerGroup) || ((_b = el.parentElement.dataset) === null || _b === void 0 ? void 0 : _b.formulaForm)) {

@@ -262,3 +271,3 @@ return undefined;

return getRadioGroupParent(el.parentElement);
return getRadioGroupParent(el === null || el === void 0 ? void 0 : el.parentElement);
}

@@ -276,2 +285,6 @@

function setAriaRole(el, elements) {
if (el.hasAttribute('aria-role')) {
return;
}
if (el.type === 'radio') {

@@ -324,17 +337,32 @@ if (elements.length < 2) {

* Sets ARIA attributes based on the current value
* @param el
* @param element
* @param elGroup
*/
function setAriaValue(el, elGroup) {
if (el.type === 'radio') {
elGroup.forEach(function (el) {
return el.removeAttribute('aria-checked');
});
function setAriaValue(element, elGroup) {
var e_1, _a;
if (element.type === 'radio') {
try {
for (var elGroup_1 = __values(elGroup), elGroup_1_1 = elGroup_1.next(); !elGroup_1_1.done; elGroup_1_1 = elGroup_1.next()) {
var el = elGroup_1_1.value;
el.removeAttribute('aria-checked');
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (elGroup_1_1 && !elGroup_1_1.done && (_a = elGroup_1["return"])) _a.call(elGroup_1);
} finally {
if (e_1) throw e_1.error;
}
}
}
if (el.checked) {
el.setAttribute('aria-checked', 'checked');
if (element.checked) {
element.setAttribute('aria-checked', 'checked');
} else {
el.removeAttribute('aria-checked');
element.removeAttribute('aria-checked');
}

@@ -349,8 +377,32 @@ }

function setAriaContainer(container, isGroup) {
container.setAttribute('aria-role', isGroup ? 'row' : 'form');
if (!container.hasAttribute('aria-role')) {
container.setAttribute('aria-role', isGroup ? 'row' : 'form');
}
}
/**
* Add the ARIA button role to all buttons contained in the form that don't already have an ARIA role
* @param container
*/
function setAriaButtons(container) {
Array.from(container.querySelectorAll('button')).forEach(function (el) {
return el.setAttribute('aria-role', 'button');
});
var e_2, _a;
var nonAriaButtons = Array.from(container.querySelectorAll('button:not([aria-role])'));
try {
for (var nonAriaButtons_1 = __values(nonAriaButtons), nonAriaButtons_1_1 = nonAriaButtons_1.next(); !nonAriaButtons_1_1.done; nonAriaButtons_1_1 = nonAriaButtons_1.next()) {
var el = nonAriaButtons_1_1.value;
el.setAttribute('aria-role', 'button');
}
} catch (e_2_1) {
e_2 = {
error: e_2_1
};
} finally {
try {
if (nonAriaButtons_1_1 && !nonAriaButtons_1_1.done && (_a = nonAriaButtons_1["return"])) _a.call(nonAriaButtons_1);
} finally {
if (e_2) throw e_2.error;
}
}
}

@@ -490,7 +542,3 @@

var isMultiValue = function () {
if (elementGroup[0].type === 'radio') {
return false;
}
return !elementGroup[0].multiple;
return elementGroup[0].type === 'radio' ? false : !elementGroup[0].multiple;
}() && elementGroup.length > 1;

@@ -547,6 +595,5 @@ /**

/**
* Create an enrichment object for the field
* Creates an enrichment object for the named group,
* @param name
* @param options
*/

@@ -556,30 +603,43 @@

return function (value) {
var e_1, _a;
return Object.entries(options.enrich[name]).reduce(function (a, _a) {
var _b = __read(_a, 2),
key = _b[0],
fn = _b[1];
var results = {};
a[key] = fn(value);
return a;
}, {});
};
}
try {
for (var _b = __values(Object.entries(options.enrich[name])), _c = _b.next(); !_c.done; _c = _b.next()) {
var _d = __read(_c.value, 2),
key = _d[0],
fn = _d[1];
/**
* Do validation on the form and set the form validity state and set the form to invalid if there
* are any form validations
* @param formValidators
* @param stores
*/
results[key] = fn(value);
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
} finally {
if (e_1) throw e_1.error;
}
function formValidation(formValidators, stores) {
var currentValues = store.get(stores.formValues);
stores.formValidity.set({});
var validators = Object.entries(formValidators);
var invalidStates = {};
for (var i = 0; i < validators.length; i++) {
var _a = __read(validators[i], 2),
name_1 = _a[0],
validator = _a[1];
var invalid = validator(currentValues);
if (invalid !== null) {
invalidStates[name_1] = invalid;
}
}
return results;
};
if (Object.keys(invalidStates).length > 0) {
stores.formValidity.set(invalidStates);
stores.isFormValid.set(false);
}
}
/**

@@ -594,2 +654,3 @@ * Update the value and error stores, also update form validity

function valueUpdate(details, stores, options, hiddenFields, enrich) {

@@ -600,54 +661,35 @@ var _a;

value = details.value,
validity = __rest(details, ["name", "value"]); // Update form values and if onChanges passed run it
validity = __rest(details, ["name", "value"]);
stores.formValues.update(function (state) {
var _a;
var result = __assign(__assign({}, state), (_a = {}, _a[name] = value, _a));
return __assign(__assign({}, state), (_a = {}, _a[name] = value, _a));
});
hiddenFields.forEach(function (group, name) {
return result[name] = group.length > 1 ? group.map(function (e) {
return e.value;
}) : group[0].value;
if (hiddenFields.size) {
stores.formValues.update(function (state) {
hiddenFields.forEach(function (group, name) {
return state[name] = group.length > 1 ? group.map(function (e) {
return e.value;
}) : group[0].value;
});
return state;
});
return result;
});
var currentValues = store.get(stores.formValues); // Update validity and form validity
} // Update validity and form validity
stores.validity.update(function (state) {
var _a;
var result = __assign(__assign({}, state), (_a = {}, _a[name] = validity, _a));
return __assign(__assign({}, state), (_a = {}, _a[name] = validity, _a));
});
stores.isFormValid.set(Object.values(store.get(stores.validity)).every(function (v) {
return v.valid;
}));
stores.isFormValid.set(Object.values(result).every(function (v) {
return v.valid;
}));
if (options === null || options === void 0 ? void 0 : options.formValidators) {
formValidation(options.formValidators, stores);
}
if (options === null || options === void 0 ? void 0 : options.formValidators) {
stores.formValidity.set({});
var validators = Object.entries(options === null || options === void 0 ? void 0 : options.formValidators);
var invalidStates = {};
for (var i = 0; i < validators.length; i++) {
var _b = __read(validators[i], 2),
name_1 = _b[0],
validator = _b[1];
var invalid = validator(currentValues);
if (invalid !== null) {
invalidStates[name_1] = invalid;
}
}
if (Object.keys(invalidStates).length > 0) {
stores.formValidity.set(invalidStates);
stores.isFormValid.set(false);
}
}
return result;
});
if (enrich) {

@@ -657,3 +699,5 @@ stores.enrichment.set((_a = {}, _a[name] = enrich(value), _a));

if (options === null || options === void 0 ? void 0 : options.postChanges) options === null || options === void 0 ? void 0 : options.postChanges(currentValues);
if (typeof (options === null || options === void 0 ? void 0 : options.postChanges) === 'function') {
options === null || options === void 0 ? void 0 : options.postChanges(store.get(stores.formValues));
}
}

@@ -671,3 +715,3 @@ /**

return function (event) {
if (options === null || options === void 0 ? void 0 : options.preChanges) options === null || options === void 0 ? void 0 : options.preChanges(); // Allow elements to update by letting the browser do a tick
if (typeof (options === null || options === void 0 ? void 0 : options.preChanges) === 'function') options.preChanges(); // Allow elements to update by letting the browser do a tick

@@ -697,11 +741,7 @@ setTimeout(function () {

var enrich;
if ((_a = options === null || options === void 0 ? void 0 : options.enrich) === null || _a === void 0 ? void 0 : _a[name]) {
enrich = createEnrichField(name, options);
}
if ((_a = options === null || options === void 0 ? void 0 : options.enrich) === null || _a === void 0 ? void 0 : _a[name]) enrich = createEnrichField(name, options);
var handler = createHandlerForData(extract, stores, options, hiddenGroups, enrich);
element.addEventListener(eventName, handler);
return function () {
element.removeEventListener(eventName, handler);
return element.removeEventListener(eventName, handler);
};

@@ -718,6 +758,3 @@ }

return function () {
if (!form.noValidate) {
form.reportValidity();
}
if (!form.noValidate) form.reportValidity();
stores.formValues.subscribe(function (v) {

@@ -950,7 +987,7 @@ return stores.submitValues.set(v);

function matchingArrays(array1, array2) {
var matchingArrays = function matchingArrays(array1, array2) {
return array1.every(function (e) {
return array2.includes(e);
});
}
};
/**

@@ -984,3 +1021,3 @@ * Creates the handler for a group of elements for the dirty event on the group name, once an

var destroy = function destroy() {
var setDirtyAndStopListening = function setDirtyAndStopListening() {
var e_2, _a;

@@ -1024,15 +1061,7 @@

return function () {
var startValue = initialValues.get(groupName); // Take the current form values and check if the user has changed it
var startValue = initialValues.get(groupName);
var currentValues = store.get(stores.formValues);
stores.formValues.subscribe(function (v) {
if (Array.isArray(v[groupName])) {
if (!matchingArrays(v[groupName], startValue)) {
stores.dirty.update(function (state) {
var _a;
return __assign(__assign({}, state), (_a = {}, _a[groupName] = true, _a));
});
destroy();
}
} else if (v[groupName] !== startValue) {
if (Array.isArray(currentValues[groupName])) {
if (!matchingArrays(currentValues[groupName], startValue)) {
stores.dirty.update(function (state) {

@@ -1043,5 +1072,12 @@ var _a;

});
destroy();
setDirtyAndStopListening();
}
})();
} else if (currentValues[groupName] !== startValue) {
stores.dirty.update(function (state) {
var _a;
return __assign(__assign({}, state), (_a = {}, _a[groupName] = true, _a));
});
setDirtyAndStopListening();
}
};

@@ -1069,3 +1105,3 @@ }

return destroy;
return setDirtyAndStopListening;
}

@@ -1282,3 +1318,3 @@

customBindings.split('|').forEach(function (event) {
eventHandlers.set(el, createHandler(name, event, el, elements, stores, innerOpt, hiddenGroups));
return eventHandlers.set(el, createHandler(name, event, el, elements, stores, innerOpt, hiddenGroups));
});

@@ -1322,7 +1358,4 @@ } else if (el instanceof HTMLSelectElement) {

if (node.id && globalStore) {
globalStore.set(node.id, stores);
} // If the HTML element attached is a form, also listen for the submit event
if (node.id && globalStore) globalStore.set(node.id, stores); // If the HTML element attached is a form, also listen for the submit event
if (node instanceof HTMLFormElement) {

@@ -1361,6 +1394,3 @@ submitHandler = createSubmitHandler(stores, node);

});
if (submitHandler) {
currentNode.removeEventListener('submit', submitHandler);
}
if (submitHandler) currentNode.removeEventListener('submit', submitHandler);
}

@@ -1379,3 +1409,3 @@

cleanupSubscriptions();
currentNode.id && globalStore && globalStore["delete"](name);
currentNode.id && globalStore && globalStore["delete"](currentNode.id);
}

@@ -1402,3 +1432,3 @@ };

cleanupSubscriptions();
currentNode.id && globalStore && globalStore["delete"](name);
currentNode.id && globalStore && globalStore["delete"](currentNode.id);
},

@@ -1470,8 +1500,23 @@

function cleanupStores(rows) {
Object.keys(groupStores).forEach(function (key) {
if (['formValues', 'initialValues', 'submitValues'].includes(key)) return;
groupStores[key].update(function (state) {
return Array.isArray(state) ? state.slice(0, rows.length) : state;
});
});
var e_1, _a;
try {
for (var _b = __values(Object.keys(groupStores)), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
if (['formValues', 'initialValues', 'submitValues'].includes(key)) return;
groupStores[key].update(function (state) {
return Array.isArray(state) ? state.slice(0, rows.length) : state;
});
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
} finally {
if (e_1) throw e_1.error;
}
}
}

@@ -1486,10 +1531,10 @@ /**

function setupSubscriptions(form, index) {
var e_2, _a;
var initial = true;
Object.entries(form.stores).forEach(function (_a) {
var _b = __read(_a, 2),
key = _b[0],
store = _b[1];
var formStores = Object.entries(form.stores);
var _loop_1 = function _loop_1(key, store) {
var unsub = store.subscribe(function (value) {
if (initial && key === 'formValues') return; //Don't emit the form values when there is a form value change from the group
if (initial && key === 'formValues') return; // Don't emit the initial change

@@ -1506,3 +1551,24 @@ groupStores[key].update(function (state) {

subscriptions.add(unsub);
});
};
try {
for (var formStores_1 = __values(formStores), formStores_1_1 = formStores_1.next(); !formStores_1_1.done; formStores_1_1 = formStores_1.next()) {
var _b = __read(formStores_1_1.value, 2),
key = _b[0],
store = _b[1];
_loop_1(key, store);
}
} catch (e_2_1) {
e_2 = {
error: e_2_1
};
} finally {
try {
if (formStores_1_1 && !formStores_1_1.done && (_a = formStores_1["return"])) _a.call(formStores_1);
} finally {
if (e_2) throw e_2.error;
}
}
initial = false;

@@ -1525,3 +1591,5 @@ }

row.setAttribute('data-beaker-index', "" + i);
var form = createForm(formulaOptions, undefined, groupName, currentVals[i]);
var form = createForm(__assign(__assign({}, formulaOptions), {
defaultValues: defaultValues[i] || {}
}), undefined, groupName, currentVals[i]);
var instance = form.form(row);

@@ -1542,3 +1610,3 @@ formulaInstances.set(row, form);

function setupGroupContainer(node) {
globalObserver = new MutationObserver(function (mutations) {
globalObserver = new MutationObserver(function () {
var rows = node.querySelectorAll(':scope > *');

@@ -1565,3 +1633,7 @@ groupHasChanged(Array.from(rows));

node.setAttribute('data-beaker-group', 'true');
node.setAttribute('aria-role', 'group');
if (!node.hasAttribute('aria-role')) {
node.setAttribute('aria-role', 'group');
}
setupGroupContainer(node);

@@ -1568,0 +1640,0 @@ return {

@@ -5,5 +5,10 @@ import { Writable } from 'svelte/store';

/**
* Internal type for object
*/
export declare type FormulaValue = Record<string, any>;
export declare type FormulaValueDefault = Record<string, unknown>;
/**
* The stores available in Formula
*/
export interface FormulaStores<T extends Record<string, unknown | unknown[]>> {
export interface FormulaStores<T extends FormulaValue = FormulaValueDefault> {
/**

@@ -48,3 +53,3 @@ * A store containing the current form values

*/
enrichment: Writable<Record<string, Record<string, unknown>>>;
enrichment: Writable<Record<string, T>>;
}

@@ -54,3 +59,3 @@ /**

*/
export interface Formula<T extends Record<string, unknown | unknown[]>> extends FormulaStores<T> {
export interface Formula<T extends FormulaValue = FormulaValueDefault> extends FormulaStores<T> {
/**

@@ -66,3 +71,3 @@ * The form object for use with the Svelte use directive

*/
updateForm: (updatedOpts?: FormulaOptions) => void;
updateForm: (updatedOpts?: FormulaOptions<T>) => void;
/**

@@ -79,3 +84,3 @@ * Destroy

*/
stores: FormulaStores<Record<string, unknown | unknown[]>>;
stores: FormulaStores<T>;
}
import { Writable } from 'svelte/store';
import { Formula, FormulaError, FormulaOptions } from '../types';
import { Formula, FormulaError, FormulaOptions, FormulaValue, FormulaValueDefault } from '../types';
/**
* The stores available in Beaker
*/
export interface BeakerStores<T extends Record<string, unknown | unknown[]>> {
export interface BeakerStores<T extends FormulaValue = FormulaValueDefault> {
/**

@@ -46,3 +46,3 @@ * A store containing the current form values

*/
enrichment: Writable<Record<string, Record<string, unknown>>[]>;
enrichment: Writable<Record<string, T>[]>;
}

@@ -52,3 +52,3 @@ /**

*/
export interface Beaker<T extends Record<string, unknown | unknown[]>> extends BeakerStores<T> {
export interface Beaker<T extends FormulaValue = FormulaValueDefault> extends BeakerStores<T> {
/**

@@ -64,3 +64,3 @@ * The form object for use with the Svelte use directive

*/
update: (options?: FormulaOptions) => void;
update: (options?: FormulaOptions<T>) => void;
/**

@@ -67,0 +67,0 @@ * Destroy

import { CustomValidationMessages, ValidationRule, ValidationRules } from './validation';
import { EnrichFields } from './enrich';
import { FormulaValue, FormulaValueDefault } from '../types/formula';
interface BaseOptions {

@@ -28,7 +29,7 @@ /**

*/
export interface FormulaOptions extends BaseOptions {
export interface FormulaOptions<T extends FormulaValue = FormulaValueDefault> extends BaseOptions {
/**
* Default values are used as initial values for the form fields if there is no value already set on the form
*/
defaultValues?: Record<string, unknown | unknown[]>;
defaultValues?: T;
/**

@@ -41,3 +42,3 @@ * Method called as soon as a change has been detected, before any values are read or stores are updated

*/
postChanges?: (values: Record<string, unknown | unknown[]>) => void;
postChanges?: (values: T) => void;
}

@@ -47,8 +48,8 @@ /**

*/
export interface BeakerOptions extends BaseOptions {
export interface BeakerOptions<T extends FormulaValue = FormulaValueDefault> extends BaseOptions {
/**
* Default values are used as initial values for the form fields if there is no value already set on the form
*/
defaultValues?: Record<string, unknown | unknown[]>[];
defaultValues?: T[];
}
export {};
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