@optionfactory/fml 9.0.0-rc11 → 9.0.0-rc12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ful.mjs CHANGED
@@ -1412,15 +1412,22 @@ const INPUT_MODES = { numeric: 'numeric', decimal: 'decimal' };
1412
1412
 
1413
1413
  const signed = (v, digits) => (v.startsWith('-') ? '-' : '') + digits(v);
1414
1414
 
1415
- const NUMERIC_FILTERS = {
1416
- numeric: (v) => signed(v, (t) => t.replace(/\D/g, '')),
1415
+ const NUMERIC_DIGITS = {
1416
+ numeric: (t) => t.replace(/\D/g, ''),
1417
1417
  //one separator, the first: the rest are a slip while typing, not a value
1418
- decimal: (v) =>
1419
- signed(v, (t) => {
1420
- const kept = t.replace(/[^\d.,]/g, '');
1421
- const at = kept.search(/[.,]/);
1422
- return at === -1 ? kept : kept.slice(0, at + 1) + kept.slice(at + 1).replace(/[.,]/g, '');
1423
- }),
1418
+ decimal: (t) => {
1419
+ const kept = t.replace(/[^\d.,]/g, '');
1420
+ const at = kept.search(/[.,]/);
1421
+ return at === -1 ? kept : kept.slice(0, at + 1) + kept.slice(at + 1).replace(/[.,]/g, '');
1422
+ },
1423
+ };
1424
+
1425
+ const numericFilter = (type, unsigned) => {
1426
+ const digits = NUMERIC_DIGITS[type];
1427
+ if (!digits) {
1428
+ return null;
1429
+ }
1430
+ return unsigned ? digits : (v) => signed(v, digits);
1424
1431
  };
1425
1432
 
1426
1433
  const warnedBoth = new WeakSet();
@@ -1442,7 +1449,7 @@ const filterOf = (el) => {
1442
1449
  const re = compiled('reject', reject);
1443
1450
  return re && ((v) => v.replace(re, ''));
1444
1451
  }
1445
- return NUMERIC_FILTERS[el._type()] ?? null;
1452
+ return numericFilter(el._type(), el.declared('unsigned'));
1446
1453
  };
1447
1454
 
1448
1455
  /** A labelled text input over any native type or textarea; the temporal inputs are its subclasses. */
@@ -1457,6 +1464,7 @@ class Input extends Field {
1457
1464
  'reject',
1458
1465
  'uppercase:presence',
1459
1466
  'trim:presence',
1467
+ 'unsigned:presence',
1460
1468
  'autocomplete',
1461
1469
  ];
1462
1470
  static slots = true;
@@ -4836,27 +4844,41 @@ class BooleanFilter extends Field {
4836
4844
  * operator, differing only in what the server converts them to.
4837
4845
  */
4838
4846
  class InFilter extends Select {
4839
- async upgrade() {
4840
- //the snapshot is taken inside super.upgrade(), so an attribute this
4841
- //element does not let an author turn off has to be written before it
4842
- this.toggleAttribute('multiple', true);
4843
- await super.upgrade();
4847
+ static attributes = ['operator'];
4848
+ /** the selection as the array the wire takes, whether one key was chosen or many */
4849
+ #keys() {
4850
+ const chosen = super.value;
4851
+ if (this.multiple) {
4852
+ return chosen;
4853
+ }
4854
+ return chosen === null || chosen === undefined ? [] : [chosen];
4844
4855
  }
4845
4856
  get value() {
4846
- const keys = super.value;
4857
+ const keys = this.#keys();
4847
4858
  //an empty set is no filter: the table drops a falsy value, where an
4848
4859
  //empty array would travel and match nothing
4849
- return keys.length === 0 ? null : keys;
4860
+ if (keys.length === 0) {
4861
+ return null;
4862
+ }
4863
+ const operator = this.declared('operator');
4864
+ return operator ? [operator, ...keys] : keys;
4850
4865
  }
4851
4866
  set value(v) {
4852
- super.value = v ?? [];
4867
+ const operator = this.declared('operator');
4868
+ let keys = v === null || v === undefined ? [] : Array.isArray(v) ? v : [v];
4869
+ //what the getter answers has to be assignable back, and it carries the
4870
+ //operator in front of the keys
4871
+ if (operator && keys[0] === operator) {
4872
+ keys = keys.slice(1);
4873
+ }
4874
+ super.value = this.multiple ? keys : (keys[0] ?? null);
4853
4875
  }
4854
4876
  /** @returns {FilterCriterion|null} */
4855
4877
  get criterion() {
4856
4878
  return asCriterion(
4857
4879
  labelTextOf(this),
4858
- null,
4859
- (super.entry ?? []).map((e) => e.label),
4880
+ this.declared('operator'),
4881
+ [super.entry].flat().filter((e) => e).map((e) => e.label),
4860
4882
  );
4861
4883
  }
4862
4884
  }