Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(data-grid): add scale-selection event and enhance editable text field #2362

Merged
merged 8 commits into from
Nov 6, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const TextCell: Cell = {
iconPrefix,
iconSuffix,
label,
textFieldProps = {},
} = field;

// Input component doesn't expand with content, so need to return a fake element that simulates width
Expand All @@ -52,6 +53,7 @@ export const TextCell: Cell = {
if (editable) {
const props = {
type: 'text',
...textFieldProps,
value: content,
label,
} as any;
Expand Down
32 changes: 21 additions & 11 deletions packages/components/src/components/data-grid/data-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export class DataGrid {
/** (optional) Set to true to add selection column */
@Prop() selectable?: boolean = false;
/** Read-only selection array - populated with raw data from selected rows */
@Prop() selection: string[] = [];
@Prop({ mutable: true }) selection: any[] = [];
/** (optional) Shade every second row darker */
@Prop() shadeAlternate?: boolean = true;
/** (optional) Injected css styles */
Expand Down Expand Up @@ -136,6 +136,9 @@ export class DataGrid {
/** @deprecated in v3 in favor of kebab-case event names */
@Event({ eventName: 'scaleSort' })
scaleSortLegacy: EventEmitter<DataGridSortedEventDetail>;
/** Event triggered every time the selection list updates */
@Event({ eventName: 'scale-selection' })
scaleSelection: EventEmitter<any[]>;
/* 5. Private Properties (alphabetical) */
/** Used to update column divider during interaction */
private activeDivider: any;
Expand Down Expand Up @@ -221,6 +224,9 @@ export class DataGrid {

@Watch('rows')
rowsHandler() {
if (!this.rows) {
return;
}
// Reset pagination to the last page of the new records if new records are less than previous.
if (this.paginationStart > this.rows.length) {
this.paginationStart =
Expand Down Expand Up @@ -249,7 +255,8 @@ export class DataGrid {
this.sortTable(
this.fields[this.activeSortingIndex].sortDirection,
this.fields[this.activeSortingIndex].type,
this.activeSortingIndex
this.activeSortingIndex,
true
);
}
}
Expand Down Expand Up @@ -399,14 +406,14 @@ export class DataGrid {
}

updateReadableSelection() {
this.selection.length = 0;
this.selection = [];
this.rows.forEach((row) => row.selected && this.selection.push(row));

// Check header checkbox if any or none are selected
const selectAll = this.hostElement.shadowRoot.querySelector(
'.thead__cell--selection scale-checkbox'
) as HTMLInputElement;
selectAll.checked = !!this.selection.length;
emitEvent(this, 'scaleSelection', this.selection);
// selectAll.indeterminate = !!this.selection.length;
}

Expand All @@ -432,7 +439,7 @@ export class DataGrid {
this.sortTable(newSortDirection, type, columnIndex);
}

sortTable(sortDirection, type, columnIndex) {
sortTable(sortDirection, type, columnIndex, shouldTriggerEvent = true) {
const format = this.fields[columnIndex].format;
if (sortDirection === 'none') {
this.rows.sort((a, b) => {
Expand Down Expand Up @@ -489,8 +496,10 @@ export class DataGrid {
}
}
this.forceRender++;
// Trigger event
this.triggerSortEvent(sortDirection, type, columnIndex);
if (shouldTriggerEvent) {
// Trigger event
this.triggerSortEvent(sortDirection, type, columnIndex);
}
}

resetSortingToggle() {
Expand All @@ -514,7 +523,7 @@ export class DataGrid {
: 'ascending';
this.activeSortingIndex = columnIndex;
this.fields[columnIndex].sortDirection = direction;
this.sortTable(direction, columnToPresort.type, columnIndex);
this.sortTable(direction, columnToPresort.type, columnIndex, false);
}

// Column resize handlers
Expand Down Expand Up @@ -947,6 +956,7 @@ export class DataGrid {
<div
ref={(el) => (this.elScrollContainer = el)}
class={`${name}__scroll-container`}
part="scrollable"
style={{ height: this.height || 'auto' }}
onScroll={() => this.onTableScroll()}
>
Expand Down Expand Up @@ -1024,7 +1034,7 @@ export class DataGrid {
<tr class={`thead__row`}>
{this.numbered && this.renderTableHeadNumberedCell()}
{this.selectable && this.renderTableHeadSelectableCell()}
{this.fields.map(
{this.fields?.map(
(
{
type,
Expand Down Expand Up @@ -1165,7 +1175,7 @@ export class DataGrid {
ref={(el) => (this.elToggleSelectAll = el)}
onScaleChange={() => this.toggleSelectAll()}
hideLabel={true}
aria-label="Select"
ariaLabelCheckbox="Select"
></scale-checkbox>
</th>
);
Expand Down Expand Up @@ -1384,7 +1394,7 @@ export class DataGrid {
>
{this.styles && <style>{this.styles}</style>}
<div class={this.getCssClassMap()}>
<div class={`${name}__title-block`}>
<div class={`${name}__title-block`} part="title">
{/* h4 tag + h5 styles feels weird, ideally one should be able to set the tag with an attribute */}
{this.heading && (
<h4 class={`${name}__heading scl-h5`}>{this.heading}</h4>
Expand Down
23 changes: 16 additions & 7 deletions packages/components/src/components/data-grid/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
| `pageSize` | `page-size` | (optional) Set number of rows to display per pagination page | `number` | `Infinity` |
| `rows` | `rows` | Input data array | `any` | `undefined` |
| `selectable` | `selectable` | (optional) Set to true to add selection column | `boolean` | `false` |
| `selection` | -- | Read-only selection array - populated with raw data from selected rows | `string[]` | `[]` |
| `selection` | -- | Read-only selection array - populated with raw data from selected rows | `any[]` | `[]` |
| `shadeAlternate` | `shade-alternate` | (optional) Shade every second row darker | `boolean` | `true` |
| `sortableColumnTitle` | `sortable-column-title` | (optional) Title for sortable columns | `string` | `'Activate to sort column'` |
| `styles` | `styles` | (optional) Injected css styles | `any` | `undefined` |
Expand All @@ -29,12 +29,21 @@

## Events

| Event | Description | Type |
| ------------ | -------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| `scale-edit` | Event triggered every time the editable cells are changed, updating the original rows data | `CustomEvent<DataGridEditEventDetail>` |
| `scale-sort` | Event triggered every time the data is sorted, changing original rows data | `CustomEvent<DataGridSortedEventDetail>` |
| `scaleEdit` | <span style="color:red">**[DEPRECATED]**</span> in v3 in favor of kebab-case event names<br/><br/> | `CustomEvent<DataGridEditEventDetail>` |
| `scaleSort` | <span style="color:red">**[DEPRECATED]**</span> in v3 in favor of kebab-case event names<br/><br/> | `CustomEvent<DataGridSortedEventDetail>` |
| Event | Description | Type |
| ----------------- | -------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| `scale-edit` | Event triggered every time the editable cells are changed, updating the original rows data | `CustomEvent<DataGridEditEventDetail>` |
| `scale-selection` | Event triggered every time the selection list updates | `CustomEvent<any[]>` |
| `scale-sort` | Event triggered every time the data is sorted, changing original rows data | `CustomEvent<DataGridSortedEventDetail>` |
| `scaleEdit` | <span style="color:red">**[DEPRECATED]**</span> in v3 in favor of kebab-case event names<br/><br/> | `CustomEvent<DataGridEditEventDetail>` |
| `scaleSort` | <span style="color:red">**[DEPRECATED]**</span> in v3 in favor of kebab-case event names<br/><br/> | `CustomEvent<DataGridSortedEventDetail>` |


## Shadow Parts

| Part | Description |
| -------------- | ----------- |
| `"scrollable"` | |
| `"title"` | |


## Dependencies
Expand Down
40 changes: 38 additions & 2 deletions packages/components/src/html/data-grid.html
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,16 @@
style: 'switch',
editable: true,
},
{
type: 'text',
label: 'Nr-edit',
editable: true,
width: 60,
textFieldProps: {
type: 'number',
max: 2,
},
},
{
type: 'graph',
label: 'Progress',
Expand Down Expand Up @@ -222,6 +232,7 @@
'00:00:20',
101045.0,
false,
1,
15,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -255,6 +266,7 @@
'00:01:15',
43.2,
true,
2,
73.2,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -288,6 +300,7 @@
'00:00:20',
102045.0,
false,
3,
15,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -326,6 +339,7 @@
'00:01:15',
45.2,
true,
4,
73.2,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -359,6 +373,7 @@
'00:00:20',
103045.0,
false,
5,
15,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -392,6 +407,7 @@
'00:01:15',
47.2,
true,
6,
73.2,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -425,6 +441,7 @@
'00:00:20',
105045.0,
false,
7,
15,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -458,6 +475,7 @@
'00:01:15',
48.2,
true,
8,
73.2,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -491,6 +509,7 @@
'00:00:20',
109045.0,
false,
9,
15,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -524,6 +543,7 @@
'00:01:15',
40.2,
true,
10,
73.2,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -557,6 +577,7 @@
'00:00:20',
108045.0,
false,
11,
15,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -590,6 +611,7 @@
'00:01:15',
43.2,
true,
12,
73.2,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -622,6 +644,7 @@
'00:00:20',
102045.0,
false,
13,
15,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -655,6 +678,7 @@
'00:01:15',
43.2,
true,
14,
73.2,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -689,6 +713,7 @@
102045.0,
false,
15,
15,
(() => {
const demoNestedContent = document.createElement('div');
demoNestedContent.innerHTML = `<scale-button href="https://example.com" target="_blank" title="External link, opens in new tab">
Expand Down Expand Up @@ -721,6 +746,7 @@
'00:01:15',
43.2,
true,
16,
73.2,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -754,6 +780,7 @@
'00:00:20',
102045.0,
false,
17,
15,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -787,6 +814,7 @@
'00:01:15',
43.2,
true,
18,
73.2,
(() => {
const demoNestedContent = document.createElement('div');
Expand Down Expand Up @@ -817,12 +845,20 @@
select: 'SelectLoc',
tableOptions: 'OptionsLoc',
expand: 'Klicken Sie zu expanden',
collapse: 'Klicken Sie zu collapsen',
};

// Pass in data
const table = document.querySelector('#table1');

document
.querySelector('scale-data-grid')
.addEventListener('scale-sort', ({ detail }) => {
console.log('sort', detail);
});
document
.querySelector('scale-data-grid')
.addEventListener('scale-selection', ({ detail }) => {
console.log('select', detail);
});
table.fields = fields;
table.rows = rows;
table.localization = localization;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ import ScaleDataGrid from './ScaleDataGrid.vue';
description: `Event triggered every time the data is sorted, changing original rows data`,
control: { type: null },
},
eventScaleSelection: {
name: '[event] scale-selection',
table: {
type: { summary: 'event' },
},
description: `Event triggered every time the selection list updates`,
control: { type: null },
},
slotMenu: {
name: '[slot] menu',
table: {
Expand Down Expand Up @@ -740,8 +748,12 @@ Expected format: unformatted `string`, eg `'this is a string'`
- `iconPrefix?: scale-icon-string (eg 'action-download')`
- `iconSuffix?: scale-icon-string (eg 'action-download')`
- `editable?: boolean = false`
- `textFieldProps?: Object (eg { type: 'number', helperText: 'Enter a number' })`

<Canvas withSource="close">

If `editable` is set to `true`, a `scale-text-field` is used for the element. The properties of the `scale-text-field` can be passed directly to the editable component using the `textFieldProps` attribute.
and if the `editable` is set to `false`, the `textFieldProps` has no effect, as the cell will be read-only.
<Canvas withSource="close">
<Story name="Text Cell">
{`<content>
<scale-data-grid id="text-example" hide-menu></scale-data-grid>
Expand Down
Loading