@visitwonders/assembly 0.16.1 → 0.18.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/declarations/action/button-group.d.ts +5 -8
- package/declarations/action/button-group.d.ts.map +1 -1
- package/declarations/data/pagination.d.ts +3 -5
- package/declarations/data/pagination.d.ts.map +1 -1
- package/declarations/data/table.d.ts +12 -11
- package/declarations/data/table.d.ts.map +1 -1
- package/declarations/form/calendar.d.ts +19 -12
- package/declarations/form/calendar.d.ts.map +1 -1
- package/declarations/form/checkbox-group.d.ts +2 -8
- package/declarations/form/checkbox-group.d.ts.map +1 -1
- package/declarations/form/checkbox.d.ts +4 -8
- package/declarations/form/checkbox.d.ts.map +1 -1
- package/declarations/form/combobox-field.d.ts +1 -1
- package/declarations/form/combobox-field.d.ts.map +1 -1
- package/declarations/form/combobox.d.ts +1 -1
- package/declarations/form/combobox.d.ts.map +1 -1
- package/declarations/form/date-picker-field.d.ts +4 -3
- package/declarations/form/date-picker-field.d.ts.map +1 -1
- package/declarations/form/date-picker.d.ts +11 -8
- package/declarations/form/date-picker.d.ts.map +1 -1
- package/declarations/form/date-range-picker-field.d.ts +4 -3
- package/declarations/form/date-range-picker-field.d.ts.map +1 -1
- package/declarations/form/date-range-picker.d.ts +6 -9
- package/declarations/form/date-range-picker.d.ts.map +1 -1
- package/declarations/form/input.d.ts +1 -4
- package/declarations/form/input.d.ts.map +1 -1
- package/declarations/form/money-field.d.ts +13 -3
- package/declarations/form/money-field.d.ts.map +1 -1
- package/declarations/form/multi-combobox-field.d.ts +1 -1
- package/declarations/form/multi-combobox-field.d.ts.map +1 -1
- package/declarations/form/multi-combobox.d.ts +1 -1
- package/declarations/form/multi-combobox.d.ts.map +1 -1
- package/declarations/form/radio.d.ts +3 -5
- package/declarations/form/radio.d.ts.map +1 -1
- package/declarations/form/search-input.d.ts +2 -1
- package/declarations/form/search-input.d.ts.map +1 -1
- package/declarations/form/text-field.d.ts +1 -7
- package/declarations/form/text-field.d.ts.map +1 -1
- package/declarations/form/textarea.d.ts +1 -7
- package/declarations/form/textarea.d.ts.map +1 -1
- package/declarations/form/toggle-field.d.ts +2 -4
- package/declarations/form/toggle-field.d.ts.map +1 -1
- package/declarations/form/toggle.d.ts +3 -9
- package/declarations/form/toggle.d.ts.map +1 -1
- package/declarations/overlay/drawer.d.ts +10 -9
- package/declarations/overlay/drawer.d.ts.map +1 -1
- package/declarations/overlay/modal.d.ts +10 -10
- package/declarations/overlay/modal.d.ts.map +1 -1
- package/declarations/overlay/popover.d.ts +9 -8
- package/declarations/overlay/popover.d.ts.map +1 -1
- package/declarations/overlay/tooltip.d.ts +9 -8
- package/declarations/overlay/tooltip.d.ts.map +1 -1
- package/dist/action/button-group.js +2 -25
- package/dist/data/pagination.js +10 -24
- package/dist/data/table.css +51 -3
- package/dist/data/table.js +14 -71
- package/dist/form/calendar.js +29 -57
- package/dist/form/checkbox-group.js +3 -23
- package/dist/form/checkbox.js +3 -17
- package/dist/form/combobox-field.js.map +1 -1
- package/dist/form/date-picker-field.js +1 -1
- package/dist/form/date-picker-field.js.map +1 -1
- package/dist/form/date-picker.js +10 -28
- package/dist/form/date-range-picker-field.js +1 -1
- package/dist/form/date-range-picker-field.js.map +1 -1
- package/dist/form/date-range-picker.js +8 -31
- package/dist/form/input.js +1 -6
- package/dist/form/money-field.js +23 -22
- package/dist/form/multi-combobox-field.js.map +1 -1
- package/dist/form/radio.js +3 -4
- package/dist/form/search-input.js +6 -9
- package/dist/form/text-field.js +3 -22
- package/dist/form/textarea.js +2 -17
- package/dist/form/toggle-field.js +1 -1
- package/dist/form/toggle.js +4 -18
- package/dist/overlay/drawer.js +6 -26
- package/dist/overlay/modal.js +5 -29
- package/dist/overlay/popover.js +15 -16
- package/dist/overlay/tooltip.js +14 -16
- package/package.json +16 -17
|
@@ -1,38 +1,21 @@
|
|
|
1
1
|
import "./button-group.css"
|
|
2
2
|
import Component from '@glimmer/component';
|
|
3
|
-
import { tracked } from '@glimmer/tracking';
|
|
4
3
|
import { action } from '@ember/object';
|
|
5
4
|
import { on } from '@ember/modifier';
|
|
6
5
|
import { fn, hash } from '@ember/helper';
|
|
7
6
|
import Button from './button.js';
|
|
8
7
|
import { precompileTemplate } from '@ember/template-compilation';
|
|
9
8
|
import { setComponentTemplate } from '@ember/component';
|
|
10
|
-
import {
|
|
9
|
+
import { n } from 'decorator-transforms/runtime';
|
|
11
10
|
|
|
12
11
|
;
|
|
13
12
|
|
|
14
13
|
class ButtonGroup extends Component {
|
|
15
|
-
static {
|
|
16
|
-
g(this.prototype, "internalValue", [tracked]);
|
|
17
|
-
}
|
|
18
|
-
#internalValue = (i(this, "internalValue"), void 0);
|
|
19
|
-
constructor(owner, args) {
|
|
20
|
-
super(owner, args);
|
|
21
|
-
const defaultVal = args.defaultValue;
|
|
22
|
-
if (this.selectionType === 'multiple') {
|
|
23
|
-
this.internalValue = Array.isArray(defaultVal) ? [...defaultVal] : defaultVal ? [defaultVal] : [];
|
|
24
|
-
} else {
|
|
25
|
-
this.internalValue = Array.isArray(defaultVal) ? defaultVal[0] ?? '' : defaultVal ?? '';
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
14
|
get selectionType() {
|
|
29
15
|
return this.args.type ?? 'single';
|
|
30
16
|
}
|
|
31
|
-
get isControlled() {
|
|
32
|
-
return this.args.value !== undefined;
|
|
33
|
-
}
|
|
34
17
|
get selectedValue() {
|
|
35
|
-
return this.
|
|
18
|
+
return this.args.value;
|
|
36
19
|
}
|
|
37
20
|
get variant() {
|
|
38
21
|
return this.args.variant ?? 'outline';
|
|
@@ -74,15 +57,9 @@ class ButtonGroup extends Component {
|
|
|
74
57
|
} else {
|
|
75
58
|
newValues = [...currentArray, value];
|
|
76
59
|
}
|
|
77
|
-
if (!this.isControlled) {
|
|
78
|
-
this.internalValue = newValues;
|
|
79
|
-
}
|
|
80
60
|
this.args.onChange?.(newValues);
|
|
81
61
|
} else {
|
|
82
62
|
if (this.selectedValue === value) return;
|
|
83
|
-
if (!this.isControlled) {
|
|
84
|
-
this.internalValue = value;
|
|
85
|
-
}
|
|
86
63
|
this.args.onChange?.(value);
|
|
87
64
|
}
|
|
88
65
|
}
|
package/dist/data/pagination.js
CHANGED
|
@@ -20,13 +20,6 @@ import { g, i } from 'decorator-transforms/runtime';
|
|
|
20
20
|
// Component
|
|
21
21
|
// ============================================================================
|
|
22
22
|
class Pagination extends Component {
|
|
23
|
-
static {
|
|
24
|
-
g(this.prototype, "internalCurrentPage", [tracked], function () {
|
|
25
|
-
return 1;
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
#internalCurrentPage = (i(this, "internalCurrentPage"), void 0); // Uncontrolled-mode state. When the consumer passes `@currentPage`, this
|
|
29
|
-
// value is ignored; otherwise it tracks page locally.
|
|
30
23
|
// Tracked snapshot of the last seen totalPages so the refresh-clamp modifier
|
|
31
24
|
// can detect a shrink-under-the-user without scheduling its own runloop.
|
|
32
25
|
previousTotalPages = null;
|
|
@@ -86,15 +79,10 @@ class Pagination extends Component {
|
|
|
86
79
|
return this.args.showJumpTo ?? false;
|
|
87
80
|
}
|
|
88
81
|
// ============================================================================
|
|
89
|
-
//
|
|
90
|
-
// Note: unlike Table, @onChange fires in BOTH modes — Pagination models a
|
|
91
|
-
// navigation event. See spec §Behaviour > Callback contract.
|
|
82
|
+
// Current page (the consumer owns it)
|
|
92
83
|
// ============================================================================
|
|
93
|
-
get isControlled() {
|
|
94
|
-
return this.args.currentPage !== undefined;
|
|
95
|
-
}
|
|
96
84
|
get currentPage() {
|
|
97
|
-
return this.args.currentPage
|
|
85
|
+
return this.args.currentPage;
|
|
98
86
|
}
|
|
99
87
|
// ============================================================================
|
|
100
88
|
// Derived counts
|
|
@@ -182,14 +170,11 @@ class Pagination extends Component {
|
|
|
182
170
|
// ============================================================================
|
|
183
171
|
// Navigation
|
|
184
172
|
// ============================================================================
|
|
185
|
-
// Single
|
|
186
|
-
//
|
|
187
|
-
// Spec §Behaviour > Callback contract.
|
|
173
|
+
// Single navigation path. Clamps to [1, totalPages] and fires @onChange with
|
|
174
|
+
// the result; the consumer advances @currentPage. The component never writes
|
|
175
|
+
// its own page. Spec §Behaviour > Callback contract.
|
|
188
176
|
goToPage(page) {
|
|
189
177
|
const clamped = Math.max(1, Math.min(this.totalPages, page));
|
|
190
|
-
if (!this.isControlled) {
|
|
191
|
-
this.internalCurrentPage = clamped;
|
|
192
|
-
}
|
|
193
178
|
this.args.onChange(clamped);
|
|
194
179
|
}
|
|
195
180
|
handlePageClick = page => {
|
|
@@ -253,10 +238,11 @@ class Pagination extends Component {
|
|
|
253
238
|
// assumed to be valid.
|
|
254
239
|
if (previous === null) return;
|
|
255
240
|
// Only clamp on shrink-past-current. Growth never re-fires.
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
//
|
|
259
|
-
//
|
|
241
|
+
// @onChange is deferred to a microtask: the modifier reads `currentPage`
|
|
242
|
+
// (i.e. @currentPage), and firing @onChange drives the consumer to update
|
|
243
|
+
// that same arg. Glimmer rejects mutating a tracked value read in the
|
|
244
|
+
// same computation, so we punt the fire to the next microtask. Tests
|
|
245
|
+
// flush it with `await settled()`.
|
|
260
246
|
if (totalPages < previous && currentPage > totalPages) {
|
|
261
247
|
void Promise.resolve().then(() => this.goToPage(totalPages));
|
|
262
248
|
}
|
package/dist/data/table.css
CHANGED
|
@@ -9,6 +9,19 @@
|
|
|
9
9
|
font-size: var(--font-size-md);
|
|
10
10
|
color: var(--color-text);
|
|
11
11
|
background-color: var(--color-bg-surface);
|
|
12
|
+
|
|
13
|
+
/* Edge inset: how far the first/last column sit from the table's edges.
|
|
14
|
+
Driven by @paddingInline; defaults to today's 16px. Only the outer side
|
|
15
|
+
of the edge columns reads it, so inter-column gutters never change. */
|
|
16
|
+
--_table-edge-inset: var(--spacing-inset-md);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.table_e4aed93fe[data-padding-inline="sm"] {
|
|
20
|
+
--_table-edge-inset: var(--spacing-inset-sm);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.table_e4aed93fe[data-padding-inline="lg"] {
|
|
24
|
+
--_table-edge-inset: var(--spacing-inset-lg);
|
|
12
25
|
}
|
|
13
26
|
|
|
14
27
|
.table_e4aed93fe:focus {
|
|
@@ -53,7 +66,7 @@
|
|
|
53
66
|
}
|
|
54
67
|
|
|
55
68
|
.header-cell_e4aed93fe {
|
|
56
|
-
padding: var(--spacing-
|
|
69
|
+
padding: var(--spacing-inset-sm) var(--spacing-inset-md);
|
|
57
70
|
font-weight: var(--font-weight-medium);
|
|
58
71
|
color: var(--color-text-secondary);
|
|
59
72
|
text-align: left;
|
|
@@ -98,7 +111,7 @@
|
|
|
98
111
|
justify-content: space-between;
|
|
99
112
|
gap: var(--spacing-1);
|
|
100
113
|
width: 100%;
|
|
101
|
-
padding: var(--spacing-
|
|
114
|
+
padding: var(--spacing-inset-sm) var(--spacing-inset-md);
|
|
102
115
|
border: none;
|
|
103
116
|
background: none;
|
|
104
117
|
font: inherit;
|
|
@@ -194,7 +207,7 @@
|
|
|
194
207
|
============================================================================ */
|
|
195
208
|
|
|
196
209
|
.cell_e4aed93fe {
|
|
197
|
-
padding: var(--spacing-
|
|
210
|
+
padding: var(--spacing-inset-sm) var(--spacing-inset-md);
|
|
198
211
|
vertical-align: middle;
|
|
199
212
|
}
|
|
200
213
|
|
|
@@ -215,6 +228,41 @@
|
|
|
215
228
|
padding-right: 0;
|
|
216
229
|
}
|
|
217
230
|
|
|
231
|
+
/* ============================================================================
|
|
232
|
+
Edge Inset (@paddingInline)
|
|
233
|
+
============================================================================
|
|
234
|
+
The inset lands on the outer side of the first and last columns only, so
|
|
235
|
+
inter-column gutters and row-background bleed stay put. It composes with
|
|
236
|
+
@isCompact: density owns the inner padding, this owns the outer edge.
|
|
237
|
+
|
|
238
|
+
A sortable header cell is zeroed and its padding lives on the sort button.
|
|
239
|
+
So on a sortable edge column the inset lands on the button, not the zeroed
|
|
240
|
+
cell. Otherwise its label would not line up with the body cells below. */
|
|
241
|
+
|
|
242
|
+
.table_e4aed93fe .header-row_e4aed93fe > .header-cell_e4aed93fe:first-child:not([data-sortable="true"]),
|
|
243
|
+
.table_e4aed93fe .row_e4aed93fe > .cell_e4aed93fe:first-child {
|
|
244
|
+
padding-inline-start: var(--_table-edge-inset);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.table_e4aed93fe .header-row_e4aed93fe > .header-cell_e4aed93fe:last-child:not([data-sortable="true"]),
|
|
248
|
+
.table_e4aed93fe .row_e4aed93fe > .cell_e4aed93fe:last-child {
|
|
249
|
+
padding-inline-end: var(--_table-edge-inset);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.table_e4aed93fe
|
|
253
|
+
.header-row_e4aed93fe
|
|
254
|
+
> .header-cell_e4aed93fe:first-child[data-sortable="true"]
|
|
255
|
+
.sort-button_e4aed93fe {
|
|
256
|
+
padding-inline-start: var(--_table-edge-inset);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.table_e4aed93fe
|
|
260
|
+
.header-row_e4aed93fe
|
|
261
|
+
> .header-cell_e4aed93fe:last-child[data-sortable="true"]
|
|
262
|
+
.sort-button_e4aed93fe {
|
|
263
|
+
padding-inline-end: var(--_table-edge-inset);
|
|
264
|
+
}
|
|
265
|
+
|
|
218
266
|
/* ============================================================================
|
|
219
267
|
Bordered Variant
|
|
220
268
|
============================================================================ */
|
package/dist/data/table.js
CHANGED
|
@@ -54,18 +54,6 @@ class Table extends Component {
|
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
56
|
#focusedRowIndex = (i(this, "focusedRowIndex"), void 0);
|
|
57
|
-
static {
|
|
58
|
-
g(this.prototype, "internalSortState", [tracked], function () {
|
|
59
|
-
return null;
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
#internalSortState = (i(this, "internalSortState"), void 0);
|
|
63
|
-
static {
|
|
64
|
-
g(this.prototype, "internalSelectedIds", [tracked], function () {
|
|
65
|
-
return [];
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
#internalSelectedIds = (i(this, "internalSelectedIds"), void 0);
|
|
69
57
|
static {
|
|
70
58
|
g(this.prototype, "lastSelectedIndex", [tracked], function () {
|
|
71
59
|
return null;
|
|
@@ -92,60 +80,23 @@ class Table extends Component {
|
|
|
92
80
|
get visibleColumns() {
|
|
93
81
|
return this.args.columns.filter(col => !col.hidden);
|
|
94
82
|
}
|
|
95
|
-
|
|
96
|
-
|
|
83
|
+
// Edge inset on the spacing-inset scale. Always resolves to a value so the
|
|
84
|
+
// attribute is present on every render; `md` is today's default.
|
|
85
|
+
get paddingInline() {
|
|
86
|
+
return this.args.paddingInline ?? 'md';
|
|
97
87
|
}
|
|
98
88
|
get selectedIds() {
|
|
99
|
-
return this.
|
|
100
|
-
}
|
|
101
|
-
get isControlledSort() {
|
|
102
|
-
return this.args.sortBy !== undefined || this.args.onSortChange !== undefined;
|
|
89
|
+
return this.args.selectedIds ?? [];
|
|
103
90
|
}
|
|
104
91
|
get sortState() {
|
|
105
|
-
return this.
|
|
106
|
-
}
|
|
107
|
-
get sortedData() {
|
|
108
|
-
const data = this.args.data ?? [];
|
|
109
|
-
const sort = this.sortState;
|
|
110
|
-
if (!sort) return data;
|
|
111
|
-
const column = this.args.columns.find(col => col.id === sort.columnId);
|
|
112
|
-
if (!column) return data;
|
|
113
|
-
const sorted = [...data];
|
|
114
|
-
sorted.sort((a, b) => {
|
|
115
|
-
// Use custom sort function if provided
|
|
116
|
-
if (column.sortFn) {
|
|
117
|
-
const result = column.sortFn(a, b);
|
|
118
|
-
return sort.direction === 'desc' ? -result : result;
|
|
119
|
-
}
|
|
120
|
-
// Default sort using accessor
|
|
121
|
-
const aVal = this.getCellValue(a, column);
|
|
122
|
-
const bVal = this.getCellValue(b, column);
|
|
123
|
-
let result = 0;
|
|
124
|
-
if (aVal === bVal) {
|
|
125
|
-
result = 0;
|
|
126
|
-
} else if (aVal === null || aVal === undefined) {
|
|
127
|
-
result = 1;
|
|
128
|
-
} else if (bVal === null || bVal === undefined) {
|
|
129
|
-
result = -1;
|
|
130
|
-
} else if (typeof aVal === 'string' && typeof bVal === 'string') {
|
|
131
|
-
result = aVal.localeCompare(bVal);
|
|
132
|
-
} else if (typeof aVal === 'number' && typeof bVal === 'number') {
|
|
133
|
-
result = aVal - bVal;
|
|
134
|
-
} else {
|
|
135
|
-
// Handle other types by converting to string safely
|
|
136
|
-
const aStr = stringifyValue(aVal);
|
|
137
|
-
const bStr = stringifyValue(bVal);
|
|
138
|
-
result = aStr.localeCompare(bStr);
|
|
139
|
-
}
|
|
140
|
-
return sort.direction === 'desc' ? -result : result;
|
|
141
|
-
});
|
|
142
|
-
return sorted;
|
|
92
|
+
return this.args.sortBy ?? null;
|
|
143
93
|
}
|
|
94
|
+
// The table renders @data in the order it is given and never sorts it. The
|
|
95
|
+
// consumer owns the sort: @sortBy drives the header indicator and
|
|
96
|
+
// @onSortChange reports a click; the consumer reorders the data.
|
|
97
|
+
// See docs/decisions/0003-sorting-model.md.
|
|
144
98
|
get displayData() {
|
|
145
|
-
|
|
146
|
-
return [];
|
|
147
|
-
}
|
|
148
|
-
return this.sortedData;
|
|
99
|
+
return this.args.isLoading ? [] : this.args.data ?? [];
|
|
149
100
|
}
|
|
150
101
|
get isEmpty() {
|
|
151
102
|
return !this.args.isLoading && this.displayData.length === 0;
|
|
@@ -229,18 +180,10 @@ class Table extends Component {
|
|
|
229
180
|
return 'none';
|
|
230
181
|
};
|
|
231
182
|
updateSelection(newIds) {
|
|
232
|
-
|
|
233
|
-
this.args.onSelectionChange?.(newIds);
|
|
234
|
-
} else {
|
|
235
|
-
this.internalSelectedIds = newIds;
|
|
236
|
-
}
|
|
183
|
+
this.args.onSelectionChange?.(newIds);
|
|
237
184
|
}
|
|
238
185
|
updateSort(newSort) {
|
|
239
|
-
|
|
240
|
-
this.args.onSortChange?.(newSort);
|
|
241
|
-
} else {
|
|
242
|
-
this.internalSortState = newSort;
|
|
243
|
-
}
|
|
186
|
+
this.args.onSortChange?.(newSort);
|
|
244
187
|
}
|
|
245
188
|
moveFocus(direction) {
|
|
246
189
|
const rows = this.displayData;
|
|
@@ -440,7 +383,7 @@ class Table extends Component {
|
|
|
440
383
|
// Template
|
|
441
384
|
// ============================================================================
|
|
442
385
|
static {
|
|
443
|
-
setComponentTemplate(precompileTemplate("<table class=\"table_e4aed93fe\" data-sticky-header={{if @hasStickyHeader \"true\"}} data-striped={{if @isStriped \"true\"}} data-bordered={{if @isBordered \"true\"}} data-compact={{if @isCompact \"true\"}} data-loading={{if @isLoading \"true\"}} data-test-table tabindex=\"0\" {{this.setupRef}} {{!-- template-lint-disable no-pointer-down-event-binding --}} {{on \"mousedown\" this.handleMouseDown}} {{on \"keydown\" this.handleKeyDown}} {{on \"focus\" this.handleFocus}} {{on \"blur\" this.handleBlur}} ...attributes>\n {{#if @caption}}\n <caption class=\"caption_e4aed93fe\" data-test-table-caption>\n {{@caption}}\n </caption>\n {{/if}}\n\n <thead class=\"thead_e4aed93fe\" data-test-table-header>\n <tr class=\"header-row_e4aed93fe\">\n {{#if @isSelectable}}\n <th class=\"header-cell_e4aed93fe checkbox-cell_e4aed93fe\" data-test-table-header-checkbox>\n <Checkbox @isChecked={{this.allRowsSelected}} @isIndeterminate={{this.someRowsSelected}} @isLabelHidden={{true}} @label=\"Select all rows\" @size=\"sm\" data-table-checkbox {{on \"change\" this.handleSelectAll}} />\n </th>\n {{/if}}\n\n {{#each this.visibleColumns as |column|}}\n <th class=\"header-cell_e4aed93fe\" data-align={{column.align}} data-sortable={{if (this.isColumnSortable column) \"true\"}} data-sorted={{if (this.getColumnSortDirection column) \"true\"}} data-sort-direction={{this.getColumnSortDirection column}} aria-sort={{this.getAriaSortValue column}} style={{if column.width (concat \"width:\" column.width \";\")}} data-test-table-header-cell data-test-column-id={{column.id}}>\n {{#if (this.isColumnSortable column)}}\n <button type=\"button\" class=\"sort-button_e4aed93fe\" {{on \"click\" (fn this.handleSort column)}} data-test-table-sort-button>\n <span class=\"header-text_e4aed93fe\">{{column.header}}</span>\n <span class=\"sort-icon_e4aed93fe\" aria-hidden=\"true\">\n {{#if (this.getColumnSortDirection column)}}\n {{#if (eq (this.getColumnSortDirection column) \"asc\")}}\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon_e4aed93fe\">\n <path d=\"M4 10l4-4 4 4\" />\n </svg>\n {{else}}\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon_e4aed93fe\">\n <path d=\"M4 6l4 4 4-4\" />\n </svg>\n {{/if}}\n {{else}}\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon_e4aed93fe icon-unsorted_e4aed93fe\">\n <path d=\"M4 6l4-3 4 3M4 10l4 3 4-3\" />\n </svg>\n {{/if}}\n </span>\n </button>\n {{else}}\n <span class=\"header-text_e4aed93fe\">{{column.header}}</span>\n {{/if}}\n </th>\n {{/each}}\n </tr>\n </thead>\n\n <tbody class=\"tbody_e4aed93fe\" data-test-table-body>\n {{#if @isLoading}}\n {{#if (has-block \"loading\")}}\n {{yield to=\"loading\"}}\n {{else}}\n {{!-- template-lint-disable no-unused-block-params --}}\n {{#each (repeat this.loadingRowCount)}}\n <tr class=\"row_e4aed93fe skeleton-row_e4aed93fe\" data-test-table-skeleton-row>\n {{#if @isSelectable}}\n <td class=\"cell_e4aed93fe checkbox-cell_e4aed93fe\">\n <Skeleton @width={{16}} @height={{16}} @radius=\"sm\" />\n </td>\n {{/if}}\n {{#each this.visibleColumns as |column|}}\n <td class=\"cell_e4aed93fe\" data-align={{column.align}}>\n <Skeleton @width=\"70%\" @height={{16}} />\n </td>\n {{/each}}\n </tr>\n {{/each}}\n {{/if}}\n {{else if this.isEmpty}}\n {{#if (has-block \"empty\")}}\n <tr class=\"empty-row_e4aed93fe\">\n <td colspan={{if @isSelectable (add (len this.visibleColumns) 1) (len this.visibleColumns)}}>\n {{yield to=\"empty\"}}\n </td>\n </tr>\n {{else}}\n <tr class=\"empty-row_e4aed93fe\" data-test-table-empty>\n <td class=\"empty-cell_e4aed93fe\" colspan={{if @isSelectable (add (len this.visibleColumns) 1) (len this.visibleColumns)}}>\n {{#if @emptyMessage}}\n {{@emptyMessage}}\n {{else}}\n No data available\n {{/if}}\n </td>\n </tr>\n {{/if}}\n {{else}}\n {{#each this.displayData as |row rowIndex|}}\n {{!-- template-lint-disable no-invalid-interactive --}}\n <tr id={{this.getRowElementId row}} class=\"row_e4aed93fe\" data-selected={{if (this.isRowSelected row) \"true\" \"false\"}} data-focused={{if (this.isRowFocused rowIndex) \"true\" \"false\"}} data-disabled={{if (@isRowDisabled row) \"true\" \"false\"}} data-clickable={{if @onRowClick \"true\"}} aria-selected={{if @isSelectable (if (this.isRowSelected row) \"true\" \"false\")}} data-test-table-row data-test-row-id={{this.getRowId row}} {{on \"click\" (fn this.handleRowClick row)}}>\n {{#if @isSelectable}}\n <td class=\"cell_e4aed93fe checkbox-cell_e4aed93fe\" data-test-table-row-checkbox>\n <Checkbox @isChecked={{this.isRowSelected row}} @isDisabled={{@isRowDisabled row}} @isLabelHidden={{true}} @label=\"Select row\" @size=\"sm\" data-table-checkbox {{on \"click\" (fn this.handleRowSelect row)}} />\n </td>\n {{/if}}\n\n {{#each this.visibleColumns as |column|}}\n <td class=\"cell_e4aed93fe\" data-align={{column.align}} data-test-table-cell data-test-column-id={{column.id}}>\n {{#if (has-block \"cell\")}}\n {{yield (this.getCellContext row column rowIndex) to=\"cell\"}}\n {{else}}\n {{this.formatCellValue row column}}\n {{/if}}\n </td>\n {{/each}}\n </tr>\n {{/each}}\n {{/if}}\n </tbody>\n</table>", {
|
|
386
|
+
setComponentTemplate(precompileTemplate("<table class=\"table_e4aed93fe\" data-sticky-header={{if @hasStickyHeader \"true\"}} data-striped={{if @isStriped \"true\"}} data-bordered={{if @isBordered \"true\"}} data-compact={{if @isCompact \"true\"}} data-padding-inline={{this.paddingInline}} data-loading={{if @isLoading \"true\"}} data-test-table tabindex=\"0\" {{this.setupRef}} {{!-- template-lint-disable no-pointer-down-event-binding --}} {{on \"mousedown\" this.handleMouseDown}} {{on \"keydown\" this.handleKeyDown}} {{on \"focus\" this.handleFocus}} {{on \"blur\" this.handleBlur}} ...attributes>\n {{#if @caption}}\n <caption class=\"caption_e4aed93fe\" data-test-table-caption>\n {{@caption}}\n </caption>\n {{/if}}\n\n <thead class=\"thead_e4aed93fe\" data-test-table-header>\n <tr class=\"header-row_e4aed93fe\">\n {{#if @isSelectable}}\n <th class=\"header-cell_e4aed93fe checkbox-cell_e4aed93fe\" data-test-table-header-checkbox>\n <Checkbox @isChecked={{this.allRowsSelected}} @isIndeterminate={{this.someRowsSelected}} @isLabelHidden={{true}} @label=\"Select all rows\" @size=\"sm\" data-table-checkbox {{on \"change\" this.handleSelectAll}} />\n </th>\n {{/if}}\n\n {{#each this.visibleColumns as |column|}}\n <th class=\"header-cell_e4aed93fe\" data-align={{column.align}} data-sortable={{if (this.isColumnSortable column) \"true\"}} data-sorted={{if (this.getColumnSortDirection column) \"true\"}} data-sort-direction={{this.getColumnSortDirection column}} aria-sort={{this.getAriaSortValue column}} style={{if column.width (concat \"width:\" column.width \";\")}} data-test-table-header-cell data-test-column-id={{column.id}}>\n {{#if (this.isColumnSortable column)}}\n <button type=\"button\" class=\"sort-button_e4aed93fe\" {{on \"click\" (fn this.handleSort column)}} data-test-table-sort-button>\n <span class=\"header-text_e4aed93fe\">{{column.header}}</span>\n <span class=\"sort-icon_e4aed93fe\" aria-hidden=\"true\">\n {{#if (this.getColumnSortDirection column)}}\n {{#if (eq (this.getColumnSortDirection column) \"asc\")}}\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon_e4aed93fe\">\n <path d=\"M4 10l4-4 4 4\" />\n </svg>\n {{else}}\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon_e4aed93fe\">\n <path d=\"M4 6l4 4 4-4\" />\n </svg>\n {{/if}}\n {{else}}\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon_e4aed93fe icon-unsorted_e4aed93fe\">\n <path d=\"M4 6l4-3 4 3M4 10l4 3 4-3\" />\n </svg>\n {{/if}}\n </span>\n </button>\n {{else}}\n <span class=\"header-text_e4aed93fe\">{{column.header}}</span>\n {{/if}}\n </th>\n {{/each}}\n </tr>\n </thead>\n\n <tbody class=\"tbody_e4aed93fe\" data-test-table-body>\n {{#if @isLoading}}\n {{#if (has-block \"loading\")}}\n {{yield to=\"loading\"}}\n {{else}}\n {{!-- template-lint-disable no-unused-block-params --}}\n {{#each (repeat this.loadingRowCount)}}\n <tr class=\"row_e4aed93fe skeleton-row_e4aed93fe\" data-test-table-skeleton-row>\n {{#if @isSelectable}}\n <td class=\"cell_e4aed93fe checkbox-cell_e4aed93fe\">\n <Skeleton @width={{16}} @height={{16}} @radius=\"sm\" />\n </td>\n {{/if}}\n {{#each this.visibleColumns as |column|}}\n <td class=\"cell_e4aed93fe\" data-align={{column.align}}>\n <Skeleton @width=\"70%\" @height={{16}} />\n </td>\n {{/each}}\n </tr>\n {{/each}}\n {{/if}}\n {{else if this.isEmpty}}\n {{#if (has-block \"empty\")}}\n <tr class=\"empty-row_e4aed93fe\">\n <td colspan={{if @isSelectable (add (len this.visibleColumns) 1) (len this.visibleColumns)}}>\n {{yield to=\"empty\"}}\n </td>\n </tr>\n {{else}}\n <tr class=\"empty-row_e4aed93fe\" data-test-table-empty>\n <td class=\"empty-cell_e4aed93fe\" colspan={{if @isSelectable (add (len this.visibleColumns) 1) (len this.visibleColumns)}}>\n {{#if @emptyMessage}}\n {{@emptyMessage}}\n {{else}}\n No data available\n {{/if}}\n </td>\n </tr>\n {{/if}}\n {{else}}\n {{#each this.displayData as |row rowIndex|}}\n {{!-- template-lint-disable no-invalid-interactive --}}\n <tr id={{this.getRowElementId row}} class=\"row_e4aed93fe\" data-selected={{if (this.isRowSelected row) \"true\" \"false\"}} data-focused={{if (this.isRowFocused rowIndex) \"true\" \"false\"}} data-disabled={{if (@isRowDisabled row) \"true\" \"false\"}} data-clickable={{if @onRowClick \"true\"}} aria-selected={{if @isSelectable (if (this.isRowSelected row) \"true\" \"false\")}} data-test-table-row data-test-row-id={{this.getRowId row}} {{on \"click\" (fn this.handleRowClick row)}}>\n {{#if @isSelectable}}\n <td class=\"cell_e4aed93fe checkbox-cell_e4aed93fe\" data-test-table-row-checkbox>\n <Checkbox @isChecked={{this.isRowSelected row}} @isDisabled={{@isRowDisabled row}} @isLabelHidden={{true}} @label=\"Select row\" @size=\"sm\" data-table-checkbox {{on \"click\" (fn this.handleRowSelect row)}} />\n </td>\n {{/if}}\n\n {{#each this.visibleColumns as |column|}}\n <td class=\"cell_e4aed93fe\" data-align={{column.align}} data-test-table-cell data-test-column-id={{column.id}}>\n {{#if (has-block \"cell\")}}\n {{yield (this.getCellContext row column rowIndex) to=\"cell\"}}\n {{else}}\n {{this.formatCellValue row column}}\n {{/if}}\n </td>\n {{/each}}\n </tr>\n {{/each}}\n {{/if}}\n </tbody>\n</table>", {
|
|
444
387
|
strictMode: true,
|
|
445
388
|
scope: () => ({
|
|
446
389
|
on,
|
package/dist/form/calendar.js
CHANGED
|
@@ -18,35 +18,26 @@ import { g, i } from 'decorator-transforms/runtime';
|
|
|
18
18
|
// ============================================================================
|
|
19
19
|
class Calendar extends Component {
|
|
20
20
|
static {
|
|
21
|
-
g(this.prototype, "
|
|
21
|
+
g(this.prototype, "_navigationMonth", [tracked], function () {
|
|
22
22
|
return new Date();
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
-
#
|
|
25
|
+
#_navigationMonth = (i(this, "_navigationMonth"), void 0);
|
|
26
|
+
/**
|
|
27
|
+
* The month the calendar is currently showing. This is the calendar's own
|
|
28
|
+
* navigation mechanics, not the consumer's domain state: the user pages
|
|
29
|
+
* through months to find a date. It seeds to the current month and the prev
|
|
30
|
+
* and next buttons (and keyboard month paging) drive it. When the consumer
|
|
31
|
+
* passes `@month`, that override wins and this field is bypassed.
|
|
32
|
+
*/
|
|
26
33
|
static {
|
|
27
34
|
g(this.prototype, "focusedDate", [tracked], function () {
|
|
28
35
|
return null;
|
|
29
36
|
});
|
|
30
37
|
}
|
|
31
|
-
#focusedDate = (i(this, "focusedDate"), void 0);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return null;
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
#internalValue = (i(this, "internalValue"), void 0);
|
|
38
|
-
static {
|
|
39
|
-
g(this.prototype, "internalMultiValue", [tracked], function () {
|
|
40
|
-
return [];
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
#internalMultiValue = (i(this, "internalMultiValue"), void 0);
|
|
44
|
-
static {
|
|
45
|
-
g(this.prototype, "internalRangeValue", [tracked], function () {
|
|
46
|
-
return null;
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
#internalRangeValue = (i(this, "internalRangeValue"), void 0);
|
|
38
|
+
#focusedDate = (i(this, "focusedDate"), void 0); // Ephemeral UI mechanics the calendar owns: which day has keyboard focus,
|
|
39
|
+
// which day is hovered during a range drag, and the first-click anchor of an
|
|
40
|
+
// in-progress range before the second click lands.
|
|
50
41
|
static {
|
|
51
42
|
g(this.prototype, "rangeSelectionStart", [tracked], function () {
|
|
52
43
|
return null;
|
|
@@ -78,46 +69,32 @@ class Calendar extends Component {
|
|
|
78
69
|
get showToday() {
|
|
79
70
|
return this.args.showToday ?? true;
|
|
80
71
|
}
|
|
81
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* The month on screen. The `@month` override wins when present; otherwise the
|
|
74
|
+
* calendar's own navigation state drives. Writing it (via the prev and next
|
|
75
|
+
* buttons or keyboard month paging) updates the navigation state and reports
|
|
76
|
+
* the new month up. The override is left untouched — when it is in play the
|
|
77
|
+
* consumer updates it in response to `onMonthChange`, exactly as it owns the
|
|
78
|
+
* selection.
|
|
79
|
+
*/
|
|
82
80
|
get currentMonth() {
|
|
83
|
-
|
|
84
|
-
return this.args.month;
|
|
85
|
-
}
|
|
86
|
-
if (this.args.defaultMonth !== undefined && !this.hasInternalMonthChanged) {
|
|
87
|
-
return this.args.defaultMonth;
|
|
88
|
-
}
|
|
89
|
-
return this.internalMonth;
|
|
81
|
+
return this.args.month ?? this._navigationMonth;
|
|
90
82
|
}
|
|
91
|
-
hasInternalMonthChanged = false;
|
|
92
|
-
hasInternalValueChanged = false;
|
|
93
83
|
set currentMonth(value) {
|
|
94
|
-
this.
|
|
95
|
-
this.internalMonth = value;
|
|
84
|
+
this._navigationMonth = value;
|
|
96
85
|
this.args.onMonthChange?.(value);
|
|
97
86
|
}
|
|
98
|
-
/** Selected value for single mode
|
|
87
|
+
/** Selected value for single mode, owned by the consumer via `@value`. */
|
|
99
88
|
get selectedValue() {
|
|
100
|
-
|
|
101
|
-
return this.args.value;
|
|
102
|
-
}
|
|
103
|
-
if (this.args.defaultValue !== undefined && !this.hasInternalValueChanged) {
|
|
104
|
-
return this.args.defaultValue;
|
|
105
|
-
}
|
|
106
|
-
return this.internalValue;
|
|
89
|
+
return this.args.value ?? null;
|
|
107
90
|
}
|
|
108
|
-
/** Selected values for multiple mode */
|
|
91
|
+
/** Selected values for multiple mode, owned by the consumer via `@multiValue`. */
|
|
109
92
|
get selectedMultiValue() {
|
|
110
|
-
|
|
111
|
-
return this.args.multiValue;
|
|
112
|
-
}
|
|
113
|
-
return this.internalMultiValue;
|
|
93
|
+
return this.args.multiValue ?? [];
|
|
114
94
|
}
|
|
115
|
-
/** Selected range for range mode */
|
|
95
|
+
/** Selected range for range mode, owned by the consumer via `@rangeValue`. */
|
|
116
96
|
get selectedRange() {
|
|
117
|
-
|
|
118
|
-
return this.args.rangeValue;
|
|
119
|
-
}
|
|
120
|
-
return this.internalRangeValue;
|
|
97
|
+
return this.args.rangeValue ?? null;
|
|
121
98
|
}
|
|
122
99
|
/** Weekday labels starting from weekStartsOn */
|
|
123
100
|
get weekdayLabels() {
|
|
@@ -278,8 +255,6 @@ class Calendar extends Component {
|
|
|
278
255
|
selectDate = date => {
|
|
279
256
|
if (this.isDateDisabled(date)) return;
|
|
280
257
|
if (this.mode === 'single') {
|
|
281
|
-
this.hasInternalValueChanged = true;
|
|
282
|
-
this.internalValue = date;
|
|
283
258
|
this.args.onChange?.(date);
|
|
284
259
|
} else if (this.mode === 'multiple') {
|
|
285
260
|
const current = [...this.selectedMultiValue];
|
|
@@ -291,13 +266,11 @@ class Calendar extends Component {
|
|
|
291
266
|
} else {
|
|
292
267
|
current.push(date);
|
|
293
268
|
}
|
|
294
|
-
this.internalMultiValue = current;
|
|
295
269
|
this.args.onMultiChange?.(current);
|
|
296
270
|
} else if (this.mode === 'range') {
|
|
297
271
|
if (!this.rangeSelectionStart) {
|
|
298
|
-
// First click: set range start and clear
|
|
272
|
+
// First click: set range start (ephemeral anchor) and clear the range.
|
|
299
273
|
this.rangeSelectionStart = date;
|
|
300
|
-
this.internalRangeValue = null;
|
|
301
274
|
this.args.onRangeChange?.(null);
|
|
302
275
|
} else {
|
|
303
276
|
// Second click: complete range
|
|
@@ -312,7 +285,6 @@ class Calendar extends Component {
|
|
|
312
285
|
};
|
|
313
286
|
this.rangeSelectionStart = null;
|
|
314
287
|
this.hoveredDate = null;
|
|
315
|
-
this.internalRangeValue = range;
|
|
316
288
|
this.args.onRangeChange?.(range);
|
|
317
289
|
}
|
|
318
290
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import "./checkbox-group.css"
|
|
2
2
|
import Component from '@glimmer/component';
|
|
3
|
-
import { tracked } from '@glimmer/tracking';
|
|
4
3
|
import { action } from '@ember/object';
|
|
5
4
|
import { on } from '@ember/modifier';
|
|
6
5
|
import { hash } from '@ember/helper';
|
|
@@ -9,25 +8,14 @@ import Checkbox from './checkbox.js';
|
|
|
9
8
|
import ErrorMessage from './error-message.js';
|
|
10
9
|
import { precompileTemplate } from '@ember/template-compilation';
|
|
11
10
|
import { setComponentTemplate } from '@ember/component';
|
|
12
|
-
import {
|
|
11
|
+
import { n } from 'decorator-transforms/runtime';
|
|
13
12
|
|
|
14
13
|
;
|
|
15
14
|
|
|
16
15
|
class CheckboxGroup extends Component {
|
|
17
|
-
static {
|
|
18
|
-
g(this.prototype, "internalValues", [tracked]);
|
|
19
|
-
}
|
|
20
|
-
#internalValues = (i(this, "internalValues"), void 0);
|
|
21
|
-
constructor(owner, args) {
|
|
22
|
-
super(owner, args);
|
|
23
|
-
this.internalValues = [...(args.defaultValue ?? [])];
|
|
24
|
-
}
|
|
25
16
|
guid = guidFor(this);
|
|
26
|
-
get isControlled() {
|
|
27
|
-
return this.args.value !== undefined;
|
|
28
|
-
}
|
|
29
17
|
get selectedValues() {
|
|
30
|
-
return this.
|
|
18
|
+
return this.args.value;
|
|
31
19
|
}
|
|
32
20
|
get orientation() {
|
|
33
21
|
return this.args.orientation ?? 'vertical';
|
|
@@ -48,15 +36,7 @@ class CheckboxGroup extends Component {
|
|
|
48
36
|
return this.selectedValues.includes(value);
|
|
49
37
|
};
|
|
50
38
|
handleCheckboxChange(value, isChecked) {
|
|
51
|
-
|
|
52
|
-
if (isChecked) {
|
|
53
|
-
newValues = [...this.selectedValues, value];
|
|
54
|
-
} else {
|
|
55
|
-
newValues = this.selectedValues.filter(v => v !== value);
|
|
56
|
-
}
|
|
57
|
-
if (!this.isControlled) {
|
|
58
|
-
this.internalValues = newValues;
|
|
59
|
-
}
|
|
39
|
+
const newValues = isChecked ? [...this.selectedValues, value] : this.selectedValues.filter(v => v !== value);
|
|
60
40
|
this.args.onChange?.(newValues);
|
|
61
41
|
}
|
|
62
42
|
static {
|
package/dist/form/checkbox.js
CHANGED
|
@@ -1,32 +1,20 @@
|
|
|
1
1
|
import "./checkbox.css"
|
|
2
2
|
import Component from '@glimmer/component';
|
|
3
|
-
import { tracked } from '@glimmer/tracking';
|
|
4
3
|
import { action } from '@ember/object';
|
|
5
4
|
import { on } from '@ember/modifier';
|
|
6
5
|
import { modifier } from 'ember-modifier';
|
|
7
6
|
import { precompileTemplate } from '@ember/template-compilation';
|
|
8
7
|
import { setComponentTemplate } from '@ember/component';
|
|
9
|
-
import {
|
|
8
|
+
import { n } from 'decorator-transforms/runtime';
|
|
10
9
|
|
|
11
10
|
;
|
|
12
11
|
|
|
13
12
|
class Checkbox extends Component {
|
|
14
|
-
static {
|
|
15
|
-
g(this.prototype, "internalChecked", [tracked]);
|
|
16
|
-
}
|
|
17
|
-
#internalChecked = (i(this, "internalChecked"), void 0);
|
|
18
|
-
constructor(owner, args) {
|
|
19
|
-
super(owner, args);
|
|
20
|
-
this.internalChecked = args.defaultChecked ?? false;
|
|
21
|
-
}
|
|
22
13
|
get size() {
|
|
23
14
|
return this.args.size ?? 'md';
|
|
24
15
|
}
|
|
25
|
-
get isControlled() {
|
|
26
|
-
return this.args.isChecked !== undefined;
|
|
27
|
-
}
|
|
28
16
|
get checked() {
|
|
29
|
-
return this.
|
|
17
|
+
return this.args.isChecked;
|
|
30
18
|
}
|
|
31
19
|
get ariaChecked() {
|
|
32
20
|
if (this.args.isIndeterminate) {
|
|
@@ -49,9 +37,7 @@ class Checkbox extends Component {
|
|
|
49
37
|
});
|
|
50
38
|
handleChange(event) {
|
|
51
39
|
const target = event.target;
|
|
52
|
-
|
|
53
|
-
this.internalChecked = target.checked;
|
|
54
|
-
}
|
|
40
|
+
this.args.onChange?.(target.checked, event);
|
|
55
41
|
}
|
|
56
42
|
static {
|
|
57
43
|
n(this.prototype, "handleChange", [action]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox-field.js","sources":["../../src/form/combobox-field.gts"],"sourcesContent":["import Component from '@glimmer/component';\n\nimport Control from './control.gts';\nimport ComboBox from './combobox.gts';\nimport type { ComboBoxItems, ComboBoxOption } from './combobox-shared.ts';\n\nexport type LabelVisibility = 'visible' | 'hidden';\n\nexport interface ComboBoxFieldSignature {\n Element: HTMLDivElement;\n Args: {\n /** Label text (required). */\n label: string;\n\n /** Available options. Flat or pre-grouped. */\n items: ComboBoxItems;\n\n /**
|
|
1
|
+
{"version":3,"file":"combobox-field.js","sources":["../../src/form/combobox-field.gts"],"sourcesContent":["import Component from '@glimmer/component';\n\nimport Control from './control.gts';\nimport ComboBox from './combobox.gts';\nimport type { ComboBoxItems, ComboBoxOption } from './combobox-shared.ts';\n\nexport type LabelVisibility = 'visible' | 'hidden';\n\nexport interface ComboBoxFieldSignature {\n Element: HTMLDivElement;\n Args: {\n /** Label text (required). */\n label: string;\n\n /** Available options. Flat or pre-grouped. */\n items: ComboBoxItems;\n\n /** The selected value. The consumer owns it; pair with `onChange`. */\n value?: string | null;\n\n /** Fires when the selection changes. */\n onChange?: (value: string | null, option: ComboBoxOption | null) => void;\n\n /** Async search (passed through to ComboBox). */\n onSearch?: (query: string) => Promise<ComboBoxItems>;\n\n /** Debounce for `onSearch` in ms. */\n searchDebounceMs?: number;\n\n /** Force the loading state. */\n isLoading?: boolean;\n\n /** Called when an `onSearch` promise rejects. */\n onSearchError?: (error: unknown) => void;\n\n /** Loading row text. */\n loadingText?: string;\n\n /** Input placeholder. */\n placeholder?: string;\n\n /** Empty state text. */\n noResultsText?: string;\n\n /** Allow creating new options from a non-matching query. */\n isCreatable?: boolean;\n\n /** Fires when the user activates the create row. */\n onCreate?: (query: string) => void;\n\n /** Build the create-row label. */\n createLabel?: (query: string) => string;\n\n /** Help text displayed below the control. */\n helpText?: string;\n\n /** Error message (also sets invalid state). */\n error?: string;\n\n /** Field is required. */\n isRequired?: boolean;\n\n /** Field is disabled. */\n isDisabled?: boolean;\n\n /** Show the clear button when a value is set. */\n isClearable?: boolean;\n\n /** Info tooltip text shown next to the label. */\n labelInfo?: string;\n\n /** Optional indicator - shows \"optional\" or custom text next to the label. */\n optionalIndicator?: boolean | string;\n\n /** Label visibility. */\n labelVisibility?: LabelVisibility;\n\n /** Input name for forms. */\n name?: string;\n\n /** Blur event handler. */\n onBlur?: (event: FocusEvent) => void;\n\n /** Focus event handler. */\n onFocus?: (event: FocusEvent) => void;\n\n /** Fires when the dropdown opens. */\n onOpen?: () => void;\n\n /** Fires when the dropdown closes. */\n onClose?: () => void;\n };\n Blocks: {\n /** Rich tooltip content shown next to the label. */\n info: [];\n };\n}\n\nexport default class ComboBoxField extends Component<ComboBoxFieldSignature> {\n get isInvalid(): boolean {\n return !!this.args.error;\n }\n\n get isLabelHidden(): boolean {\n return this.args.labelVisibility === 'hidden';\n }\n\n /** Build aria-describedby from the control's help text and error IDs. */\n getAriaDescribedBy = (controlId: string): string | undefined => {\n const parts: string[] = [];\n if (this.args.helpText) {\n parts.push(`${controlId}-help-text`);\n }\n if (this.args.error) {\n parts.push(`${controlId}-error-message`);\n }\n return parts.length > 0 ? parts.join(' ') : undefined;\n };\n\n <template>\n <Control\n @isInvalid={{this.isInvalid}}\n @isDisabled={{@isDisabled}}\n @isRequired={{@isRequired}}\n @labelInfo={{@labelInfo}}\n @optionalIndicator={{@optionalIndicator}}\n ...attributes\n as |ctrl|\n >\n {{#if (has-block \"info\")}}\n <ctrl.Label @isVisuallyHidden={{this.isLabelHidden}}>\n <:default>{{@label}}</:default>\n <:info>{{yield to=\"info\"}}</:info>\n </ctrl.Label>\n {{else}}\n <ctrl.Label @isVisuallyHidden={{this.isLabelHidden}}>\n {{@label}}\n </ctrl.Label>\n {{/if}}\n\n <ComboBox\n @id={{ctrl.id}}\n @name={{@name}}\n @items={{@items}}\n @value={{@value}}\n @placeholder={{@placeholder}}\n @noResultsText={{@noResultsText}}\n @onSearch={{@onSearch}}\n @searchDebounceMs={{@searchDebounceMs}}\n @isLoading={{@isLoading}}\n @onSearchError={{@onSearchError}}\n @loadingText={{@loadingText}}\n @isCreatable={{@isCreatable}}\n @onCreate={{@onCreate}}\n @createLabel={{@createLabel}}\n @isDisabled={{@isDisabled}}\n @isInvalid={{this.isInvalid}}\n @isRequired={{@isRequired}}\n @isClearable={{@isClearable}}\n @aria-describedby={{this.getAriaDescribedBy ctrl.id}}\n @onChange={{@onChange}}\n @onBlur={{@onBlur}}\n @onFocus={{@onFocus}}\n @onOpen={{@onOpen}}\n @onClose={{@onClose}}\n data-test-combobox-field\n />\n\n {{#if @helpText}}\n <ctrl.HelpText>{{@helpText}}</ctrl.HelpText>\n {{/if}}\n\n {{#if @error}}\n <ctrl.ErrorMessage>{{@error}}</ctrl.ErrorMessage>\n {{/if}}\n </Control>\n </template>\n}\n"],"names":["ComboBoxField","Component","isInvalid","args","error","isLabelHidden","labelVisibility","getAriaDescribedBy","controlId","parts","helpText","push","length","join","undefined","setComponentTemplate","precompileTemplate","strictMode","scope","Control","ComboBox"],"mappings":";;;;;;AAkGe,MAAMA,sBAAsBC,SAAA,CAAU;EACnD,IAAIC,SAAAA,GAAqB;AACvB,IAAA,OAAO,CAAC,CAAC,IAAI,CAACC,IAAI,CAACC,KAAK;AAC1B,EAAA;EAEA,IAAIC,aAAAA,GAAyB;AAC3B,IAAA,OAAO,IAAI,CAACF,IAAI,CAACG,eAAe,KAAK,QAAA;AACvC,EAAA;AAEA;EACAC,qBAAsBC,SAAiB,IAAqB;IAC1D,MAAMC,KAAa,GAAK,EAAE;AAC1B,IAAA,IAAI,IAAI,CAACN,IAAI,CAACO,QAAQ,EAAE;AACtBD,MAAAA,KAAA,CAAME,IAAI,CAAC,CAAA,EAAGH,SAAA,YAAqB,CAAA;AACrC,IAAA;AACA,IAAA,IAAI,IAAI,CAACL,IAAI,CAACC,KAAK,EAAE;AACnBK,MAAAA,KAAA,CAAME,IAAI,CAAC,CAAA,EAAGH,SAAA,gBAAyB,CAAA;AACzC,IAAA;AACA,IAAA,OAAOC,MAAMG,MAAM,GAAG,IAAIH,KAAA,CAAMI,IAAI,CAAC,GAAA,CAAA,GAAOC,SAAA;EAC9C,CAAA;AAEA,EAAA;IAAAC,oBAAA,CAAAC,kBAAA,CAAA,81CAAA,EAyDA;MAAAC,UAAA,EAAA,IAAA;AAAAC,MAAAA,KAAA,EAAAA,OAAA;QAAAC,OAAA;AAAAC,QAAAA;AAAA,OAAA;KAAU,CAAA,EAAV,IAAW,CAAA;AAAD;AACZ;;;;"}
|
|
@@ -23,7 +23,7 @@ class DatePickerField extends Component {
|
|
|
23
23
|
return parts.length > 0 ? parts.join(' ') : undefined;
|
|
24
24
|
};
|
|
25
25
|
static {
|
|
26
|
-
setComponentTemplate(precompileTemplate("<Control @isInvalid={{this.isInvalid}} @isDisabled={{@isDisabled}} @isRequired={{@isRequired}} @isReadOnly={{@isReadOnly}} @labelInfo={{@labelInfo}} @optionalIndicator={{@optionalIndicator}} ...attributes as |ctrl|>\n {{#if (has-block \"info\")}}\n <ctrl.Label @isVisuallyHidden={{this.isLabelHidden}}>\n <:default>{{@label}}</:default>\n <:info>{{yield to=\"info\"}}</:info>\n </ctrl.Label>\n {{else}}\n <ctrl.Label @isVisuallyHidden={{this.isLabelHidden}}>\n {{@label}}\n </ctrl.Label>\n {{/if}}\n\n <DatePicker @id={{ctrl.id}} @name={{@name}} @value={{@value}} @
|
|
26
|
+
setComponentTemplate(precompileTemplate("<Control @isInvalid={{this.isInvalid}} @isDisabled={{@isDisabled}} @isRequired={{@isRequired}} @isReadOnly={{@isReadOnly}} @labelInfo={{@labelInfo}} @optionalIndicator={{@optionalIndicator}} ...attributes as |ctrl|>\n {{#if (has-block \"info\")}}\n <ctrl.Label @isVisuallyHidden={{this.isLabelHidden}}>\n <:default>{{@label}}</:default>\n <:info>{{yield to=\"info\"}}</:info>\n </ctrl.Label>\n {{else}}\n <ctrl.Label @isVisuallyHidden={{this.isLabelHidden}}>\n {{@label}}\n </ctrl.Label>\n {{/if}}\n\n <DatePicker @id={{ctrl.id}} @name={{@name}} @value={{@value}} @placeholder={{@placeholder}} @format={{@format}} @minDate={{@minDate}} @maxDate={{@maxDate}} @disabledDates={{@disabledDates}} @disabledDaysOfWeek={{@disabledDaysOfWeek}} @weekStartsOn={{@weekStartsOn}} @showOutsideDays={{@showOutsideDays}} @showToday={{@showToday}} @allowTextInput={{@allowTextInput}} @closeOnSelect={{@closeOnSelect}} @showIcon={{@showIcon}} @clearable={{@clearable}} @isDisabled={{@isDisabled}} @isInvalid={{this.isInvalid}} @isRequired={{@isRequired}} @isReadOnly={{@isReadOnly}} @aria-describedby={{this.getAriaDescribedBy ctrl.id}} @onChange={{@onChange}} @onBlur={{@onBlur}} @onFocus={{@onFocus}} @onOpenChange={{@onOpenChange}} data-test-date-picker-field />\n\n {{#if @helpText}}\n <ctrl.HelpText>{{@helpText}}</ctrl.HelpText>\n {{/if}}\n\n {{#if @error}}\n <ctrl.ErrorMessage>{{@error}}</ctrl.ErrorMessage>\n {{/if}}\n</Control>", {
|
|
27
27
|
strictMode: true,
|
|
28
28
|
scope: () => ({
|
|
29
29
|
Control,
|