From 526a3583294eb5109f0e2c01456ed1863db97b87 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Wed, 10 May 2023 17:34:03 +0530 Subject: [PATCH] chore: Add the ability to use icons in WdsButton (#23014) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the ability to pass icon in button component and adds button group to the storybook ## Description Fixes #21924 Fixes #21926 Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video ## Type of change - Bug fix ## How Has This Been Tested? - Manual ### Test Plan > Add Testsmith test cases links that relate to this PR ### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) ## Checklist: ### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag ### QA activity: - [ ] Test plan has been approved by relevant developers - [ ] Test plan has been peer reviewed by QA - [ ] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reveiwing all Cypress test --- .../src/components/Button/Button.stories.mdx | 23 +++ .../headless/src/components/Button/Button.tsx | 9 +- .../headless/src/components/Icon/Icon.tsx | 32 +++ .../headless/src/components/Icon/index.tsx | 1 + .../design-system/headless/src/index.ts | 1 + .../design-system/widgets/jest.config.js | 5 + .../design-system/widgets/package.json | 3 +- .../src/components/Button/Button.stories.mdx | 53 +++++ .../src/components/Button/Button.test.tsx | 66 ++++++ .../widgets/src/components/Button/Button.tsx | 21 +- .../src/components/Button/index.styled.tsx | 11 +- .../ButtonGroup/ButtonGroup.stories.mdx | 192 ++++++++++++++++++ .../components/ButtonGroup/ButtonGroup.tsx | 22 +- .../components/ButtonGroup/index.styled.tsx | 80 +++++--- .../packages/storybook/.storybook/main.js | 2 + 15 files changed, 477 insertions(+), 44 deletions(-) create mode 100644 app/client/packages/design-system/headless/src/components/Button/Button.stories.mdx create mode 100644 app/client/packages/design-system/headless/src/components/Icon/Icon.tsx create mode 100644 app/client/packages/design-system/headless/src/components/Icon/index.tsx create mode 100644 app/client/packages/design-system/widgets/jest.config.js create mode 100644 app/client/packages/design-system/widgets/src/components/Button/Button.test.tsx create mode 100644 app/client/packages/design-system/widgets/src/components/ButtonGroup/ButtonGroup.stories.mdx diff --git a/app/client/packages/design-system/headless/src/components/Button/Button.stories.mdx b/app/client/packages/design-system/headless/src/components/Button/Button.stories.mdx new file mode 100644 index 0000000000..90d9263ad7 --- /dev/null +++ b/app/client/packages/design-system/headless/src/components/Button/Button.stories.mdx @@ -0,0 +1,23 @@ +import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; + +import { Button } from "./"; + + + +export const Template = (args) => ); + expect(screen.getByRole("button")).toHaveTextContent("Click me"); + }); + + it("passes type to button component", () => { + render( + + + + ), + }} +/> + +export const Template = (args) => ; + +## Button Group + +A button group is a group of buttons that are visually connected together. + + + {Template.bind({})} + + + + +# Variants + + + + + + + + ), + }} + > + {Template.bind({})} + + + + + + + ), + }} + > + {Template.bind({})} + + + + + + + ), + }} + > + {Template.bind({})} + + + +# Orientation + + + + + + + + ), + }} + > + {Template.bind({})} + + + + + + + ), + }} + > + {Template.bind({})} + + + + + + + ), + }} + > + {Template.bind({})} + + + +# Disabled + + + + + + + + ), + }} + > + {Template.bind({})} + + + + + + + ), + }} + > + {Template.bind({})} + + + + + + + ), + }} + > + {Template.bind({})} + + diff --git a/app/client/packages/design-system/widgets/src/components/ButtonGroup/ButtonGroup.tsx b/app/client/packages/design-system/widgets/src/components/ButtonGroup/ButtonGroup.tsx index 8d865a99d4..675bc50093 100644 --- a/app/client/packages/design-system/widgets/src/components/ButtonGroup/ButtonGroup.tsx +++ b/app/client/packages/design-system/widgets/src/components/ButtonGroup/ButtonGroup.tsx @@ -3,11 +3,12 @@ import React, { forwardRef } from "react"; import { StyledContainer } from "./index.styled"; // types -export enum Orientation { - VERTICAL = "vertical", - HORIZONTAL = "horizontal", -} +export const ORIENTATION = { + VERTICAL: "vertical", + HORIZONTAL: "horizontal", +} as const; +type Orientation = (typeof ORIENTATION)[keyof typeof ORIENTATION]; export interface ButtonGroupProps extends React.ComponentPropsWithoutRef<"div"> { children?: React.ReactNode; @@ -17,8 +18,17 @@ export interface ButtonGroupProps // component export const ButtonGroup = forwardRef( (props, ref) => { - const { orientation = Orientation.HORIZONTAL, ...others } = props; - return ; + const { orientation = ORIENTATION.HORIZONTAL, ...others } = props; + + return ( + + ); }, ); diff --git a/app/client/packages/design-system/widgets/src/components/ButtonGroup/index.styled.tsx b/app/client/packages/design-system/widgets/src/components/ButtonGroup/index.styled.tsx index 2ff533fe63..b5fe780214 100644 --- a/app/client/packages/design-system/widgets/src/components/ButtonGroup/index.styled.tsx +++ b/app/client/packages/design-system/widgets/src/components/ButtonGroup/index.styled.tsx @@ -3,13 +3,16 @@ import styled from "styled-components"; import type { ButtonGroupProps } from "./ButtonGroup"; export const StyledContainer = styled.div` - --border-width: 1px; - display: flex; height: 100%; width: 100%; - flex-direction: ${({ orientation }) => - orientation === "vertical" ? "column" : "row"}; + flex-direction: row; + align-items: center; + justify-content: center; + + &[data-orientation="vertical"] { + flex-direction: column; + } & [data-button] { // increasing z index to make sure the focused button is on top of the others @@ -17,48 +20,65 @@ export const StyledContainer = styled.div` z-index: 1; } - &:is([data-variant="filled"]):not([data-disabled]) { - border-color: var(--wds-vs-color-border-onaccent); - } - - &:is([data-variant="light"]):not([data-disabled]) { - border-color: var(--wds-vs-color-border-onaccent-light); - } - &:first-child { border-bottom-right-radius: 0; - ${({ orientation }) => - orientation === "vertical" - ? "border-bottom-left-radius: 0; border-bottom-width: calc(var(--border-width) / 2);" - : "border-top-right-radius: 0; border-right-width: calc(var(--border-width) / 2);"} } &:last-of-type { border-top-left-radius: 0; - ${({ orientation }) => - orientation === "vertical" - ? "border-top-right-radius: 0; border-top-width: calc(var(--border-width) / 2);" - : "border-bottom-left-radius: 0; border-left-width: calc(var(--border-width) / 2);"} } &:not(:first-child):not(:last-of-type) { border-radius: 0; + } + } - ${({ orientation }) => - orientation === "vertical" - ? "border-top-width: calc(var(--border-width) / 2); border-bottom-width: calc(var(--border-width) / 2);" - : "border-left-width: calc(var(--border-width) / 2); border-right-width: calc(var(--border-width) / 2);"} + &:not([data-orientation="vertical"]) [data-button] { + &:first-child { + border-top-right-radius: 0; + border-right-width: calc(var(--border-width-1) / 2); + } + + &:last-of-type { + border-bottom-left-radius: 0; + border-left-width: calc(var(--border-width-1) / 2); + } + + &:not(:first-child):not(:last-of-type) { + border-left-width: calc(var(--border-width-1) / 2); + border-right-width: calc(var(--border-width-1) / 2); } & + [data-button] { - ${({ orientation }) => - orientation === "vertical" - ? "margin-top: calc(var(--border-width) * -1);" - : "margin-left: calc(var(--border-width) * -1);"} + margin-left: calc(var(--border-width-1) * -1); @media (min-resolution: 192dpi) { - ${({ orientation }) => - orientation === "vertical" ? "margin-top: 0px;" : "margin-left: 0px;"} + margin-left: 0px; + } + } + } + + &[data-orientation="vertical"] [data-button] { + &:first-child { + border-bottom-left-radius: 0; + border-bottom-width: calc(var(--border-width-1) / 2); + } + + &:last-of-type { + border-top-right-radius: 0; + border-top-width: calc(var(--border-width-1) / 2); + } + + &:not(:first-child):not(:last-of-type) { + border-top-width: calc(var(--border-width-1) / 2); + border-bottom-width: calc(var(--border-width-1) / 2); + } + + & + [data-button] { + margin-top: calc(var(--border-width-1) * -1); + + @media (min-resolution: 192dpi) { + margin-top: 0px; } } } diff --git a/app/client/packages/storybook/.storybook/main.js b/app/client/packages/storybook/.storybook/main.js index d8b71a5e68..d168963faa 100644 --- a/app/client/packages/storybook/.storybook/main.js +++ b/app/client/packages/storybook/.storybook/main.js @@ -23,7 +23,9 @@ async function webpackConfig(config) { module.exports = { stories: [ "../../design-system/widgets/src/**/*.stories.mdx", + "../../design-system/headless/src/**/*.stories.mdx", "../../design-system/widgets/src/**/*.stories.@(js|jsx|ts|tsx)", + "../../design-system/headless/src/**/*.stories.@(js|jsx|ts|tsx)", ], addons: [ "@storybook/addon-links",