Skip to content

Commit 3d1a2cc

Browse files
authored
Merge branch 'master' into rkaraivanov/chat-fix-typing-change-event-behavior
2 parents f061b3a + b0d8a22 commit 3d1a2cc

File tree

7 files changed

+76
-81
lines changed

7 files changed

+76
-81
lines changed

src/components/chat/chat.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,9 @@ describe('Chat', () => {
313313
await elementUpdated(chat);
314314

315315
const { input, suggestionsContainer } = getChatDOM(chat);
316-
expect(suggestionsContainer.getBoundingClientRect().top).lessThanOrEqual(
317-
input.self.getBoundingClientRect().bottom
318-
);
316+
expect(
317+
suggestionsContainer.getBoundingClientRect().top
318+
).greaterThanOrEqual(input.self.getBoundingClientRect().bottom);
319319
});
320320

321321
it('should render typing indicator if `isTyping` is true', async () => {

src/components/chat/chat.ts

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -502,27 +502,29 @@ export default class IgcChatComponent extends EventEmitterMixin<
502502
: nothing}
503503
</div>
504504
505-
<igc-chat-input
506-
exportparts="
507-
input-container: input-area-container,
508-
input-wrapper: input-container,
509-
attachments: input-attachments-container,
510-
attachment-wrapper: input-attachment-container,
511-
attachment-name: input-attachment-name,
512-
attachment-icon: input-attachment-icon,
513-
text-input,
514-
actions-container: input-actions-container,
515-
input-actions-start,
516-
input-actions-end,
517-
file-upload-container,
518-
file-upload,
519-
send-button-container,
520-
send-button"
521-
>
522-
</igc-chat-input>
523-
${this._state.suggestionsPosition === 'below-input'
524-
? suggestions
525-
: nothing}
505+
<div part="input-area-container">
506+
<igc-chat-input
507+
exportparts="
508+
input-container: input-area-container,
509+
input-wrapper: input-container,
510+
attachments: input-attachments-container,
511+
attachment-wrapper: input-attachment-container,
512+
attachment-name: input-attachment-name,
513+
attachment-icon: input-attachment-icon,
514+
text-input,
515+
actions-container: input-actions-container,
516+
input-actions-start,
517+
input-actions-end,
518+
file-upload-container,
519+
file-upload,
520+
send-button-container,
521+
send-button"
522+
>
523+
</igc-chat-input>
524+
${this._state.suggestionsPosition === 'below-input'
525+
? suggestions
526+
: nothing}
527+
</div>
526528
</div>
527529
`;
528530
}

src/components/chat/themes/chat.base.scss

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,28 @@ $inline-inset: rem(24px);
2525
height: 100%;
2626
}
2727

28+
[part='input-area-container'],
2829
[part='message-area-container'] {
2930
display: grid;
3031
grid-template-columns: subgrid;
3132
overflow: hidden auto;
3233
grid-column: 1 / -1;
3334
grid-template-rows: auto 1fr;
3435
align-items: start;
36+
}
37+
38+
[part='message-area-container'] {
3539
grid-row: 2;
3640

3741
&:has([part='empty-state']) {
3842
grid-template-rows: 1fr auto;
3943
}
4044
}
4145

46+
[part='input-area-container'] {
47+
grid-row: 3;
48+
}
49+
4250
[part='message-list'],
4351
[part='empty-state'],
4452
[part='suggestions-container'] {
@@ -125,10 +133,6 @@ slot[name='prefix'] {
125133
margin-inline-end: rem(32px);
126134
}
127135

128-
igc-chat-input {
129-
grid-row: 3;
130-
}
131-
132136
igc-list {
133137
--ig-size: 3;
134138

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,46 @@
1-
import { groupBy } from '../../common/util.js';
21
import type { DataController } from '../controllers/data.js';
32
import type { ComboRecord, Keys } from '../types.js';
43

5-
export default class GroupDataOperation<T extends object> {
6-
protected orderBy = new Map(
7-
Object.entries({
8-
asc: 1,
9-
desc: -1,
10-
})
11-
);
4+
const OrderBy = Object.freeze({ asc: 1, desc: -1 });
125

13-
public apply(data: ComboRecord<T>[], controller: DataController<T>) {
6+
export default class GroupDataOperation<T extends object> {
7+
public apply(
8+
data: ComboRecord<T>[],
9+
controller: DataController<T>
10+
): ComboRecord<T>[] {
1411
const {
1512
groupingOptions: { groupKey, valueKey, displayKey, direction },
1613
} = controller;
1714

18-
if (!groupKey) return data;
15+
if (!groupKey) {
16+
return data;
17+
}
1918

20-
const groups = Object.entries(
21-
groupBy(data, (item) => item.value[groupKey] ?? 'Other')
19+
const grouped = Map.groupBy(
20+
data,
21+
(item) => (item.value[groupKey] as string) ?? 'Other'
2222
);
2323

24+
const keys = Array.from(grouped.keys());
25+
2426
if (direction !== 'none') {
25-
const orderBy = this.orderBy.get(direction);
26-
groups.sort((a, b) => {
27-
return orderBy! * controller.compareCollator.compare(a[0], b[0]);
28-
});
27+
const orderBy = OrderBy[direction];
28+
keys.sort((a, b) => orderBy * controller.compareCollator.compare(a, b));
2929
}
3030

31-
return groups.flatMap(([group, items]) => {
32-
items.unshift({
33-
dataIndex: -1,
34-
header: true,
35-
value: {
36-
[valueKey as Keys<T>]: group,
37-
[displayKey as Keys<T>]: group,
38-
[groupKey as Keys<T>]: group,
39-
} as T,
40-
});
41-
42-
return items;
31+
return keys.flatMap((key) => {
32+
return [
33+
{
34+
value: {
35+
[valueKey as Keys<T>]: key,
36+
[displayKey as Keys<T>]: key,
37+
[groupKey as Keys<T>]: key,
38+
} as T,
39+
header: true,
40+
dataIndex: -1,
41+
},
42+
...(grouped.get(key) ?? []),
43+
];
4344
});
4445
}
4546
}

src/components/common/util.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -168,24 +168,6 @@ export function findElementFromEventPath<T extends Element>(
168168
return getElementsFromEventPath(event).find(func) as T | undefined;
169169
}
170170

171-
export function groupBy<T>(array: T[], key: keyof T | ((item: T) => any)) {
172-
const result: Record<string, T[]> = {};
173-
const _get = isFunction(key) ? key : (item: T) => item[key];
174-
175-
for (const item of array) {
176-
const category = _get(item);
177-
const group = result[category];
178-
179-
if (Array.isArray(group)) {
180-
group.push(item);
181-
} else {
182-
result[category] = [item];
183-
}
184-
}
185-
186-
return result;
187-
}
188-
189171
export function first<T>(arr: T[]) {
190172
return arr.at(0) as T;
191173
}

stories/select.stories.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ import {
55
} from '@igniteui/material-icons-extended';
66
import type { Meta, StoryObj } from '@storybook/web-components-vite';
77
import { html } from 'lit';
8-
98
import {
109
IgcIconComponent,
1110
IgcSelectComponent,
1211
defineComponents,
1312
registerIconFromText,
1413
} from 'igniteui-webcomponents';
15-
import { groupBy } from '../src/components/common/util.js';
1614
import {
1715
disableStoryControls,
1816
formControls,
@@ -265,8 +263,16 @@ const items = [
265263
>`
266264
);
267265

266+
type CountryInfo = {
267+
continent: string;
268+
country: string;
269+
value: string;
270+
selected: boolean;
271+
disabled: boolean;
272+
};
273+
268274
const countries = Object.entries(
269-
groupBy(
275+
Object.groupBy(
270276
[
271277
{
272278
continent: 'Europe',
@@ -310,9 +316,9 @@ const countries = Object.entries(
310316
selected: false,
311317
disabled: true,
312318
},
313-
],
314-
'continent'
315-
)
319+
] as CountryInfo[],
320+
(item) => item.continent
321+
) as Record<string, CountryInfo[]>
316322
);
317323

318324
export const Basic: Story = {

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"compilerOptions": {
33
"target": "es2022",
44
"module": "NodeNext",
5-
"lib": ["es2023", "DOM", "DOM.Iterable"],
5+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
66
"outDir": "dist",
77
"rootDir": "./",
88
"declaration": true,

0 commit comments

Comments
 (0)