Skip to content

Commit

Permalink
Merge pull request #1450 from dxc-technology/gomezivann-select-updates
Browse files Browse the repository at this point in the history
Select specification updates & more
  • Loading branch information
jsuarezgonz committed Feb 2, 2023
2 parents 453c87a + c290f61 commit a062293
Show file tree
Hide file tree
Showing 10 changed files with 311 additions and 348 deletions.
11 changes: 5 additions & 6 deletions lib/src/paginator/Paginator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import DxcPaginator from "./Paginator";

// Mocking DOMRect for Radix Primitive Popover
global.globalThis = global;
global.DOMRect = {
fromRect: () => ({ top: 0, left: 0, bottom: 0, right: 0, width: 0, height: 0 }),
};
global.ResizeObserver = class ResizeObserver {
constructor(cb) {
this.cb = cb;
}
observe() {
this.cb([{ borderBoxSize: { inlineSize: 0, blockSize: 0 } }]);
}
observe() {}
unobserve() {}
disconnect() {}
};

global.DOMRect = {
Expand Down
17 changes: 6 additions & 11 deletions lib/src/resultsetTable/ResultsetTable.test.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
import React from "react";
import { render, fireEvent, act } from "@testing-library/react";
import { render, fireEvent } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import DxcResultsetTable from "./ResultsetTable";

// Mocking DOMRect for Radix Primitive Popover
global.globalThis = global;
global.ResizeObserver = class ResizeObserver {
constructor(cb) {
this.cb = cb;
}
observe() {
this.cb([{ borderBoxSize: { inlineSize: 0, blockSize: 0 } }]);
}
unobserve() {}
};

global.DOMRect = {
fromRect: () => ({ top: 0, left: 0, bottom: 0, right: 0, width: 0, height: 0 }),
};
global.ResizeObserver = class ResizeObserver {
observe() {}
unobserve() {}
disconnect() {}
};

const columns = [
{
Expand Down
100 changes: 40 additions & 60 deletions lib/src/select/Listbox.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useState, useLayoutEffect, useEffect, useRef } from "react";
import styled, { ThemeProvider } from "styled-components";
import useTheme from "../useTheme";
import React, { useLayoutEffect, useRef } from "react";
import styled from "styled-components";
import useTranslatedLabels from "../useTranslatedLabels";
import { ListboxProps } from "./types";
import Option from "./Option";
Expand All @@ -20,14 +19,12 @@ const Listbox = ({
optionalItem,
searchable,
handleOptionOnClick,
getSelectWidth,
styles,
}: ListboxProps): JSX.Element => {
const colorsTheme = useTheme();
const translatedLabels = useTranslatedLabels();
const listboxRef = useRef(null);
const [styles, setStyles] = useState(null);

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

const handleResize = () => {
setStyles({ width: getSelectWidth() });
};

useLayoutEffect(() => {
handleResize();
} , [getSelectWidth]);

useEffect(() => {
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, [getSelectWidth]);

return (
<ThemeProvider theme={colorsTheme.select}>
<ListboxContainer
id={id}
onClick={(event) => {
event.stopPropagation();
}}
onMouseDown={(event) => {
event.preventDefault();
}}
ref={listboxRef}
role="listbox"
aria-multiselectable={multiple}
style={styles}
>
{searchable && (options.length === 0 || !groupsHaveOptions(options)) ? (
<OptionsSystemMessage>
<NoMatchesFoundIcon>{selectIcons.searchOff}</NoMatchesFoundIcon>
{translatedLabels.select.noMatchesErrorMessage}
</OptionsSystemMessage>
) : (
optional &&
!multiple && (
<Option
key={`option-${optionalItem.value}`}
id={`option-${0}`}
option={optionalItem}
onClick={handleOptionOnClick}
multiple={multiple}
visualFocused={visualFocusIndex === 0}
isGroupedOption={false}
isLastOption={lastOptionIndex === 0}
isSelected={multiple ? currentValue.includes(optionalItem.value) : currentValue === optionalItem.value}
/>
)
)}
{options.map(mapOptionFunc)}
</ListboxContainer>
</ThemeProvider>
<ListboxContainer
id={id}
onClick={(event) => {
event.stopPropagation();
}}
onMouseDown={(event) => {
event.preventDefault();
}}
ref={listboxRef}
role="listbox"
aria-multiselectable={multiple}
style={styles}
>
{searchable && (options.length === 0 || !groupsHaveOptions(options)) ? (
<OptionsSystemMessage>
<NoMatchesFoundIcon>{selectIcons.searchOff}</NoMatchesFoundIcon>
{translatedLabels.select.noMatchesErrorMessage}
</OptionsSystemMessage>
) : (
optional &&
!multiple && (
<Option
key={`option-${optionalItem.value}`}
id={`option-${0}`}
option={optionalItem}
onClick={handleOptionOnClick}
multiple={multiple}
visualFocused={visualFocusIndex === 0}
isGroupedOption={false}
isLastOption={lastOptionIndex === 0}
isSelected={multiple ? currentValue.includes(optionalItem.value) : currentValue === optionalItem.value}
/>
)
)}
{options.map(mapOptionFunc)}
</ListboxContainer>
);
};

Expand Down
73 changes: 33 additions & 40 deletions lib/src/select/Option.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from "react";
import styled, { ThemeProvider } from "styled-components";
import styled from "styled-components";
import { OptionProps } from "../select/types";
import useTheme from "../useTheme";
import DxcCheckbox from "../checkbox/Checkbox";
import selectIcons from "./Icons";

Expand All @@ -14,47 +13,41 @@ const Option = ({
isGroupedOption = false,
isLastOption,
isSelected,
}: OptionProps): JSX.Element => {
const colorsTheme = useTheme();

return (
<ThemeProvider theme={colorsTheme.select}>
<OptionItem
id={id}
onClick={() => {
onClick(option);
}}
visualFocused={visualFocused}
selected={isSelected}
role="option"
aria-selected={isSelected}
>
<StyledOption
visualFocused={visualFocused}
selected={isSelected}
last={isLastOption}
}: OptionProps): JSX.Element => (
<OptionItem
id={id}
onClick={() => {
onClick(option);
}}
visualFocused={visualFocused}
selected={isSelected}
role="option"
aria-selected={isSelected}
>
<StyledOption
visualFocused={visualFocused}
selected={isSelected}
last={isLastOption}
grouped={isGroupedOption}
multiple={multiple}
>
{multiple && <DxcCheckbox checked={isSelected} tabIndex={-1} />}
{option.icon && (
<OptionIcon
grouped={isGroupedOption}
multiple={multiple}
role={!(typeof option.icon === "string") ? "img" : undefined}
>
{multiple && <DxcCheckbox checked={isSelected} tabIndex={-1} />}
{option.icon && (
<OptionIcon
grouped={isGroupedOption}
multiple={multiple}
role={!(typeof option.icon === "string") ? "img" : undefined}
>
{typeof option.icon === "string" ? <img src={option.icon} /> : option.icon}
</OptionIcon>
)}
<OptionContent grouped={isGroupedOption} hasIcon={option.icon ? true : false} multiple={multiple}>
<OptionLabel>{option.label}</OptionLabel>
{!multiple && isSelected && <OptionSelectedIndicator>{selectIcons.selected}</OptionSelectedIndicator>}
</OptionContent>
</StyledOption>
</OptionItem>
</ThemeProvider>
);
};
{typeof option.icon === "string" ? <img src={option.icon} /> : option.icon}
</OptionIcon>
)}
<OptionContent grouped={isGroupedOption} hasIcon={option.icon ? true : false} multiple={multiple}>
<OptionLabel>{option.label}</OptionLabel>
{!multiple && isSelected && <OptionSelectedIndicator>{selectIcons.selected}</OptionSelectedIndicator>}
</OptionContent>
</StyledOption>
</OptionItem>
);

type OptionItemProps = {
visualFocused: boolean;
Expand Down

0 comments on commit a062293

Please sign in to comment.