Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion apps/website/screens/components/select/code/SelectCodePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,21 @@ const sections = [
<TableCode>false</TableCode>
</td>
</tr>
<tr>
<td>
<DxcFlex direction="column" gap="var(--spacing-gap-xs)" alignItems="baseline">
<StatusBadge status="new" />
enableSelectAll
</DxcFlex>
</td>
<td>
<TableCode>boolean</TableCode>
</td>
<td>Enables users to select multiple items from the list.</td>
<td>
<TableCode>false</TableCode>
</td>
</tr>
<tr>
<td>error</td>
<td>
Expand Down Expand Up @@ -305,7 +320,7 @@ const sections = [
content: <Example example={groups} defaultIsVisible />,
},
{
title: "Icons",
title: "Icon usage",
content: <Example example={icons} defaultIsVisible />,
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,26 @@ import { DxcSelect, DxcInset } from "@dxc-technology/halstack-react";
const code = `() => {
const options = [
{
label: "Managers",
label: "Designers",
options: [
{ label: "Pablo", value: "pablo" },
{ label: "Marcos", value: "marcos" },
{ label: "Rachel", value: "rachel" },
{ label: "Margaret", value: "margaret" },
{ label: "Lara", value: "lara" },
{ label: "Irene", value: "irene" }
],
},
{
label: "Engineers",
label: "Developers",
options: [
{ label: "Yiminghe", value: "yiminghe" },
{ label: "Manuel", value: "manuel" },
{ label: "Bryan", value: "bryan" },
{ label: "Anand", value: "anand" },
{ label: "Jairo", value: "jairo" },
{ label: "Enrique", value: "enrique" },
{ label: "Jiale", value: "jiale" },
{ label: "Iván", value: "ivan" }
],
},
{
label: "Designers",
label: "Managers",
options: [
{ label: "Alex", value: "alex" },
{ label: "Tim", value: "tim" },
{ label: "Jairo", value: "Jairo" },
{ label: "Aitor", value: "aitor" },
{ label: "Raquel", value: "Raquel" }
],
},
];
Expand Down
6 changes: 4 additions & 2 deletions apps/website/screens/components/select/code/examples/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ const code = `() => {
return (
<DxcInset space="var(--spacing-padding-xl)">
<DxcSelect
label="Select your favourite social media"
placeholder="Choose an option"
label="Select your favourite hobbies"
placeholder="Choose your hobbies"
options={options_material}
multiple
enableSelectAll
/>
</DxcInset>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import multiple from "./examples/multiple";
import filterable from "./examples/filterable";
import Image from "@/common/Image";
import anatomy from "./images/select_anatomy.png";
import Code from "@/common/Code";

const sections = [
{
Expand Down Expand Up @@ -158,6 +159,61 @@ const sections = [
</>
),
},
{
title: "Select all and grouped selection",
content: (
<DxcParagraph>
<strong>Select all</strong> and <strong>grouped selection</strong> options provide users with efficient ways
to manage large sets of checkable items within a list, dropdown, or multi-select component. These options
help reduce interaction costs and minimize repetitive actions, especially when dealing with categorized data
or bulk selection scenarios.
</DxcParagraph>
),
subSections: [
{
title: "Select all",
content: (
<>
<DxcParagraph>
The <strong>select all</strong> option (<Code>enableSelectAll</Code>) allows users to quickly select
or deselect all items in a list with a single action.
</DxcParagraph>
<DxcParagraph>
When the flag is set to true, a checkbox labelled with <em>"Select all"</em> text is placed at the top
of the list or above grouped items. It should visually reflect the current state:
</DxcParagraph>
<DxcBulletedList>
<DxcBulletedList.Item>Unselected when no items are selected.</DxcBulletedList.Item>
<DxcBulletedList.Item>Selected when all items are selected.</DxcBulletedList.Item>
<DxcBulletedList.Item>Indeterminate when only some items are selected.</DxcBulletedList.Item>
</DxcBulletedList>
</>
),
},
{
title: "Grouped selection",
content: (
<>
<DxcParagraph>
<strong>Grouped selection</strong> enables users to manage selections within categorized sections of a
list. Each group has its own header with a group-level checkbox. This allows users to:
</DxcParagraph>
<DxcBulletedList>
<DxcBulletedList.Item>Quickly select all items within a specific group.</DxcBulletedList.Item>
<DxcBulletedList.Item>Understand how items are organized.</DxcBulletedList.Item>
<DxcBulletedList.Item>
Maintain more granular control over selection without losing the efficiency of bulk actions.
</DxcBulletedList.Item>
</DxcBulletedList>
<DxcParagraph>
Just like the global select all, group checkboxes also reflect the selection state (selected,
unselected, indeterminate) based on the individual items in that group.
</DxcParagraph>
</>
),
},
],
},
],
},
{
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 12 additions & 6 deletions apps/website/screens/principles/localization/LocalizationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -539,12 +539,6 @@ const sections = [
</tr>
</thead>
<tbody>
<tr>
<td>
<Code>noMatchesErrorMessage</Code>
</td>
<td>No matches found</td>
</tr>
<tr>
<td>
<Code>actionClearSelectionTitle</Code>
Expand All @@ -557,6 +551,18 @@ const sections = [
</td>
<td>Clear search</td>
</tr>
<tr>
<td>
<Code>noMatchesErrorMessage</Code>
</td>
<td>No matches found</td>
</tr>
<tr>
<td>
<Code>selectAllLabel</Code>
</td>
<td>Select all</td>
</tr>
</tbody>
</DxcTable>
),
Expand Down
4 changes: 3 additions & 1 deletion packages/lib/src/checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import styled from "styled-components";
import { HalstackLanguageContext } from "../HalstackContext";
import CheckboxPropsType, { RefType } from "./types";
import { calculateWidth, icons, spaces } from "./utils";
import CheckboxContext from "./CheckboxContext";

const Label = styled.span<{
disabled: CheckboxPropsType["disabled"];
Expand Down Expand Up @@ -93,6 +94,7 @@ const DxcCheckbox = forwardRef<RefType, CheckboxPropsType>(
const [innerChecked, setInnerChecked] = useState(defaultChecked);
const checkboxRef = useRef<HTMLSpanElement | null>(null);
const translatedLabels = useContext(HalstackLanguageContext);
const { partial } = useContext(CheckboxContext) ?? {};

const handleOnChange = () => {
if (!disabled && !readOnly) {
Expand Down Expand Up @@ -142,7 +144,7 @@ const DxcCheckbox = forwardRef<RefType, CheckboxPropsType>(
ref={checkboxRef}
tabIndex={disabled ? -1 : tabIndex}
>
{(checked ?? innerChecked) ? icons.checked : icons.unchecked}
{partial ? icons.partial : (checked ?? innerChecked) ? icons.checked : icons.unchecked}
</Checkbox>
<input
checked={checked ?? innerChecked}
Expand Down
4 changes: 4 additions & 0 deletions packages/lib/src/checkbox/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,8 @@ type Props = {
*/
export type RefType = HTMLDivElement;

export type CheckboxContextProps = {
partial: boolean;
};

export default Props;
8 changes: 8 additions & 0 deletions packages/lib/src/checkbox/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ export const icons = {
/>
</svg>
),
partial: (
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<path
d="M19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3ZM19 19H5V5H19V19ZM7 11H17V13H7V11Z"
fill="currentColor"
/>
</svg>
),
unchecked: (
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<path
Expand Down
3 changes: 2 additions & 1 deletion packages/lib/src/common/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1516,9 +1516,10 @@ export const defaultTranslatedComponentLabels = {
optionalItemLabelDefault: "N/A",
},
select: {
noMatchesErrorMessage: "No matches found",
actionClearSelectionTitle: "Clear selection",
actionClearSearchTitle: "Clear search",
noMatchesErrorMessage: "No matches found",
selectAllLabel: "Select all"
},
tabs: {
scrollLeft: "Scroll left",
Expand Down
11 changes: 7 additions & 4 deletions packages/lib/src/select/ListOption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ const OptionIcon = styled.span`
place-items: center;
color: var(--color-fg-neutral-dark);
font-size: var(--height-xxs);

svg {
height: var(--height-xxs);
width: 16px;
Expand All @@ -66,7 +65,8 @@ const OptionContent = styled.span`
}
`;

const OptionLabel = styled.span`
const OptionLabel = styled.span<{ isSelectAllOption: OptionProps["isSelectAllOption"] }>`
${({ isSelectAllOption }) => isSelectAllOption && "font-weight: var(--typography-label-semibold);"}
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
Expand All @@ -77,6 +77,7 @@ const ListOption = ({
isGroupedOption = false,
isLastOption,
isSelected,
isSelectAllOption = false,
multiple,
onClick,
option,
Expand Down Expand Up @@ -107,13 +108,15 @@ const ListOption = ({
selected={isSelected}
visualFocused={visualFocused}
>
<StyledOption grouped={isGroupedOption} selected={isSelected} visualFocused={visualFocused} last={isLastOption}>
<StyledOption grouped={isGroupedOption} last={isLastOption} selected={isSelected} visualFocused={visualFocused}>
{multiple && <DxcCheckbox checked={isSelected} tabIndex={-1} ref={checkboxRef} />}
{option.icon && (
<OptionIcon>{typeof option.icon === "string" ? <DxcIcon icon={option.icon} /> : option.icon}</OptionIcon>
)}
<OptionContent>
<OptionLabel onMouseEnter={handleOnMouseEnter}>{option.label}</OptionLabel>
<OptionLabel isSelectAllOption={isSelectAllOption} onMouseEnter={handleOnMouseEnter}>
{option.label}
</OptionLabel>
{!multiple && isSelected && <DxcIcon icon="done" />}
</OptionContent>
</StyledOption>
Expand Down
Loading