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

SWED-2266 disable dropdown icon rotation #901

Merged
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
8 changes: 3 additions & 5 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@

## Bug Fixes

- We reverted back the way CSS stylesheets were imported internally. It caused a regression bug, svg files would not load when imported from CSS properties (e.g. checkbox, ...). Paths resolution were failing. (not an issue for projects importing CSS via CDN, only for the ones importing styles via the local npm package)

## Component changes

### Non breaking UI changes

- add possibility to disable rotation of the dropdown toggle icon on active state

## Testing

- E2E tests for topbar
- E2E tests for dropdown component

## Design System website

- fix a homepage UI bug (section's height)
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,18 @@ exports[`Documentation: Dropdown DeveloperDocumentation renders 1`] = `
>
Developer Documentation
</h2>
<h3>
Style
</h3>
<p>
Add
<code
className="code-tags code-tags-secondary"
>
.no-rotation
</code>
CSS class on the dropdown toggle to disable the icon rotation.
</p>
<h3>
JavaScript methods
</h3>
Expand Down
31 changes: 29 additions & 2 deletions src/App/ComponentsDocumentation/components/Dropdown/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ const dropdownSidebarOptions = () => ({
],
},
{
id: "preffered_position",
id: "preferred_position",
title: "Position",
values: [
{
Expand Down Expand Up @@ -186,6 +186,19 @@ const dropdownSidebarOptions = () => ({
],
},
],
checkbox: [
{
inputs: [
{
id: "toggle-icon-rotation",
name: "Disable toggle icon rotation",
value: {
noRotation: true,
},
},
],
},
],
});

export const overviewDropdown = {
Expand Down Expand Up @@ -237,7 +250,7 @@ export const overviewDropdown = {
],
},
{
id: "preffered_position",
id: "preferred_position",
title: "Position",
values: [
{
Expand Down Expand Up @@ -276,6 +289,19 @@ export const overviewDropdown = {
],
},
],
checkbox: [
{
inputs: [
{
id: "toggle-icon-rotation",
name: "Disable toggle icon rotation",
value: {
noRotation: true,
},
},
],
},
],
},
title: "Select",
description: (
Expand Down Expand Up @@ -485,6 +511,7 @@ export const howToUse = [
icon="filter_list"
iconAfter={false}
largePadding={true}
noRotation={true}
/>
<ButtonComponent
type="secondary"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
// @ts-check
const { test, expect } = require("@playwright/test");

/**
*
* @param {import("@playwright/test").Page} page
* @returns boolean
*/
const checkIfOptionsDisplayed = async (page) =>
await (
await page.locator(".showcase-panel-advanced").getAttribute("class")
).includes("options-active");

const openOptions = async (page) => {
const areOptionsDisplayed = await checkIfOptionsDisplayed(page);

if (!areOptionsDisplayed) {
await page.getByRole("button", { name: "Open options menu" }).click();
}
};

const closeOptions = async (page) => {
const areOptionsDisplayed = await checkIfOptionsDisplayed(page);

if (areOptionsDisplayed) {
await page.getByRole("button", { name: "Close options menu" }).click();
}
};

test("Dropdown page exist", async ({ page }) => {
await page.goto("http://localhost:3000/");
await page
.getByRole("link", {
name: "Components Find all currently available components here",
})
.click();
await expect(page.getByRole("link", { name: "Dropdown" })).toHaveCount(
page.viewportSize().width < 991 ? 1 : 2
);
await page.getByText("expand_moreDropdownarrow_forward").click();
await expect(page).toHaveTitle(/Dropdown/);
await expect(
page.getByRole("heading", { name: "Dropdown", exact: true, level: 1 })
).toBeVisible();
});
test.describe(`dropdown visual regressions`, () => {
/**
* @type string
*/
let brand;
/**
* @type {import("@playwright/test").Locator}
*/
let previewContainer;

test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:3000/components/dropdown");

brand = (await page.title()).includes("Swedbank") ? "SwedbankPay" : "PayEx";
previewContainer = await page.locator(".component-preview-content > div");
});

test(`visual regresion dropdown - toggle normal`, async ({ page }) => {
await expect(previewContainer).toHaveScreenshot(
`${brand}-dropdown-toggle-normal.png`
);
});
test(`visual regresion dropdown - toggle hovered`, async ({ page }) => {
await previewContainer.getByRole("button").hover();
await expect(previewContainer).toHaveScreenshot(
`${brand}-dropdown-toggle-hovered.png`
);
});
test(`visual regresion dropdown - toggle active`, async ({ page }) => {
await previewContainer.getByRole("button").click();
await expect(previewContainer).toHaveScreenshot(
`${brand}-dropdown-toggle-active.png`
);
});
test(`visual regresion dropdown - select dropdown opened`, async ({
page,
}) => {
await previewContainer.getByRole("button").click();
await expect(page.locator(".component-preview-content")).toHaveScreenshot(
`${brand}-dropdown-select-opened-previewContainer.png`
);
await expect(
previewContainer.getByText(
"VISA Mastercard AMEX Maestro card Stripe Vipps Swish"
)
).toHaveScreenshot(`${brand}-dropdown-select-opened-dropdownContainer.png`);
});
});

test.describe(`dropdown options behave correctly`, () => {
/**
* @type string
*/
let brand;
/**
* @type {import("@playwright/test").Locator}
*/
let previewContainer;

test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:3000/components/dropdown");

brand = (await page.title()).includes("Swedbank") ? "SwedbankPay" : "PayEx";
previewContainer = await page.locator(".component-preview-content > div");
});

test("dropdown options - disable rotation", async ({ page }) => {
await expect(previewContainer.getByRole("button")).not.toHaveClass(
"no-rotation"
);
await expect(previewContainer.getByRole("button").locator("i")).toHaveCSS(
"transform",
"none"
);
await previewContainer.getByRole("button").click();
await expect(previewContainer.getByRole("button").locator("i")).toHaveCSS(
"transform",
"matrix(-1, 0, 0, -1, 0, 0)"
);
await previewContainer.getByRole("button").first().click();
await expect(previewContainer.getByRole("button").locator("i")).toHaveCSS(
"transform",
"none"
);
await openOptions(page);
await page
.getByLabel("Disable toggle icon rotation")
.click({ force: true });
await closeOptions(page);
await expect(previewContainer.getByRole("button").first()).toHaveClass(
/no-rotation/
);
await previewContainer.getByRole("button").click();
await expect(
previewContainer.getByRole("button").first().locator("i")
).toHaveCSS("transform", "none");
});
// TODO: test toggle type
test("dropdown options - menu width", async ({ page }) => {
const buttonWidth = (
await previewContainer.getByRole("button").first().boundingBox()
).width;

await previewContainer.getByRole("button").first().click();
await expect(
(
await previewContainer.locator(".dropdown-menu").boundingBox()
).width
).not.toBe(buttonWidth);
await previewContainer.getByRole("button").first().click();
await openOptions(page);
await page.getByLabel("Full width").click({ force: true });
await closeOptions(page);
await previewContainer.getByRole("button").first().click();
await expect(
(
await previewContainer.locator(".dropdown-menu").boundingBox()
).width
).toBe(buttonWidth);
});
// TODO: test menu position
// TODO: test states (error, etc)
// TODO: test keyboard navigation
// TODO: test accessibility
// TODO: test custom content
// TODO: test navigation inside modal
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/App/ComponentsDocumentation/components/Dropdown/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ const ContentGuidelines = () => (
const DeveloperDocumentation = () => (
<section>
<h2 id="developer-documentation">Developer Documentation</h2>
<h3>Style</h3>
<p>
Add <CodeTags type="secondary" code=".no-rotation" /> CSS class on the
dropdown toggle to disable the icon rotation.
</p>
<h3>JavaScript methods</h3>
<p>
Use <CodeTags type="secondary" code="dg.dropdown.init()" /> to initialize
Expand Down
17 changes: 14 additions & 3 deletions src/App/components/Dropdown/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import React, { useEffect, useState, Fragment } from "react";
import PropTypes from "prop-types";
import { dropdown } from "@src/scripts/main";

const DropdownSelect = ({ disabled, errorMessage, fullWidth, position }) => {
const DropdownSelect = ({
disabled,
errorMessage,
fullWidth,
position,
noRotation = false,
}) => {
const [buttonLabel, setButtonLabel] = useState("Card type");
const cardTypes = [
"VISA",
Expand All @@ -28,7 +34,7 @@ const DropdownSelect = ({ disabled, errorMessage, fullWidth, position }) => {
<div className="toggle-menu-container">
{"\n"}
<button
className="dropdown-toggle"
className={`dropdown-toggle${noRotation ? " no-rotation" : ""}`}
id="dropdownSelect"
type="button"
aria-label="dropdown button"
Expand Down Expand Up @@ -75,6 +81,7 @@ const DropdownToggle = ({
label = "Default label",
icon = isIconButton ? "more_vert" : "keyboard_arrow_down",
iconAfter,
noRotation = false,
}) => {
useEffect(() => {
dropdown.init();
Expand All @@ -85,7 +92,7 @@ const DropdownToggle = ({
<button
className={`dropdown-toggle${
isIconButton ? " dropdown-toggle-icon" : ""
}`}
}${noRotation ? " no-rotation" : ""}`}
type="button"
aria-label="dropdown button"
disabled={disabled}
Expand Down Expand Up @@ -139,6 +146,7 @@ const Dropdown = ({
disabled,
dropdownSelect,
disableDefaultKeyboardNavigation = false,
noRotation = false,
}) => (
<>
{dropdownSelect ? (
Expand All @@ -147,6 +155,7 @@ const Dropdown = ({
errorMessage={errorMessage}
fullWidth={fullWidth}
position={position}
noRotation={noRotation}
/>
) : (
<div
Expand All @@ -167,6 +176,7 @@ const Dropdown = ({
label={label}
icon={icon}
iconAfter={iconAfter}
noRotation={noRotation}
/>
<div
className={`dropdown-menu${fullWidth ? " full-width" : ""}${
Expand Down Expand Up @@ -204,6 +214,7 @@ Dropdown.propTypes = {
largePadding: PropTypes.bool,
dropdownSelect: PropTypes.bool,
disableDefaultKeyboardNavigation: PropTypes.bool,
noRotation: PropTypes.bool,
};

export default Dropdown;
Loading
Loading