pict-section-picker 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -162,6 +162,24 @@ OnCreate: (pTerm) =>
162
162
  | `OnCreate` | — | `(term) => {Value, Text}` to enable creatable entries. |
163
163
  | `OnChange` | — | Called after a selection: single → `(value, record)`, multi → `(values, records)`. |
164
164
 
165
+ ## View methods
166
+
167
+ Call these on the picker view instance — `this.pict.views['<hash>']`:
168
+
169
+ | Method | Description |
170
+ |--------|-------------|
171
+ | `render()` | Paint (or repaint) the control into its destination. |
172
+ | `getValue()` | The current selection — a scalar in single mode, an array of values in multi mode. |
173
+ | `setValue(pValue)` | Set the selection programmatically — the supported counterpart to `getValue()`. Single mode takes a scalar; multi mode takes an array (or a csv string). Writes through to the bound address(es), resolves the display label of any unknown value (from the loaded options, else via `ResolveValue` in async mode), and repaints. Does **not** fire `OnChange` — it is a programmatic set (e.g. a host marshaling a form value into the control), not a user pick. Returns the view for chaining. |
174
+ | `getSelectedRecords()` | (multi) The full `{Value, Text}` record list for the current selection. |
175
+
176
+ ```javascript
177
+ const tmpPicker = this.pict.views['AuthorPicker'];
178
+ tmpPicker.setValue(141); // single: select author 141 (label resolves via ResolveValue if async)
179
+ tmpPicker.setValue([ 2, 10, 141 ]); // multi: select these values (array or "2,10,141" csv both accepted)
180
+ const tmpSelected = tmpPicker.getValue();
181
+ ```
182
+
165
183
  ## Theming
166
184
 
167
185
  The widget paints from `--theme-color-*` tokens with sensible hex fallbacks, so it inherits the host app's theme. Relevant tokens: `--theme-color-brand-primary`, `--theme-color-text-primary`, `--theme-color-text-muted`, `--theme-color-border-default`, `--theme-color-border-light`, `--theme-color-border-strong`, `--theme-color-background-primary`, `--theme-color-background-panel`, `--theme-color-background-tertiary`.
package/form.js ADDED
@@ -0,0 +1,5 @@
1
+ // Sub-path entry: `require('pict-section-picker/form')`.
2
+ //
3
+ // The pict-section-form input-type adapter — kept off the package's main entry so the picker core
4
+ // stays usable without pict-section-form (which is an OPTIONAL peer dependency, required only here).
5
+ module.exports = require('./source/form/Pict-Section-Picker-FormInput.js');
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "pict-section-picker",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Pict-native themeable searchable select / combobox — single & multi select, server pagination, categorized groups and creatable entries, driven by a host-agnostic async DataProvider (with a built-in Meadow EntityProvider adapter). A jQuery/select2-free replacement.",
5
5
  "main": "source/Pict-Section-Picker.js",
6
6
  "types": "types/Pict-Section-Picker.d.ts",
7
7
  "files": [
8
8
  "source",
9
- "types"
9
+ "types",
10
+ "form.js"
10
11
  ],
11
12
  "scripts": {
12
13
  "test": "npx mocha -u tdd -R spec",
@@ -48,11 +49,20 @@
48
49
  "pict-provider": "^1.0.13",
49
50
  "pict-view": "^1.0.68"
50
51
  },
52
+ "peerDependencies": {
53
+ "pict-section-form": ">=1.0.0"
54
+ },
55
+ "peerDependenciesMeta": {
56
+ "pict-section-form": {
57
+ "optional": true
58
+ }
59
+ },
51
60
  "devDependencies": {
52
61
  "@types/mocha": "^10.0.10",
53
62
  "@types/node": "^16.18.126",
54
63
  "browser-env": "^3.3.0",
55
64
  "pict": "^1.0.372",
65
+ "pict-section-form": "^1.0.0",
56
66
  "quackage": "^1.3.0",
57
67
  "typescript": "^5.9.3"
58
68
  }
@@ -0,0 +1,299 @@
1
+ /**
2
+ * pict-section-form input-type adapter for pict-section-picker.
3
+ *
4
+ * Renders a picker widget into a dynamic-form cell — the host-agnostic replacement for a select2
5
+ * entity input. Registered as a pict-section-form InputType (default name `Picker`); a host opts a
6
+ * field in with `PictForm.InputType: 'Picker'` (+ Entity / SearchFields / Multiple / …). Used by the
7
+ * pict-section-recordset entity filters and by document forms alike.
8
+ *
9
+ * Contextual scoping (project / spec-year / tenant / …) stays host configuration: the descriptor may
10
+ * carry a `PictForm.GetContextScopeFilter()` hook, OR a host subclass overrides
11
+ * `getContextualSearchFilters(pInput)`. Either way the module never learns what the context means.
12
+ *
13
+ * Requires `pict-section-form` (an OPTIONAL peer dependency — only loaded when you require this file)
14
+ * and the `Pict-Section-Picker` provider registered on the pict instance.
15
+ */
16
+ const libPictInputExtension = require('pict-section-form').PictInputExtensionProvider;
17
+
18
+ /** @type {Record<string, any>} */
19
+ const _DEFAULT_CONFIGURATION =
20
+ {
21
+ ProviderIdentifier: 'Pict-Input-Picker',
22
+ AutoInitialize: true,
23
+ AutoInitializeOrdinal: 0,
24
+ AutoSolveWithApp: false,
25
+ };
26
+
27
+ /**
28
+ * Build the InputType metatemplate entries (a hidden informary input + a host element the picker
29
+ * renders into) for a given InputType name + provider hash. Injected via injectTemplateSet.
30
+ *
31
+ * @param {string} pInputTypeName - e.g. 'Picker'.
32
+ * @param {string} pProviderHash - the input-extension provider service hash to auto-attach.
33
+ * @return {Array<Record<string, any>>}
34
+ */
35
+ const buildPickerInputTemplates = (pInputTypeName, pProviderHash) =>
36
+ [
37
+ {
38
+ // Mirror the host's DEFAULT input metatemplate structure exactly — a label span + the control
39
+ // where the <input>/<select> would be — so the picker inherits the host's filter/form chrome
40
+ // (label style, spacing, and the row's flex-end trash alignment) instead of inventing its own.
41
+ HashPostfix: `-Template-Input-InputType-${pInputTypeName}`,
42
+ DefaultInputExtensions: [ pProviderHash ],
43
+ Template: /*html*/`
44
+ <!-- InputType ${pInputTypeName} {~D:Record.Hash~} {~D:Record.DataType~} -->
45
+ <input type="hidden" id="{~D:Record.Macro.RawHTMLID~}" tabindex="-1" {~D:Record.Macro.InputFullProperties~} {~D:Record.Macro.InputChangeHandler~} value="" />
46
+ <span>{~D:Record.Name~}:</span> <div class="pps-form-host" id="PICKER-FOR-{~D:Record.Macro.RawHTMLID~}"></div>`,
47
+ },
48
+ {
49
+ HashPostfix: `-VerticalTemplate-Input-InputType-${pInputTypeName}`,
50
+ DefaultInputExtensions: [ pProviderHash ],
51
+ Template: /*html*/`
52
+ <!-- InputType ${pInputTypeName} {~D:Record.Hash~} {~D:Record.DataType~} -->
53
+ <input type="hidden" id="{~D:Record.Macro.RawHTMLID~}" tabindex="-1" {~D:Record.Macro.InputFullProperties~} {~D:Record.Macro.InputChangeHandler~} value="" />
54
+ <span>{~D:Record.Name~}:</span> <div class="pps-form-host" id="PICKER-FOR-{~D:Record.Macro.RawHTMLID~}"></div>`,
55
+ },
56
+ {
57
+ HashPostfix: `-TabularTemplate-Begin-Input-InputType-${pInputTypeName}`,
58
+ DefaultInputExtensions: [ pProviderHash ],
59
+ Template: /*html*/`
60
+ <input type="hidden" id="PICKER-TABULAR-DATA-{~D:Record.Macro.RawHTMLID~}-{~D:Context[2].Key~}" tabindex="-1" {~D:Record.Macro.InformaryTabular~} `,
61
+ },
62
+ {
63
+ HashPostfix: `-TabularTemplate-End-Input-InputType-${pInputTypeName}`,
64
+ DefaultInputExtensions: [ pProviderHash ],
65
+ Template: /*html*/`
66
+ value="" />
67
+ <div class="pps-form-host" id="PICKER-TABULAR-{~D:Record.Macro.RawHTMLID~}-{~D:Context[2].Key~}"></div>`,
68
+ },
69
+ ];
70
+
71
+ class PictInputTypePicker extends libPictInputExtension
72
+ {
73
+ constructor(pFable, pOptions, pServiceHash)
74
+ {
75
+ super(pFable, Object.assign({}, _DEFAULT_CONFIGURATION, pOptions), pServiceHash);
76
+ /** @type {any} */
77
+ this.pict;
78
+ }
79
+
80
+ // Visible host + picker-view-hash ids. Must match the metatemplate element ids above.
81
+ getPickerHostID(pRawHTMLID) { return `#PICKER-FOR-${pRawHTMLID}`; }
82
+ getPickerHash(pRawHTMLID) { return `Picker-${pRawHTMLID}`; }
83
+ getTabularPickerHostID(pRawHTMLID, pRowIndex) { return `#PICKER-TABULAR-${pRawHTMLID}-${pRowIndex}`; }
84
+ getTabularPickerHash(pRawHTMLID, pRowIndex) { return `Picker-${pRawHTMLID}-${pRowIndex}`; }
85
+ getTabularHiddenID(pRawHTMLID, pRowIndex) { return `#PICKER-TABULAR-DATA-${pRawHTMLID}-${pRowIndex}`; }
86
+
87
+ /**
88
+ * Overridable: extra FoxHound scope stanza(s) AND-applied to the entity search. Default reads the
89
+ * descriptor's `GetContextScopeFilter()` hook (set by the host / recordset filter base), else its
90
+ * static `BaseFilter`. Host subclasses override this to read app state (project / spec-year / …).
91
+ *
92
+ * @param {Record<string, any>} pInput @return {string|Array<string>}
93
+ */
94
+ getContextualSearchFilters(pInput)
95
+ {
96
+ const tmpHook = pInput && pInput.PictForm && pInput.PictForm.GetContextScopeFilter;
97
+ if (typeof tmpHook === 'function')
98
+ {
99
+ try { return tmpHook() || ''; }
100
+ catch (pError) { this.pict.log.warn(`Pict-Input-Picker: GetContextScopeFilter threw.`, pError); return ''; }
101
+ }
102
+ return (pInput && pInput.PictForm && pInput.PictForm.BaseFilter) || '';
103
+ }
104
+
105
+ /** Build the picker config from a form input descriptor. */
106
+ _buildPickerConfig(pInput, pHostSelector, fOnChange)
107
+ {
108
+ const tmpPF = pInput.PictForm || {};
109
+ return {
110
+ DestinationAddress: pHostSelector,
111
+ Mode: tmpPF.Multiple ? 'multi' : 'single',
112
+ Placeholder: tmpPF.Placeholder || (tmpPF.Entity ? `Select ${tmpPF.Entity}…` : 'Select…'),
113
+ Searchable: (tmpPF.Searchable !== false),
114
+ Entity: tmpPF.Entity,
115
+ SearchFields: tmpPF.SearchFields,
116
+ ValueField: tmpPF.ValueField,
117
+ TextField: tmpPF.TextField,
118
+ PageSize: tmpPF.PageSize || 20,
119
+ Options: tmpPF.Options || [],
120
+ // Per-search contextual scope — the generic hook the host fills.
121
+ BaseFilter: () => this.getContextualSearchFilters(pInput),
122
+ OnChange: fOnChange,
123
+ };
124
+ }
125
+
126
+ /** Instantiate (or reuse) the picker view for a config — entity-backed when Entity is set. */
127
+ _instantiatePicker(pPickerHash, pConfig)
128
+ {
129
+ const tmpProvider = this.pict.providers['Pict-Section-Picker'];
130
+ if (!tmpProvider)
131
+ {
132
+ this.pict.log.warn('Pict-Input-Picker: the Pict-Section-Picker provider is not registered.');
133
+ return null;
134
+ }
135
+ return pConfig.Entity
136
+ ? tmpProvider.createEntityPicker(pPickerHash, pConfig)
137
+ : tmpProvider.createPicker(pPickerHash, pConfig);
138
+ }
139
+
140
+ /**
141
+ * Write a picker value into the form: csv to the hidden informary input (+ dataChanged), plus the
142
+ * raw array to `PictForm.ValueArrayAddress` when set (the recordset filter reads Values as an
143
+ * array). The csv-vs-array bridge lives HERE (generic) instead of in each host.
144
+ */
145
+ _commit(pView, pInput, pValue, pHTMLSelector)
146
+ {
147
+ const tmpCSV = Array.isArray(pValue) ? pValue.join(',') : (pValue === undefined || pValue === null ? '' : pValue);
148
+ this.pict.ContentAssignment.assignContent(pHTMLSelector, tmpCSV);
149
+ if (pInput.PictForm && pInput.PictForm.ValueArrayAddress && pView.Bundle)
150
+ {
151
+ const tmpArray = Array.isArray(pValue) ? pValue : (tmpCSV === '' ? [] : String(tmpCSV).split(','));
152
+ this.pict.manifest.setValueAtAddress(pView.Bundle, pInput.PictForm.ValueArrayAddress, tmpArray);
153
+ }
154
+ pView.dataChanged(pInput.Hash);
155
+ }
156
+
157
+ _commitTabular(pView, pInput, pValue, pHiddenID, pRowIndex)
158
+ {
159
+ const tmpCSV = Array.isArray(pValue) ? pValue.join(',') : (pValue === undefined || pValue === null ? '' : pValue);
160
+ this.pict.ContentAssignment.assignContent(pHiddenID, tmpCSV);
161
+ pView.dataChangedTabular(pInput.PictForm.GroupIndex, pInput.PictForm.InputIndex, pRowIndex);
162
+ }
163
+
164
+ /**
165
+ * Idempotently mount (or reuse) the picker into its host element + seed its value. Called from both
166
+ * onInputInitialize and onDataMarshalToForm because, in the async-virtual filter render, the host
167
+ * element only exists in the real DOM by the marshal pass — whichever hook fires post-DOM wins, and
168
+ * re-calls are harmless (the picker view is reused by hash).
169
+ * @return {boolean} true if the picker is mounted.
170
+ */
171
+ _mountPicker(pView, pInput, pValue, pHostSelector, pPickerHash, fOnChange)
172
+ {
173
+ if (!this.pict.ContentAssignment.getElement(pHostSelector)?.[0]) { return false; }
174
+ const tmpView = this._instantiatePicker(pPickerHash, this._buildPickerConfig(pInput, pHostSelector, fOnChange));
175
+ if (!tmpView) { return false; }
176
+ tmpView.render();
177
+ tmpView.setValue(pValue);
178
+ return true;
179
+ }
180
+
181
+ // --- non-tabular lifecycle ---
182
+
183
+ onInputInitialize(pView, pGroup, pRow, pInput, pValue, pHTMLSelector, pTransactionGUID)
184
+ {
185
+ const tmpRaw = pInput.Macro.RawHTMLID;
186
+ this._mountPicker(pView, pInput, pValue, this.getPickerHostID(tmpRaw), this.getPickerHash(tmpRaw),
187
+ (pNewValue) => this._commit(pView, pInput, pNewValue, pInput.Macro.HTMLSelector));
188
+ return super.onInputInitialize(pView, pGroup, pRow, pInput, pValue, pHTMLSelector, pTransactionGUID);
189
+ }
190
+
191
+ onDataMarshalToForm(pView, pGroup, pRow, pInput, pValue, pHTMLSelector, pTransactionGUID)
192
+ {
193
+ const tmpRaw = pInput.Macro.RawHTMLID;
194
+ const tmpPickerHash = this.getPickerHash(tmpRaw);
195
+ // Mount if it isn't already (post-DOM hook), else just re-seed the value.
196
+ if (!this._mountPicker(pView, pInput, pValue, this.getPickerHostID(tmpRaw), tmpPickerHash,
197
+ (pNewValue) => this._commit(pView, pInput, pNewValue, pInput.Macro.HTMLSelector)))
198
+ {
199
+ const tmpView = this.pict.views[tmpPickerHash];
200
+ if (tmpView) { tmpView.setValue(pValue); }
201
+ }
202
+ return super.onDataMarshalToForm(pView, pGroup, pRow, pInput, pValue, pHTMLSelector, pTransactionGUID);
203
+ }
204
+
205
+ onDataRequest(pView, pInput, pValue, pHTMLSelector)
206
+ {
207
+ const tmpView = this.pict.views[this.getPickerHash(pInput.Macro.RawHTMLID)];
208
+ const tmpVal = tmpView ? tmpView.getValue() : pValue;
209
+ this._commit(pView, pInput, tmpVal, pHTMLSelector);
210
+ return super.onDataRequest(pView, pInput, tmpVal, pHTMLSelector);
211
+ }
212
+
213
+ // --- tabular lifecycle (one picker view instance per (input, row)) ---
214
+
215
+ /** Idempotent tabular mount (see _mountPicker). @return {boolean} */
216
+ _mountPickerTabular(pView, pInput, pValue, pRowIndex)
217
+ {
218
+ const tmpRaw = pInput.Macro.RawHTMLID;
219
+ const tmpHostSelector = this.getTabularPickerHostID(tmpRaw, pRowIndex);
220
+ if (!this.pict.ContentAssignment.getElement(tmpHostSelector)?.[0]) { return false; }
221
+ const tmpHiddenID = this.getTabularHiddenID(tmpRaw, pRowIndex);
222
+ const tmpView = this._instantiatePicker(this.getTabularPickerHash(tmpRaw, pRowIndex),
223
+ this._buildPickerConfig(pInput, tmpHostSelector, (pNewValue) => this._commitTabular(pView, pInput, pNewValue, tmpHiddenID, pRowIndex)));
224
+ if (!tmpView) { return false; }
225
+ tmpView.render();
226
+ tmpView.setValue(pValue);
227
+ return true;
228
+ }
229
+
230
+ onInputInitializeTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID)
231
+ {
232
+ this._mountPickerTabular(pView, pInput, pValue, pRowIndex);
233
+ return super.onInputInitializeTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID);
234
+ }
235
+
236
+ onDataMarshalToFormTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID)
237
+ {
238
+ if (!this._mountPickerTabular(pView, pInput, pValue, pRowIndex))
239
+ {
240
+ const tmpView = this.pict.views[this.getTabularPickerHash(pInput.Macro.RawHTMLID, pRowIndex)];
241
+ if (tmpView) { tmpView.setValue(pValue); }
242
+ }
243
+ return super.onDataMarshalToFormTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID);
244
+ }
245
+
246
+ onDataRequestTabular(pView, pInput, pValue, pHTMLSelector, pRowIndex)
247
+ {
248
+ const tmpView = this.pict.views[this.getTabularPickerHash(pInput.Macro.RawHTMLID, pRowIndex)];
249
+ const tmpVal = tmpView ? tmpView.getValue() : pValue;
250
+ this._commitTabular(pView, pInput, tmpVal, this.getTabularHiddenID(pInput.Macro.RawHTMLID, pRowIndex), pRowIndex);
251
+ return super.onDataRequestTabular(pView, pInput, tmpVal, pHTMLSelector, pRowIndex);
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Register the Picker InputType on a pict instance: the input-extension provider + its metatemplate(s).
257
+ * Idempotent. Requires `pict-section-form` loaded (PictFormSectionDefaultTemplateProvider present) and
258
+ * the `Pict-Section-Picker` provider registered.
259
+ *
260
+ * @param {any} pPict - the pict instance.
261
+ * @param {Record<string, any>} [pOptions]
262
+ * - InputTypeName {string} - the InputType string (default 'Picker').
263
+ * - ProviderHash {string} - the input-extension provider service hash (default 'Pict-Input-Picker').
264
+ * - ProviderClass {Function} - provider class to register (default PictInputTypePicker; a host
265
+ * passes a subclass that overrides getContextualSearchFilters for its scoping).
266
+ * - TemplatePrefix {string|Array<string>} - the form template prefix(es) to inject the metatemplate
267
+ * under (default 'Pict-MT-Base'; Headlight uses its theme prefixes).
268
+ * @return {boolean} true if registered.
269
+ */
270
+ const registerPickerInputType = (pPict, pOptions) =>
271
+ {
272
+ const tmpOptions = pOptions || {};
273
+ const tmpInputTypeName = tmpOptions.InputTypeName || 'Picker';
274
+ const tmpProviderHash = tmpOptions.ProviderHash || 'Pict-Input-Picker';
275
+ const tmpProviderClass = tmpOptions.ProviderClass || PictInputTypePicker;
276
+ const tmpPrefixes = Array.isArray(tmpOptions.TemplatePrefix) ? tmpOptions.TemplatePrefix : [ tmpOptions.TemplatePrefix || 'Pict-MT-Base' ];
277
+
278
+ if (!pPict.providers[tmpProviderHash])
279
+ {
280
+ pPict.addProvider(tmpProviderHash, Object.assign({}, _DEFAULT_CONFIGURATION, { ProviderIdentifier: tmpProviderHash }), tmpProviderClass);
281
+ }
282
+
283
+ const tmpTemplateProvider = pPict.providers.PictFormSectionDefaultTemplateProvider;
284
+ if (!tmpTemplateProvider || typeof tmpTemplateProvider.injectTemplateSet !== 'function')
285
+ {
286
+ pPict.log.warn('Pict-Input-Picker: PictFormSectionDefaultTemplateProvider not available; cannot register the Picker metatemplate (is pict-section-form loaded?).');
287
+ return false;
288
+ }
289
+ const tmpTemplates = buildPickerInputTemplates(tmpInputTypeName, tmpProviderHash);
290
+ tmpPrefixes.forEach((pPrefix) => tmpTemplateProvider.injectTemplateSet({ TemplatePrefix: pPrefix, Templates: tmpTemplates }));
291
+ return true;
292
+ };
293
+
294
+ module.exports = PictInputTypePicker;
295
+
296
+ module.exports.PictInputTypePicker = PictInputTypePicker;
297
+ module.exports.registerPickerInputType = registerPickerInputType;
298
+ module.exports.buildPickerInputTemplates = buildPickerInputTemplates;
299
+ module.exports.default_configuration = _DEFAULT_CONFIGURATION;
@@ -31,9 +31,15 @@ const _PickerCSS = /*css*/`
31
31
  .pps-chip-x { flex: 0 0 auto; display: inline-flex; align-items: center; cursor: pointer; font-size: 0.78rem; border-radius: 4px; padding: 0.1rem; opacity: 0.7; }
32
32
  .pps-chip-x:hover { opacity: 1; background: color-mix(in srgb, var(--theme-color-brand-primary, #156dd1) 22%, transparent); }
33
33
 
34
- /* Transparent full-viewport backdrop: closes on outside click (no document listener). */
35
- .pps-backdrop { position: fixed; inset: 0; z-index: 0; }
36
- .pps-pop { position: absolute; z-index: 40; top: calc(100% + 0.3rem); left: 0; right: 0; min-width: 200px; display: none; }
34
+ /* Transparent full-viewport backdrop: closes on outside click (no document listener). Only present
35
+ while OPEN otherwise a fixed full-viewport layer would swallow every click on the page. When open,
36
+ the control is raised above it so its chips/× stay clickable; the dropdown sits above both. */
37
+ .pps-backdrop { position: fixed; inset: 0; z-index: 0; display: none; }
38
+ .pps.pps-open .pps-backdrop { display: block; }
39
+ .pps.pps-open .pps-control { position: relative; z-index: 1; }
40
+ /* Fixed (viewport-anchored) + JS-positioned in open(), so no ancestor's overflow:hidden — a card, a
41
+ slide-out drawer, a scroll pane — can ever clip the dropdown, whatever the host's layout. */
42
+ .pps-pop { position: fixed; z-index: 40; min-width: 200px; display: none; }
37
43
  .pps.pps-open .pps-pop { display: block; }
38
44
  .pps-panel { position: relative; z-index: 1; display: flex; flex-direction: column; max-height: min(60vh, 360px);
39
45
  background: var(--theme-color-background-panel, #fff); border: 1px solid var(--theme-color-border-default, #d7dce3);
@@ -60,6 +66,10 @@ const _PickerCSS = /*css*/`
60
66
  padding: 0.45rem 0.6rem; border: none; border-radius: 6px; background: transparent; color: var(--theme-color-brand-primary, #156dd1); font-weight: 600; }
61
67
  .pps-create:hover { background: var(--theme-color-background-tertiary, #eceef2); }
62
68
  .pps-create-ic { flex: 0 0 auto; display: inline-flex; }
69
+
70
+ /* Form-input adapter (pict-section-picker/form): the picker host fills its row like the host's
71
+ native inputs (width:100% forces it to wrap below the label span + fill, matching a scalar input). */
72
+ .pps-form-host { flex: 1 1 100%; min-width: 0; width: 100%; }
63
73
  `;
64
74
 
65
75
  /** @type {Record<string, any>} */
@@ -159,7 +169,10 @@ class PictProviderPicker extends libPictProvider
159
169
  * - TextField {string} - record field used as the option Text (default `Name`).
160
170
  * - PageSize {number} - records per page (default 20).
161
171
  * - Sort {string} - optional field to sort ascending (adds `FSF~<field>~ASC~0`).
162
- * - BaseFilter {string} - optional always-applied FoxHound filter (AND), e.g. `FBV~IDCustomer~EQ~1`.
172
+ * - BaseFilter {string|Array<string>|function} - optional always-applied FoxHound filter (AND),
173
+ * e.g. `FBV~IDCustomer~EQ~1`. May be a **function** `(searchTerm, page) => string|string[]`
174
+ * evaluated on every search — the generic hook for host-injected CONTEXTUAL scoping (project,
175
+ * tenant, spec-year, …). The module stays agnostic; the host supplies the closure.
163
176
  * - MapRecord {function} - optional `(record) => {Value, Text}` mapper (overrides Value/TextField).
164
177
  * @return {(pSearchTerm: string, pPage: number) => Promise<{results: Array<any>, hasMore: boolean}>}
165
178
  */
@@ -171,7 +184,7 @@ class PictProviderPicker extends libPictProvider
171
184
  const tmpTextField = pConfig.TextField || 'Name';
172
185
  const tmpPageSize = pConfig.PageSize || 20;
173
186
  const tmpSort = pConfig.Sort || false;
174
- const tmpBaseFilter = pConfig.BaseFilter || '';
187
+ const tmpBaseFilterConfig = pConfig.BaseFilter || '';
175
188
  const tmpMapRecord = (typeof pConfig.MapRecord === 'function') ? pConfig.MapRecord : false;
176
189
 
177
190
  return (pSearchTerm, pPage) => new Promise((resolve, reject) =>
@@ -181,6 +194,17 @@ class PictProviderPicker extends libPictProvider
181
194
  return reject(new Error('Pict-Section-Picker: pict.EntityProvider is not available for entity-backed pickers.'));
182
195
  }
183
196
 
197
+ // Resolve the base filter at SEARCH time. A function form lets the host inject contextual
198
+ // scoping (e.g. "only this project's line items") without the module knowing the context;
199
+ // it can return a single stanza, an array of stanzas, or nothing.
200
+ let tmpBaseFilter = tmpBaseFilterConfig;
201
+ if (typeof tmpBaseFilterConfig === 'function')
202
+ {
203
+ try { tmpBaseFilter = tmpBaseFilterConfig(pSearchTerm, pPage); }
204
+ catch (pScopeError) { this.pict.log.warn(`Pict-Section-Picker [${tmpEntity}] BaseFilter() threw; ignoring contextual scope.`, pScopeError); tmpBaseFilter = ''; }
205
+ }
206
+ if (Array.isArray(tmpBaseFilter)) { tmpBaseFilter = tmpBaseFilter.filter(Boolean).join('~'); }
207
+
184
208
  const tmpStanzas = [];
185
209
  if (tmpBaseFilter) { tmpStanzas.push(tmpBaseFilter); }
186
210
  if (pSearchTerm) { tmpStanzas.push(this.buildSearchFilter(tmpSearchFields, pSearchTerm)); }
@@ -324,6 +324,65 @@ class PictViewPicker extends libPictView
324
324
  }
325
325
  }
326
326
 
327
+ /**
328
+ * Public: set the picker's value programmatically (e.g. when a host form marshals data into it).
329
+ * Accepts a scalar (single mode) or an array / csv string (multi mode), seeds display text for any
330
+ * unknown values (from the source rows, else async ResolveValue), then repaints.
331
+ * @param {any} pValue
332
+ * @return {PictViewPicker} this
333
+ */
334
+ setValue(pValue)
335
+ {
336
+ if (this._isMulti())
337
+ {
338
+ let tmpArray = pValue;
339
+ if (tmpArray === undefined || tmpArray === null || tmpArray === '') { tmpArray = []; }
340
+ else if (typeof tmpArray === 'string') { tmpArray = tmpArray.split(',').filter((pPart) => pPart !== ''); }
341
+ else if (!Array.isArray(tmpArray)) { tmpArray = [ tmpArray ]; }
342
+ this._setValue(tmpArray);
343
+ this._seedSelectedRecords(tmpArray);
344
+ }
345
+ else
346
+ {
347
+ this._setValue(pValue);
348
+ this._selectedText = null;
349
+ this._seedSelectedRecords((pValue === undefined || pValue === null || pValue === '') ? [] : [ pValue ]);
350
+ }
351
+ this.render();
352
+ return this;
353
+ }
354
+
355
+ /**
356
+ * Ensure each value has a {Value,Text} in _selectedRecords — from the current source rows when
357
+ * present, else (async mode) fetched via ResolveValue and painted in when it resolves.
358
+ * @param {Array<any>} pValues
359
+ */
360
+ _seedSelectedRecords(pValues)
361
+ {
362
+ pValues.forEach((pVal) =>
363
+ {
364
+ if (pVal === undefined || pVal === null || pVal === '' || this._selectedRecords[String(pVal)]) { return; }
365
+ const tmpRow = this._sourceRows().find((pRow) => String(pRow.Value) === String(pVal));
366
+ if (tmpRow)
367
+ {
368
+ this._selectedRecords[String(pVal)] = { Value: tmpRow.Value, Text: tmpRow.Text };
369
+ return;
370
+ }
371
+ if (this._isAsync() && typeof this.options.ResolveValue === 'function')
372
+ {
373
+ Promise.resolve(this.options.ResolveValue(pVal)).then((pResolved) =>
374
+ {
375
+ if (pResolved && pResolved.Text)
376
+ {
377
+ this._selectedRecords[String(pVal)] = { Value: pResolved.Value !== undefined ? pResolved.Value : pVal, Text: pResolved.Text };
378
+ if (!this._isMulti()) { this._selectedText = pResolved.Text; }
379
+ this._renderValue();
380
+ }
381
+ }).catch(() => { /* leave the raw value showing */ });
382
+ }
383
+ });
384
+ }
385
+
327
386
  /** @return {Array<{Value:any, Text:string}>} The current option source rows (async results or static Options). */
328
387
  _sourceRows()
329
388
  {
@@ -516,11 +575,51 @@ class PictViewPicker extends libPictView
516
575
  this._open = true;
517
576
  this._highlight = -1;
518
577
  this._paintOpen();
578
+ this._positionPop();
519
579
  if (this._isAsync() && !this._loaded) { this._loadPage(0, false); }
520
580
  const tmpSearch = /** @type {HTMLInputElement} */ (document.getElementById(`PPS_Search_${this.options.PickerHash}`));
521
581
  if (tmpSearch) { tmpSearch.focus(); tmpSearch.select(); }
522
582
  }
523
583
 
584
+ /**
585
+ * Position the (fixed) dropdown against the control, flipping above when there's more room there.
586
+ * Because the popover is position:fixed (viewport-anchored), no ancestor overflow can clip it; the
587
+ * trade-off is we set its top/left/width ourselves from the control's rect on open.
588
+ */
589
+ _positionPop()
590
+ {
591
+ const tmpRoot = document.getElementById(`PPS_${this.options.PickerHash}`);
592
+ if (!tmpRoot) { return; }
593
+ const tmpControl = tmpRoot.querySelector('.pps-control');
594
+ const tmpPop = /** @type {HTMLElement} */ (tmpRoot.querySelector('.pps-pop'));
595
+ const tmpPanel = /** @type {HTMLElement} */ (tmpRoot.querySelector('.pps-panel'));
596
+ if (!tmpControl || !tmpPop) { return; }
597
+ const tmpRect = tmpControl.getBoundingClientRect();
598
+ const tmpGap = 5;
599
+ const tmpMargin = 8;
600
+ const tmpVH = window.innerHeight;
601
+ const tmpVW = window.innerWidth;
602
+ const tmpWidth = Math.max(200, Math.round(tmpRect.width));
603
+ tmpPop.style.width = `${tmpWidth}px`;
604
+ tmpPop.style.left = `${Math.round(Math.max(tmpMargin, Math.min(tmpRect.left, tmpVW - tmpWidth - tmpMargin)))}px`;
605
+ tmpPop.style.right = 'auto';
606
+ const tmpSpaceBelow = tmpVH - tmpRect.bottom - tmpGap - tmpMargin;
607
+ const tmpSpaceAbove = tmpRect.top - tmpGap - tmpMargin;
608
+ // Prefer the natural downward direction; only flip above when the room below is genuinely cramped.
609
+ if (tmpSpaceBelow >= 200 || tmpSpaceBelow >= tmpSpaceAbove)
610
+ {
611
+ tmpPop.style.top = `${Math.round(tmpRect.bottom + tmpGap)}px`;
612
+ tmpPop.style.bottom = 'auto';
613
+ if (tmpPanel) { tmpPanel.style.maxHeight = `${Math.max(140, Math.min(tmpSpaceBelow, 360))}px`; }
614
+ }
615
+ else
616
+ {
617
+ tmpPop.style.top = 'auto';
618
+ tmpPop.style.bottom = `${Math.round(tmpVH - tmpRect.top + tmpGap)}px`;
619
+ if (tmpPanel) { tmpPanel.style.maxHeight = `${Math.max(140, Math.min(tmpSpaceAbove, 360))}px`; }
620
+ }
621
+ }
622
+
524
623
  /** Async mode: load + append the next page of results. */
525
624
  loadMore()
526
625
  {
@@ -0,0 +1,89 @@
1
+ export = PictInputTypePicker;
2
+ declare const PictInputTypePicker_base: typeof import("pict-section-form/types/source/providers/Pict-Provider-InputExtension");
3
+ declare class PictInputTypePicker extends PictInputTypePicker_base {
4
+ constructor(pFable: any, pOptions: any, pServiceHash: any);
5
+ getPickerHostID(pRawHTMLID: any): string;
6
+ getPickerHash(pRawHTMLID: any): string;
7
+ getTabularPickerHostID(pRawHTMLID: any, pRowIndex: any): string;
8
+ getTabularPickerHash(pRawHTMLID: any, pRowIndex: any): string;
9
+ getTabularHiddenID(pRawHTMLID: any, pRowIndex: any): string;
10
+ /**
11
+ * Overridable: extra FoxHound scope stanza(s) AND-applied to the entity search. Default reads the
12
+ * descriptor's `GetContextScopeFilter()` hook (set by the host / recordset filter base), else its
13
+ * static `BaseFilter`. Host subclasses override this to read app state (project / spec-year / …).
14
+ *
15
+ * @param {Record<string, any>} pInput @return {string|Array<string>}
16
+ */
17
+ getContextualSearchFilters(pInput: Record<string, any>): string | Array<string>;
18
+ /** Build the picker config from a form input descriptor. */
19
+ _buildPickerConfig(pInput: any, pHostSelector: any, fOnChange: any): {
20
+ DestinationAddress: any;
21
+ Mode: string;
22
+ Placeholder: any;
23
+ Searchable: boolean;
24
+ Entity: any;
25
+ SearchFields: any;
26
+ ValueField: any;
27
+ TextField: any;
28
+ PageSize: any;
29
+ Options: any;
30
+ BaseFilter: () => string | string[];
31
+ OnChange: any;
32
+ };
33
+ /** Instantiate (or reuse) the picker view for a config — entity-backed when Entity is set. */
34
+ _instantiatePicker(pPickerHash: any, pConfig: any): any;
35
+ /**
36
+ * Write a picker value into the form: csv to the hidden informary input (+ dataChanged), plus the
37
+ * raw array to `PictForm.ValueArrayAddress` when set (the recordset filter reads Values as an
38
+ * array). The csv-vs-array bridge lives HERE (generic) instead of in each host.
39
+ */
40
+ _commit(pView: any, pInput: any, pValue: any, pHTMLSelector: any): void;
41
+ _commitTabular(pView: any, pInput: any, pValue: any, pHiddenID: any, pRowIndex: any): void;
42
+ /**
43
+ * Idempotently mount (or reuse) the picker into its host element + seed its value. Called from both
44
+ * onInputInitialize and onDataMarshalToForm because, in the async-virtual filter render, the host
45
+ * element only exists in the real DOM by the marshal pass — whichever hook fires post-DOM wins, and
46
+ * re-calls are harmless (the picker view is reused by hash).
47
+ * @return {boolean} true if the picker is mounted.
48
+ */
49
+ _mountPicker(pView: any, pInput: any, pValue: any, pHostSelector: any, pPickerHash: any, fOnChange: any): boolean;
50
+ onInputInitialize(pView: any, pGroup: any, pRow: any, pInput: any, pValue: any, pHTMLSelector: any, pTransactionGUID: any): boolean;
51
+ onDataMarshalToForm(pView: any, pGroup: any, pRow: any, pInput: any, pValue: any, pHTMLSelector: any, pTransactionGUID: any): boolean;
52
+ onDataRequest(pView: any, pInput: any, pValue: any, pHTMLSelector: any): boolean;
53
+ /** Idempotent tabular mount (see _mountPicker). @return {boolean} */
54
+ _mountPickerTabular(pView: any, pInput: any, pValue: any, pRowIndex: any): boolean;
55
+ onInputInitializeTabular(pView: any, pGroup: any, pInput: any, pValue: any, pHTMLSelector: any, pRowIndex: any, pTransactionGUID: any): boolean;
56
+ onDataMarshalToFormTabular(pView: any, pGroup: any, pInput: any, pValue: any, pHTMLSelector: any, pRowIndex: any, pTransactionGUID: any): boolean;
57
+ onDataRequestTabular(pView: any, pInput: any, pValue: any, pHTMLSelector: any, pRowIndex: any): boolean;
58
+ }
59
+ declare namespace PictInputTypePicker {
60
+ export { PictInputTypePicker, registerPickerInputType, buildPickerInputTemplates, _DEFAULT_CONFIGURATION as default_configuration };
61
+ }
62
+ /**
63
+ * Register the Picker InputType on a pict instance: the input-extension provider + its metatemplate(s).
64
+ * Idempotent. Requires `pict-section-form` loaded (PictFormSectionDefaultTemplateProvider present) and
65
+ * the `Pict-Section-Picker` provider registered.
66
+ *
67
+ * @param {any} pPict - the pict instance.
68
+ * @param {Record<string, any>} [pOptions]
69
+ * - InputTypeName {string} - the InputType string (default 'Picker').
70
+ * - ProviderHash {string} - the input-extension provider service hash (default 'Pict-Input-Picker').
71
+ * - ProviderClass {Function} - provider class to register (default PictInputTypePicker; a host
72
+ * passes a subclass that overrides getContextualSearchFilters for its scoping).
73
+ * - TemplatePrefix {string|Array<string>} - the form template prefix(es) to inject the metatemplate
74
+ * under (default 'Pict-MT-Base'; Headlight uses its theme prefixes).
75
+ * @return {boolean} true if registered.
76
+ */
77
+ declare function registerPickerInputType(pPict: any, pOptions?: Record<string, any>): boolean;
78
+ /**
79
+ * Build the InputType metatemplate entries (a hidden informary input + a host element the picker
80
+ * renders into) for a given InputType name + provider hash. Injected via injectTemplateSet.
81
+ *
82
+ * @param {string} pInputTypeName - e.g. 'Picker'.
83
+ * @param {string} pProviderHash - the input-extension provider service hash to auto-attach.
84
+ * @return {Array<Record<string, any>>}
85
+ */
86
+ declare function buildPickerInputTemplates(pInputTypeName: string, pProviderHash: string): Array<Record<string, any>>;
87
+ /** @type {Record<string, any>} */
88
+ declare const _DEFAULT_CONFIGURATION: Record<string, any>;
89
+ //# sourceMappingURL=Pict-Section-Picker-FormInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pict-Section-Picker-FormInput.d.ts","sourceRoot":"","sources":["../../source/form/Pict-Section-Picker-FormInput.js"],"names":[],"mappings":";;AAsEA;IAEC,2DAKC;IAGD,yCAAmE;IACnE,uCAA4D;IAC5D,gEAAsG;IACtG,8DAA2F;IAC3F,4DAAuG;IAEvG;;;;;;OAMG;IACH,mCAFW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAkB,MAAM,GAAC,KAAK,CAAC,MAAM,CAAC,CAWnE;IAED,4DAA4D;IAC5D;;;;;;;;;;;;;MAkBC;IAED,8FAA8F;IAC9F,wDAWC;IAED;;;;OAIG;IACH,wEAUC;IAED,2FAKC;IAED;;;;;;OAMG;IACH,0GAFY,OAAO,CAUlB;IAID,oIAMC;IAED,sIAYC;IAED,iFAMC;IAID,qEAAqE;IACrE,2EAD0D,OAAO,CAahE;IAED,gJAIC;IAED,kJAQC;IAED,wGAMC;CACD;;;;AAED;;;;;;;;;;;;;;GAcG;AACH,gDAVW,GAAG,aACH,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAOlB,OAAO,CAwBlB;AAzQD;;;;;;;GAOG;AACH,2DAJW,MAAM,iBACN,MAAM,GACL,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAoCrC;AAnDD,kCAAkC;AAClC,sCADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAO5B"}
@@ -46,7 +46,10 @@ declare class PictProviderPicker extends libPictProvider {
46
46
  * - TextField {string} - record field used as the option Text (default `Name`).
47
47
  * - PageSize {number} - records per page (default 20).
48
48
  * - Sort {string} - optional field to sort ascending (adds `FSF~<field>~ASC~0`).
49
- * - BaseFilter {string} - optional always-applied FoxHound filter (AND), e.g. `FBV~IDCustomer~EQ~1`.
49
+ * - BaseFilter {string|Array<string>|function} - optional always-applied FoxHound filter (AND),
50
+ * e.g. `FBV~IDCustomer~EQ~1`. May be a **function** `(searchTerm, page) => string|string[]`
51
+ * evaluated on every search — the generic hook for host-injected CONTEXTUAL scoping (project,
52
+ * tenant, spec-year, …). The module stays agnostic; the host supplies the closure.
50
53
  * - MapRecord {function} - optional `(record) => {Value, Text}` mapper (overrides Value/TextField).
51
54
  * @return {(pSearchTerm: string, pPage: number) => Promise<{results: Array<any>, hasMore: boolean}>}
52
55
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Pict-Provider-Picker.d.ts","sourceRoot":"","sources":["../../source/providers/Pict-Provider-Picker.js"],"names":[],"mappings":";AAyEA;;;GAGG;AACH;IAEC,2DASC;IAED;;;;;;;;;;;;;;OAcG;IACH,0BAZW,MAAM,WAEN,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAQlB,GAAG,CAqBd;IAED;;;;;;;;;;;OAWG;IACH,iCAJW,KAAK,CAAC,MAAM,CAAC,SACb,MAAM,GACL,MAAM,CAWjB;IAED;;;;;;;;;;;;;;;OAeG;IACH,kCAXW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GASlB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;QAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAC,CAAC,CAuCnG;IAED;;;;;;OAMG;IACH,kCAHW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClB,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAsBxC;IAED;;;;;;;;;OASG;IACH,gCAJW,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClB,GAAG,CAQd;CACD;;;;;AA1LD,kCAAkC;AAClC,sCADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAO5B"}
1
+ {"version":3,"file":"Pict-Provider-Picker.d.ts","sourceRoot":"","sources":["../../source/providers/Pict-Provider-Picker.js"],"names":[],"mappings":";AAmFA;;;GAGG;AACH;IAEC,2DASC;IAED;;;;;;;;;;;;;;OAcG;IACH,0BAZW,MAAM,WAEN,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAQlB,GAAG,CAqBd;IAED;;;;;;;;;;;OAWG;IACH,iCAJW,KAAK,CAAC,MAAM,CAAC,SACb,MAAM,GACL,MAAM,CAWjB;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,kCAdW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAYlB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;QAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAC,CAAC,CAkDnG;IAED;;;;;;OAMG;IACH,kCAHW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClB,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAsBxC;IAED;;;;;;;;;OASG;IACH,gCAJW,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClB,GAAG,CAQd;CACD;;;;;AAxMD,kCAAkC;AAClC,sCADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAO5B"}
@@ -34,6 +34,20 @@ declare class PictViewPicker extends libPictView {
34
34
  */
35
35
  _setValue(pValue: any): void;
36
36
  _value: any;
37
+ /**
38
+ * Public: set the picker's value programmatically (e.g. when a host form marshals data into it).
39
+ * Accepts a scalar (single mode) or an array / csv string (multi mode), seeds display text for any
40
+ * unknown values (from the source rows, else async ResolveValue), then repaints.
41
+ * @param {any} pValue
42
+ * @return {PictViewPicker} this
43
+ */
44
+ setValue(pValue: any): PictViewPicker;
45
+ /**
46
+ * Ensure each value has a {Value,Text} in _selectedRecords — from the current source rows when
47
+ * present, else (async mode) fetched via ResolveValue and painted in when it resolves.
48
+ * @param {Array<any>} pValues
49
+ */
50
+ _seedSelectedRecords(pValues: Array<any>): void;
37
51
  /** @return {Array<{Value:any, Text:string}>} The current option source rows (async results or static Options). */
38
52
  _sourceRows(): Array<{
39
53
  Value: any;
@@ -66,6 +80,12 @@ declare class PictViewPicker extends libPictView {
66
80
  onControlKey(pEvent: any): void;
67
81
  /** Open the dropdown and focus the search box. */
68
82
  open(): void;
83
+ /**
84
+ * Position the (fixed) dropdown against the control, flipping above when there's more room there.
85
+ * Because the popover is position:fixed (viewport-anchored), no ancestor overflow can clip it; the
86
+ * trade-off is we set its top/left/width ourselves from the control's rect on open.
87
+ */
88
+ _positionPop(): void;
69
89
  /** Async mode: load + append the next page of results. */
70
90
  loadMore(): void;
71
91
  /** Close the dropdown. */
@@ -1 +1 @@
1
- {"version":3,"file":"PictView-Picker.d.ts","sourceRoot":"","sources":["../../source/views/PictView-Picker.js"],"names":[],"mappings":";AA6KA;IAEC,2DA0CC;IAlCA,sBAA2E;IAQ3E,eAAkB;IAClB,gBAAiB;IACjB,mBAAoB;IAEpB,sBAAwB;IACxB,cAAc;IACd,kBAAqB;IACrB,kBAAqB;IACrB,iBAAoB;IACpB,6BAAwB;IACxB,mBAAyB;IAGzB,eAAiB;IACjB,qBAA0B;IAc3B,6FAA6F;IAC7F,YADa,OAAO,CAInB;IAED,8EAA8E;IAC9E,YADa,OAAO,CAInB;IAED,4EAA4E;IAC5E,UADa,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAM/B;IAED,qGAAqG;IACrG,8BA+BC;IAED;;;OAGG;IACH,YAHY,GAAG,CAgBd;IAED;;;;OAIG;IACH,kBAFW,GAAG,QA6Bb;IAvBC,YAAoB;IAyBtB,kHAAkH;IAClH,eADa,KAAK,CAAC;QAAC,KAAK,EAAC,GAAG,CAAC;QAAC,IAAI,EAAC,MAAM,CAAA;KAAC,CAAC,CAK3C;IAED;;;OAGG;IACH,mCAgGC;IAED;;;;;OAKG;IACH,sBAHW,GAAG,GACF;QAAC,KAAK,EAAC,GAAG,CAAC;QAAC,IAAI,EAAC,MAAM,CAAA;KAAC,GAAC,IAAI,CAQxC;IAED;;;;OAIG;IACH,iBAHW,MAAM,WACN,OAAO,QA4BjB;IAWD,uCAAuC;IACvC,0BAIC;IAED,+EAA+E;IAC/E,gCAWC;IAED,kDAAkD;IAClD,aAQC;IAED,0DAA0D;IAC1D,iBAMC;IAED,0BAA0B;IAC1B,cAKC;IAED,6DAA6D;IAC7D,mBAIC;IAED,kFAAkF;IAClF,oBAKC;IAED;sGACkG;IAClG,qBAKC;IAED,2EAA2E;IAC3E,eADY,MAAM,QAejB;IAED,iGAAiG;IACjG,+BAgCC;IAED;;;;OAIG;IACH,kBAFW,MAAM,QA4ChB;IAED,sGAAsG;IACtG,sBADa,KAAK,CAAC;QAAC,KAAK,EAAC,GAAG,CAAC;QAAC,IAAI,EAAC,MAAM,CAAA;KAAC,CAAC,CAI3C;IAED;;;;OAIG;IACH,yBA6CC;IAED,oFAAoF;IACpF,iCAWC;CAWD;;;;;AAxuBD,kCAAkC;AAClC,sCADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAyK5B"}
1
+ {"version":3,"file":"PictView-Picker.d.ts","sourceRoot":"","sources":["../../source/views/PictView-Picker.js"],"names":[],"mappings":";AA6KA;IAEC,2DA0CC;IAlCA,sBAA2E;IAQ3E,eAAkB;IAClB,gBAAiB;IACjB,mBAAoB;IAEpB,sBAAwB;IACxB,cAAc;IACd,kBAAqB;IACrB,kBAAqB;IACrB,iBAAoB;IACpB,6BAAwB;IACxB,mBAAyB;IAGzB,eAAiB;IACjB,qBAA0B;IAc3B,6FAA6F;IAC7F,YADa,OAAO,CAInB;IAED,8EAA8E;IAC9E,YADa,OAAO,CAInB;IAED,4EAA4E;IAC5E,UADa,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAM/B;IAED,qGAAqG;IACrG,8BA+BC;IAED;;;OAGG;IACH,YAHY,GAAG,CAgBd;IAED;;;;OAIG;IACH,kBAFW,GAAG,QA6Bb;IAvBC,YAAoB;IAyBtB;;;;;;OAMG;IACH,iBAHW,GAAG,GACF,cAAc,CAqBzB;IAED;;;;OAIG;IACH,8BAFW,KAAK,CAAC,GAAG,CAAC,QA0BpB;IAED,kHAAkH;IAClH,eADa,KAAK,CAAC;QAAC,KAAK,EAAC,GAAG,CAAC;QAAC,IAAI,EAAC,MAAM,CAAA;KAAC,CAAC,CAK3C;IAED;;;OAGG;IACH,mCAgGC;IAED;;;;;OAKG;IACH,sBAHW,GAAG,GACF;QAAC,KAAK,EAAC,GAAG,CAAC;QAAC,IAAI,EAAC,MAAM,CAAA;KAAC,GAAC,IAAI,CAQxC;IAED;;;;OAIG;IACH,iBAHW,MAAM,WACN,OAAO,QA4BjB;IAWD,uCAAuC;IACvC,0BAIC;IAED,+EAA+E;IAC/E,gCAWC;IAED,kDAAkD;IAClD,aASC;IAED;;;;OAIG;IACH,qBAgCC;IAED,0DAA0D;IAC1D,iBAMC;IAED,0BAA0B;IAC1B,cAKC;IAED,6DAA6D;IAC7D,mBAIC;IAED,kFAAkF;IAClF,oBAKC;IAED;sGACkG;IAClG,qBAKC;IAED,2EAA2E;IAC3E,eADY,MAAM,QAejB;IAED,iGAAiG;IACjG,+BAgCC;IAED;;;;OAIG;IACH,kBAFW,MAAM,QA4ChB;IAED,sGAAsG;IACtG,sBADa,KAAK,CAAC;QAAC,KAAK,EAAC,GAAG,CAAC;QAAC,IAAI,EAAC,MAAM,CAAA;KAAC,CAAC,CAI3C;IAED;;;;OAIG;IACH,yBA6CC;IAED,oFAAoF;IACpF,iCAWC;CAWD;;;;;AA30BD,kCAAkC;AAClC,sCADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAyK5B"}