From 12192553f01b0bc039f986c875c83ad791e03b94 Mon Sep 17 00:00:00 2001 From: Eduardo Formiga Date: Tue, 12 Jul 2022 12:11:47 -0300 Subject: [PATCH] Feat: Adds new tokens to `Breadcrumb` (#146) * Feat: Adds new tokens to `Breadcrumb` (#162) * Adds CSS Modules and themification to breadcrumb * Tweaks hover first item * Creates Breadcrumb stories using new format * Adds CHANGELOG entry * Adds margin top token * Removes irrelevant rule * tweaks bkg token name Co-authored-by: Renata Motta * Removes margin token from button * Uses DotsThree icon instead of text * Centralizes dropdown button * Tweaks tokens to use home instead of first * Uses last-child instead of current data-attr * Trigger CI Co-authored-by: Renata Motta * Removes scss imports * Adds CHANGELOG entry Co-authored-by: Renata Motta --- CHANGELOG.md | 1 + .../ui/Breadcrumb/Breadcrumb.stories.mdx | 197 ++++++++++++++++++ .../ui/Breadcrumb/Breadcrumb.stories.tsx | 49 ----- src/components/ui/Breadcrumb/Breadcrumb.tsx | 36 +++- .../ui/Breadcrumb/breadcrumb.module.scss | 142 +++++++++++++ src/components/ui/Breadcrumb/breadcrumb.scss | 113 ---------- .../ui/Dropdown/DropdownItem.stories.mdx | 4 + src/components/ui/Dropdown/DropdownItem.tsx | 2 +- .../ui/Dropdown/dropdown.module.scss | 5 + src/styles/global/storybook-components.scss | 1 - src/styles/pages/pdp.scss | 3 - src/styles/pages/plp.scss | 3 - src/styles/pages/search.scss | 3 - static/icons.svg | 1 + 14 files changed, 376 insertions(+), 184 deletions(-) create mode 100644 src/components/ui/Breadcrumb/Breadcrumb.stories.mdx delete mode 100644 src/components/ui/Breadcrumb/Breadcrumb.stories.tsx create mode 100644 src/components/ui/Breadcrumb/breadcrumb.module.scss delete mode 100644 src/components/ui/Breadcrumb/breadcrumb.scss diff --git a/CHANGELOG.md b/CHANGELOG.md index d849c004..e2026c64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Applies new local tokens to `Breadcrumb` ([#146](https://github.com/vtex-sites/gatsby.store/pull/146)) - Applies new local tokens to `SlideOver` ([#142](https://github.com/vtex-sites/gatsby.store/pull/142)) - Applies new local tokens to `CartSidebar` ([#142](https://github.com/vtex-sites/gatsby.store/pull/142)) - Adds [MSW Addon](https://storybook.js.org/addons/msw-storybook-addon) ([#143](https://github.com/vtex-sites/gatsby.store/pull/143)) diff --git a/src/components/ui/Breadcrumb/Breadcrumb.stories.mdx b/src/components/ui/Breadcrumb/Breadcrumb.stories.mdx new file mode 100644 index 00000000..35e776d2 --- /dev/null +++ b/src/components/ui/Breadcrumb/Breadcrumb.stories.mdx @@ -0,0 +1,197 @@ +import { Meta, Canvas, Story, ArgsTable } from '@storybook/addon-docs' +import Breadcrumb from '.' + +import { + TokenTable, + TokenRow, + TokenDivider, +} from 'src/../.storybook/components' + + + +export const breadcrumbList = [ + { item: 'technology', name: 'Technology', position: 1 }, + { + item: 'technology/electronics', + name: 'Electronics', + position: 2, + }, + { + item: 'technology/electronics/audio-and-video', + name: 'Audio & Video', + position: 3, + }, + { + item: 'technology/electronics/audio-and-video/headphones', + name: 'Headphones', + position: 4, + }, +] + +export const Template = (args) => + +
+ +# Breadcrumb + +Breadcrumbs indicate the user's location in a website hierarchy, facilitating the navigation to previous page levels. + +
+ +## Overview + +The `Breadcrumb` component uses [FastStore UI Breadcrumb](https://www.faststore.dev/reference/ui/molecules/Breadcrumb) as base. + + + + {Template.bind({})} + + + {Template.bind({})} + + + +--- + +## Usage + +`import Breadcrumb from 'src/components/ui/Breadcrumb'` + + + + {Template.bind({})} + + + + + + + + + +--- + +## Nested Elements + +### List Item + + + + + + + + + +### Link + + + + + +### Link Home + + + + + + + + + + +### Divider + + + + + + + + + +### Dropdown Button + + + + + + + + + + + + diff --git a/src/components/ui/Breadcrumb/Breadcrumb.stories.tsx b/src/components/ui/Breadcrumb/Breadcrumb.stories.tsx deleted file mode 100644 index dac96699..00000000 --- a/src/components/ui/Breadcrumb/Breadcrumb.stories.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import type { BreadcrumbProps } from '.' -import Breadcrumb from '.' - -export default { - component: Breadcrumb, - title: 'Molecules/Breadcrumb', -} - -const breadcrumbList = [ - { item: 'technology', name: 'Technology', position: 1 }, - { - item: 'technology/electronics', - name: 'Electronics', - position: 2, - }, - { - item: 'technology/electronics/audio-and-video', - name: 'Audio & Video', - position: 3, - }, - { - item: 'technology/electronics/audio-and-video/headphones', - name: 'Headphones', - position: 4, - }, -] - -const Template = ({ children, ...args }: BreadcrumbProps) => ( - {children} -) - -export const WithDropdown = Template.bind({}) - -WithDropdown.args = { - breadcrumbList: [ - ...breadcrumbList, - { - item: 'technology/electronics/audio-and-video/headphones/headphonesaedle-vk1-headphone', - name: 'Aedle VK-1 L Headphone', - position: 5, - }, - ], -} - -export const Default = Template.bind({}) - -Default.args = { - breadcrumbList, -} diff --git a/src/components/ui/Breadcrumb/Breadcrumb.tsx b/src/components/ui/Breadcrumb/Breadcrumb.tsx index 1e464d48..1491608f 100644 --- a/src/components/ui/Breadcrumb/Breadcrumb.tsx +++ b/src/components/ui/Breadcrumb/Breadcrumb.tsx @@ -1,7 +1,7 @@ -import { navigate } from 'gatsby' -import { memo } from 'react' import type { BreadcrumbProps as UIBreadcrumbProps } from '@faststore/ui' import { Breadcrumb as UIBreadcrumb } from '@faststore/ui' +import { navigate } from 'gatsby' +import { memo } from 'react' import Dropdown, { DropdownButton, DropdownItem, @@ -10,12 +10,17 @@ import Dropdown, { import Icon from 'src/components/ui/Icon' import Link from 'src/components/ui/Link' +import styles from './breadcrumb.module.scss' + type ItemElement = { item: string name: string position: number } export interface BreadcrumbProps extends UIBreadcrumbProps { + /** + * Array of ItemElement that represents each breadcrumb item. + */ breadcrumbList: ItemElement[] } @@ -39,9 +44,16 @@ function BaseBreadcrumb({ return ( - + @@ -50,25 +62,27 @@ function BaseBreadcrumb({ return breadcrumbList.length === index + 1 ? ( {name} ) : ( - + {name} ) })} {collapseBreadcrumb && firstItem && ( - {firstItem.name} + + {firstItem.name} + )} {collapseBreadcrumb && ( - - ... + + - + {mediumItems.map(({ item, name }, index) => ( } @@ -87,7 +101,7 @@ function BaseBreadcrumb({ return lastItems.length === index + 1 ? ( {name} ) : ( - + {name} ) diff --git a/src/components/ui/Breadcrumb/breadcrumb.module.scss b/src/components/ui/Breadcrumb/breadcrumb.module.scss new file mode 100644 index 00000000..84c269d5 --- /dev/null +++ b/src/components/ui/Breadcrumb/breadcrumb.module.scss @@ -0,0 +1,142 @@ +@import "src/styles/scaffold"; + +.fs-breadcrumb { + // -------------------------------------------------------- + // Design Tokens for Breadcrumb + // -------------------------------------------------------- + + // Default properties + --fs-breadcrumb-margin-left : calc(-1 * var(--fs-spacing-1)); + + // List item + --fs-breadcrumb-list-item-padding : var(--fs-spacing-0); + --fs-breadcrumb-list-item-last-text-color : var(--fs-color-text-light); + --fs-breadcrumb-list-item-max-width-mobile : 30%; + + // Link + --fs-breadcrumb-link-color-visited : var(--fs-color-link); + + // Link Home + --fs-breadcrumb-link-home-padding : var(--fs-spacing-1); + --fs-breadcrumb-link-home-border-radius : var(--fs-border-radius-circle); + --fs-breadcrumb-link-home-hover-bkg-color : var(--fs-color-primary-bkg-light); + --fs-breadcrumb-link-home-color : var(--fs-color-text); + + // Divider + --fs-breadcrumb-divider-height : var(--fs-spacing-3); + --fs-breadcrumb-divider-margin : var(--fs-spacing-1); + --fs-breadcrumb-divider-border-left-width : var(--fs-border-width); + --fs-breadcrumb-divider-border-left-color : var(--fs-border-color-light); + + // Dropdown Button + --fs-breadcrumb-dropdown-button-margin-left : var(--fs-breadcrumb-margin-left); + --fs-breadcrumb-dropdown-button-color : var(--fs-color-link); + --fs-breadcrumb-dropdown-button-border-radius : var(--fs-spacing-0); + --fs-breadcrumb-dropdown-button-transition-property : var(--fs-transition-property); + --fs-breadcrumb-dropdown-button-transition-timing : var(--fs-transition-timing); + --fs-breadcrumb-dropdown-button-transition-function : var(--fs-transition-function); + + // -------------------------------------------------------- + // Structural Styles + // -------------------------------------------------------- + + width: 100%; + + @include media(">=notebook") { + width: 50%; + } + + [data-breadcrumb-list] { + display: flex; + align-items: center; + margin-left: var(--fs-breadcrumb-margin-left); + overflow-x: hidden; + } + + [data-breadcrumb-list-item] { + display: inline-flex; + align-items: center; + padding: var(--fs-breadcrumb-list-item-padding); + + &:not(:first-child) { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + @include media("<=tablet") { + max-width: var(--fs-breadcrumb-list-item-max-width-mobile); + } + } + + [data-fs-breadcrumb-link-home] { + display: flex; + align-items: center; + padding: var(--fs-breadcrumb-link-home-padding); + border-radius: var(--fs-breadcrumb-link-home-border-radius); + + &:hover, &:focus { + background-color: var(--fs-breadcrumb-link-home-hover-bkg-color); + } + + svg { + color: var(--fs-breadcrumb-link-home-color); + } + } + + &:nth-child(2) { + overflow: visible; + } + + &:last-child { + color: var(--fs-breadcrumb-list-item-last-text-color); + } + + @include media(">=notebook") { + &:nth-child(3) { + overflow: visible; + } + + &:nth-child(2) { + overflow: hidden; + } + } + } + + [data-breadcrumb-item] { + display: block; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + [data-breadcrumb-divider] { + height: var(--fs-breadcrumb-divider-height); + margin: var(--fs-breadcrumb-divider-margin); + border-left: var(--fs-breadcrumb-divider-border-left-width) solid var(--fs-breadcrumb-divider-border-left-color); + } + + [data-fs-breadcrumb-link] { + padding: 0; + + &:visited { + color: var(--fs-breadcrumb-link-color-visited); + } + } + + [data-fs-breadcrumb-dropdown-button] { + display: flex; + align-items: center; + margin-left: var(--fs-breadcrumb-dropdown-button-margin-left); + color: var(--fs-breadcrumb-dropdown-button-color); + cursor: pointer; + background-color: transparent; + border-width: 0; + border-radius: var(--fs-breadcrumb-dropdown-button-border-radius); + transition: var(--fs-breadcrumb-dropdown-button-transition-property) var(--fs-breadcrumb-dropdown-button-transition-timing) var(--fs-breadcrumb-dropdown-button-transition-function); + + &:focus, &:focus-visible { + @include focus-ring; + } + } +} diff --git a/src/components/ui/Breadcrumb/breadcrumb.scss b/src/components/ui/Breadcrumb/breadcrumb.scss deleted file mode 100644 index 2a2d5a07..00000000 --- a/src/components/ui/Breadcrumb/breadcrumb.scss +++ /dev/null @@ -1,113 +0,0 @@ -@import "src/styles/scaffold"; - -[data-store-breadcrumb] { - width: 100%; - - @include media(">=notebook") { - width: 50%; - } - - [data-breadcrumb-list] { - display: flex; - align-items: center; - margin-left: calc(-1 * var(--fs-spacing-1)); - overflow-x: hidden; - - [data-breadcrumb-list-item] { - display: inline-flex; - align-items: center; - padding: var(--fs-spacing-0); - - &:first-child [data-fs-link] { - display: flex; - align-items: center; - padding: var(--fs-spacing-1); - border-radius: var(--fs-border-radius-circle); - - &:hover, &:focus { - background-color: var(--fs-color-primary-bkg-light); - } - } - - &:not(:first-child) { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - - @include media("<=tablet") { max-width: 30%; } - } - - &:nth-child(2) { - overflow: visible; - } - - @include media(">=notebook") { - &:nth-child(3) { - overflow: visible; - } - - &:nth-child(2) { - overflow: hidden; - } - } - } - - [data-breadcrumb-item] { - display: block; - width: 100%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - - svg { - color: var(--fs-color-text); - } - } - - [data-breadcrumb-divider] { - height: var(--fs-spacing-3); - margin: var(--fs-spacing-1); - border-left: var(--fs-border-width) solid var(--fs-border-color-light); - } - - [data-fs-link] { - padding: 0; - - &:visited { - color: var(--fs-color-link); - } - } - - [data-fs-dropdown-button] { - display: inline; - padding: 0 calc(var(--fs-spacing-0) / 2); - margin: calc(var(--fs-spacing-0) / 4); - color: var(--fs-color-link); - letter-spacing: var(--fs-spacing-0); - cursor: pointer; - background-color: transparent; - border-width: 0; - border-radius: var(--fs-spacing-0); - transition: var(--fs-transition-property) var(--fs-transition-timing) var(--fs-transition-function); - - &:focus, &:focus-visible { - @include focus-ring; - } - - span { - display: inline-block; - font-size: var(--fs-text-size-3); - font-weight: var(--fs-text-weight-bold); - transform: translate(rem(1px), rem(-6px)); - } - } - - [data-breadcrumb-item="current"] { - color: var(--fs-color-text-light); - } - } -} - -[data-breadcrumb-dropdown-item] [data-fs-dropdown-item-icon] { - margin-top: calc(-1 * var(--fs-spacing-1)); -} diff --git a/src/components/ui/Dropdown/DropdownItem.stories.mdx b/src/components/ui/Dropdown/DropdownItem.stories.mdx index 328f7880..5cdf36bc 100644 --- a/src/components/ui/Dropdown/DropdownItem.stories.mdx +++ b/src/components/ui/Dropdown/DropdownItem.stories.mdx @@ -132,4 +132,8 @@ The `DropdownItem` is part of [Dropdown](?path=/docs/molecules-dropdown-default- token="--fs-dropdown-item-icon-margin-right" value="var(--fs-spacing-0)" /> + diff --git a/src/components/ui/Dropdown/DropdownItem.tsx b/src/components/ui/Dropdown/DropdownItem.tsx index 6c16dfe1..70c0a6cb 100644 --- a/src/components/ui/Dropdown/DropdownItem.tsx +++ b/src/components/ui/Dropdown/DropdownItem.tsx @@ -1,5 +1,5 @@ -import { DropdownItem as UIDropdownItem, Icon as UIIcon } from '@faststore/ui' import type { DropdownItemProps } from '@faststore/ui' +import { DropdownItem as UIDropdownItem, Icon as UIIcon } from '@faststore/ui' import type { ReactNode } from 'react' export type Props = DropdownItemProps & { diff --git a/src/components/ui/Dropdown/dropdown.module.scss b/src/components/ui/Dropdown/dropdown.module.scss index d91075bf..9c6da1cc 100644 --- a/src/components/ui/Dropdown/dropdown.module.scss +++ b/src/components/ui/Dropdown/dropdown.module.scss @@ -27,6 +27,7 @@ // Icon --fs-dropdown-item-icon-min-width : 1.125rem; --fs-dropdown-item-icon-margin-right : var(--fs-spacing-0); + --fs-dropdown-item-icon-margin-top : calc(-1 * var(--fs-spacing-1)); // Small --fs-dropdown-item-small-min-height : 1.75rem; @@ -93,4 +94,8 @@ font-size: var(--fs-dropdown-item-small-text-size); } } + + [data-fs-breadcrumb-dropdown-item] [data-fs-dropdown-item-icon] { + margin-top: var(--fs-dropdown-item-icon-margin-top); + } } diff --git a/src/styles/global/storybook-components.scss b/src/styles/global/storybook-components.scss index 9105b056..e4209949 100644 --- a/src/styles/global/storybook-components.scss +++ b/src/styles/global/storybook-components.scss @@ -28,7 +28,6 @@ // UI @import "src/components/ui/Badge/badge.scss"; -@import "src/components/ui/Breadcrumb/breadcrumb.scss"; @import "src/components/ui/InputText/input-text.scss"; @import "src/components/ui/SlideOver/overlay.scss"; @import "src/components/ui/SROnly/sr-only.scss"; diff --git a/src/styles/pages/pdp.scss b/src/styles/pages/pdp.scss index c01db6b7..c583848e 100644 --- a/src/styles/pages/pdp.scss +++ b/src/styles/pages/pdp.scss @@ -7,6 +7,3 @@ @import "src/components/skeletons/ProductCardSkeleton/product-card-skeleton.scss"; @import "src/components/skeletons/Shimmer/shimmer.scss"; @import "src/components/skeletons/SkeletonElement/skeleton-element.scss"; - -// UI -@import "src/components/ui/Breadcrumb/breadcrumb.scss"; diff --git a/src/styles/pages/plp.scss b/src/styles/pages/plp.scss index 0294ac36..c2f91955 100644 --- a/src/styles/pages/plp.scss +++ b/src/styles/pages/plp.scss @@ -10,6 +10,3 @@ @import "src/components/skeletons/ProductCardSkeleton/product-card-skeleton.scss"; @import "src/components/skeletons/Shimmer/shimmer.scss"; @import "src/components/skeletons/SkeletonElement/skeleton-element.scss"; - -// UI -@import "src/components/ui/Breadcrumb/breadcrumb.scss"; diff --git a/src/styles/pages/search.scss b/src/styles/pages/search.scss index 76403fe4..12b613f9 100644 --- a/src/styles/pages/search.scss +++ b/src/styles/pages/search.scss @@ -7,6 +7,3 @@ @import "src/components/skeletons/ProductCardSkeleton/product-card-skeleton.scss"; @import "src/components/skeletons/Shimmer/shimmer.scss"; @import "src/components/skeletons/SkeletonElement/skeleton-element.scss"; - -// UI -@import "src/components/ui/Breadcrumb/breadcrumb.scss"; diff --git a/static/icons.svg b/static/icons.svg index aeed38b7..f3884082 100644 --- a/static/icons.svg +++ b/static/icons.svg @@ -50,4 +50,5 @@ +