@ni/ok-components 1.10.3 → 1.11.1

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 (48) hide show
  1. package/dist/all-components-bundle.js +1125 -448
  2. package/dist/all-components-bundle.js.map +1 -1
  3. package/dist/all-components-bundle.min.js +5885 -5585
  4. package/dist/all-components-bundle.min.js.map +1 -1
  5. package/dist/custom-elements.json +1009 -0
  6. package/dist/custom-elements.md +140 -0
  7. package/dist/esm/fv/all-fv.d.ts +3 -0
  8. package/dist/esm/fv/all-fv.js +3 -0
  9. package/dist/esm/fv/all-fv.js.map +1 -1
  10. package/dist/esm/fv/bulk-edit-field/index.d.ts +40 -0
  11. package/dist/esm/fv/bulk-edit-field/index.js +120 -0
  12. package/dist/esm/fv/bulk-edit-field/index.js.map +1 -0
  13. package/dist/esm/fv/bulk-edit-field/styles.d.ts +1 -0
  14. package/dist/esm/fv/bulk-edit-field/styles.js +83 -0
  15. package/dist/esm/fv/bulk-edit-field/styles.js.map +1 -0
  16. package/dist/esm/fv/bulk-edit-field/template.d.ts +2 -0
  17. package/dist/esm/fv/bulk-edit-field/template.js +36 -0
  18. package/dist/esm/fv/bulk-edit-field/template.js.map +1 -0
  19. package/dist/esm/fv/bulk-edit-field/types.d.ts +7 -0
  20. package/dist/esm/fv/bulk-edit-field/types.js +7 -0
  21. package/dist/esm/fv/bulk-edit-field/types.js.map +1 -0
  22. package/dist/esm/fv/bulk-edit-state/index.d.ts +47 -0
  23. package/dist/esm/fv/bulk-edit-state/index.js +114 -0
  24. package/dist/esm/fv/bulk-edit-state/index.js.map +1 -0
  25. package/dist/esm/fv/edit-commit-bar/index.d.ts +32 -0
  26. package/dist/esm/fv/edit-commit-bar/index.js +92 -0
  27. package/dist/esm/fv/edit-commit-bar/index.js.map +1 -0
  28. package/dist/esm/fv/edit-commit-bar/styles.d.ts +1 -0
  29. package/dist/esm/fv/edit-commit-bar/styles.js +65 -0
  30. package/dist/esm/fv/edit-commit-bar/styles.js.map +1 -0
  31. package/dist/esm/fv/edit-commit-bar/template.d.ts +2 -0
  32. package/dist/esm/fv/edit-commit-bar/template.js +45 -0
  33. package/dist/esm/fv/edit-commit-bar/template.js.map +1 -0
  34. package/dist/esm/fv/edit-commit-bar/types.d.ts +4 -0
  35. package/dist/esm/fv/edit-commit-bar/types.js +2 -0
  36. package/dist/esm/fv/edit-commit-bar/types.js.map +1 -0
  37. package/dist/esm/fv/search-input/styles.js +4 -1
  38. package/dist/esm/fv/search-input/styles.js.map +1 -1
  39. package/dist/esm/fv/split-layout/index.d.ts +48 -0
  40. package/dist/esm/fv/split-layout/index.js +195 -0
  41. package/dist/esm/fv/split-layout/index.js.map +1 -0
  42. package/dist/esm/fv/split-layout/styles.d.ts +1 -0
  43. package/dist/esm/fv/split-layout/styles.js +42 -0
  44. package/dist/esm/fv/split-layout/styles.js.map +1 -0
  45. package/dist/esm/fv/split-layout/template.d.ts +2 -0
  46. package/dist/esm/fv/split-layout/template.js +24 -0
  47. package/dist/esm/fv/split-layout/template.js.map +1 -0
  48. package/package.json +1 -1
@@ -34,6 +34,63 @@
34
34
 
35
35
  <hr/>
36
36
 
37
+ ## class: `FvBulkEditField`
38
+
39
+ ### Superclass
40
+
41
+ | Name | Module | Package |
42
+ | ------------------- | ------ | ------------------- |
43
+ | `FoundationElement` | | @ni/fast-foundation |
44
+
45
+ ### Fields
46
+
47
+ | Name | Privacy | Type | Default | Description | Inherited From |
48
+ | --------------- | ------- | ------------------------- | ------- | ----------------------------------------------------------- | -------------- |
49
+ | `label` | public | `string` | `''` | | |
50
+ | `status` | public | `BulkEditFieldStatusType` | | | |
51
+ | `resetDisabled` | public | `boolean` | `false` | | |
52
+ | `clearDisabled` | public | `boolean` | `false` | | |
53
+ | `controlLabel` | public | `string` | | Accessible name applied to directly slotted field controls. | |
54
+
55
+ ### Attributes
56
+
57
+ | Name | Field | Inherited From |
58
+ | ---------------- | ------------- | -------------- |
59
+ | `label` | label | |
60
+ | `status` | status | |
61
+ | `reset-disabled` | resetDisabled | |
62
+ | `clear-disabled` | clearDisabled | |
63
+
64
+ <hr/>
65
+
66
+ ## class: `BulkEditState`
67
+
68
+ ### Fields
69
+
70
+ | Name | Privacy | Type | Default | Description | Inherited From |
71
+ | ----------------- | ------- | ---------------------------------- | ------- | ----------- | -------------- |
72
+ | `selectedIds` | public | `readonly RecordId[]` | | | |
73
+ | `changes` | public | `Readonly<PendingChanges<TField>>` | | | |
74
+ | `selectedRecords` | public | `readonly TRecord[]` | | | |
75
+
76
+ ### Methods
77
+
78
+ | Name | Privacy | Description | Parameters | Return | Inherited From |
79
+ | ------------------ | ------- | ----------- | ------------------------------------------------------------------------------------ | --------------------------------- | -------------- |
80
+ | `field` | public | | `field: TField` | `BulkEditFieldValue` | |
81
+ | `edit` | public | | `field: TField, value: string` | `void` | |
82
+ | `clear` | public | | `field: TField` | `void` | |
83
+ | `resetField` | public | | `field: TField` | `void` | |
84
+ | `revert` | public | | | `void` | |
85
+ | `isSelection` | public | | `ids: readonly RecordId[]` | `boolean` | |
86
+ | `visibleSelection` | public | | `visibleIds: readonly RecordId[]` | `readonly RecordId[]` | |
87
+ | `mergeVisible` | public | | `visibleIds: readonly RecordId[], selectedVisibleIds: readonly RecordId[], additive` | `readonly RecordId[]` | |
88
+ | `select` | public | | `ids: readonly RecordId[]` | `void` | |
89
+ | `createCommit` | public | | | `BulkEditCommit<TRecord, TField>` | |
90
+ | `commitSucceeded` | public | | `updatedRecords: readonly TRecord[]` | `void` | |
91
+
92
+ <hr/>
93
+
37
94
  ## class: `FvCard`
38
95
 
39
96
  ### Superclass
@@ -136,6 +193,43 @@
136
193
 
137
194
  <hr/>
138
195
 
196
+ ## class: `FvEditCommitBar`
197
+
198
+ ### Superclass
199
+
200
+ | Name | Module | Package |
201
+ | ------------------- | ------ | ------------------- |
202
+ | `FoundationElement` | | @ni/fast-foundation |
203
+
204
+ ### Fields
205
+
206
+ | Name | Privacy | Type | Default | Description | Inherited From |
207
+ | ------------------------ | ------- | ---------------------------- | ------- | ----------- | -------------- |
208
+ | `heading` | public | `string` | `''` | | |
209
+ | `changeCount` | public | `number` | `0` | | |
210
+ | `affectedRowCount` | public | `number` | `0` | | |
211
+ | `hiddenAffectedRowCount` | public | `number` | `0` | | |
212
+ | `saveDisabled` | public | `boolean` | `false` | | |
213
+ | `revertDisabled` | public | `boolean` | `false` | | |
214
+ | `actionsHidden` | public | `boolean` | `false` | | |
215
+ | `hideEmptySummary` | public | `boolean` | `false` | | |
216
+ | `message` | public | `CommitMessage \| undefined` | | | |
217
+
218
+ ### Attributes
219
+
220
+ | Name | Field | Inherited From |
221
+ | --------------------------- | ---------------------- | -------------- |
222
+ | `heading` | heading | |
223
+ | `change-count` | changeCount | |
224
+ | `affected-row-count` | affectedRowCount | |
225
+ | `hidden-affected-row-count` | hiddenAffectedRowCount | |
226
+ | `save-disabled` | saveDisabled | |
227
+ | `revert-disabled` | revertDisabled | |
228
+ | `actions-hidden` | actionsHidden | |
229
+ | `hide-empty-summary` | hideEmptySummary | |
230
+
231
+ <hr/>
232
+
139
233
  ## class: `FvMasterDetailList`
140
234
 
141
235
  ### Superclass
@@ -308,6 +402,52 @@
308
402
 
309
403
  <hr/>
310
404
 
405
+ ## class: `FvSplitLayout`
406
+
407
+ ### Superclass
408
+
409
+ | Name | Module | Package |
410
+ | ------------------- | ------ | ------------------- |
411
+ | `FoundationElement` | | @ni/fast-foundation |
412
+
413
+ ### Fields
414
+
415
+ | Name | Privacy | Type | Default | Description | Inherited From |
416
+ | -------------------- | ------- | --------- | ------------------------------------------------ | ----------- | -------------- |
417
+ | `position` | public | `number` | `60` | | |
418
+ | `min` | public | `number` | `35` | | |
419
+ | `max` | public | `number` | `75` | | |
420
+ | `minSecondaryPixels` | public | `number` | `300` | | |
421
+ | `collapsed` | public | `boolean` | `false` | | |
422
+ | `step` | public | `number` | `1` | | |
423
+ | `primaryPaneId` | public | `string` | `` `ok-fv-split-layout-primary-${layoutId}` `` | | |
424
+ | `secondaryPaneId` | public | `string` | `` `ok-fv-split-layout-secondary-${layoutId}` `` | | |
425
+
426
+ ### Methods
427
+
428
+ | Name | Privacy | Description | Parameters | Return | Inherited From |
429
+ | --------------------------- | ------- | ----------- | ---------- | ------ | -------------- |
430
+ | `positionChanged` | public | | | `void` | |
431
+ | `minChanged` | public | | | `void` | |
432
+ | `maxChanged` | public | | | `void` | |
433
+ | `minSecondaryPixelsChanged` | public | | | `void` | |
434
+ | `collapsedChanged` | public | | | `void` | |
435
+
436
+ ### Attributes
437
+
438
+ | Name | Field | Inherited From |
439
+ | ---------------------- | ------------------ | -------------- |
440
+ | `position` | position | |
441
+ | `min` | min | |
442
+ | `max` | max | |
443
+ | `min-secondary-pixels` | minSecondaryPixels | |
444
+ | `collapsed` | collapsed | |
445
+ | `step` | step | |
446
+ | `primary-pane-id` | primaryPaneId | |
447
+ | `secondary-pane-id` | secondaryPaneId | |
448
+
449
+ <hr/>
450
+
311
451
  ## class: `FvSplitter`
312
452
 
313
453
  ### Superclass
@@ -1,7 +1,9 @@
1
1
  import './accordion-item';
2
2
  import './card';
3
+ import './bulk-edit-field';
3
4
  import './chip-selector';
4
5
  import './context-help';
6
+ import './edit-commit-bar';
5
7
  import './master-detail-list-item';
6
8
  import './master-detail-list';
7
9
  import './split-button';
@@ -11,3 +13,4 @@ import './summary-panel';
11
13
  import './summary-panel-tile';
12
14
  import './search-input';
13
15
  import './splitter';
16
+ import './split-layout';
@@ -1,7 +1,9 @@
1
1
  import './accordion-item';
2
2
  import './card';
3
+ import './bulk-edit-field';
3
4
  import './chip-selector';
4
5
  import './context-help';
6
+ import './edit-commit-bar';
5
7
  import './master-detail-list-item';
6
8
  import './master-detail-list';
7
9
  import './split-button';
@@ -11,4 +13,5 @@ import './summary-panel';
11
13
  import './summary-panel-tile';
12
14
  import './search-input';
13
15
  import './splitter';
16
+ import './split-layout';
14
17
  //# sourceMappingURL=all-fv.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"all-fv.js","sourceRoot":"","sources":["../../../src/fv/all-fv.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,QAAQ,CAAC;AAChB,OAAO,iBAAiB,CAAC;AACzB,OAAO,gBAAgB,CAAC;AACxB,OAAO,2BAA2B,CAAC;AACnC,OAAO,sBAAsB,CAAC;AAC9B,OAAO,gBAAgB,CAAC;AACxB,OAAO,uBAAuB,CAAC;AAC/B,OAAO,iBAAiB,CAAC;AACzB,OAAO,iBAAiB,CAAC;AACzB,OAAO,sBAAsB,CAAC;AAC9B,OAAO,gBAAgB,CAAC;AACxB,OAAO,YAAY,CAAC","sourcesContent":["import './accordion-item';\nimport './card';\nimport './chip-selector';\nimport './context-help';\nimport './master-detail-list-item';\nimport './master-detail-list';\nimport './split-button';\nimport './split-button-anchor';\nimport './sticky-header';\nimport './summary-panel';\nimport './summary-panel-tile';\nimport './search-input';\nimport './splitter';\n"]}
1
+ {"version":3,"file":"all-fv.js","sourceRoot":"","sources":["../../../src/fv/all-fv.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,QAAQ,CAAC;AAChB,OAAO,mBAAmB,CAAC;AAC3B,OAAO,iBAAiB,CAAC;AACzB,OAAO,gBAAgB,CAAC;AACxB,OAAO,mBAAmB,CAAC;AAC3B,OAAO,2BAA2B,CAAC;AACnC,OAAO,sBAAsB,CAAC;AAC9B,OAAO,gBAAgB,CAAC;AACxB,OAAO,uBAAuB,CAAC;AAC/B,OAAO,iBAAiB,CAAC;AACzB,OAAO,iBAAiB,CAAC;AACzB,OAAO,sBAAsB,CAAC;AAC9B,OAAO,gBAAgB,CAAC;AACxB,OAAO,YAAY,CAAC;AACpB,OAAO,gBAAgB,CAAC","sourcesContent":["import './accordion-item';\nimport './card';\nimport './bulk-edit-field';\nimport './chip-selector';\nimport './context-help';\nimport './edit-commit-bar';\nimport './master-detail-list-item';\nimport './master-detail-list';\nimport './split-button';\nimport './split-button-anchor';\nimport './sticky-header';\nimport './summary-panel';\nimport './summary-panel-tile';\nimport './search-input';\nimport './splitter';\nimport './split-layout';\n"]}
@@ -0,0 +1,40 @@
1
+ import { FoundationElement } from '@ni/fast-foundation';
2
+ import { BulkEditFieldStatus, type BulkEditFieldStatus as BulkEditFieldStatusType } from './types';
3
+ declare global {
4
+ interface HTMLElementTagNameMap {
5
+ 'ok-fv-bulk-edit-field': FvBulkEditField;
6
+ }
7
+ }
8
+ /**
9
+ * A labeled field shell for single- and multi-record editing.
10
+ */
11
+ export declare class FvBulkEditField extends FoundationElement {
12
+ label: string;
13
+ status: BulkEditFieldStatusType;
14
+ resetDisabled: boolean;
15
+ clearDisabled: boolean;
16
+ /** @internal */
17
+ controls: HTMLElement[];
18
+ private readonly labelObserver;
19
+ connectedCallback(): void;
20
+ disconnectedCallback(): void;
21
+ /** Accessible name applied to directly slotted field controls. */
22
+ get controlLabel(): string;
23
+ /** @internal */
24
+ controlsChanged(): void;
25
+ /** @internal */
26
+ labelChanged(): void;
27
+ /** @internal */
28
+ statusChanged(): void;
29
+ /** @internal */
30
+ get statusText(): string;
31
+ /** @internal */
32
+ reset(): boolean;
33
+ /** @internal */
34
+ clear(): boolean;
35
+ private updateControlLabels;
36
+ private observeControlLabels;
37
+ }
38
+ export declare const fvBulkEditFieldTag = "ok-fv-bulk-edit-field";
39
+ export { BulkEditFieldStatus };
40
+ export type { BulkEditFieldStatusType };
@@ -0,0 +1,120 @@
1
+ import { __decorate } from "tslib";
2
+ import { attr, DOM, observable } from '@ni/fast-element';
3
+ import { DesignSystem, FoundationElement } from '@ni/fast-foundation';
4
+ import { styles } from './styles';
5
+ import { template } from './template';
6
+ import { BulkEditFieldStatus } from './types';
7
+ /**
8
+ * A labeled field shell for single- and multi-record editing.
9
+ */
10
+ export class FvBulkEditField extends FoundationElement {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.label = '';
14
+ this.status = BulkEditFieldStatus.unchanged;
15
+ this.resetDisabled = false;
16
+ this.clearDisabled = false;
17
+ /** @internal */
18
+ this.controls = [];
19
+ // Some controls reapply their own label bindings when reconnected.
20
+ this.labelObserver = new MutationObserver(() => this.updateControlLabels());
21
+ }
22
+ connectedCallback() {
23
+ super.connectedCallback();
24
+ this.observeControlLabels();
25
+ this.updateControlLabels();
26
+ }
27
+ disconnectedCallback() {
28
+ this.labelObserver.disconnect();
29
+ super.disconnectedCallback();
30
+ }
31
+ /** Accessible name applied to directly slotted field controls. */
32
+ get controlLabel() {
33
+ const description = this.status === BulkEditFieldStatus.mixed
34
+ ? 'Mixed values. Enter a value to overwrite all selected rows.'
35
+ : this.statusText;
36
+ return description ? `${this.label}. ${description}` : this.label;
37
+ }
38
+ /** @internal */
39
+ controlsChanged() {
40
+ this.observeControlLabels();
41
+ this.updateControlLabels();
42
+ }
43
+ /** @internal */
44
+ labelChanged() {
45
+ this.updateControlLabels();
46
+ }
47
+ /** @internal */
48
+ statusChanged() {
49
+ this.updateControlLabels();
50
+ }
51
+ /** @internal */
52
+ get statusText() {
53
+ switch (this.status) {
54
+ case BulkEditFieldStatus.mixed:
55
+ return 'Mixed values';
56
+ case BulkEditFieldStatus.changed:
57
+ return 'Changed';
58
+ case BulkEditFieldStatus.willClear:
59
+ return 'Will clear';
60
+ default:
61
+ return '';
62
+ }
63
+ }
64
+ /** @internal */
65
+ reset() {
66
+ if (!this.resetDisabled) {
67
+ this.$emit('reset');
68
+ }
69
+ return true;
70
+ }
71
+ /** @internal */
72
+ clear() {
73
+ if (!this.clearDisabled) {
74
+ this.$emit('clear');
75
+ }
76
+ return true;
77
+ }
78
+ updateControlLabels() {
79
+ DOM.queueUpdate(() => {
80
+ this.controls?.forEach(control => {
81
+ if (control.getAttribute('aria-label') !== this.controlLabel) {
82
+ control.setAttribute('aria-label', this.controlLabel);
83
+ }
84
+ });
85
+ });
86
+ }
87
+ observeControlLabels() {
88
+ this.labelObserver?.disconnect();
89
+ if (this.isConnected) {
90
+ this.controls?.forEach(control => this.labelObserver.observe(control, {
91
+ attributes: true,
92
+ attributeFilter: ['aria-label']
93
+ }));
94
+ }
95
+ }
96
+ }
97
+ __decorate([
98
+ attr
99
+ ], FvBulkEditField.prototype, "label", void 0);
100
+ __decorate([
101
+ attr
102
+ ], FvBulkEditField.prototype, "status", void 0);
103
+ __decorate([
104
+ attr({ attribute: 'reset-disabled', mode: 'boolean' })
105
+ ], FvBulkEditField.prototype, "resetDisabled", void 0);
106
+ __decorate([
107
+ attr({ attribute: 'clear-disabled', mode: 'boolean' })
108
+ ], FvBulkEditField.prototype, "clearDisabled", void 0);
109
+ __decorate([
110
+ observable
111
+ ], FvBulkEditField.prototype, "controls", void 0);
112
+ const okFvBulkEditField = FvBulkEditField.compose({
113
+ baseName: 'fv-bulk-edit-field',
114
+ template,
115
+ styles
116
+ });
117
+ DesignSystem.getOrCreate().withPrefix('ok').register(okFvBulkEditField());
118
+ export const fvBulkEditFieldTag = 'ok-fv-bulk-edit-field';
119
+ export { BulkEditFieldStatus };
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/fv/bulk-edit-field/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { attr, DOM, observable } from '@ni/fast-element';\nimport { DesignSystem, FoundationElement } from '@ni/fast-foundation';\nimport { styles } from './styles';\nimport { template } from './template';\nimport {\n BulkEditFieldStatus,\n type BulkEditFieldStatus as BulkEditFieldStatusType\n} from './types';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ok-fv-bulk-edit-field': FvBulkEditField;\n }\n}\n\n/**\n * A labeled field shell for single- and multi-record editing.\n */\nexport class FvBulkEditField extends FoundationElement {\n @attr\n public label = '';\n\n @attr\n public status: BulkEditFieldStatusType = BulkEditFieldStatus.unchanged;\n\n @attr({ attribute: 'reset-disabled', mode: 'boolean' })\n public resetDisabled = false;\n\n @attr({ attribute: 'clear-disabled', mode: 'boolean' })\n public clearDisabled = false;\n\n /** @internal */\n @observable\n public controls: HTMLElement[] = [];\n\n // Some controls reapply their own label bindings when reconnected.\n private readonly labelObserver = new MutationObserver(() => this.updateControlLabels());\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.observeControlLabels();\n this.updateControlLabels();\n }\n\n public override disconnectedCallback(): void {\n this.labelObserver.disconnect();\n super.disconnectedCallback();\n }\n\n /** Accessible name applied to directly slotted field controls. */\n public get controlLabel(): string {\n const description = this.status === BulkEditFieldStatus.mixed\n ? 'Mixed values. Enter a value to overwrite all selected rows.'\n : this.statusText;\n return description ? `${this.label}. ${description}` : this.label;\n }\n\n /** @internal */\n public controlsChanged(): void {\n this.observeControlLabels();\n this.updateControlLabels();\n }\n\n /** @internal */\n public labelChanged(): void {\n this.updateControlLabels();\n }\n\n /** @internal */\n public statusChanged(): void {\n this.updateControlLabels();\n }\n\n /** @internal */\n public get statusText(): string {\n switch (this.status) {\n case BulkEditFieldStatus.mixed:\n return 'Mixed values';\n case BulkEditFieldStatus.changed:\n return 'Changed';\n case BulkEditFieldStatus.willClear:\n return 'Will clear';\n default:\n return '';\n }\n }\n\n /** @internal */\n public reset(): boolean {\n if (!this.resetDisabled) {\n this.$emit('reset');\n }\n return true;\n }\n\n /** @internal */\n public clear(): boolean {\n if (!this.clearDisabled) {\n this.$emit('clear');\n }\n return true;\n }\n\n private updateControlLabels(): void {\n DOM.queueUpdate(() => {\n this.controls?.forEach(control => {\n if (control.getAttribute('aria-label') !== this.controlLabel) {\n control.setAttribute('aria-label', this.controlLabel);\n }\n });\n });\n }\n\n private observeControlLabels(): void {\n this.labelObserver?.disconnect();\n if (this.isConnected) {\n this.controls?.forEach(control => this.labelObserver.observe(control, {\n attributes: true,\n attributeFilter: ['aria-label']\n }));\n }\n }\n}\n\nconst okFvBulkEditField = FvBulkEditField.compose({\n baseName: 'fv-bulk-edit-field',\n template,\n styles\n});\n\nDesignSystem.getOrCreate().withPrefix('ok').register(okFvBulkEditField());\nexport const fvBulkEditFieldTag = 'ok-fv-bulk-edit-field';\nexport { BulkEditFieldStatus };\nexport type { BulkEditFieldStatusType };\n"]}
@@ -0,0 +1 @@
1
+ export declare const styles: import("@ni/fast-element").ElementStyles;
@@ -0,0 +1,83 @@
1
+ import { css } from '@ni/fast-element';
2
+ import { controlLabelFont, controlLabelFontColor, bodyFont, bodyFontColor, informationColor, warningColor, warningFontColor, controlHeight, labelHeight, mediumPadding, smallPadding, standardPadding } from '@ni/nimble-components/dist/esm/theme-provider/design-tokens';
3
+ import { display } from '../../utilities/style/display';
4
+ export const styles = css `
5
+ ${display('block')}
6
+
7
+ :host {
8
+ color: ${bodyFontColor};
9
+ font: ${bodyFont};
10
+ }
11
+
12
+ .field {
13
+ display: grid;
14
+ grid-template-columns: 3px minmax(0, 1fr);
15
+ column-gap: ${standardPadding};
16
+ }
17
+
18
+ .marker {
19
+ width: 3px;
20
+ border-radius: 2px;
21
+ }
22
+
23
+ :host([status='changed']) .marker,
24
+ :host([status='will-clear']) .marker {
25
+ background: ${warningColor};
26
+ }
27
+
28
+ .content,
29
+ .control {
30
+ min-width: 0;
31
+ }
32
+
33
+ .header,
34
+ .actions {
35
+ display: flex;
36
+ align-items: center;
37
+ gap: ${smallPadding};
38
+ }
39
+
40
+ .header {
41
+ flex-wrap: wrap;
42
+ margin-block-end: 0;
43
+ }
44
+
45
+ .label {
46
+ font: ${controlLabelFont};
47
+ color: ${controlLabelFontColor};
48
+ margin-inline-end: auto;
49
+ }
50
+
51
+ .status {
52
+ font-size: 0.875em;
53
+ line-height: 1;
54
+ padding: 0 5px;
55
+ border: 1px solid ${informationColor};
56
+ border-radius: 4px;
57
+ color: ${informationColor};
58
+ }
59
+
60
+ :host([status='changed']) .status,
61
+ :host([status='will-clear']) .status {
62
+ border-color: ${warningColor};
63
+ color: ${warningFontColor};
64
+ }
65
+
66
+ .control {
67
+ display: block;
68
+ }
69
+
70
+ .actions {
71
+ justify-content: flex-end;
72
+ gap: 4px;
73
+ margin-inline-end: ${mediumPadding};
74
+ ${controlHeight.cssCustomProperty}: ${labelHeight};
75
+ }
76
+
77
+ ::slotted(:not([slot])) {
78
+ box-sizing: border-box;
79
+ width: 100%;
80
+ min-width: 0;
81
+ }
82
+ `;
83
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../src/fv/bulk-edit-field/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EACH,gBAAgB,EAChB,qBAAqB,EACrB,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,eAAe,EAClB,MAAM,6DAA6D,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAExD,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;MACnB,OAAO,CAAC,OAAO,CAAC;;;iBAGL,aAAa;gBACd,QAAQ;;;;;;sBAMF,eAAe;;;;;;;;;;sBAUf,YAAY;;;;;;;;;;;;eAYnB,YAAY;;;;;;;;;gBASX,gBAAgB;iBACf,qBAAqB;;;;;;;;4BAQV,gBAAgB;;iBAE3B,gBAAgB;;;;;wBAKT,YAAY;iBACnB,gBAAgB;;;;;;;;;;6BAUJ,aAAa;UAChC,aAAa,CAAC,iBAAiB,KAAK,WAAW;;;;;;;;CAQxD,CAAC","sourcesContent":["import { css } from '@ni/fast-element';\nimport {\n controlLabelFont,\n controlLabelFontColor,\n bodyFont,\n bodyFontColor,\n informationColor,\n warningColor,\n warningFontColor,\n controlHeight,\n labelHeight,\n mediumPadding,\n smallPadding,\n standardPadding\n} from '@ni/nimble-components/dist/esm/theme-provider/design-tokens';\nimport { display } from '../../utilities/style/display';\n\nexport const styles = css`\n ${display('block')}\n\n :host {\n color: ${bodyFontColor};\n font: ${bodyFont};\n }\n\n .field {\n display: grid;\n grid-template-columns: 3px minmax(0, 1fr);\n column-gap: ${standardPadding};\n }\n\n .marker {\n width: 3px;\n border-radius: 2px;\n }\n\n :host([status='changed']) .marker,\n :host([status='will-clear']) .marker {\n background: ${warningColor};\n }\n\n .content,\n .control {\n min-width: 0;\n }\n\n .header,\n .actions {\n display: flex;\n align-items: center;\n gap: ${smallPadding};\n }\n\n .header {\n flex-wrap: wrap;\n margin-block-end: 0;\n }\n\n .label {\n font: ${controlLabelFont};\n color: ${controlLabelFontColor};\n margin-inline-end: auto;\n }\n\n .status {\n font-size: 0.875em;\n line-height: 1;\n padding: 0 5px;\n border: 1px solid ${informationColor};\n border-radius: 4px;\n color: ${informationColor};\n }\n\n :host([status='changed']) .status,\n :host([status='will-clear']) .status {\n border-color: ${warningColor};\n color: ${warningFontColor};\n }\n\n .control {\n display: block;\n }\n\n .actions {\n justify-content: flex-end;\n gap: 4px;\n margin-inline-end: ${mediumPadding};\n ${controlHeight.cssCustomProperty}: ${labelHeight};\n }\n\n ::slotted(:not([slot])) {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n }\n`;\n"]}
@@ -0,0 +1,2 @@
1
+ import type { FvBulkEditField } from '.';
2
+ export declare const template: import("@ni/fast-element").ViewTemplate<FvBulkEditField, any>;
@@ -0,0 +1,36 @@
1
+ import { html, slotted, elements, when } from '@ni/fast-element';
2
+ import { buttonTag } from '@ni/nimble-components/dist/esm/button';
3
+ import { iconArrowPartialRotateLeftTag } from '@ni/nimble-components/dist/esm/icons/arrow-partial-rotate-left';
4
+ import { iconTimesTag } from '@ni/nimble-components/dist/esm/icons/times';
5
+ export const template = html `
6
+ <div class="field">
7
+ <span class="marker" aria-hidden="true"></span>
8
+ <div class="content">
9
+ <div class="header">
10
+ <span class="label">${x => x.label}</span>
11
+ ${when(x => x.statusText.length > 0, html `<span class="status">${x => x.statusText}</span>`)}
12
+ <div class="actions">
13
+ <${buttonTag}
14
+ appearance="ghost"
15
+ content-hidden
16
+ title="${x => `Reset ${x.label}`}"
17
+ ?disabled="${x => x.resetDisabled}"
18
+ @click="${x => x.reset()}"
19
+ ><${iconArrowPartialRotateLeftTag} slot="start"></${iconArrowPartialRotateLeftTag}>Reset ${x => x.label}</${buttonTag}>
20
+ <${buttonTag}
21
+ appearance="ghost"
22
+ content-hidden
23
+ title="${x => `Clear ${x.label} for selected rows`}"
24
+ ?disabled="${x => x.clearDisabled}"
25
+ @click="${x => x.clear()}"
26
+ ><${iconTimesTag} slot="start"></${iconTimesTag}>Clear ${x => x.label}</${buttonTag}>
27
+ <slot name="actions"></slot>
28
+ </div>
29
+ </div>
30
+ <div class="control">
31
+ <slot ${slotted({ property: 'controls', filter: elements() })}></slot>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ `;
36
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/fv/bulk-edit-field/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,gEAAgE,CAAC;AAC/G,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAG1E,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAiB;;;;;sCAKP,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;kBAChC,IAAI,CACF,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAC5B,IAAI,CAAiB,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,SAAS,CAC1E;;mBAEE,SAAS;;;6BAGC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE;iCACnB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;8BACvB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE;oBACxB,6BAA6B,mBAAmB,6BAA6B,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS;mBAClH,SAAS;;;6BAGC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,oBAAoB;iCACrC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;8BACvB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE;oBACxB,YAAY,mBAAmB,YAAY,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS;;;;;wBAK3E,OAAO,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;;;;CAI5E,CAAC","sourcesContent":["import { html, slotted, elements, when } from '@ni/fast-element';\nimport { buttonTag } from '@ni/nimble-components/dist/esm/button';\nimport { iconArrowPartialRotateLeftTag } from '@ni/nimble-components/dist/esm/icons/arrow-partial-rotate-left';\nimport { iconTimesTag } from '@ni/nimble-components/dist/esm/icons/times';\nimport type { FvBulkEditField } from '.';\n\nexport const template = html<FvBulkEditField>`\n <div class=\"field\">\n <span class=\"marker\" aria-hidden=\"true\"></span>\n <div class=\"content\">\n <div class=\"header\">\n <span class=\"label\">${x => x.label}</span>\n ${when(\n x => x.statusText.length > 0,\n html<FvBulkEditField>`<span class=\"status\">${x => x.statusText}</span>`\n )}\n <div class=\"actions\">\n <${buttonTag}\n appearance=\"ghost\"\n content-hidden\n title=\"${x => `Reset ${x.label}`}\"\n ?disabled=\"${x => x.resetDisabled}\"\n @click=\"${x => x.reset()}\"\n ><${iconArrowPartialRotateLeftTag} slot=\"start\"></${iconArrowPartialRotateLeftTag}>Reset ${x => x.label}</${buttonTag}>\n <${buttonTag}\n appearance=\"ghost\"\n content-hidden\n title=\"${x => `Clear ${x.label} for selected rows`}\"\n ?disabled=\"${x => x.clearDisabled}\"\n @click=\"${x => x.clear()}\"\n ><${iconTimesTag} slot=\"start\"></${iconTimesTag}>Clear ${x => x.label}</${buttonTag}>\n <slot name=\"actions\"></slot>\n </div>\n </div>\n <div class=\"control\">\n <slot ${slotted({ property: 'controls', filter: elements() })}></slot>\n </div>\n </div>\n </div>\n`;\n"]}
@@ -0,0 +1,7 @@
1
+ export declare const BulkEditFieldStatus: {
2
+ readonly unchanged: "unchanged";
3
+ readonly mixed: "mixed";
4
+ readonly changed: "changed";
5
+ readonly willClear: "will-clear";
6
+ };
7
+ export type BulkEditFieldStatus = (typeof BulkEditFieldStatus)[keyof typeof BulkEditFieldStatus];
@@ -0,0 +1,7 @@
1
+ export const BulkEditFieldStatus = {
2
+ unchanged: 'unchanged',
3
+ mixed: 'mixed',
4
+ changed: 'changed',
5
+ willClear: 'will-clear'
6
+ };
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/fv/bulk-edit-field/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG;IAC/B,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,YAAY;CACjB,CAAC","sourcesContent":["export const BulkEditFieldStatus = {\n unchanged: 'unchanged',\n mixed: 'mixed',\n changed: 'changed',\n willClear: 'will-clear'\n} as const;\n\nexport type BulkEditFieldStatus = (typeof BulkEditFieldStatus)[keyof typeof BulkEditFieldStatus];\n"]}
@@ -0,0 +1,47 @@
1
+ export type RecordId = string;
2
+ export type PendingChanges<TField extends PropertyKey> = {
3
+ [Field in TField]?: string;
4
+ };
5
+ export interface BulkEditFieldValue {
6
+ value: string;
7
+ mixed: boolean;
8
+ pending: boolean;
9
+ willClear: boolean;
10
+ }
11
+ export interface BulkEditCommit<TRecord, TField extends PropertyKey> {
12
+ selectedIds: readonly RecordId[];
13
+ changes: Readonly<PendingChanges<TField>>;
14
+ affectedRecords: readonly TRecord[];
15
+ }
16
+ export interface BulkEditStateOptions<TRecord, TField extends PropertyKey> {
17
+ records: readonly TRecord[];
18
+ id: (record: TRecord) => RecordId;
19
+ read: (record: TRecord, field: TField) => string;
20
+ }
21
+ /**
22
+ * Framework-neutral state for editing common fields across selected records.
23
+ */
24
+ export declare class BulkEditState<TRecord, TField extends PropertyKey> {
25
+ private records;
26
+ private readonly id;
27
+ private readonly read;
28
+ private selected;
29
+ private readonly pending;
30
+ private readonly draft;
31
+ constructor(options: BulkEditStateOptions<TRecord, TField>);
32
+ get selectedIds(): readonly RecordId[];
33
+ get changes(): Readonly<PendingChanges<TField>>;
34
+ get selectedRecords(): readonly TRecord[];
35
+ field(field: TField): BulkEditFieldValue;
36
+ edit(field: TField, value: string): void;
37
+ clear(field: TField): void;
38
+ resetField(field: TField): void;
39
+ revert(): void;
40
+ isSelection(ids: readonly RecordId[]): boolean;
41
+ visibleSelection(visibleIds: readonly RecordId[]): readonly RecordId[];
42
+ mergeVisible(visibleIds: readonly RecordId[], selectedVisibleIds: readonly RecordId[], additive?: boolean): readonly RecordId[];
43
+ select(ids: readonly RecordId[]): void;
44
+ createCommit(): BulkEditCommit<TRecord, TField>;
45
+ commitSucceeded(updatedRecords?: readonly TRecord[]): void;
46
+ private setPending;
47
+ }