@pacem/pacem 1.0.0-bessel → 1.0.0-binet

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.
Files changed (66) hide show
  1. package/dist/browser/pacem-2d.js +149 -2
  2. package/dist/browser/pacem-2d.js.map +1 -1
  3. package/dist/browser/pacem-2d.min.js +1 -1
  4. package/dist/browser/pacem-3d.js +646 -2
  5. package/dist/browser/pacem-3d.js.map +1 -1
  6. package/dist/browser/pacem-3d.min.js +1 -1
  7. package/dist/browser/pacem-charts.js +21 -1
  8. package/dist/browser/pacem-charts.js.map +1 -1
  9. package/dist/browser/pacem-charts.min.js +1 -1
  10. package/dist/browser/pacem-cms.js +118 -3
  11. package/dist/browser/pacem-cms.js.map +1 -1
  12. package/dist/browser/pacem-cms.min.js +1 -1
  13. package/dist/browser/pacem-core.js +870 -9
  14. package/dist/browser/pacem-core.js.map +1 -1
  15. package/dist/browser/pacem-core.min.js +2 -2
  16. package/dist/browser/pacem-foundation.js +296 -1
  17. package/dist/browser/pacem-foundation.js.map +1 -1
  18. package/dist/browser/pacem-foundation.min.js +1 -1
  19. package/dist/browser/pacem-fx.js +18 -1
  20. package/dist/browser/pacem-fx.js.map +1 -1
  21. package/dist/browser/pacem-fx.min.js +1 -1
  22. package/dist/browser/pacem-logging.js +15 -1
  23. package/dist/browser/pacem-logging.js.map +1 -1
  24. package/dist/browser/pacem-logging.min.js +1 -1
  25. package/dist/browser/pacem-maps.js +97 -1
  26. package/dist/browser/pacem-maps.js.map +1 -1
  27. package/dist/browser/pacem-maps.min.js +1 -1
  28. package/dist/browser/pacem-media.js +14 -1
  29. package/dist/browser/pacem-media.js.map +1 -1
  30. package/dist/browser/pacem-media.min.js +1 -1
  31. package/dist/browser/pacem-networking.js +22 -1
  32. package/dist/browser/pacem-networking.js.map +1 -1
  33. package/dist/browser/pacem-networking.min.js +1 -1
  34. package/dist/browser/pacem-numerical.js +360 -1
  35. package/dist/browser/pacem-numerical.js.map +1 -1
  36. package/dist/browser/pacem-numerical.min.js +1 -1
  37. package/dist/browser/pacem-plus.js +195 -4
  38. package/dist/browser/pacem-plus.js.map +1 -1
  39. package/dist/browser/pacem-plus.min.js +1 -1
  40. package/dist/browser/pacem-scaffolding.js +420 -38
  41. package/dist/browser/pacem-scaffolding.js.map +1 -1
  42. package/dist/browser/pacem-scaffolding.min.js +2 -2
  43. package/dist/browser/pacem-ui.js +143 -19
  44. package/dist/browser/pacem-ui.js.map +1 -1
  45. package/dist/browser/pacem-ui.min.js +2 -2
  46. package/dist/bundle/pacem.min.mjs +147 -147
  47. package/dist/bundle/pacem.mjs +2905 -1417
  48. package/dist/bundle/pacem.mjs.map +3 -3
  49. package/dist/docs/pacem-2d.json +11549 -0
  50. package/dist/docs/pacem-3d.json +29096 -0
  51. package/dist/docs/pacem-charts.json +4244 -0
  52. package/dist/docs/pacem-cms.json +9325 -0
  53. package/dist/docs/pacem-core.json +40109 -0
  54. package/dist/docs/pacem-foundation.json +8941 -0
  55. package/dist/docs/pacem-fx.json +3121 -0
  56. package/dist/docs/pacem-logging.json +941 -0
  57. package/dist/docs/pacem-maps.json +17387 -0
  58. package/dist/docs/pacem-media.json +1203 -0
  59. package/dist/docs/pacem-networking.json +1798 -0
  60. package/dist/docs/pacem-numerical.json +13706 -0
  61. package/dist/docs/pacem-plus.json +8468 -0
  62. package/dist/docs/pacem-scaffolding.json +34788 -0
  63. package/dist/docs/pacem-ui.json +18628 -0
  64. package/dist/typings/index.d.ts +4109 -31
  65. package/dist/vscode.html-custom.json +1303 -741
  66. package/package.json +4 -2
@@ -1,12 +1,14 @@
1
1
  /*!
2
- * @pacem/pacem v1.0.0-bessel (https://js.pacem.it)
2
+ * @pacem/pacem v1.0.0-binet (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
6
6
  (function (pacemFoundation, pacemCore, pacemUi, pacemMaps) {
7
7
  'use strict';
8
8
 
9
+ /** Event type name (`'change'`) dispatched as a {@link FieldChangeEvent}. */
9
10
  const FieldChangeEventName = 'change';
11
+ /** Dispatched by a scaffolding field (see `PacemBaseElement.changeHandler` in `types-components.ts`) whenever its `value` actually changes as a result of user interaction; bubbles so an ancestor {@link PacemFormElement}/`PacemFormFieldElement` can react to it. */
10
12
  class FieldChangeEvent extends pacemCore.CustomTypedEvent {
11
13
  constructor(args) {
12
14
  super(FieldChangeEventName, args, { bubbles: true, cancelable: false });
@@ -14,6 +16,7 @@
14
16
  }
15
17
  //}
16
18
 
19
+ /** The primitive kinds an {@link ApiParameter} (or {@link DataField}) can be translated to, used to choose the appropriate auto-generated form field editor. */
17
20
  var ApiParameterType;
18
21
  (function (ApiParameterType) {
19
22
  ApiParameterType["String"] = "string";
@@ -23,7 +26,14 @@
23
26
  ApiParameterType["Binary"] = "binary";
24
27
  ApiParameterType["Object"] = "object";
25
28
  })(ApiParameterType || (ApiParameterType = {}));
29
+ /** Shared base for the OpenAPI/Swagger parsers: implements the common fetch-then-parse {@link ApiParser.load} flow, leaving the actual schema-to-{@link ApiManifest} translation to derived classes' `parse` implementation. */
26
30
  class ApiParserBase {
31
+ /**
32
+ * Fetches the API description document from `url` and parses it into an {@link ApiManifest}.
33
+ * @param url Url the API description (OpenAPI/Swagger document) is fetched from.
34
+ * @param headers Optional request headers (e.g. for authentication) sent along with the fetch.
35
+ * @returns The parsed manifest, or `null` if the response could not be retrieved/parsed as JSON.
36
+ */
27
37
  async load(url, headers) {
28
38
  let resp = await fetch(url, {
29
39
  mode: 'cors', credentials: 'omit', headers: headers
@@ -38,6 +48,12 @@
38
48
  }
39
49
  }
40
50
  const $refPattern = /^#\/(definitions|components\/schemas)\/(.+)$/;
51
+ /**
52
+ * Resolves a `$ref` pointer (e.g. `#/definitions/Foo` or `#/components/schemas/Foo`) against an {@link ApiManifest}'s `definitions` map.
53
+ * @param manifest Manifest whose `definitions` are searched.
54
+ * @param $ref The `$ref` pointer to resolve.
55
+ * @returns The referenced definition's name and schema, or `null` if `$ref` doesn't match the expected pattern.
56
+ */
41
57
  function getOpenApiDefinition(manifest, $ref) {
42
58
  var rec = $refPattern.exec($ref);
43
59
  if (rec && rec.length > 2) {
@@ -49,6 +65,7 @@
49
65
 
50
66
  //namespace Pacem.Scaffolding.OpenApi {
51
67
  const ApiMethod = pacemCore.Net.HttpMethod;
68
+ /** Parses a Swagger (OpenAPI 2.0) document into a format-agnostic {@link ApiManifest}, translating its `paths`/`definitions` into endpoints, resolved schema definitions and parameter types used to auto-generate form fields. */
52
69
  class SwaggerParser extends ApiParserBase {
53
70
  _findDefinitionName(definitionHashTag) {
54
71
  var pattern = /#\/definitions\/(.+)/;
@@ -57,6 +74,12 @@
57
74
  return definitionHashTag;
58
75
  return arr[1];
59
76
  }
77
+ /**
78
+ * Parses a Swagger (OpenAPI 2.0) document into an {@link ApiManifest}.
79
+ * @param content The Swagger document, either as a parsed object or as a JSON string.
80
+ * @param url Base url of the API, used to derive `baseUrl` when the document doesn't specify `host`/`schemes`.
81
+ * @returns The parsed manifest, with endpoints and resolved schema definitions.
82
+ */
60
83
  parse(content, url) {
61
84
  let j = content;
62
85
  if (typeof j === 'string') {
@@ -176,7 +199,14 @@
176
199
  }
177
200
  }
178
201
 
202
+ /** Parses an OpenAPI 3.x document into a format-agnostic {@link ApiManifest}, translating its `paths`/`components.schemas` into endpoints, resolved schema definitions and parameter types used to auto-generate form fields. */
179
203
  class OpenApi3Parser extends ApiParserBase {
204
+ /**
205
+ * Parses an OpenAPI 3.x document into an {@link ApiManifest}.
206
+ * @param content The OpenAPI 3.x document, either as a parsed object or as a JSON string.
207
+ * @param url Base url of the API, used as the manifest's `baseUrl`.
208
+ * @returns The parsed manifest, with endpoints and resolved schema definitions.
209
+ */
180
210
  parse(content, url) {
181
211
  let j = content;
182
212
  if (typeof j === 'string') {
@@ -289,12 +319,19 @@
289
319
  }
290
320
 
291
321
  //namespace Pacem.Scaffolding.OpenApi {
322
+ /** Format-detecting facade parser: inspects an API description document and delegates to {@link OpenApi3Parser} or {@link SwaggerParser} accordingly, producing a unified {@link ApiManifest} used to auto-generate form fields regardless of the source spec version. */
292
323
  class OpenApiParser extends ApiParserBase {
293
324
  constructor(_openApi3 = new OpenApi3Parser(), _swagger = new SwaggerParser()) {
294
325
  super();
295
326
  this._openApi3 = _openApi3;
296
327
  this._swagger = _swagger;
297
328
  }
329
+ /**
330
+ * Parses `content` as either an OpenAPI 3.x or a Swagger (OpenAPI 2.0) document, dispatching on the presence of an `openapi` property.
331
+ * @param content The API description, either as a parsed object or as a JSON string.
332
+ * @param url Base url of the API, forwarded to the delegate parser to resolve/derive the manifest's `baseUrl`.
333
+ * @returns The parsed manifest.
334
+ */
298
335
  parse(content, url) {
299
336
  let j = content;
300
337
  if (typeof j === 'string') {
@@ -330,6 +367,7 @@
330
367
  validator: (validatorType, validatorTypeIndex, prop, dictionary) => dictionary['validator_' + validatorType + '_' + prop] ?? dictionary['validator_' + validatorType + validatorTypeIndex + '_' + prop],
331
368
  commandTooltip: (commandName, dictionary) => dictionary['command_tooltip_' + commandName]
332
369
  };
370
+ /** Namespace-like static helper for localizing form {@link TypeMetadata} (labels, watermarks, descriptions, validator error messages, command tooltips) against a translation dictionary. */
333
371
  class Forms {
334
372
  /**
335
373
  * Localizes the metadata of a form **in place** using a translation dictionary.
@@ -404,20 +442,37 @@
404
442
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
405
443
  return c > 3 && r && Object.defineProperty(target, key, r), r;
406
444
  };
445
+ /** Event type name (`'submit'`) dispatched as a {@link FormSubmitEvent}. */
407
446
  const FormSubmitEventName = 'submit';
447
+ /** Event type name (`'reset'`) dispatched as a {@link FormResetEvent}. */
408
448
  const FormResetEventName = 'reset';
449
+ /**
450
+ * Dispatched by {@link PacemFormElement} right before a submission is actually sent to the server, once all
451
+ * fields have validated successfully. Cancelable: calling `preventDefault()` (or handling the event and
452
+ * returning `false`) aborts the submission before any request is made - useful to inject/transform
453
+ * {@link FormSubmitEventArgs#parameters} or veto the submit outright.
454
+ */
409
455
  class FormSubmitEvent extends pacemCore.CustomTypedEvent {
410
456
  constructor(args) {
411
457
  super(FormSubmitEventName, args, { bubbles: true, cancelable: true });
412
458
  }
413
459
  }
460
+ /** Dispatched by {@link PacemFormElement} when the form is about to be reset (programmatically or via its generated reset button). Cancelable: calling `preventDefault()` aborts the reset, leaving fields as they were. */
414
461
  class FormResetEvent extends Event {
415
462
  constructor() {
416
463
  super(FormResetEventName, { bubbles: true, cancelable: true });
417
464
  }
418
465
  }
466
+ /** Event types re-dispatched/handled on behalf of a {@link PacemFormElement} by its {@link FormEventEmitter}: upload `download` events, field {@link FieldChangeEventName} changes, and item `command` events (see {@link Components.CommandEvent}). */
419
467
  const EMITTABLE_EVENT_TYPES = ['download' /* < dedicated, for the upload custom element */, FieldChangeEventName /* expose */, pacemCore.CommandEventName];
468
+ /** Sentinel value used to reject a submission's promise when it was canceled via {@link FormSubmitEvent#preventDefault}, as opposed to a genuine fetch failure. */
420
469
  const SUBMIT_CANCELLATION_TOKEN = false;
470
+ /**
471
+ * Listens on a {@link PacemEventTarget} (typically a {@link PacemFormElement}) for the events listed in
472
+ * {@link EMITTABLE_EVENT_TYPES} and pipes each through the target's `handle` method, additionally
473
+ * re-dispatching `command` events as a synthesized `'item' + commandName`-named `CustomEvent` (e.g.
474
+ * `itemdelete`, `itemselect`) so listeners can subscribe to the specific command they care about.
475
+ */
421
476
  class FormEventEmitter {
422
477
  constructor(_element) {
423
478
  this._element = _element;
@@ -431,13 +486,16 @@
431
486
  }
432
487
  };
433
488
  }
489
+ /** Starts listening for {@link EMITTABLE_EVENT_TYPES} on the target element. */
434
490
  start() {
435
491
  EMITTABLE_EVENT_TYPES.forEach(t => this._element.addEventListener(t, this._itemEmitHandler, false));
436
492
  }
493
+ /** Stops listening for {@link EMITTABLE_EVENT_TYPES} on the target element. */
437
494
  stop() {
438
495
  EMITTABLE_EVENT_TYPES.forEach(t => this._element.removeEventListener(t, this._itemEmitHandler, false));
439
496
  }
440
497
  }
498
+ /** Base class for elements that need a reference to their closest ancestor {@link PacemFormElement} (form fields, validators): resolves and exposes it as {@link form} on activation. */
441
499
  class PacemFormRelevantElement extends pacemCore.Components.PacemElement {
442
500
  viewActivatedCallback() {
443
501
  super.viewActivatedCallback();
@@ -447,9 +505,18 @@
447
505
  __decorate$J([
448
506
  pacemCore.Watch({ converter: pacemCore.PropertyConverters.Element })
449
507
  ], PacemFormRelevantElement.prototype, "form", void 0);
508
+ /**
509
+ * `<p-form>`: the scaffolding package's central form element. Aggregates the validity/dirty state of its
510
+ * registered fields ({@link registerField}) and validators ({@link registerValidator}), of any nested
511
+ * sub-forms ({@link registerSubForm} - e.g. from a {@link Pacem.Components.Scaffolding.PacemChildFormElement}
512
+ * in `childform.ts`), drives submission ({@link submit}) and reset ({@link reset}), and - when `autogenerate`
513
+ * is `true` and `metadata` is provided - builds its own field markup from a {@link TypeMetadata}/
514
+ * {@link PropertyMetadata} description instead of requiring hand-authored markup.
515
+ */
450
516
  let PacemFormElement = class PacemFormElement extends PacemFormRelevantElement {
451
517
  constructor() {
452
518
  super('form');
519
+ /** Gets or sets the HTTP method used by the auto-generated fetcher. Defaults to `POST`. */
453
520
  this.method = pacemCore.Net.HttpMethod.Post;
454
521
  this._emitter = null;
455
522
  this._buttons = { submit: undefined, reset: undefined };
@@ -608,6 +675,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
608
675
  return this._buttons;
609
676
  }
610
677
  #fetching;
678
+ /** @readonly Gets whether a submission is currently in flight; also reflected as the `pacem-fetching` CSS class. */
611
679
  get fetching() {
612
680
  return this.#fetching;
613
681
  }
@@ -789,6 +857,11 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
789
857
  }
790
858
  return Promise.resolve(false);
791
859
  }
860
+ /**
861
+ * Validates a single named field, or - when `name` is omitted - every field of this form and its
862
+ * sub-forms, running each field's registered validators and updating their `valid`/`invalid` state.
863
+ * @param name Optional name of a single field to validate; validates the whole form (recursively) when omitted.
864
+ */
792
865
  // @Concurrent()
793
866
  validate(name) {
794
867
  if (!pacemCore.Utils.isNullOrEmpty(name)) {
@@ -887,6 +960,11 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
887
960
  this.valid = valid;
888
961
  }
889
962
  ;
963
+ /**
964
+ * Registers a nested {@link PacemFormElement} (e.g. rendered by a `PacemChildFormElement`, see
965
+ * `childform.ts`) so its fields' validity/dirtyness roll up into this form's own {@link valid}/{@link dirty}.
966
+ * @param form Sub-form to enroll
967
+ */
890
968
  registerSubForm(form) {
891
969
  let arr = this._subForms;
892
970
  if (arr.indexOf(form) == -1) {
@@ -896,6 +974,10 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
896
974
  this._checkDirtyness();
897
975
  }
898
976
  }
977
+ /**
978
+ * Removes a previously-registered nested form; its fields no longer influence this form's {@link valid}/{@link dirty}.
979
+ * @param form Sub-form to remove
980
+ */
899
981
  unregisterSubForm(form) {
900
982
  let arr = this._subForms, ndx = arr.indexOf(form);
901
983
  if (ndx >= 0) {
@@ -905,6 +987,11 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
905
987
  this._checkDirtyness();
906
988
  }
907
989
  }
990
+ /**
991
+ * Registers a field's {@link PacemModel} under `name`, so it is included in submission ({@link FormSubmitEventArgs#fields}), validation, dirty/valid roll-up and reset. Typically called by the field itself (see `PacemModelElement._registerFieldConditionally` in `types-components.ts`) rather than directly.
992
+ * @param name Field name to register under
993
+ * @param model Field implementing {@link PacemModel}
994
+ */
908
995
  registerField(name, model) {
909
996
  var container = this._fields;
910
997
  if (container[name] != model) {
@@ -918,6 +1005,11 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
918
1005
  this._checkDirtyness();
919
1006
  }
920
1007
  }
1008
+ /**
1009
+ * Removes a previously-registered field.
1010
+ * @param name Field name to remove
1011
+ * @param check Whether to re-check the form's overall validity/dirtyness afterwards (default `true`)
1012
+ */
921
1013
  unregisterField(name, check = true) {
922
1014
  var container = this._fields, current = container[name];
923
1015
  if (current instanceof HTMLElement) {
@@ -929,6 +1021,11 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
929
1021
  this._checkDirtyness();
930
1022
  }
931
1023
  }
1024
+ /**
1025
+ * Registers a {@link Validator} (typically a {@link PacemBaseValidatorElement}) against the named field, so it participates in that field's validation. Typically called by the validator itself rather than directly.
1026
+ * @param name Name of the field being validated
1027
+ * @param validator Validator to enroll
1028
+ */
932
1029
  registerValidator(name, validator) {
933
1030
  var container = this._validators[name] = this._validators[name] || [], index = container.indexOf(validator);
934
1031
  if (index == -1) {
@@ -941,6 +1038,11 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
941
1038
  this._checkFieldValidity(name);
942
1039
  }
943
1040
  }
1041
+ /**
1042
+ * Removes a previously-registered validator from the named field.
1043
+ * @param name Name of the field the validator was registered against
1044
+ * @param validator Validator to remove
1045
+ */
944
1046
  unregisterValidator(name, validator) {
945
1047
  this._unregisterValidator(name, validator, true);
946
1048
  }
@@ -1024,7 +1126,17 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1024
1126
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1025
1127
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1026
1128
  };
1129
+ /** Attached-property key used to stash a field's pristine value on the element itself (see {@link PacemModelElement.originalValue}). */
1027
1130
  const ORIGINAL_VALUE_FIELD = 'pacem:model:original-value';
1131
+ /**
1132
+ * Base class for any element that behaves as a bindable, form-aware model value: it registers itself by
1133
+ * `name` with the ancestor {@link PacemFormElement} (found via {@link PacemFormRelevantElement}), tracks
1134
+ * `dirty`/`valid` state (reflected as `pacem-dirty`/`pacem-invalid` CSS classes), and remembers the value it
1135
+ * had when activated/set-pristine so {@link reset} can restore it.
1136
+ *
1137
+ * Concrete input/selection fields don't extend this directly - see {@link PacemBaseElement}, the abstract
1138
+ * subclass that adds readonly/required/focus/keyboard handling on top of it.
1139
+ */
1028
1140
  class PacemModelElement extends PacemFormRelevantElement {
1029
1141
  viewActivatedCallback() {
1030
1142
  super.viewActivatedCallback();
@@ -1090,22 +1202,26 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1090
1202
  form.unregisterField(name);
1091
1203
  super.disconnectedCallback();
1092
1204
  }
1205
+ /** @readonly The `value` this element had the last time it was activated or explicitly marked pristine (via {@link setPristine}); what {@link reset} restores. */
1093
1206
  get originalValue() {
1094
1207
  return pacemCore.CustomElementUtils.getAttachedPropertyValue(this, ORIGINAL_VALUE_FIELD);
1095
1208
  }
1096
1209
  _setAsOriginalValue(v) {
1097
1210
  pacemCore.CustomElementUtils.setAttachedPropertyValue(this, ORIGINAL_VALUE_FIELD, v);
1098
1211
  }
1212
+ /** Restores {@link value} to {@link originalValue} and clears {@link dirty}. */
1099
1213
  reset() {
1100
1214
  this.value = this.originalValue;
1101
1215
  // then
1102
1216
  this.dirty = false;
1103
1217
  }
1218
+ /** Marks the current `value` as the new baseline for {@link reset}/{@link originalValue} and clears {@link dirty}. */
1104
1219
  setPristine() {
1105
1220
  this._setAsOriginalValue(this.value);
1106
1221
  //
1107
1222
  this.dirty = false;
1108
1223
  }
1224
+ /** Marks this field as `dirty`. */
1109
1225
  setDirty() {
1110
1226
  this.dirty = true;
1111
1227
  }
@@ -1135,6 +1251,16 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1135
1251
  __decorate$I([
1136
1252
  pacemCore.Watch({ converter: pacemCore.PropertyConverters.String })
1137
1253
  ], PacemModelElement.prototype, "name", void 0);
1254
+ /**
1255
+ * Base class for editable form fields: it adds `required`/`autofocus`/`readonly`/`placeholder` state, focus
1256
+ * and keyboard handling (Esc to revert, Enter submit prevention), and the plumbing that wires the
1257
+ * `focus`/`blur`/`change`/`keydown`/`keyup` handlers onto whichever native {@link inputFields} a derived
1258
+ * class exposes.
1259
+ *
1260
+ * Not extended directly by concrete fields either - see {@link PacemBaseInputElement} (in `input.ts`) for
1261
+ * `<input>`/`<textarea>`-backed fields, and {@link PacemDataSourceElement} for datasource-driven ones
1262
+ * (lists, selects, radio groups, ...).
1263
+ */
1138
1264
  class PacemBaseElement extends PacemModelElement {
1139
1265
  constructor() {
1140
1266
  super(...arguments);
@@ -1205,6 +1331,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1205
1331
  compareValuePropertyValues(old, val) {
1206
1332
  return pacemCore.DefaultComparer(old, val);
1207
1333
  }
1334
+ /** @overridable Whether pressing Enter within this field should be prevented from submitting an ancestor form. Defaults to `false`. */
1208
1335
  get preventKeyboardSubmit() {
1209
1336
  return false;
1210
1337
  }
@@ -1338,12 +1465,18 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1338
1465
  __decorate$I([
1339
1466
  pacemCore.Watch({ converter: pacemCore.PropertyConverters.String })
1340
1467
  ], PacemBaseElement.prototype, "placeholder", void 0);
1468
+ /**
1469
+ * Scaffolding-specific counterpart of `@pacem/pacem-ui`'s `PacemItemElement`: a base class for elements that
1470
+ * register themselves against an ancestor {@link PacemItemsContainerBaseElement} (found via
1471
+ * {@link findContainer}) on activation, and unregister on disconnect. Extended by {@link PacemDataItemElement}.
1472
+ */
1341
1473
  class PacemItemElement extends pacemCore.Components.PacemElement {
1342
1474
  #container;
1343
- /** @overridable */
1475
+ /** @overridable Locates the ancestor items-container this item registers against. Defaults to the nearest {@link PacemItemsContainerBaseElement}. */
1344
1476
  findContainer() {
1345
1477
  return pacemCore.CustomElementUtils.findAncestor(this, n => n instanceof PacemItemsContainerBaseElement);
1346
1478
  }
1479
+ /** @readonly Gets the items-container this item is currently registered with, if any. */
1347
1480
  get container() {
1348
1481
  return this.#container;
1349
1482
  }
@@ -1361,6 +1494,12 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1361
1494
  super.disconnectedCallback();
1362
1495
  }
1363
1496
  }
1497
+ /**
1498
+ * Base class for form fields that also act as a registry of {@link PacemItemElement} children (e.g. a
1499
+ * datasource-backed selection field whose options are declared, not just databound). Combines
1500
+ * {@link PacemBaseElement}'s field behavior with `ItemsContainer<TItem>`'s registration API.
1501
+ * See {@link PacemDataSourceElement} for the concrete specialization holding {@link PacemDataItemElement}s.
1502
+ */
1364
1503
  class PacemItemsContainerBaseElement extends PacemBaseElement {
1365
1504
  /**
1366
1505
  * Registers a new item among the items.
@@ -1395,6 +1534,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1395
1534
  __decorate$I([
1396
1535
  pacemCore.Watch( /* can only be databound or assigned at runtime */)
1397
1536
  ], PacemItemsContainerBaseElement.prototype, "items", void 0);
1537
+ /** A single, declaratively-authored option (`<p-data-item>`) of a {@link PacemDataSourceElement}, as an alternative to a databound `datasource` array. */
1398
1538
  let PacemDataItemElement = class PacemDataItemElement extends PacemItemElement {
1399
1539
  };
1400
1540
  __decorate$I([
@@ -1429,6 +1569,13 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1429
1569
  PacemDataItemElement = __decorate$I([
1430
1570
  pacemCore.CustomElement({ tagName: pacemCore.P + '-data-item' })
1431
1571
  ], PacemDataItemElement);
1572
+ /**
1573
+ * Base class for datasource-driven selection fields (lists, dropdowns, radio/checkbox groups, autocomplete,
1574
+ * ...): adapts a raw `datasource` (an array of arbitrary entities, or declared {@link PacemDataItemElement}
1575
+ * children registered via {@link PacemItemsContainerBaseElement}) into a normalized {@link DataSource}, and
1576
+ * provides the value/view-value mapping and selection-matching logic (single or, when `multipleChoice` is
1577
+ * `true`, multi-select) that concrete subclasses build their UI on top of.
1578
+ */
1432
1579
  class PacemDataSourceElement extends PacemItemsContainerBaseElement {
1433
1580
  constructor(multipleChoice = false) {
1434
1581
  super();
@@ -1459,9 +1606,11 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1459
1606
  }
1460
1607
  return flag;
1461
1608
  }
1609
+ /** @overridable Maps a raw `datasource` array into its {@link DataSource} representation via {@link mapEntityToItem}. */
1462
1610
  buildAdaptedDatasource(ds = this.datasource) {
1463
1611
  return ds && ds.map(i => this.mapEntityToItem(i));
1464
1612
  }
1613
+ /** Recomputes {@link adaptedDatasource} and, if the current `value` no longer matches any item, calls {@link handleDatasourceMismatch}. Debounced. */
1465
1614
  databind(datasource = this.buildAdaptedDatasource(this.datasource)) {
1466
1615
  if (pacemCore.Utils.isNull(datasource) && pacemCore.Utils.isNull(this.adaptedDatasource))
1467
1616
  return;
@@ -1470,6 +1619,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1470
1619
  if (pacemCore.Utils.isNullOrEmpty(ds.filter(i => this.isDataSourceItemSelected(i))))
1471
1620
  this.handleDatasourceMismatch(ds);
1472
1621
  }
1622
+ /** @overridable Called by {@link databind} when the current `value` matches none of the adapted `datasource` items. Defaults to clearing `value`. */
1473
1623
  handleDatasourceMismatch(datasource) {
1474
1624
  this.value = undefined;
1475
1625
  }
@@ -1519,6 +1669,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1519
1669
  return false;
1520
1670
  }
1521
1671
  }
1672
+ /** @overridable Extracts the selectable `value` out of a raw datasource entity (via {@link valueProperty}, or `entity.value` for a {@link PacemDataItemElement}). */
1522
1673
  mapEntityToValue(entity) {
1523
1674
  if (entity == null) {
1524
1675
  throw 'entity cannot be null';
@@ -1534,6 +1685,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1534
1685
  }
1535
1686
  return value;
1536
1687
  }
1688
+ /** @overridable Extracts the display text out of a raw datasource entity (via {@link textProperty}, or `entity.label`/`entity.value` for a {@link PacemDataItemElement}). */
1537
1689
  mapEntityToViewValue(entity) {
1538
1690
  if (entity == null)
1539
1691
  throw 'entity cannot be null';
@@ -1548,6 +1700,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1548
1700
  }
1549
1701
  return viewValue;
1550
1702
  }
1703
+ /** @overridable Adapts a raw datasource entity into its normalized {@link DataSourceItem} shape, using {@link mapEntityToValue}, {@link mapEntityToViewValue} and {@link disabledProperty}. */
1551
1704
  mapEntityToItem(entity) {
1552
1705
  if (entity == null) {
1553
1706
  throw 'entity cannot be null';
@@ -1631,7 +1784,9 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1631
1784
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1632
1785
  };
1633
1786
  //namespace Pacem.Components.Scaffolding {
1787
+ /** Markup fragment for a `pacem-char-count` companion element, meant to be spliced into a `@CustomElement` template so a text field can display its own character counter. */
1634
1788
  const CHAR_COUNTER_CHILD = `<${pacemCore.P}-char-count hide="{{ :host.readonly || !(:host.minlength > 0 || :host.maxlength > 0) }}" minlength="{{ :host.minlength }}" maxlength="{{ :host.maxlength }}" string="{{ :host.value }}"></${pacemCore.P}-char-count>`;
1789
+ /** Displays how many characters {@link string} contains, relative to {@link minlength}/{@link maxlength}, flagging validity via CSS class. */
1635
1790
  let PacemCharCountElement = class PacemCharCountElement extends pacemCore.Components.PacemElement {
1636
1791
  _isValid(v) {
1637
1792
  const l = this._length(v);
@@ -1680,6 +1835,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1680
1835
  super('contenteditablechange', { html: html });
1681
1836
  }
1682
1837
  }
1838
+ /** Base class for {@link PacemContenteditableElement} toolbar/command items, registered as {@link PacemItemElement} children of the editor. */
1683
1839
  class PacemContenteditableCommandElement extends PacemItemElement {
1684
1840
  constructor() {
1685
1841
  super(...arguments);
@@ -1736,6 +1892,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1736
1892
  function isElement(node) {
1737
1893
  return node?.nodeType == Node.ELEMENT_NODE;
1738
1894
  }
1895
+ /** Rich-text (`contenteditable`) field, hosting {@link PacemContenteditableCommandElement} toolbar commands and tracking an undo/redo {@link history}. */
1739
1896
  let PacemContenteditableElement = class PacemContenteditableElement extends PacemItemsContainerBaseElement {
1740
1897
  constructor() {
1741
1898
  super('rich text editor');
@@ -1816,6 +1973,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1816
1973
  //this._workspace = document.createElement('div');
1817
1974
  }
1818
1975
  #history;
1976
+ /** @readonly Gets the undo/redo history service tracking this editor's HTML content. */
1819
1977
  get history() {
1820
1978
  return this.#history;
1821
1979
  }
@@ -1995,6 +2153,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
1995
2153
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1996
2154
  };
1997
2155
  //namespace Pacem.Components.Scaffolding {
2156
+ /** Base class for the toolbar button-shaped contenteditable commands (bold, align, link, wrap, ...), sharing icon/shortcut/tooltip/active-state behavior. */
1998
2157
  class PacemContenteditableButtonCommandElement extends PacemContenteditableCommandElement {
1999
2158
  cleanUp(_) {
2000
2159
  // do nothing
@@ -2036,6 +2195,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2036
2195
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2037
2196
  };
2038
2197
  //namespace Pacem.Components.Scaffolding {
2198
+ /** Toolbar button undoing or redoing the last change tracked by the contenteditable host's history. */
2039
2199
  let PacemContenteditableHistoryCommandElement = class PacemContenteditableHistoryCommandElement extends PacemContenteditableButtonCommandElement {
2040
2200
  exec() {
2041
2201
  return new Promise((resolve, _) => {
@@ -2099,6 +2259,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2099
2259
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2100
2260
  };
2101
2261
  //namespace Pacem.Components.Scaffolding {
2262
+ /** Toolbar button creating or removing a hyperlink (`<a>`) around the current selection. */
2102
2263
  let PacemContenteditableLinkCommandElement = class PacemContenteditableLinkCommandElement extends PacemContenteditableButtonCommandElement {
2103
2264
  isRelevant(range) {
2104
2265
  return !pacemCore.Utils.isNull(ContenteditableUtils.findSurroundingNode(range, HTMLAnchorElement));
@@ -2189,6 +2350,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2189
2350
  });
2190
2351
  });
2191
2352
  }
2353
+ /** Toolbar button inserting a (rescalable) picture into the contenteditable host, either by file picker or by pasted/dropped image file. */
2192
2354
  let PacemContenteditableImageCommandElement = class PacemContenteditableImageCommandElement extends PacemContenteditableButtonCommandElement {
2193
2355
  constructor() {
2194
2356
  super(...arguments);
@@ -2368,6 +2530,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2368
2530
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2369
2531
  };
2370
2532
  //namespace Pacem.Components.Scaffolding {
2533
+ /** Well-known `document.execCommand` commands supported out-of-the-box by {@link PacemContenteditableExecCommandElement}. */
2371
2534
  var KnownExecCommand;
2372
2535
  (function (KnownExecCommand) {
2373
2536
  KnownExecCommand["Bold"] = "bold";
@@ -2443,6 +2606,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2443
2606
  return ['none'];
2444
2607
  }
2445
2608
  }
2609
+ /** Toolbar button applying a native `document.execCommand`-backed formatting command (bold, italic, lists, ...) to the contenteditable host. */
2446
2610
  let PacemContenteditableExecCommandElement = class PacemContenteditableExecCommandElement extends PacemContenteditableButtonCommandElement {
2447
2611
  _matchRelevance(range, arg) {
2448
2612
  const found = (typeof arg === 'object') ?
@@ -2528,7 +2692,14 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2528
2692
  && element.hasAttribute('role')
2529
2693
  && element.attributes['role'].value === 'presenter';
2530
2694
  }
2695
+ /** Watches a contenteditable host for insertion/removal of elements matching a given selector (e.g. inert `[contenteditable=false]` islands), notifying a callback for each match, recursively. */
2531
2696
  class ContenteditableDOMObserver {
2697
+ /**
2698
+ * Initializes the observer, immediately scanning the given container and then watching it for further mutations.
2699
+ * @param contentElement The contenteditable container to observe.
2700
+ * @param mutationCallback Invoked for each matching node found, added or removed.
2701
+ * @param selector CSS selector used to filter relevant nodes.
2702
+ */
2532
2703
  constructor(contentElement, mutationCallback, selector = '*[contenteditable=false]') {
2533
2704
  this.#callback = mutationCallback;
2534
2705
  this.#selector = selector;
@@ -2564,6 +2735,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2564
2735
  }
2565
2736
  contentElement.querySelectorAll(this.#selector).forEach(el => this.#callback(el, true));
2566
2737
  }
2738
+ /** Stops observing and notifies the callback, as a removal, for every currently matching node. */
2567
2739
  dispose() {
2568
2740
  this._disposeContainer(this.#contentElement);
2569
2741
  }
@@ -2572,7 +2744,9 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2572
2744
  #contentElement;
2573
2745
  #mutationObserver;
2574
2746
  }
2747
+ /** Collection of static DOM/Range helper methods shared by the contenteditable command elements. */
2575
2748
  class ContenteditableUtils {
2749
+ /** Builds the default toolbar dashboard (undo/redo, formatting, alignment, link and image commands) as a detached fragment. */
2576
2750
  static getDefaultDashboard() {
2577
2751
  const frag = new DocumentFragment();
2578
2752
  const toolbar0 = document.createElement('div');
@@ -2637,9 +2811,17 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2637
2811
  }
2638
2812
  return node;
2639
2813
  }
2814
+ /**
2815
+ * Seeks for the nearest surrounding block-level element of a given Selection's range.
2816
+ * @param range
2817
+ */
2640
2818
  static findSurroundingBlockElement(range) {
2641
2819
  return this.findSurroundingNode(range, ContenteditableUtils.isBlockElement);
2642
2820
  }
2821
+ /**
2822
+ * Retrieves the sibling block-level elements (e.g. paragraphs) touched by a given Selection's range.
2823
+ * @param range
2824
+ */
2643
2825
  static findSurroundingSiblingBlockElements(range) {
2644
2826
  let output = [];
2645
2827
  if (isRoot(range.startContainer)) {
@@ -2679,6 +2861,10 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2679
2861
  }
2680
2862
  return started ? output : (root instanceof Element && !isRoot(root) ? [root] : []);
2681
2863
  }
2864
+ /**
2865
+ * Retrieves the top-level (direct children of the contenteditable root) elements spanned by a given Selection's range.
2866
+ * @param range
2867
+ */
2682
2868
  static findContainingRootElements(range) {
2683
2869
  const range1 = range.cloneRange(), range2 = range.cloneRange();
2684
2870
  range1.collapse(true);
@@ -2690,9 +2876,18 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2690
2876
  }
2691
2877
  return retval;
2692
2878
  }
2879
+ /**
2880
+ * Checks whether the given node is an `Element` with a block-level (non-`inline*`) computed display.
2881
+ * @param node
2882
+ */
2693
2883
  static isBlockElement(node) {
2694
2884
  return node instanceof Element && !getComputedStyle(node).display.startsWith('inline');
2695
2885
  }
2886
+ /**
2887
+ * Selects a node (or its contents, when `inside` is `true`) and applies the resulting range to the current document Selection.
2888
+ * @param node
2889
+ * @param inside
2890
+ */
2696
2891
  static select(node, inside = false) {
2697
2892
  const range = document.createRange();
2698
2893
  if (!inside) {
@@ -2708,6 +2903,11 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2708
2903
  selection.addRange(range);
2709
2904
  return range;
2710
2905
  }
2906
+ /**
2907
+ * Copies all attributes from one element onto another.
2908
+ * @param to
2909
+ * @param from
2910
+ */
2711
2911
  static copyAttributes(to, from) {
2712
2912
  const attrs = from.attributes;
2713
2913
  for (let j = 0; j < attrs.length; j++) {
@@ -2741,6 +2941,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2741
2941
  function getAlignIcon(align) {
2742
2942
  return 'format_align_' + align;
2743
2943
  }
2944
+ /** Toolbar button applying a text-alignment (left/center/right/justify) style to the block(s) touched by the current selection. */
2744
2945
  let PacemContenteditableAlignCommandElement = class PacemContenteditableAlignCommandElement extends PacemContenteditableButtonCommandElement {
2745
2946
  isRelevant(range) {
2746
2947
  const els = ContenteditableUtils.findSurroundingSiblingBlockElements(range);
@@ -2819,6 +3020,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2819
3020
  }
2820
3021
  return { result: false };
2821
3022
  }
3023
+ /** Dropdown command inserting an inert (`contenteditable=false`) placeholder token, picked from a suggestable datasource, into the contenteditable host. */
2822
3024
  let PacemContenteditablePlaceholderElement = class PacemContenteditablePlaceholderElement extends PacemContenteditableCommandElement {
2823
3025
  constructor() {
2824
3026
  super(...arguments);
@@ -2955,6 +3157,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
2955
3157
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2956
3158
  };
2957
3159
  //namespace Pacem.Components.Scaffolding {
3160
+ /** Toolbar button wrapping (or, if already applied, unwrapping) the block(s) touched by the current selection with a given tag (e.g. `blockquote`, `h1`). */
2958
3161
  let PacemContenteditableWrapCommandElement = class PacemContenteditableWrapCommandElement extends PacemContenteditableButtonCommandElement {
2959
3162
  isRelevant(range) {
2960
3163
  return !pacemCore.Utils.isNull(ContenteditableUtils.findSurroundingNode(range, this.tagname));
@@ -3065,6 +3268,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
3065
3268
  }
3066
3269
  return header;
3067
3270
  }
3271
+ /** Utility 12-month grid picker, used internally by {@link PacemCalendarPickerElement} to pick a month within {@link viewYear}. */
3068
3272
  let PacemCalendarMonthPickerElement = class PacemCalendarMonthPickerElement extends pacemCore.Components.PacemElement {
3069
3273
  propertyChangedCallback(name, old, val, first) {
3070
3274
  super.propertyChangedCallback(name, old, val, first);
@@ -3113,6 +3317,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
3113
3317
  template: `<div class="${pacemCore.PCSS}-month-picker">${buildMonthGrid()}</div>`
3114
3318
  })
3115
3319
  ], PacemCalendarMonthPickerElement);
3320
+ /** Dispatched by {@link PacemCalendarPickerElement} when its clear button is used to unselect the current date. */
3116
3321
  class CalendarDateUnselectEvent extends pacemUi.Components.UI.DateSelectEvent {
3117
3322
  constructor() {
3118
3323
  super(void 0);
@@ -3132,6 +3337,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
3132
3337
  const mod = y % 10;
3133
3338
  return y - mod;
3134
3339
  }
3340
+ /** Utility grid picker of {@link YEARS_IN_RANGE} years, used internally by {@link PacemCalendarPickerElement} to pick a year within the range containing {@link viewYear}. */
3135
3341
  let PacemCalendarYearPickerElement = class PacemCalendarYearPickerElement extends pacemCore.Components.PacemElement {
3136
3342
  propertyChangedCallback(name, old, val, first) {
3137
3343
  super.propertyChangedCallback(name, old, val, first);
@@ -3187,9 +3393,11 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
3187
3393
  }
3188
3394
  return `<${pacemCore.P}-panel hide="{{ :host.viewmode !== 'calendar' }}" class="calendar-header">${header}</${pacemCore.P}-panel>`;
3189
3395
  }
3396
+ /** {@link PacemBaseInputElement}-alike field that pops up a `pacem-calendar` (with month/year zoom levels) to pick a `Date` value. */
3190
3397
  let PacemCalendarPickerElement = class PacemCalendarPickerElement extends PacemBaseElement {
3191
3398
  constructor() {
3192
3399
  super(...arguments);
3400
+ /** Gets or sets which picker is currently shown in the dropdown: the day calendar, the month grid, or the year grid. */
3193
3401
  this.viewmode = 'calendar';
3194
3402
  this.#locked = false;
3195
3403
  this._swipeHandler = (e) => {
@@ -3522,9 +3730,11 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
3522
3730
  convert: (attr) => attr === 'true' ? true : (attr === 'false' ? false : attr),
3523
3731
  convertBack: (prop) => prop.toString()
3524
3732
  };
3733
+ /** {@link PacemBaseElement}-based single checkbox field, mapping its checked state to {@link trueValue}/{@link falseValue}. */
3525
3734
  let PacemCheckboxElement = class PacemCheckboxElement extends PacemBaseElement {
3526
3735
  constructor() {
3527
3736
  super('checkbox');
3737
+ /** Gets or sets the label displayed next to the checkbox (and used as the read-only view value when checked). */
3528
3738
  this.caption = '';
3529
3739
  this._key = '_' + pacemCore.Utils.uniqueCode();
3530
3740
  }
@@ -3628,6 +3838,7 @@ disabled="{{ (#${uid}.suddenValidation && (!(#${uid}.valid && #${uid}.dirty))) |
3628
3838
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3629
3839
  };
3630
3840
  //namespace Pacem.Components.Scaffolding {
3841
+ /** Renders {@link PacemDataSourceElement#datasource} as a list of `pacem-checkbox` items, producing an array `value` of the checked items' mapped values. */
3631
3842
  let PacemCheckboxListElement = class PacemCheckboxListElement extends PacemDataSourceElement {
3632
3843
  acceptValue(val) {
3633
3844
  // no need to implement
@@ -3950,17 +4161,24 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
3950
4161
  // super('datetimechange', { date: date });
3951
4162
  // }
3952
4163
  //}
4164
+ /** {@link PacemBaseElement}-based field composing a set of `pacem-select` dropdowns (year/month/day and, depending on {@link precision}, time) into a single `Date` value. */
3953
4165
  let PacemDatetimePickerElement = class PacemDatetimePickerElement extends PacemBaseElement {
3954
4166
  constructor() {
3955
4167
  super();
4168
+ /** Gets or sets the granularity of the picker: date only, or including hours/minutes ('minute') or hours/minutes/seconds ('second'). */
3956
4169
  this.precision = 'day';
3957
4170
  this._months = [];
4171
+ /** Internal: datasource of selectable days for the current {@link year}/{@link month}. */
3958
4172
  this._dates = [];
3959
4173
  this._a24 = [];
3960
4174
  this._a60 = [];
4175
+ /** Internal: datasource of selectable years, computed from {@link min}/{@link max}. */
3961
4176
  this._years = [];
4177
+ /** Internal: the hours select's current value. */
3962
4178
  this.hours = '00';
4179
+ /** Internal: the minutes select's current value. */
3963
4180
  this.minutes = '00';
4181
+ /** Internal: the seconds select's current value. */
3964
4182
  this.seconds = '00';
3965
4183
  }
3966
4184
  get inputFields() {
@@ -4240,6 +4458,13 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4240
4458
  return c > 3 && r && Object.defineProperty(target, key, r), r;
4241
4459
  };
4242
4460
  // TODO: add warning state
4461
+ /**
4462
+ * Base class for all `p-*-validator` elements: registers/unregisters itself against the ancestor
4463
+ * {@link PacemFormElement} field named by `watch`, and turns the abstract {@link evaluate} logic into the
4464
+ * `Validator` contract's `validate` (short-circuiting to valid when `disabled`). Concrete validators only
4465
+ * need to implement {@link evaluate}; the field's own error UI reads `invalid`/`errorMessage` off the
4466
+ * element (see {@link BASIC_VALIDATOR_TEMPLATE}).
4467
+ */
4243
4468
  class PacemBaseValidatorElement extends PacemFormRelevantElement {
4244
4469
  constructor() {
4245
4470
  super();
@@ -4273,6 +4498,7 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4273
4498
  }
4274
4499
  }
4275
4500
  #easer;
4501
+ /** Asks the owning {@link PacemFormElement} to re-validate the watched field on the next animation frame; call after a configuration property (e.g. `min`/`max`/`pattern`) changes so the field re-evaluates against the new rule. */
4276
4502
  triggerFormFieldValidation() {
4277
4503
  const form = this.form, watch = this.watch;
4278
4504
  if (!pacemCore.Utils.isNull(form) && !pacemCore.Utils.isNullOrEmpty(watch)) {
@@ -4282,6 +4508,7 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4282
4508
  });
4283
4509
  }
4284
4510
  }
4511
+ /** Validates `val` against this validator's rule; always resolves `true` (skips {@link evaluate}) when the validator is `disabled`. */
4285
4512
  validate(val) {
4286
4513
  if (this.disabled) {
4287
4514
  return pacemCore.Utils.fromResult(true);
@@ -4298,11 +4525,13 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4298
4525
  __decorate$s([
4299
4526
  pacemCore.Watch({ emit: false, reflectBack: true, converter: pacemCore.PropertyConverters.String })
4300
4527
  ], PacemBaseValidatorElement.prototype, "watch", void 0);
4528
+ /** Default shadow-DOM template shared by every built-in `p-*-validator`: a `<p-span>` (exposed as the `error-message` part) shown only while `invalid`, displaying `errorMessage`. */
4301
4529
  const BASIC_VALIDATOR_TEMPLATE = `<${pacemCore.P}-span part="error-message" hide="{{ !:host.invalid }}" text="{{ :host.errorMessage }}"></${pacemCore.P}-span>`;
4302
4530
  // #region TEXTUAL
4303
4531
  function isValueEmpty(val) {
4304
4532
  return pacemCore.Utils.isNullOrEmpty(val);
4305
4533
  }
4534
+ /** Validates that a field's value is not empty (`p-required-validator`). */
4306
4535
  let PacemRequiredValidatorElement = class PacemRequiredValidatorElement extends PacemBaseValidatorElement {
4307
4536
  evaluate(val) {
4308
4537
  let retval = !isValueEmpty(val);
@@ -4312,6 +4541,7 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4312
4541
  PacemRequiredValidatorElement = __decorate$s([
4313
4542
  pacemCore.CustomElement({ tagName: pacemCore.P + '-required-validator', template: BASIC_VALIDATOR_TEMPLATE, shadow: pacemCore.Defaults.USE_SHADOW_ROOT })
4314
4543
  ], PacemRequiredValidatorElement);
4544
+ /** Validates that a field's (non-empty) value matches a regular expression (`p-regex-validator`). */
4315
4545
  let PacemRegexValidatorElement = class PacemRegexValidatorElement extends PacemBaseValidatorElement {
4316
4546
  propertyChangedCallback(name, old, val, first) {
4317
4547
  super.propertyChangedCallback(name, old, val, first);
@@ -4333,6 +4563,7 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4333
4563
  PacemRegexValidatorElement = __decorate$s([
4334
4564
  pacemCore.CustomElement({ tagName: pacemCore.P + '-regex-validator', template: BASIC_VALIDATOR_TEMPLATE, shadow: pacemCore.Defaults.USE_SHADOW_ROOT })
4335
4565
  ], PacemRegexValidatorElement);
4566
+ /** Validates that a field's (non-empty) value's string length falls within `[min, max]` (`p-length-validator`). */
4336
4567
  let PacemLengthValidatorElement = class PacemLengthValidatorElement extends PacemBaseValidatorElement {
4337
4568
  propertyChangedCallback(name, old, val, first) {
4338
4569
  super.propertyChangedCallback(name, old, val, first);
@@ -4363,6 +4594,7 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4363
4594
  ], PacemLengthValidatorElement);
4364
4595
  // #endregion
4365
4596
  // #region NUMERIC/ORDINAL
4597
+ /** Validates that a field's (non-empty) numeric or date value falls within `[min, max]` (`p-range-validator`); dates (parsed via `Utils.parseDate`) are compared by their timestamp. */
4366
4598
  let PacemRangeValidatorElement = class PacemRangeValidatorElement extends PacemBaseValidatorElement {
4367
4599
  propertyChangedCallback(name, old, val, first) {
4368
4600
  super.propertyChangedCallback(name, old, val, first);
@@ -4402,6 +4634,7 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4402
4634
  ], PacemRangeValidatorElement);
4403
4635
  // #endregion
4404
4636
  // #region COMPLEX
4637
+ /** Validates a field's (non-empty) value against another (non-empty) value `to`, using the given comparison `operator` (`p-compare-validator`); dates are compared by their timestamp. */
4405
4638
  let PacemCompareValidatorElement = class PacemCompareValidatorElement extends PacemBaseValidatorElement {
4406
4639
  propertyChangedCallback(name, old, val, first) {
4407
4640
  super.propertyChangedCallback(name, old, val, first);
@@ -4456,6 +4689,7 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4456
4689
  pacemCore.CustomElement({ tagName: pacemCore.P + '-compare-validator', template: BASIC_VALIDATOR_TEMPLATE, shadow: pacemCore.Defaults.USE_SHADOW_ROOT })
4457
4690
  ], PacemCompareValidatorElement);
4458
4691
  // #endregion
4692
+ /** Validates a {@link BinaryValue}/file-name (non-empty) upload against an optional filename `pattern` and/or `maxSize` in bytes (`p-binary-validator`). */
4459
4693
  let PacemBinaryValidatorElement = class PacemBinaryValidatorElement extends PacemBaseValidatorElement {
4460
4694
  propertyChangedCallback(name, old, val, first) {
4461
4695
  super.propertyChangedCallback(name, old, val, first);
@@ -4489,6 +4723,13 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4489
4723
  PacemBinaryValidatorElement = __decorate$s([
4490
4724
  pacemCore.CustomElement({ tagName: pacemCore.P + '-binary-validator', template: BASIC_VALIDATOR_TEMPLATE, shadow: pacemCore.Defaults.USE_SHADOW_ROOT })
4491
4725
  ], PacemBinaryValidatorElement);
4726
+ /**
4727
+ * Validates a field's (non-empty) value by calling a remote `url` (`p-async-validator`), sending it - along
4728
+ * with any extra `parameters` - as a request parameter named after {@link PacemBaseValidatorElement#watch}.
4729
+ * The response is considered valid when it is the literal text `'true'`, or a fetched JSON payload whose API
4730
+ * result (see `Utils.getApiResult`) is truthy; anything else (including a failed fetch) is invalid.
4731
+ * Debounces requests by 1 second and memoizes the last request/result to avoid redundant round-trips.
4732
+ */
4492
4733
  let PacemAsyncValidatorElement = class PacemAsyncValidatorElement extends PacemBaseValidatorElement {
4493
4734
  constructor() {
4494
4735
  super(...arguments);
@@ -4608,6 +4849,7 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4608
4849
  template: BASIC_VALIDATOR_TEMPLATE + `<${pacemCore.P}-fetch autofetch="false" throttle="true" credentials="{{ :host.fetchCredentials }}" headers="{{ :host.fetchHeaders }}"></${pacemCore.P}-fetch>`, shadow: pacemCore.Defaults.USE_SHADOW_ROOT
4609
4850
  })
4610
4851
  ], PacemAsyncValidatorElement);
4852
+ /** Validates a field's (non-empty) value by deferring entirely to the externally-controlled {@link isValid} flag (`p-custom-validator`), for validation logic that doesn't fit the other built-in validators. */
4611
4853
  let PacemCustomValidatorElement = class PacemCustomValidatorElement extends PacemBaseValidatorElement {
4612
4854
  propertyChangedCallback(name, old, val, first) {
4613
4855
  super.propertyChangedCallback(name, old, val, first);
@@ -4650,6 +4892,11 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4650
4892
  function isValidatorFactory(v) {
4651
4893
  return 'attributes' in v && typeof v.attributes === 'function';
4652
4894
  }
4895
+ /**
4896
+ * Renders a single editing field (label, input, validators, tooltip) for {@link entity}'s property described by {@link metadata},
4897
+ * dynamically choosing and building up the concrete input element (e.g. `pacem-input-text`, `pacem-select`, `pacem-checkbox`, ...)
4898
+ * based on the metadata's `dataType`/`ui` hints. Used internally by `pacem-form` for autogenerated forms.
4899
+ */
4653
4900
  let PacemFormFieldElement = class PacemFormFieldElement extends PacemFormRelevantElement {
4654
4901
  constructor(_md = new pacemUi.Components.UI.MarkdownService()) {
4655
4902
  super();
@@ -4663,12 +4910,15 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
4663
4910
  };
4664
4911
  this._key = '_' + pacemCore.Utils.uniqueCode();
4665
4912
  }
4913
+ /** @readonly Gets this field's unique key, used to derive DOM ids for the label/input/fetcher. */
4666
4914
  get key() {
4667
4915
  return this._key;
4668
4916
  }
4917
+ /** @readonly Gets the inner `pacem-fetch` element used to retrieve remotely-sourced datasources for this field. */
4669
4918
  get fetcher() {
4670
4919
  return this._fetcher;
4671
4920
  }
4921
+ /** @readonly Gets the concrete input element built for this field (e.g. `pacem-input-text`, `pacem-select`, ...). */
4672
4922
  get field() {
4673
4923
  return this._field;
4674
4924
  }
@@ -5697,6 +5947,7 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
5697
5947
  return c > 3 && r && Object.defineProperty(target, key, r), r;
5698
5948
  };
5699
5949
  const MIN_LENGTH = 3;
5950
+ /** {@link PacemBaseElement}-based field pairing an address `pacem-suggest` (forward geocoding) with a draggable map marker (reverse geocoding) to pick an {@link Address}. */
5700
5951
  let PacemGeolocateElement = class PacemGeolocateElement extends PacemBaseElement {
5701
5952
  constructor() {
5702
5953
  super(...arguments);
@@ -5906,6 +6157,10 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
5906
6157
  const HIERARCHYITEM_MOVE_CSSCLASS = 'item-move';
5907
6158
  const HIERARCHYITEM_MOVE_ICON = 'drag_indicator';
5908
6159
  const DEFAULT_PARENTSPROPERTY = 'parents';
6160
+ /**
6161
+ * {@link PacemBaseElement}-based field for editing a DAG-like parent/child hierarchy over {@link datasource}: items are
6162
+ * arranged level-by-level and linked/unlinked via drag-drop, producing an array `value` of `{ [valueProperty]: any, parents: any[] }`.
6163
+ */
5909
6164
  let PacemHierarchyElement = class PacemHierarchyElement extends PacemBaseElement {
5910
6165
  getViewValue(value) {
5911
6166
  return '';
@@ -5917,6 +6172,7 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
5917
6172
  super();
5918
6173
  this.#bindings = new Map();
5919
6174
  this.#dropTargets = new Map();
6175
+ /** Gets or sets the caption of the balloon button used to unlink a parent/child relation. */
5920
6176
  this.unlinkCaption = 'Delete';
5921
6177
  this._binderClickHandler = (evt) => {
5922
6178
  const origType = evt.originalEvent.type;
@@ -6396,16 +6652,30 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
6396
6652
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6397
6653
  };
6398
6654
  //namespace Pacem.Components.Scaffolding {
6655
+ /** When a {@link PacemBaseInputElement} propagates its native input's value to the `value` property: on every keystroke (`Input`), or only once the field loses focus (`Blur`). */
6399
6656
  var ChangePolicy;
6400
6657
  (function (ChangePolicy) {
6401
6658
  ChangePolicy["Input"] = "input";
6402
6659
  ChangePolicy["Blur"] = "blur";
6403
6660
  })(ChangePolicy || (ChangePolicy = {}));
6661
+ /** Attached-property key used to mark a native `<input>`/`<textarea>` as already wired up, so re-registration doesn't double-attach listeners (see {@link PacemBaseInputElement#registerInputFields}). */
6404
6662
  const INPUT_FIELD_ACTIVATED_PROP = 'pacem:scaffolding:input_field';
6663
+ /**
6664
+ * Base class for fields backed by one or more native `<input>`/`<textarea>` elements ({@link inputField}):
6665
+ * wires `input`/`focus` listeners onto them, applies `changePolicy`/`debounce` to decide when the native
6666
+ * value is read back into {@link PacemModelElement#value} (via {@link getValue}), and optionally
6667
+ * auto-selects the field's content on focus.
6668
+ *
6669
+ * Extended by {@link PacemOrdinalInputElement} (numeric/date-like inputs) and
6670
+ * {@link PacemTextualInputElement} (text-like inputs); further specialized by the concrete `input-*.ts`
6671
+ * elements in this package (e.g. text, number, date, password, ...).
6672
+ */
6405
6673
  class PacemBaseInputElement extends PacemBaseElement {
6406
6674
  constructor() {
6407
6675
  super(...arguments);
6676
+ /** Gets or sets how long to wait, after the native input changes, before propagating the value: `false` (default, propagate on the next animation frame), `true` (propagate via `requestAnimationFrame`), or a number of milliseconds to debounce by. */
6408
6677
  this.debounce = false;
6678
+ /** Gets or sets when the native input's value gets read back into {@link PacemModelElement#value}: on every `input` event, or only on `blur`. Defaults to {@link ChangePolicy.Input}. */
6409
6679
  this.changePolicy = ChangePolicy.Input;
6410
6680
  this._focusHandler = (evt) => {
6411
6681
  if (!this.autoselect) {
@@ -6436,6 +6706,7 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
6436
6706
  this.inputField.value = pacemCore.Utils.isNullOrEmpty(val) ? '' : val;
6437
6707
  }
6438
6708
  }
6709
+ /** @readonly Gets the first (usually only) native input element among {@link PacemBaseElement#inputFields}. */
6439
6710
  get inputField() {
6440
6711
  return this.inputFields[0];
6441
6712
  }
@@ -6540,6 +6811,11 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
6540
6811
  __decorate$o([
6541
6812
  pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Boolean })
6542
6813
  ], PacemBaseInputElement.prototype, "autoselect", void 0);
6814
+ /**
6815
+ * Base class for numeric/ordinal native inputs (e.g. `number`, `range`, `date`-like fields): adds
6816
+ * `min`/`max`/`step`, mirrored onto the native input's own attributes, and parses its `value` attribute as
6817
+ * a float.
6818
+ */
6543
6819
  class PacemOrdinalInputElement extends PacemBaseInputElement {
6544
6820
  convertValueAttributeToProperty(attr) {
6545
6821
  return parseFloat(attr);
@@ -6572,6 +6848,11 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
6572
6848
  }
6573
6849
  })
6574
6850
  ], PacemOrdinalInputElement.prototype, "step", void 0);
6851
+ /**
6852
+ * Base class for text-like native inputs (e.g. `text`, `password`, `textarea` fields): adds
6853
+ * `pattern`/`minlength`/`maxlength`, mirrored onto the native input's own attributes, and treats an empty
6854
+ * string `value` as `null`.
6855
+ */
6575
6856
  class PacemTextualInputElement extends PacemBaseInputElement {
6576
6857
  convertValueAttributeToProperty(attr) {
6577
6858
  return attr;
@@ -6610,10 +6891,13 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
6610
6891
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6611
6892
  };
6612
6893
  //namespace Pacem.Components.Scaffolding {
6894
+ /** {@link PacemBaseInputElement} rendering one single-character `<input>` per position (e.g. OTP/verification codes), joining them into a single string `value`. */
6613
6895
  let PacemCharsInputElement = class PacemCharsInputElement extends PacemBaseInputElement {
6614
6896
  constructor() {
6615
6897
  super();
6898
+ /** Gets or sets how many single-character inputs to render. */
6616
6899
  this.charCount = 6;
6900
+ /** Gets or sets how the entered characters are transformed/displayed: as-is, forced to a case, or masked like a password. */
6617
6901
  this.inputTransform = 'none';
6618
6902
  this._itemCreateHandler = (e) => {
6619
6903
  const { dom, index } = e.detail;
@@ -6792,6 +7076,7 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
6792
7076
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6793
7077
  };
6794
7078
  //namespace Pacem.Components.Scaffolding {
7079
+ /** {@link PacemBaseElement}-based field pairing a native color picker with an alpha (0-100) slider, producing a hex/rgba color string `value`. */
6795
7080
  let PacemColorInputElement = class PacemColorInputElement extends PacemBaseElement {
6796
7081
  acceptValue(val) {
6797
7082
  const parsed = this._parseValue(val);
@@ -6836,7 +7121,7 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
6836
7121
  return value;
6837
7122
  }
6838
7123
  get inputFields() {
6839
- return [this._tint, this._alpha];
7124
+ return [this._tint, this._alpha].filter(e => !pacemCore.Utils.isNull(e));
6840
7125
  }
6841
7126
  };
6842
7127
  __decorate$m([
@@ -6869,21 +7154,27 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
6869
7154
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6870
7155
  };
6871
7156
  //namespace Pacem.Components.Scaffolding {
7157
+ /** {@link PacemTextualInputElement} for an `<input type="email">`, whose read-only view renders as a `mailto:` link. */
6872
7158
  let PacemEmailInputElement = class PacemEmailInputElement extends PacemTextualInputElement {
6873
7159
  toggleReadonlyView(readonly) {
6874
- this.input.hidden = readonly;
6875
- this.anchor.hidden = !readonly;
7160
+ const input = this._input, anchor = this._anchor;
7161
+ if (!pacemCore.Utils.isNull(input))
7162
+ input.hidden = readonly;
7163
+ if (!pacemCore.Utils.isNull(anchor))
7164
+ anchor.hidden = !readonly;
6876
7165
  }
6877
7166
  get inputFields() {
6878
- return [this.input];
7167
+ return pacemCore.Utils.isNull(this._input)
7168
+ ? []
7169
+ : [this._input];
6879
7170
  }
6880
7171
  };
6881
7172
  __decorate$l([
6882
7173
  pacemCore.ViewChild('input[type=email]')
6883
- ], PacemEmailInputElement.prototype, "input", void 0);
7174
+ ], PacemEmailInputElement.prototype, "_input", void 0);
6884
7175
  __decorate$l([
6885
7176
  pacemCore.ViewChild(pacemCore.P + '-a')
6886
- ], PacemEmailInputElement.prototype, "anchor", void 0);
7177
+ ], PacemEmailInputElement.prototype, "_anchor", void 0);
6887
7178
  PacemEmailInputElement = __decorate$l([
6888
7179
  pacemCore.CustomElement({
6889
7180
  tagName: pacemCore.P + '-input-email',
@@ -6897,18 +7188,22 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
6897
7188
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6898
7189
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6899
7190
  };
7191
+ /** Name of the {@link FileUploadEvent} dispatched by {@link PacemUploadElement} while/after a chunked upload progresses. */
6900
7192
  const FileUploadEventName = 'fileupload';
7193
+ /** Name of the {@link FileChangeEvent} dispatched by {@link PacemUploadElement} whenever the selected file(s)/directory change. */
6901
7194
  const FileChangeEventName = 'filechange';
6902
7195
  class StoragePickEvent extends pacemCore.CustomTypedEvent {
6903
7196
  constructor(file) {
6904
7197
  super('pick', file);
6905
7198
  }
6906
7199
  }
7200
+ /** Dispatched by {@link PacemUploadElement} to report chunked-upload progress/completion. */
6907
7201
  class FileUploadEvent extends pacemCore.CustomTypedEvent {
6908
7202
  constructor(file) {
6909
7203
  super(FileUploadEventName, file);
6910
7204
  }
6911
7205
  }
7206
+ /** Dispatched by {@link PacemUploadElement} whenever the user picks (or clears) file(s)/a directory. */
6912
7207
  class FileChangeEvent extends pacemCore.CustomTypedEvent {
6913
7208
  constructor(file) {
6914
7209
  super(FileChangeEventName, file);
@@ -6939,20 +7234,30 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
6939
7234
  return stats;
6940
7235
  }
6941
7236
  /**
6942
- * PacemUploader Component
7237
+ * PacemUploader Component: {@link PacemBaseElement}-based field to pick and (optionally chunk-)upload file(s)/a directory to {@link url},
7238
+ * or defer to the File System Access API pickers depending on {@link selectMode}.
6943
7239
  */
6944
7240
  let PacemUploadElement = class PacemUploadElement extends PacemBaseElement {
6945
7241
  constructor(_tweener = new pacemCore.Animations.TweenService()) {
6946
7242
  super();
6947
7243
  this._tweener = _tweener;
7244
+ /** Gets or sets the caption of the "undo" button, shown while an upload with {@link url} set is in progress. */
6948
7245
  this.undoCaption = 'undo';
7246
+ /** Gets or sets the caption of the "retry" button, shown after a {@link failed} upload. */
6949
7247
  this.retryCaption = 'retry';
7248
+ /** Gets or sets the caption of the "clear" button. */
6950
7249
  this.clearCaption = 'clear';
7250
+ /** @readonly Gets whether an upload is currently in progress. */
6951
7251
  this.uploading = false;
7252
+ /** @readonly Gets the total size (in bytes) of the file(s) currently being uploaded. */
6952
7253
  this.size = 0;
7254
+ /** @readonly Gets the current upload progress, from 0 to 100. */
6953
7255
  this.percentage = .0;
7256
+ /** @readonly Gets whether the current upload has completed. */
6954
7257
  this.complete = false;
7258
+ /** @readonly Gets whether the current upload chunk request failed (enabling the retry button). */
6955
7259
  this.failed = false;
7260
+ /** @readonly Gets whether the selected file failed {@link pattern}/{@link maxSize} validation. */
6956
7261
  this.invalidFile = false;
6957
7262
  this._fields = {
6958
7263
  'parallelism': 3,
@@ -7012,11 +7317,14 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
7012
7317
  }
7013
7318
  return 'filter_none';
7014
7319
  }
7320
+ /** @readonly Gets the raw blob currently being (or last) uploaded. */
7015
7321
  get blob() {
7016
7322
  return this._fields.blob;
7017
7323
  }
7018
7324
  get inputFields() {
7019
- return [this._fileupload];
7325
+ return pacemCore.Utils.isNull(this._fileupload)
7326
+ ? []
7327
+ : [this._fileupload];
7020
7328
  }
7021
7329
  getViewValue(val) {
7022
7330
  const value = this._localValue || val;
@@ -7587,18 +7895,21 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
7587
7895
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7588
7896
  };
7589
7897
  //namespace Pacem.Components.Scaffolding {
7898
+ /** {@link PacemTextualInputElement} wrapping an `<input type="hidden">`, for values that must round-trip without a visible UI. */
7590
7899
  let PacemHiddenInputElement = class PacemHiddenInputElement extends PacemTextualInputElement {
7591
7900
  constructor() {
7592
7901
  super();
7593
7902
  }
7594
7903
  toggleReadonlyView(readonly) { }
7595
7904
  get inputFields() {
7596
- return [this.input];
7905
+ return pacemCore.Utils.isNull(this._input)
7906
+ ? []
7907
+ : [this._input];
7597
7908
  }
7598
7909
  };
7599
7910
  __decorate$j([
7600
7911
  pacemCore.ViewChild('input[type=hidden]')
7601
- ], PacemHiddenInputElement.prototype, "input", void 0);
7912
+ ], PacemHiddenInputElement.prototype, "_input", void 0);
7602
7913
  PacemHiddenInputElement = __decorate$j([
7603
7914
  pacemCore.CustomElement({ tagName: pacemCore.P + '-input-hidden', template: '<input type="hidden" />', shadow: pacemCore.Defaults.USE_SHADOW_ROOT })
7604
7915
  ], PacemHiddenInputElement);
@@ -7611,6 +7922,7 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
7611
7922
  };
7612
7923
  //namespace Pacem.Components.Scaffolding {
7613
7924
  const getUserMediaFunctions = pacemCore.Utils.getUserMediaFunctions();
7925
+ /** The current stage of {@link PacemSnapshotElement}'s capture workflow: idle/upload-or-camera choice, live webcam preview, or reviewing the captured image before confirming. */
7614
7926
  var SnapshotStep;
7615
7927
  (function (SnapshotStep) {
7616
7928
  SnapshotStep["Start"] = "start";
@@ -7622,14 +7934,17 @@ css-class="{{ {'${pacemCore.PCSS}-fetching': ::_fetcher.fetching, '${pacemCore.P
7622
7934
  super('confirmsnapshot', { buffer });
7623
7935
  }
7624
7936
  }
7937
+ /** A `<p-snapshot>` field: a {@link PacemBaseElement} image-capture control that lets the user upload a file or, when a webcam is available, take a live snapshot (with an optional 3s timer); its `value` is the resulting data-URL string. */
7625
7938
  let PacemSnapshotElement = class PacemSnapshotElement extends PacemBaseElement {
7626
7939
  constructor() {
7627
7940
  super(...arguments);
7628
7941
  this._resizeHandler = (evt) => {
7629
7942
  this._renderValue();
7630
7943
  };
7944
+ /** Gets or sets the current step of the capture workflow. Defaults to {@link SnapshotStep.Start}. */
7631
7945
  this.step = SnapshotStep.Start;
7632
7946
  /*const*/ this._canUseWebcam = getUserMediaFunctions.length > 0;
7947
+ /** Seconds left before the timed shutter fires; `0` outside of a timed countdown. */
7633
7948
  this._countdown = 0;
7634
7949
  this._webcamInitialized = false;
7635
7950
  this._grabberChangeHandler = (e) => {
@@ -7933,18 +8248,26 @@ css-class="{{ {
7933
8248
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7934
8249
  };
7935
8250
  //namespace Pacem.Components.Scaffolding {
8251
+ /** A single image entry (full-size and thumbnail sources) offered as a pick candidate by {@link PacemEditImageElement}. */
7936
8252
  class Picture {
7937
8253
  }
8254
+ /** Name of the {@link ImageFetchRequestEvent} dispatched by {@link PacemEditImageElement}/{@link PacemImageInputElement} to request a page of pictures. */
7938
8255
  const ImageFetchRequestEventName = 'imagefetchrequest';
8256
+ /** Dispatched to request a page of {@link Picture}s (e.g. on scroll, or when the search hint changes); handlers are expected to respond by setting `imageSet`. */
7939
8257
  class ImageFetchRequestEvent extends pacemCore.CustomTypedEvent {
7940
8258
  constructor(args) {
7941
8259
  super(ImageFetchRequestEventName, args, { bubbles: true /*, scoped: false */ });
7942
8260
  }
7943
8261
  }
8262
+ /**
8263
+ * Picture-picker panel: lets the user search/browse a fetched {@link imageSet}, upload a new full-size/thumbnail pair, or take a
8264
+ * snapshot, resolving `value` to the chosen picture's source. Hosted inside a dialog by {@link PacemImageInputElement}.
8265
+ */
7944
8266
  let PacemEditImageElement = class PacemEditImageElement extends pacemCore.Components.PacemElement {
7945
8267
  constructor() {
7946
8268
  super(...arguments);
7947
8269
  this._index = 0;
8270
+ /** Gets or sets the search hint typed by the user, triggering a fresh {@link ImageFetchRequestEvent} when it changes. */
7948
8271
  this.hint = '';
7949
8272
  }
7950
8273
  _uploaderPropertyChangedCallback(evt) {
@@ -8115,6 +8438,10 @@ css-class="{{ {
8115
8438
  </${pacemCore.P}-panel>`
8116
8439
  })
8117
8440
  ], PacemEditImageElement);
8441
+ /**
8442
+ * {@link PacemBaseElement}-based field showing an image preview with edit/clear buttons; editing opens a dialog hosting a
8443
+ * {@link PacemEditImageElement} to pick/upload/snapshot a new picture, while `value` also accepts a directly-typed URL.
8444
+ */
8118
8445
  let PacemImageInputElement = class PacemImageInputElement extends PacemBaseElement {
8119
8446
  constructor() {
8120
8447
  super(...arguments);
@@ -8318,13 +8645,16 @@ css-class="{{ {
8318
8645
  return c > 3 && r && Object.defineProperty(target, key, r), r;
8319
8646
  };
8320
8647
  //namespace Pacem.Components.Scaffolding {
8648
+ /** {@link PacemOrdinalInputElement} for an `<input type="number">`, formatting its read-only view value via {@link format}. */
8321
8649
  let PacemNumberInputElement = class PacemNumberInputElement extends PacemOrdinalInputElement {
8322
8650
  toggleReadonlyView(readonly) {
8323
8651
  this._span.hidden = !readonly;
8324
8652
  this._input.hidden = readonly;
8325
8653
  }
8326
8654
  get inputFields() {
8327
- return [this._input];
8655
+ return pacemCore.Utils.isNull(this._input)
8656
+ ? []
8657
+ : [this._input];
8328
8658
  }
8329
8659
  getViewValue(val) {
8330
8660
  return this.value != null ? this._format(this.value) : undefined;
@@ -8374,6 +8704,7 @@ css-class="{{ {
8374
8704
  return c > 3 && r && Object.defineProperty(target, key, r), r;
8375
8705
  };
8376
8706
  //namespace Pacem.Components.Scaffolding {
8707
+ /** {@link PacemTextualInputElement} for an `<input type="password">`, with a toggle to reveal/hide the entered text and a masked read-only view. */
8377
8708
  let PacemPasswordInputElement = class PacemPasswordInputElement extends PacemTextualInputElement {
8378
8709
  constructor() {
8379
8710
  super();
@@ -8385,7 +8716,9 @@ css-class="{{ {
8385
8716
  };
8386
8717
  }
8387
8718
  get inputFields() {
8388
- return [this._input];
8719
+ return pacemCore.Utils.isNull(this._input)
8720
+ ? []
8721
+ : [this._input];
8389
8722
  }
8390
8723
  viewActivatedCallback() {
8391
8724
  super.viewActivatedCallback();
@@ -8401,6 +8734,7 @@ css-class="{{ {
8401
8734
  this._toggler.removeEventListener('mousedown', this._togglerMousedownHandler, false);
8402
8735
  }
8403
8736
  }
8737
+ /** Toggles the native input between `password` (masked) and `text` (revealed) type. */
8404
8738
  toggleVisibility() {
8405
8739
  const current = this._input.type;
8406
8740
  this._input.type = current === 'password' ? 'text' : 'password';
@@ -8442,12 +8776,15 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
8442
8776
  return c > 3 && r && Object.defineProperty(target, key, r), r;
8443
8777
  };
8444
8778
  //namespace Pacem.Components.Scaffolding {
8779
+ /** A `<p-input-search>` field: a {@link PacemTextualInputElement} backed by a native `<input type="search">`. */
8445
8780
  let PacemSearchInputElement = class PacemSearchInputElement extends PacemTextualInputElement {
8446
8781
  constructor() {
8447
8782
  super();
8448
8783
  }
8449
8784
  get inputFields() {
8450
- return [this.input];
8785
+ return pacemCore.Utils.isNull(this._input)
8786
+ ? []
8787
+ : [this._input];
8451
8788
  }
8452
8789
  toggleReadonlyView(readonly) {
8453
8790
  // no readonly view provided.
@@ -8455,7 +8792,7 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
8455
8792
  };
8456
8793
  __decorate$e([
8457
8794
  pacemCore.ViewChild('input[type=search]')
8458
- ], PacemSearchInputElement.prototype, "input", void 0);
8795
+ ], PacemSearchInputElement.prototype, "_input", void 0);
8459
8796
  PacemSearchInputElement = __decorate$e([
8460
8797
  pacemCore.CustomElement({ tagName: pacemCore.P + '-input-search', template: '<input type="search" class="' + pacemCore.PCSS + '-input" />', shadow: pacemCore.Defaults.USE_SHADOW_ROOT })
8461
8798
  ], PacemSearchInputElement);
@@ -8467,24 +8804,30 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
8467
8804
  return c > 3 && r && Object.defineProperty(target, key, r), r;
8468
8805
  };
8469
8806
  //namespace Pacem.Components.Scaffolding {
8807
+ /** A `<p-input-tel>` field: a {@link PacemTextualInputElement} backed by a native `<input type="tel">`, whose readonly view renders as a clickable `tel:` link. */
8470
8808
  let PacemTelInputElement = class PacemTelInputElement extends PacemTextualInputElement {
8471
8809
  constructor() {
8472
8810
  super();
8473
8811
  }
8474
8812
  toggleReadonlyView(readonly) {
8475
- this.input.hidden = readonly;
8476
- this.anchor.hidden = !readonly;
8813
+ const input = this._input, anchor = this._anchor;
8814
+ if (!pacemCore.Utils.isNull(input))
8815
+ input.hidden = readonly;
8816
+ if (!pacemCore.Utils.isNull(anchor))
8817
+ anchor.hidden = !readonly;
8477
8818
  }
8478
8819
  get inputFields() {
8479
- return [this.input];
8820
+ return pacemCore.Utils.isNull(this._input)
8821
+ ? []
8822
+ : [this._input];
8480
8823
  }
8481
8824
  };
8482
8825
  __decorate$d([
8483
8826
  pacemCore.ViewChild('input[type=tel]')
8484
- ], PacemTelInputElement.prototype, "input", void 0);
8827
+ ], PacemTelInputElement.prototype, "_input", void 0);
8485
8828
  __decorate$d([
8486
8829
  pacemCore.ViewChild(pacemCore.P + '-a')
8487
- ], PacemTelInputElement.prototype, "anchor", void 0);
8830
+ ], PacemTelInputElement.prototype, "_anchor", void 0);
8488
8831
  PacemTelInputElement = __decorate$d([
8489
8832
  pacemCore.CustomElement({ tagName: pacemCore.P + '-input-tel', template: `<input type="tel" class="${pacemCore.PCSS}-input" /><${pacemCore.P}-a class="${pacemCore.PCSS}-readonly" disabled="{{ $pacem.isNullOrEmpty(:host.value) }}" href="{{ 'tel:'+ :host.value }}"><${pacemCore.P}-text text="{{ :host.viewValue }}"></${pacemCore.P}-text></${pacemCore.P}-a>`, shadow: pacemCore.Defaults.USE_SHADOW_ROOT })
8490
8833
  ], PacemTelInputElement);
@@ -8496,6 +8839,7 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
8496
8839
  return c > 3 && r && Object.defineProperty(target, key, r), r;
8497
8840
  };
8498
8841
  //namespace Pacem.Components.Scaffolding {
8842
+ /** A `<p-input-text>` field: a {@link PacemTextualInputElement} backed by a native `<input type="text">`, with an optional character counter. */
8499
8843
  let PacemTextInputElement = class PacemTextInputElement extends PacemTextualInputElement {
8500
8844
  constructor() {
8501
8845
  super();
@@ -8505,7 +8849,9 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
8505
8849
  this._input.hidden = readonly;
8506
8850
  }
8507
8851
  get inputFields() {
8508
- return [this._input];
8852
+ return pacemCore.Utils.isNull(this._input)
8853
+ ? []
8854
+ : [this._input];
8509
8855
  }
8510
8856
  };
8511
8857
  __decorate$c([
@@ -8529,24 +8875,30 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
8529
8875
  return c > 3 && r && Object.defineProperty(target, key, r), r;
8530
8876
  };
8531
8877
  //namespace Pacem.Components.Scaffolding {
8878
+ /** A `<p-input-url>` field: a {@link PacemTextualInputElement} backed by a native `<input type="url">`, whose readonly view renders as a clickable link opening in a new tab. */
8532
8879
  let PacemUrlInputElement = class PacemUrlInputElement extends PacemTextualInputElement {
8533
8880
  constructor() {
8534
8881
  super();
8535
8882
  }
8536
8883
  toggleReadonlyView(readonly) {
8537
- this.input.hidden = readonly;
8538
- this.anchor.hidden = !readonly;
8884
+ const input = this._input, anchor = this._anchor;
8885
+ if (!pacemCore.Utils.isNull(input))
8886
+ input.hidden = readonly;
8887
+ if (!pacemCore.Utils.isNull(anchor))
8888
+ anchor.hidden = !readonly;
8539
8889
  }
8540
8890
  get inputFields() {
8541
- return [this.input];
8891
+ return pacemCore.Utils.isNull(this._input)
8892
+ ? []
8893
+ : [this._input];
8542
8894
  }
8543
8895
  };
8544
8896
  __decorate$b([
8545
8897
  pacemCore.ViewChild('input[type=url]')
8546
- ], PacemUrlInputElement.prototype, "input", void 0);
8898
+ ], PacemUrlInputElement.prototype, "_input", void 0);
8547
8899
  __decorate$b([
8548
8900
  pacemCore.ViewChild(pacemCore.P + '-a')
8549
- ], PacemUrlInputElement.prototype, "anchor", void 0);
8901
+ ], PacemUrlInputElement.prototype, "_anchor", void 0);
8550
8902
  PacemUrlInputElement = __decorate$b([
8551
8903
  pacemCore.CustomElement({ tagName: pacemCore.P + '-input-url', template: `<input type="url" class="${pacemCore.PCSS}-input" />${CHAR_COUNTER_CHILD}<${pacemCore.P}-a class="${pacemCore.PCSS}-readonly" disabled="{{ $pacem.isNullOrEmpty(:host.value) }}" href="{{ :host.value }}" target="_blank"><${pacemCore.P}-text text="{{ :host.viewValue }}"></${pacemCore.P}-text></${pacemCore.P}-a>`, shadow: pacemCore.Defaults.USE_SHADOW_ROOT })
8552
8904
  ], PacemUrlInputElement);
@@ -8558,11 +8910,14 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
8558
8910
  return c > 3 && r && Object.defineProperty(target, key, r), r;
8559
8911
  };
8560
8912
  //namespace Pacem.Components.Scaffolding {
8913
+ /** Default tile-layer URL template used by {@link PacemLatLngElement} when {@link LatLngOptions.tiles} isn't set (currently empty, i.e. the map adapter's own default applies). */
8561
8914
  const DEFAULT_TILES = "";
8915
+ /** Default map attribution string used by {@link PacemLatLngElement} when {@link LatLngOptions.attribution} isn't set (currently empty, i.e. the map adapter's own default applies). */
8562
8916
  const DEFAULT_ATTRIBUTION = "";
8563
8917
  //const TILES = `//api.mapbox.com/styles/v1/cmerighi/ciwz1gib7002l2prvgpi724nk/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoiY21lcmlnaGkiLCJhIjoiY2lsZHIxdGJmMDAxOHc4bHowamxpZ2Z2OCJ9.7I7ndF-rAkx_1Sqi0bw3Ew`;
8564
8918
  //const ATTRIBUTION = `Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>`
8565
8919
  const REVERSE_GEOCODE_URL = 'https://nominatim.openstreetmap.org/reverse';
8920
+ /** A `<p-latlng>` field: a {@link PacemBaseElement} coordinate picker combining paired lat/lng number inputs with an interactive, draggable-marker map (Leaflet/OSM, Azure Maps or Google Maps) and reverse-geocoded address preview. */
8566
8921
  let PacemLatLngElement = class PacemLatLngElement extends PacemBaseElement {
8567
8922
  convertValueAttributeToProperty(attr) {
8568
8923
  const regexArray = /^\s*([+-]?\d+\.?\d+)[,\s]\s*([+-]?\d+\.?\d+)\s*$/.exec(attr);
@@ -8740,10 +9095,12 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
8740
9095
  function pullEmpty() {
8741
9096
  return { name: '', value: '' };
8742
9097
  }
9098
+ /** A `<p-namevalue-list>` field: a {@link PacemBaseElement} editor for a repeatable list of name/value string pairs, whose `value` is either an array of {@link NameValuePair}s or, when {@link PacemNameValueListElement#dictionary} is set, a plain `{ [name]: value }` object. */
8743
9099
  let PacemNameValueListElement = class PacemNameValueListElement extends PacemBaseElement {
8744
9100
  constructor() {
8745
9101
  super(...arguments);
8746
9102
  this.inputFields = [];
9103
+ /** Internal editable rows, mirrored to/from `value` depending on {@link dictionary}. */
8747
9104
  this._bag = [];
8748
9105
  }
8749
9106
  toggleReadonlyView(readonly) {
@@ -8869,6 +9226,7 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
8869
9226
  return c > 3 && r && Object.defineProperty(target, key, r), r;
8870
9227
  };
8871
9228
  //namespace Pacem.Components.Scaffolding {
9229
+ /** A `<p-property-picker>` field: a {@link PacemBaseElement} wrapping a {@link PacemSelectElement} whose datasource is auto-populated with the (recursively flattened) watched property names of a `target` element. */
8872
9230
  let PacemPropertyPickerElement = class PacemPropertyPickerElement extends PacemBaseElement {
8873
9231
  get inputFields() {
8874
9232
  return [this._select];
@@ -8951,6 +9309,7 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
8951
9309
  return c > 3 && r && Object.defineProperty(target, key, r), r;
8952
9310
  };
8953
9311
  //namespace Pacem.Components.Scaffolding {
9312
+ /** A `<p-radio>` field: a {@link PacemBaseElement} wrapping a single native `<input type="radio">` with a caption label; its `value` is the radio's native value when {@link selected}, otherwise `undefined`. Used standalone or as the item template driven by {@link PacemRadioListElement}. */
8954
9313
  let PacemRadioElement = class PacemRadioElement extends PacemBaseElement {
8955
9314
  convertValueAttributeToProperty(attr) {
8956
9315
  return attr;
@@ -9028,6 +9387,7 @@ ${CHAR_COUNTER_CHILD}<span class="${pacemCore.PCSS}-readonly"><${pacemCore.P}-te
9028
9387
  return c > 3 && r && Object.defineProperty(target, key, r), r;
9029
9388
  };
9030
9389
  //namespace Pacem.Components.Scaffolding {
9390
+ /** A `<p-radio-list>` field: a {@link PacemDataSourceElement} rendering the datasource as a group of mutually-exclusive `<p-radio>` buttons. */
9031
9391
  let PacemRadioListElement = class PacemRadioListElement extends PacemDataSourceElement {
9032
9392
  acceptValue(val) {
9033
9393
  // no need to implement
@@ -9096,9 +9456,11 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
9096
9456
  return c > 3 && r && Object.defineProperty(target, key, r), r;
9097
9457
  };
9098
9458
  //namespace Pacem.Components.Scaffolding {
9459
+ /** A `<p-select>` field: a {@link PacemDataSourceElement} rendering the datasource as a native `<select>` dropdown. */
9099
9460
  let PacemSelectElement = class PacemSelectElement extends PacemDataSourceElement {
9100
9461
  constructor() {
9101
9462
  super(...arguments);
9463
+ /** Gets or sets whether an extra, empty/placeholder `<option>` is prepended to the rendered choices. Defaults to `true`. */
9102
9464
  this.emptyOption = true;
9103
9465
  }
9104
9466
  toggleReadonlyView(readonly) {
@@ -9108,7 +9470,9 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
9108
9470
  // no actual need to be idem-potent...
9109
9471
  // (take care in future)
9110
9472
  get inputFields() {
9111
- return [this._select];
9473
+ return pacemCore.Utils.isNull(this._select)
9474
+ ? []
9475
+ : [this._select];
9112
9476
  }
9113
9477
  _manageDom(evt) {
9114
9478
  const args = evt.detail, item = args.item;
@@ -9221,6 +9585,7 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
9221
9585
  };
9222
9586
  //namespace Pacem.Components.Scaffolding {
9223
9587
  // TODO: exploit 202x features like https://developer.mozilla.org/en-US/docs/Web/CSS/offset-path or https://developer.chrome.com/blog/anchor-positioning-api
9588
+ /** A `<p-slider>` field: a {@link PacemBaseElement} numeric range control with a draggable thumb, keyboard support, and an optional tooltip-style thumb label; its `value` is a number between `min` and `max`. */
9224
9589
  let PacemSliderElement = class PacemSliderElement extends PacemBaseElement {
9225
9590
  constructor() {
9226
9591
  super(...arguments);
@@ -9508,6 +9873,7 @@ on-${pacemCore.PropertyChangeEventName}=":host._selectionChanged($event, ^index,
9508
9873
  }
9509
9874
  const BALLOON_POPUP_DELAY = 100;
9510
9875
  const BALLOON_POPOUT_DELAY = 0;
9876
+ /** A `<p-suggest>` field: a {@link PacemDataSourceElement} autocomplete/typeahead text input, backed by a native `<input type="text">` and a dropdown balloon of filtered, highlighted suggestions; optionally accepts free-typed values not present in the datasource. */
9511
9877
  let PacemSuggestElement = class PacemSuggestElement extends PacemDataSourceElement {
9512
9878
  constructor() {
9513
9879
  super(...arguments);
@@ -10053,6 +10419,7 @@ class="button-flat icon-rotate ${pacemCore.PCSS}-anim anim-pop anim-sudden anim-
10053
10419
  super('tagadd', { value: value });
10054
10420
  }
10055
10421
  }
10422
+ /** A single `<p-tag>` chip: displays a label and a remove button, dispatching a `remove` event (after an out-transition) when dismissed. Rendered by {@link PacemTagsElement} for each item in its `value`. */
10056
10423
  let PacemTagElement = class PacemTagElement extends pacemCore.Components.PacemElement {
10057
10424
  propertyChangedCallback(name, old, val, first) {
10058
10425
  super.propertyChangedCallback(name, old, val, first);
@@ -10091,6 +10458,7 @@ class="button-flat icon-rotate ${pacemCore.PCSS}-anim anim-pop anim-sudden anim-
10091
10458
  <${pacemCore.P}-button on-click=":host._remove()"></${pacemCore.P}-button>`
10092
10459
  })
10093
10460
  ], PacemTagElement);
10461
+ /** A `<p-tags>` field: a {@link PacemDataSourceElement} editor rendering `value` as a list of removable {@link PacemTagElement} chips, plus a {@link PacemSuggestElement} for picking (or, when {@link allowNew} is set, typing) new tags to add. */
10094
10462
  let PacemTagsElement = class PacemTagsElement extends PacemDataSourceElement {
10095
10463
  constructor() {
10096
10464
  super(true);
@@ -10214,10 +10582,13 @@ class="button-flat icon-rotate ${pacemCore.PCSS}-anim anim-pop anim-sudden anim-
10214
10582
  return c > 3 && r && Object.defineProperty(target, key, r), r;
10215
10583
  };
10216
10584
  //namespace Pacem.Components.Scaffolding {
10585
+ /** A `<p-textarea>` field: a {@link PacemTextualInputElement} backed by a native `<textarea>`, with an optional character counter. */
10217
10586
  let PacemTextAreaElement = class PacemTextAreaElement extends PacemTextualInputElement {
10218
10587
  constructor() {
10219
10588
  super(...arguments);
10589
+ /** Gets or sets the native `<textarea>`'s `rows` attribute. Defaults to `5`. */
10220
10590
  this.rows = 5;
10591
+ /** Gets or sets the native `<textarea>`'s `cols` attribute. Defaults to `50`. */
10221
10592
  this.cols = 50;
10222
10593
  }
10223
10594
  /** @override */
@@ -10225,11 +10596,16 @@ class="button-flat icon-rotate ${pacemCore.PCSS}-anim anim-pop anim-sudden anim-
10225
10596
  return true;
10226
10597
  }
10227
10598
  toggleReadonlyView(readonly) {
10228
- this._span.hidden = !readonly;
10229
- this._input.hidden = readonly;
10599
+ const input = this._input, span = this._span;
10600
+ if (!pacemCore.Utils.isNull(input))
10601
+ input.hidden = readonly;
10602
+ if (!pacemCore.Utils.isNull(span))
10603
+ span.hidden = !readonly;
10230
10604
  }
10231
10605
  get inputFields() {
10232
- return [this._input];
10606
+ return pacemCore.Utils.isNull(this._input)
10607
+ ? []
10608
+ : [this._input];
10233
10609
  }
10234
10610
  propertyChangedCallback(name, old, val, first) {
10235
10611
  super.propertyChangedCallback(name, old, val, first);
@@ -10262,15 +10638,18 @@ class="button-flat icon-rotate ${pacemCore.PCSS}-anim anim-pop anim-sudden anim-
10262
10638
  return c > 3 && r && Object.defineProperty(target, key, r), r;
10263
10639
  };
10264
10640
  //namespace Pacem.Components.Scaffolding {
10641
+ /** A `<p-textarea-markdown>` field: a {@link PacemTextualInputElement} backed by a native `<textarea>` for editing Markdown text, whose readonly view renders the value as HTML via {@link Components.UI.MarkdownService}. */
10265
10642
  let PacemMarkdownTextAreaElement = class PacemMarkdownTextAreaElement extends PacemTextualInputElement {
10266
10643
  constructor(_md = new pacemUi.Components.UI.MarkdownService()) {
10267
10644
  super();
10268
10645
  this._md = _md;
10646
+ /** Gets or sets the native `<textarea>`'s `rows` attribute. Defaults to `5`. */
10269
10647
  this.rows = 5;
10648
+ /** Gets or sets the native `<textarea>`'s `cols` attribute. Defaults to `50`. */
10270
10649
  this.cols = 50;
10271
10650
  this._keydownHandler = (evt) => {
10272
10651
  if (evt.keyCode === 9 /* tab */) {
10273
- const input = this.input, value = input.value;
10652
+ const input = this._input, value = input.value;
10274
10653
  var ndx = input.selectionStart;
10275
10654
  input.value = value.substr(0, ndx) + ' ' + value.substr(ndx);
10276
10655
  pacemCore.preventDefaultHandler(evt);
@@ -10278,14 +10657,17 @@ class="button-flat icon-rotate ${pacemCore.PCSS}-anim anim-pop anim-sudden anim-
10278
10657
  };
10279
10658
  }
10280
10659
  toggleReadonlyView(readonly) {
10281
- this.input.hidden = readonly;
10660
+ if (!pacemCore.Utils.isNull(this._input))
10661
+ this._input.hidden = readonly;
10282
10662
  }
10283
10663
  /** @override */
10284
10664
  get preventKeyboardSubmit() {
10285
10665
  return true;
10286
10666
  }
10287
10667
  get inputFields() {
10288
- return [this.input];
10668
+ return pacemCore.Utils.isNull(this._input)
10669
+ ? []
10670
+ : [this._input];
10289
10671
  }
10290
10672
  getViewValue(val) {
10291
10673
  return this._md.toHtml(val);
@@ -10302,11 +10684,11 @@ class="button-flat icon-rotate ${pacemCore.PCSS}-anim anim-pop anim-sudden anim-
10302
10684
  }
10303
10685
  viewActivatedCallback() {
10304
10686
  super.viewActivatedCallback();
10305
- this.input.addEventListener("keydown", this._keydownHandler, false);
10687
+ this._input.addEventListener("keydown", this._keydownHandler, false);
10306
10688
  }
10307
10689
  disconnectedCallback() {
10308
- this.input &&
10309
- this.input.removeEventListener("keydown", this._keydownHandler, false);
10690
+ this._input &&
10691
+ this._input.removeEventListener("keydown", this._keydownHandler, false);
10310
10692
  super.disconnectedCallback();
10311
10693
  }
10312
10694
  };
@@ -10318,7 +10700,7 @@ class="button-flat icon-rotate ${pacemCore.PCSS}-anim anim-pop anim-sudden anim-
10318
10700
  ], PacemMarkdownTextAreaElement.prototype, "cols", void 0);
10319
10701
  __decorate([
10320
10702
  pacemCore.ViewChild('textarea')
10321
- ], PacemMarkdownTextAreaElement.prototype, "input", void 0);
10703
+ ], PacemMarkdownTextAreaElement.prototype, "_input", void 0);
10322
10704
  __decorate([
10323
10705
  pacemCore.ViewChild(`div.${pacemCore.PCSS}-readonly`)
10324
10706
  ], PacemMarkdownTextAreaElement.prototype, "_markdown", void 0);