Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Dropdown): default maxHeight with multiSelect/showSearch #4275

Merged
merged 2 commits into from
Aug 16, 2024
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
2 changes: 1 addition & 1 deletion .config/chromatic.config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"projectId": "Project:66a1254d9d7ebf301ff1bebb",
"buildScriptName": "build:doc",
"buildScriptName": "build:doc:test",
"skip": "dependabot/**"
}
8 changes: 6 additions & 2 deletions .github/workflows/tests-visual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ on:
batch-id:
type: string

env:
IS_PR: ${{inputs.batch-id && 'true' || 'false' }}

jobs:
chromatic:
name: Chromatic
Expand All @@ -29,8 +32,9 @@ jobs:
configFile: .config/chromatic.config.json
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
forceRebuild: true
# Perform Checks on "background" in PRs, succeeding ✅ even with visual changes
exitOnceUploaded: ${{env.IS_PR}}

# Add red mark to workflow if it failed
- name: Evaluate Fail
- name: Fail on visual changes
if: ${{ steps.publish.outcome == 'failure' || steps.publish.outputs.changeCount != '0' || steps.publish.outputs.errorCount != '0' }}
run: exit 1
14 changes: 13 additions & 1 deletion packages/core/src/Dropdown/List/List.styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,19 @@ import { theme } from "@hitachivantara/uikit-styles";

export const { staticClasses, useClasses } = createClasses("HvDropdownList", {
rootList: {},
dropdownListContainer: {},
dropdownListContainer: {
overflow: "auto",
padding: 4,
margin: -4,
maxWidth: "var(--maxW)",
maxHeight: "var(--maxH)",
},
virtualized: {
maxWidth: "inherit",
maxHeight: "inherit",
overflow: "inherit",
padding: 0,
},
searchContainer: { marginBottom: theme.space.xs },
listBorderDown: {},
listContainer: { padding: theme.space.sm },
Expand Down
42 changes: 16 additions & 26 deletions packages/core/src/Dropdown/List/List.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useMemo, useState } from "react";
import {
mergeStyles,
useDefaultProps,
type ExtractNames,
} from "@hitachivantara/uikit-react-utils";
Expand Down Expand Up @@ -126,12 +127,12 @@ export const HvDropdownList = (props: HvDropdownListProps) => {
notifyChangesOnFirstRender = false,
hasTooltips = false,
singleSelectionToggle,
height: dropdownHeight,
height: heightProp,
maxHeight,
virtualized = false,
...others
} = useDefaultProps("HvDropdownList", props);
const { classes, cx, css } = useClasses(classesProp);
const { classes, cx } = useClasses(classesProp);

const [searchStr, setSearchStr] = useState<string>("");
const [list, setList] = useState<HvListValue[]>(clone(values));
Expand Down Expand Up @@ -332,6 +333,10 @@ export const HvDropdownList = (props: HvDropdownListProps) => {
};

const showList = valuesExist(values);
/** bottom margin + Panel padding + Search size + SelectAll + ActionBar size */
const elementsSize = theme.spacing(
5 + 2 + (showSearch ? 5 : 0) + (showList && multiSelect ? 4 + 6 : 0),
);

return (
<div className={classes.rootList}>
Expand All @@ -342,30 +347,15 @@ export const HvDropdownList = (props: HvDropdownListProps) => {
{showList && (
<HvList
id={setId(id, "list")}
style={mergeStyles(undefined, {
height: heightProp,
"--maxW": width,
"--maxH": maxHeight ?? `calc(${height}px - ${elementsSize})`,
})}
classes={{
root: cx(
classes.dropdownListContainer,
css({
maxWidth: width,
maxHeight:
maxHeight ??
`calc(${height}px - 32px - ${theme.space.xs} - ${theme.space.sm})`,
overflow: "auto",
padding: 4,
margin: -4,
}),
dropdownHeight &&
css({
height: dropdownHeight,
}),
virtualized &&
css({
maxWidth: "inherit",
maxHeight: "inherit",
overflow: "inherit",
padding: 0,
}),
),
root: cx(classes.dropdownListContainer, {
[classes.virtualized]: virtualized,
}),
}}
values={list}
multiSelect={multiSelect}
Expand All @@ -377,7 +367,7 @@ export const HvDropdownList = (props: HvDropdownListProps) => {
selectable
condensed
singleSelectionToggle={singleSelectionToggle}
height={dropdownHeight}
height={heightProp}
virtualized={virtualized}
{...others}
/>
Expand Down
97 changes: 26 additions & 71 deletions packages/core/src/Dropdown/stories/Dropdown.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,14 @@ import {

import { CustomDropdown as CustomDropdownStory } from "./CustomDropdown";
import CustomDropdownRaw from "./CustomDropdown?raw";
import { Empty as EmptyStory } from "./Empty";
import EmptyRaw from "./Empty?raw";
import { ExternalErrorMessage as ExternalErrorMessageStory } from "./ExternalErrorMessage";
import ExternalErrorMessageRaw from "./ExternalErrorMessage?raw";
import { Main as MainStory } from "./Main";
import MainRaw from "./Main?raw";
import { MultiSelection as MultiSelectionStory } from "./MultiSelection";
import MultiSelectionRaw from "./MultiSelection?raw";
import { SingleSelectionWithSearch as SingleSelectionWithSearchStory } from "./SingleSelectionWithSearch";
import SingleSelectionWithSearchRaw from "./SingleSelectionWithSearch?raw";
import { Variants as VariantsStory } from "./Variants";
import VariantsRaw from "./Variants?raw";
import { Virtualized as VirtualizedStory } from "./Virtualized";
import VirtualizedRaw from "./Virtualized?raw";
import { WithDefinedHeight as WithDefinedHeightStory } from "./WithDefinedHeight";
import WithDefinedHeightRaw from "./WithDefinedHeight?raw";
import { WithIcons as WithIconsStory } from "./WithIcons";
import WithIconsRaw from "./WithIcons?raw";

Expand All @@ -42,17 +34,12 @@ export default {

export const Main: StoryObj<HvDropdownProps> = {
args: {
multiSelect: true,
showSearch: true,
multiSelect: false,
showSearch: false,
disabled: false,
readOnly: false,
required: false,
defaultExpanded: true,
notifyChangesOnFirstRender: false,
hasTooltips: false,
variableWidth: false,
singleSelectionToggle: false,
virtualized: false,
status: "valid",
},
argTypes: {
Expand All @@ -64,16 +51,18 @@ export const Main: StoryObj<HvDropdownProps> = {
widthDecorator,
(Story) => <div style={{ minHeight: 400 }}>{Story()}</div>,
],
parameters: {
docs: {
source: {
code: MainRaw,
},
},
// Enables Chromatic snapshot
chromatic: { disableSnapshot: false },
},
render: (args) => <MainStory {...args} />,
render: (args) => (
<HvDropdown
{...args}
label="Select values"
values={[
{ label: "value 1" },
{ label: "value 2", selected: true },
{ label: "value 3" },
{ label: "value 4" },
]}
/>
),
};

export const Variants: StoryObj<HvDropdownProps> = {
Expand Down Expand Up @@ -130,47 +119,29 @@ export const WithIcons: StoryObj<HvDropdownProps> = {
render: () => <WithIconsStory />,
};

export const Empty: StoryObj<HvDropdownProps> = {
parameters: {
docs: {
description: {
story: "Dropdown with no values",
},
source: {
code: EmptyRaw,
},
},
},
decorators: [widthDecorator],
render: () => <EmptyStory />,
};

export const MultiSelection: StoryObj<HvDropdownProps> = {
parameters: {
docs: {
source: {
code: MultiSelectionRaw,
},
},
},
decorators: [widthDecorator],
render: () => <MultiSelectionStory />,
};

export const SingleSelectionWithSearch: StoryObj<HvDropdownProps> = {
parameters: {
docs: {
description: {
story:
"Single selection Dropdown with search and less than 10 elements",
"Dropdown example with multiple selection (`multiSelect`) and search (`showSearch`). <br />\
The Dropdown automatically expands to fit the available height. this can be configured using the `height` (or `maxHeight`) props.",
},
source: {
code: SingleSelectionWithSearchRaw,
code: MultiSelectionRaw,
},
},
// Enables Chromatic snapshot
chromatic: { disableSnapshot: false },
},
decorators: [widthDecorator],
render: () => <SingleSelectionWithSearchStory />,
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const picker = canvas.getByRole("combobox");
await userEvent.click(picker);
await expect(canvas.getByRole("list")).toBeInTheDocument();
},
render: () => <MultiSelectionStory />,
};

export const ExternalErrorMessage: StoryObj<HvDropdownProps> = {
Expand All @@ -188,22 +159,6 @@ export const ExternalErrorMessage: StoryObj<HvDropdownProps> = {
render: () => <ExternalErrorMessageStory />,
};

export const WithDefinedHeight: StoryObj<HvDropdownProps> = {
parameters: {
docs: {
description: {
story:
"Dropdown's height can be configured using `height` (or `maxHeight`). Note: only validated in the single selection use-case.",
},
source: {
code: WithDefinedHeightRaw,
},
},
},
decorators: [widthDecorator],
render: () => <WithDefinedHeightStory />,
};

export const Virtualized: StoryObj<HvDropdownProps> = {
parameters: {
docs: {
Expand Down
3 changes: 0 additions & 3 deletions packages/core/src/Dropdown/stories/Empty.tsx

This file was deleted.

14 changes: 7 additions & 7 deletions packages/core/src/Dropdown/stories/MultiSelection.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { HvDropdown } from "@hitachivantara/uikit-react-core";

const values = [...Array(80).keys()].map((i) => ({
label: `value ${i + 1}`,
selected: i % 6 === 0,
}));

export const MultiSelection = () => (
<HvDropdown
multiSelect
showSearch
label="Dropdown Title"
values={[
{ label: "value 1" },
{ label: "value 2", selected: true },
{ label: "value 3" },
{ label: "value 4" },
]}
label="Multi Select with search"
values={values}
/>
);

This file was deleted.

1 change: 1 addition & 0 deletions packages/core/src/Dropdown/stories/Variants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export const Variants = () => (
<HvDropdown disabled label="Disabled" values={values} />
<HvDropdown readOnly label="Read-only" values={values} />
<HvDropdown status="invalid" label="Invalid" values={values} />
<HvDropdown label="Empty" />
</>
);
18 changes: 0 additions & 18 deletions packages/core/src/Dropdown/stories/WithDefinedHeight.tsx

This file was deleted.

Loading