Skip to content

Commit 4ea41d0

Browse files
authored
feat: don't trigger rowClick when element is an interactive element or has .tpk-no-row-click class (#148)
* fix: add stopPropagation when it's a custom component * feat: don't trigger rowClick when element is an interactive element or has .tpk-no-row-click class
1 parent 4b8737d commit 4ea41d0

File tree

6 files changed

+106
-3
lines changed

6 files changed

+106
-3
lines changed

doc-app/app/components/docs/ember-ui/prefabs/table-generic.gts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const TpkSelectElement: TOC<
1818
};
1919
}
2020
> = <template>
21-
<div data-test-table-generic-select>
21+
<div data-test-table-generic-select class="tpk-no-row-click">
2222
<TpkSelect
2323
@options={{@options}}
2424
@onChange={{@onChange}}

doc-app/app/models/user.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const UserSchema = withDefaults({
1313
{ name: 'phone', kind: 'attribute' },
1414
{ name: 'job', kind: 'attribute' },
1515
{ name: 'country', kind: 'attribute' },
16+
{ name: 'active', kind: 'attribute' },
1617
],
1718
});
1819

@@ -24,5 +25,6 @@ export type User = WithLegacy<{
2425
phone: string;
2526
job: string;
2627
country: string;
28+
active: boolean;
2729
[Type]: 'user';
2830
}>;

doc-app/tests/integration/components/ember-ui/table-generic/component-test.gts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { setupRenderingTest } from 'ember-qunit';
77
import TpkTableGeneric from '@triptyk/ember-ui/components/tpk-table-generic';
88
import stringify from 'doc-app/helpers/to-string';
99
import DeleteIcon from 'doc-app/assets/icons/delete.gts';
10+
import TpkCheckboxComponent from '@triptyk/ember-input/components/tpk-checkbox';
1011

1112
module('Integration | Component | table-generic', function (hooks) {
1213
setupRenderingTest(hooks);
@@ -23,6 +24,9 @@ module('Integration | Component | table-generic', function (hooks) {
2324
const rowClick = () => {
2425
assert.step('rowClick function called');
2526
};
27+
const activeAction = () => {
28+
assert.step('active action called');
29+
};
2630
const deleteAction = () => {
2731
assert.step('delete function called');
2832
};
@@ -61,6 +65,20 @@ module('Integration | Component | table-generic', function (hooks) {
6165
>
6266
Email
6367
</Header.Cell>
68+
<Header.Cell
69+
@sortable={{false}}
70+
@prop="phone"
71+
data-test-table="phone"
72+
>
73+
Téléphone
74+
</Header.Cell>
75+
<Header.Cell
76+
@sortable={{false}}
77+
@prop="status"
78+
data-test-table="status"
79+
>
80+
Statut
81+
</Header.Cell>
6482
</Table.Header>
6583
<Table.Body as |Body element|>
6684
<Body.Cell>
@@ -72,6 +90,22 @@ module('Integration | Component | table-generic', function (hooks) {
7290
<Body.Cell>
7391
{{stringify element.email}}
7492
</Body.Cell>
93+
<Body.Cell>
94+
<div data-test-phone class="tpk-no-row-click">
95+
{{stringify element.phone}}
96+
</div>
97+
</Body.Cell>
98+
<Body.Cell>
99+
<TpkCheckboxComponent
100+
@label=""
101+
{{! @glint-ignore considering element.active has undefined or boolean as value}}
102+
@checked={{element.active}}
103+
@onChange={{activeAction}}
104+
as |C|
105+
>
106+
<C.Input data-test-checkbox />
107+
</TpkCheckboxComponent>
108+
</Body.Cell>
75109
<Body.ActionMenu as |Action|>
76110
<Action
77111
@icon={{component DeleteIcon}}
@@ -161,6 +195,18 @@ module('Integration | Component | table-generic', function (hooks) {
161195
assert.verifySteps(['rowClick function called']);
162196
});
163197

198+
test('It can click on phone number without triggering rowClick', async function (assert) {
199+
await renderTableGeneric(assert);
200+
await click('[data-test-phone]');
201+
assert.verifySteps([]);
202+
});
203+
204+
test('It can click on checkbox without triggering rowClick', async function (assert) {
205+
await renderTableGeneric(assert);
206+
await click('[data-test-checkbox]');
207+
assert.verifySteps(['active action called']);
208+
});
209+
164210
test('It can sort firstName & lastName and cannot sort email', async function (assert) {
165211
await renderTableGeneric(assert);
166212
assert.dom('thead th[data-test-table="firstName"]').hasAttribute('role');
@@ -238,7 +284,7 @@ module('Integration | Component | table-generic', function (hooks) {
238284
});
239285
test('Colspan of the footer is adjusted when an action menu is yielded', async function (assert) {
240286
await renderTableGeneric(assert);
241-
assert.dom('tfoot td').hasAttribute('colspan', '4');
287+
assert.dom('tfoot td').hasAttribute('colspan', '6');
242288
});
243289
test('Colspan of the footer is reduced when no action menu is yielded', async function (assert) {
244290
await renderTableGenericWithNoAction(assert);

doc-app/tests/integration/components/ember-ui/table-generic/data/fake-data.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export default {
77
lastName: 'Marc',
88
firstName: 'Jean',
99
email: 'info@triptyk.eu',
10+
phone: '0606060606',
11+
active: true,
1012
},
1113
},
1214
{
@@ -16,6 +18,8 @@ export default {
1618
lastName: 'Lepond',
1719
firstName: 'Louis',
1820
email: 'info@triptyk.eu',
21+
phone: '0606060606',
22+
active: true,
1923
},
2024
},
2125
{
@@ -25,6 +29,8 @@ export default {
2529
lastName: 'Dragon',
2630
firstName: 'Lucas',
2731
email: 'info@triptyk.eu',
32+
phone: '0606060606',
33+
active: true,
2834
},
2935
},
3036
{
@@ -34,6 +40,8 @@ export default {
3440
lastName: 'Leroy',
3541
firstName: 'Simon',
3642
email: 'info@triptyk.eu',
43+
phone: '0606060606',
44+
active: true,
3745
},
3846
},
3947
{
@@ -43,6 +51,8 @@ export default {
4351
lastName: 'Giga',
4452
firstName: 'Chad',
4553
email: 'info@triptyk.eu',
54+
phone: '0606060606',
55+
active: true,
4656
},
4757
},
4858
],
@@ -54,6 +64,8 @@ export default {
5464
lastName: 'Giga',
5565
firstName: 'Chad',
5666
email: 'info@triptyk.eu',
67+
phone: '0606060606',
68+
active: true,
5769
},
5870
},
5971
{
@@ -63,6 +75,8 @@ export default {
6375
lastName: 'Marc',
6476
firstName: 'Jean',
6577
email: 'info@triptyk.eu',
78+
phone: '0606060606',
79+
active: true,
6680
},
6781
},
6882
{
@@ -72,6 +86,8 @@ export default {
7286
lastName: 'Lepond',
7387
firstName: 'Louis',
7488
email: 'info@triptyk.eu',
89+
phone: '0606060606',
90+
active: false,
7591
},
7692
},
7793
{
@@ -81,6 +97,8 @@ export default {
8197
lastName: 'Dragon',
8298
firstName: 'Lucas',
8399
email: 'info@triptyk.eu',
100+
phone: '0606060606',
101+
active: false,
84102
},
85103
},
86104
{
@@ -90,6 +108,8 @@ export default {
90108
lastName: 'Leroy',
91109
firstName: 'Simon',
92110
email: 'info@triptyk.eu',
111+
phone: '0606060606',
112+
active: false,
93113
},
94114
},
95115
],
@@ -101,6 +121,8 @@ export default {
101121
lastName: 'Leroy',
102122
firstName: 'Simon',
103123
email: 'info@triptyk.eu',
124+
phone: '0606060606',
125+
active: false,
104126
},
105127
},
106128
{
@@ -110,6 +132,8 @@ export default {
110132
lastName: 'Dragon',
111133
firstName: 'Lucas',
112134
email: 'info@triptyk.eu',
135+
phone: '0606060606',
136+
active: false,
113137
},
114138
},
115139
{
@@ -119,6 +143,8 @@ export default {
119143
lastName: 'Lepond',
120144
firstName: 'Louis',
121145
email: 'loempia@triptyk.eu',
146+
phone: '0606060606',
147+
active: false,
122148
},
123149
},
124150
{
@@ -128,6 +154,8 @@ export default {
128154
lastName: 'Marc',
129155
firstName: 'Jean',
130156
email: 'info@triptyk.eu',
157+
phone: '0606060606',
158+
active: false,
131159
},
132160
},
133161
{
@@ -137,6 +165,8 @@ export default {
137165
lastName: 'Giga',
138166
firstName: 'Chad',
139167
email: 'info@triptyk.eu',
168+
phone: '0606060606',
169+
active: false,
140170
},
141171
},
142172
],
@@ -148,6 +178,8 @@ export default {
148178
lastName: 'Dramix',
149179
firstName: 'Romain',
150180
email: 'info@triptyk.eu',
181+
phone: '0606060606',
182+
active: false,
151183
},
152184
},
153185
{
@@ -157,6 +189,8 @@ export default {
157189
lastName: 'Larris',
158190
firstName: 'Gilles',
159191
email: 'info@triptyk.eu',
192+
phone: '0606060606',
193+
active: false,
160194
},
161195
},
162196
{
@@ -166,6 +200,8 @@ export default {
166200
lastName: 'Truc',
167201
firstName: 'Sam',
168202
email: 'info@triptyk.eu',
203+
phone: '0606060606',
204+
active: false,
169205
},
170206
},
171207
{
@@ -175,6 +211,8 @@ export default {
175211
lastName: 'Jelra',
176212
firstName: 'Jacques',
177213
email: 'info@triptyk.eu',
214+
phone: '0606060606',
215+
active: false,
178216
},
179217
},
180218
{
@@ -184,6 +222,8 @@ export default {
184222
lastName: 'Lefou',
185223
firstName: 'Seb',
186224
email: 'info@triptyk.eu',
225+
phone: '0606060606',
226+
active: true,
187227
},
188228
},
189229
],

doc-app/tests/workers/table-generic.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export async function TableGenericUserWorker(
3232
lastName: 'Giga',
3333
firstName: 'Chad',
3434
email: 'dev@triptyk.eu',
35+
phone: '0606060606',
36+
active: true,
3537
},
3638
},
3739
];

packages/ember-ui/src/components/tpk-table-generic/body.gts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,25 @@ export default class TableGenericBodyComponent extends Component<TableGenericBod
4141
this.isExpanded = !this.isExpanded;
4242
}
4343

44+
@action
45+
handleRowClick(element: unknown, event: Event) {
46+
const target = event.target as HTMLElement;
47+
48+
const isInteractiveElement = target.closest(
49+
'button, input, select, textarea, a, [role="button"], .tpk-no-row-click',
50+
);
51+
52+
if (!isInteractiveElement) {
53+
this.args.rowClick(element);
54+
}
55+
}
56+
4457
<template>
4558
<@table.tbody class='tpk-table-body' ...attributes as |body data|>
4659
{{#each data as |element index|}}
4760
<body.row
4861
data-test-row={{element.id}}
49-
{{on 'click' (fn @rowClick element)}}
62+
{{on 'click' (fn this.handleRowClick element)}}
5063
as |row|
5164
>
5265
{{yield

0 commit comments

Comments
 (0)