Skip to content

Commit a062293

Browse files
authored
Merge pull request #1450 from dxc-technology/gomezivann-select-updates
Select specification updates & more
2 parents 453c87a + c290f61 commit a062293

File tree

10 files changed

+311
-348
lines changed

10 files changed

+311
-348
lines changed

lib/src/paginator/Paginator.test.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ import DxcPaginator from "./Paginator";
55

66
// Mocking DOMRect for Radix Primitive Popover
77
global.globalThis = global;
8+
global.DOMRect = {
9+
fromRect: () => ({ top: 0, left: 0, bottom: 0, right: 0, width: 0, height: 0 }),
10+
};
811
global.ResizeObserver = class ResizeObserver {
9-
constructor(cb) {
10-
this.cb = cb;
11-
}
12-
observe() {
13-
this.cb([{ borderBoxSize: { inlineSize: 0, blockSize: 0 } }]);
14-
}
12+
observe() {}
1513
unobserve() {}
14+
disconnect() {}
1615
};
1716

1817
global.DOMRect = {

lib/src/resultsetTable/ResultsetTable.test.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,19 @@
11
import React from "react";
2-
import { render, fireEvent, act } from "@testing-library/react";
2+
import { render, fireEvent } from "@testing-library/react";
33
import userEvent from "@testing-library/user-event";
44

55
import DxcResultsetTable from "./ResultsetTable";
66

77
// Mocking DOMRect for Radix Primitive Popover
88
global.globalThis = global;
9-
global.ResizeObserver = class ResizeObserver {
10-
constructor(cb) {
11-
this.cb = cb;
12-
}
13-
observe() {
14-
this.cb([{ borderBoxSize: { inlineSize: 0, blockSize: 0 } }]);
15-
}
16-
unobserve() {}
17-
};
18-
199
global.DOMRect = {
2010
fromRect: () => ({ top: 0, left: 0, bottom: 0, right: 0, width: 0, height: 0 }),
2111
};
12+
global.ResizeObserver = class ResizeObserver {
13+
observe() {}
14+
unobserve() {}
15+
disconnect() {}
16+
};
2217

2318
const columns = [
2419
{

lib/src/select/Listbox.tsx

Lines changed: 40 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import React, { useState, useLayoutEffect, useEffect, useRef } from "react";
2-
import styled, { ThemeProvider } from "styled-components";
3-
import useTheme from "../useTheme";
1+
import React, { useLayoutEffect, useRef } from "react";
2+
import styled from "styled-components";
43
import useTranslatedLabels from "../useTranslatedLabels";
54
import { ListboxProps } from "./types";
65
import Option from "./Option";
@@ -20,14 +19,12 @@ const Listbox = ({
2019
optionalItem,
2120
searchable,
2221
handleOptionOnClick,
23-
getSelectWidth,
22+
styles,
2423
}: ListboxProps): JSX.Element => {
25-
const colorsTheme = useTheme();
2624
const translatedLabels = useTranslatedLabels();
2725
const listboxRef = useRef(null);
28-
const [styles, setStyles] = useState(null);
2926

30-
let globalIndex = optional && !multiple ? 0 : -1; // index for options, starting from 0 to options.length -1
27+
let globalIndex = optional && !multiple ? 0 : -1;
3128
const mapOptionFunc = (option, mapIndex) => {
3229
if (option.options) {
3330
const groupId = `group-${mapIndex}`;
@@ -90,60 +87,43 @@ const Listbox = ({
9087
visualFocusedOptionEl?.scrollIntoView?.({ block: "nearest", inline: "start" });
9188
}, [visualFocusIndex]);
9289

93-
const handleResize = () => {
94-
setStyles({ width: getSelectWidth() });
95-
};
96-
97-
useLayoutEffect(() => {
98-
handleResize();
99-
} , [getSelectWidth]);
100-
101-
useEffect(() => {
102-
window.addEventListener("resize", handleResize);
103-
return () => {
104-
window.removeEventListener("resize", handleResize);
105-
};
106-
}, [getSelectWidth]);
107-
10890
return (
109-
<ThemeProvider theme={colorsTheme.select}>
110-
<ListboxContainer
111-
id={id}
112-
onClick={(event) => {
113-
event.stopPropagation();
114-
}}
115-
onMouseDown={(event) => {
116-
event.preventDefault();
117-
}}
118-
ref={listboxRef}
119-
role="listbox"
120-
aria-multiselectable={multiple}
121-
style={styles}
122-
>
123-
{searchable && (options.length === 0 || !groupsHaveOptions(options)) ? (
124-
<OptionsSystemMessage>
125-
<NoMatchesFoundIcon>{selectIcons.searchOff}</NoMatchesFoundIcon>
126-
{translatedLabels.select.noMatchesErrorMessage}
127-
</OptionsSystemMessage>
128-
) : (
129-
optional &&
130-
!multiple && (
131-
<Option
132-
key={`option-${optionalItem.value}`}
133-
id={`option-${0}`}
134-
option={optionalItem}
135-
onClick={handleOptionOnClick}
136-
multiple={multiple}
137-
visualFocused={visualFocusIndex === 0}
138-
isGroupedOption={false}
139-
isLastOption={lastOptionIndex === 0}
140-
isSelected={multiple ? currentValue.includes(optionalItem.value) : currentValue === optionalItem.value}
141-
/>
142-
)
143-
)}
144-
{options.map(mapOptionFunc)}
145-
</ListboxContainer>
146-
</ThemeProvider>
91+
<ListboxContainer
92+
id={id}
93+
onClick={(event) => {
94+
event.stopPropagation();
95+
}}
96+
onMouseDown={(event) => {
97+
event.preventDefault();
98+
}}
99+
ref={listboxRef}
100+
role="listbox"
101+
aria-multiselectable={multiple}
102+
style={styles}
103+
>
104+
{searchable && (options.length === 0 || !groupsHaveOptions(options)) ? (
105+
<OptionsSystemMessage>
106+
<NoMatchesFoundIcon>{selectIcons.searchOff}</NoMatchesFoundIcon>
107+
{translatedLabels.select.noMatchesErrorMessage}
108+
</OptionsSystemMessage>
109+
) : (
110+
optional &&
111+
!multiple && (
112+
<Option
113+
key={`option-${optionalItem.value}`}
114+
id={`option-${0}`}
115+
option={optionalItem}
116+
onClick={handleOptionOnClick}
117+
multiple={multiple}
118+
visualFocused={visualFocusIndex === 0}
119+
isGroupedOption={false}
120+
isLastOption={lastOptionIndex === 0}
121+
isSelected={multiple ? currentValue.includes(optionalItem.value) : currentValue === optionalItem.value}
122+
/>
123+
)
124+
)}
125+
{options.map(mapOptionFunc)}
126+
</ListboxContainer>
147127
);
148128
};
149129

lib/src/select/Option.tsx

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React from "react";
2-
import styled, { ThemeProvider } from "styled-components";
2+
import styled from "styled-components";
33
import { OptionProps } from "../select/types";
4-
import useTheme from "../useTheme";
54
import DxcCheckbox from "../checkbox/Checkbox";
65
import selectIcons from "./Icons";
76

@@ -14,47 +13,41 @@ const Option = ({
1413
isGroupedOption = false,
1514
isLastOption,
1615
isSelected,
17-
}: OptionProps): JSX.Element => {
18-
const colorsTheme = useTheme();
19-
20-
return (
21-
<ThemeProvider theme={colorsTheme.select}>
22-
<OptionItem
23-
id={id}
24-
onClick={() => {
25-
onClick(option);
26-
}}
27-
visualFocused={visualFocused}
28-
selected={isSelected}
29-
role="option"
30-
aria-selected={isSelected}
31-
>
32-
<StyledOption
33-
visualFocused={visualFocused}
34-
selected={isSelected}
35-
last={isLastOption}
16+
}: OptionProps): JSX.Element => (
17+
<OptionItem
18+
id={id}
19+
onClick={() => {
20+
onClick(option);
21+
}}
22+
visualFocused={visualFocused}
23+
selected={isSelected}
24+
role="option"
25+
aria-selected={isSelected}
26+
>
27+
<StyledOption
28+
visualFocused={visualFocused}
29+
selected={isSelected}
30+
last={isLastOption}
31+
grouped={isGroupedOption}
32+
multiple={multiple}
33+
>
34+
{multiple && <DxcCheckbox checked={isSelected} tabIndex={-1} />}
35+
{option.icon && (
36+
<OptionIcon
3637
grouped={isGroupedOption}
3738
multiple={multiple}
39+
role={!(typeof option.icon === "string") ? "img" : undefined}
3840
>
39-
{multiple && <DxcCheckbox checked={isSelected} tabIndex={-1} />}
40-
{option.icon && (
41-
<OptionIcon
42-
grouped={isGroupedOption}
43-
multiple={multiple}
44-
role={!(typeof option.icon === "string") ? "img" : undefined}
45-
>
46-
{typeof option.icon === "string" ? <img src={option.icon} /> : option.icon}
47-
</OptionIcon>
48-
)}
49-
<OptionContent grouped={isGroupedOption} hasIcon={option.icon ? true : false} multiple={multiple}>
50-
<OptionLabel>{option.label}</OptionLabel>
51-
{!multiple && isSelected && <OptionSelectedIndicator>{selectIcons.selected}</OptionSelectedIndicator>}
52-
</OptionContent>
53-
</StyledOption>
54-
</OptionItem>
55-
</ThemeProvider>
56-
);
57-
};
41+
{typeof option.icon === "string" ? <img src={option.icon} /> : option.icon}
42+
</OptionIcon>
43+
)}
44+
<OptionContent grouped={isGroupedOption} hasIcon={option.icon ? true : false} multiple={multiple}>
45+
<OptionLabel>{option.label}</OptionLabel>
46+
{!multiple && isSelected && <OptionSelectedIndicator>{selectIcons.selected}</OptionSelectedIndicator>}
47+
</OptionContent>
48+
</StyledOption>
49+
</OptionItem>
50+
);
5851

5952
type OptionItemProps = {
6053
visualFocused: boolean;

0 commit comments

Comments
 (0)