diff --git a/packages/harmony/src/components/index.ts b/packages/harmony/src/components/index.ts index cdf02b10b46..dc5e13683c5 100644 --- a/packages/harmony/src/components/index.ts +++ b/packages/harmony/src/components/index.ts @@ -15,3 +15,5 @@ export * from './radio' export * from './radio-group' export * from './popup-menu' export * from './modal' +export * from './progress-bar' +export * from './scrubber' diff --git a/packages/stems/src/components/ProgressBar/ProgressBar.module.css b/packages/harmony/src/components/progress-bar/ProgressBar.module.css similarity index 62% rename from packages/stems/src/components/ProgressBar/ProgressBar.module.css rename to packages/harmony/src/components/progress-bar/ProgressBar.module.css index 59502726d31..f01641475af 100644 --- a/packages/stems/src/components/ProgressBar/ProgressBar.module.css +++ b/packages/harmony/src/components/progress-bar/ProgressBar.module.css @@ -5,7 +5,7 @@ } .slider { - background-color: var(--neutral-light-9); + background-color: var(--harmony-n-50); box-shadow: inset 1px 1px 7px -2px rgba(53, 54, 79, 0.25); border-radius: 22px; height: 24px; @@ -14,11 +14,7 @@ } .sliderBar { - background: linear-gradient( - 315deg, - var(--page-header-gradient-color-1) 2.04%, - var(--page-header-gradient-color-2) 100% - ); + background: var(--harmony-gradient); bottom: 0; left: 0; position: absolute; @@ -28,7 +24,7 @@ .labels { display: flex; - font-size: var(--font-s); + font-size: var(--harmony-font-s); justify-content: space-between; margin-top: 8px; padding: 0 4px; @@ -36,6 +32,6 @@ .minLabel, .maxLabel { - color: var(--neutral-light-4); - font-weight: var(--font-bold); + color: var(--harmony-text-subdued); + font-weight: var(--harmony-font-bold); } diff --git a/packages/stems/src/components/ProgressBar/ProgressBar.tsx b/packages/harmony/src/components/progress-bar/ProgressBar.tsx similarity index 77% rename from packages/stems/src/components/ProgressBar/ProgressBar.tsx rename to packages/harmony/src/components/progress-bar/ProgressBar.tsx index 2ec3d4d2600..3c4427cc591 100644 --- a/packages/stems/src/components/ProgressBar/ProgressBar.tsx +++ b/packages/harmony/src/components/progress-bar/ProgressBar.tsx @@ -1,11 +1,8 @@ import { useState, useEffect, useMemo } from 'react' -import * as React from 'react' import BN from 'bn.js' import cn from 'classnames' -import { clampBN } from 'utils/bnHelpers' - import styles from './ProgressBar.module.css' import { ProgressBarProps, ProgressValue } from './types' @@ -14,18 +11,24 @@ const getBN = (num: ProgressValue): BN => { return new BN(num) } -export const ProgressBar: React.FC = ({ - className, - sliderClassName, - sliderBarClassName, - min = new BN(0), - max = new BN(100), - value, - showLabels = false, - minWrapper: MinWrapper, - maxWrapper: MaxWrapper, - ...other -}: ProgressBarProps) => { +function clampBN(value: BN, min: BN, max: BN): BN { + return BN.min(BN.max(value, min), max) +} + +// @beta - This component was directly ported from stems and subject to change +export const ProgressBar = (props: ProgressBarProps) => { + const { + className, + sliderClassName, + sliderBarClassName, + min = new BN(0), + max = new BN(100), + value, + showLabels = false, + minWrapper: MinWrapper, + maxWrapper: MaxWrapper, + ...other + } = props const [sliderWidth, setSliderWidth] = useState(0) const percentage = useMemo(() => { diff --git a/packages/stems/src/components/ProgressBar/index.ts b/packages/harmony/src/components/progress-bar/index.ts similarity index 100% rename from packages/stems/src/components/ProgressBar/index.ts rename to packages/harmony/src/components/progress-bar/index.ts diff --git a/packages/stems/src/components/ProgressBar/types.ts b/packages/harmony/src/components/progress-bar/types.ts similarity index 100% rename from packages/stems/src/components/ProgressBar/types.ts rename to packages/harmony/src/components/progress-bar/types.ts diff --git a/packages/stems/src/components/Scrubber/Scrubber.module.css b/packages/harmony/src/components/scrubber/Scrubber.module.css similarity index 59% rename from packages/stems/src/components/Scrubber/Scrubber.module.css rename to packages/harmony/src/components/scrubber/Scrubber.module.css index a77745d48c1..e7c9f97c18e 100644 --- a/packages/stems/src/components/Scrubber/Scrubber.module.css +++ b/packages/harmony/src/components/scrubber/Scrubber.module.css @@ -4,11 +4,12 @@ width: 100%; } -.timestampStart, .timestampEnd { - color: var(--neutral); - font-size: var(--font-2xs); +.timestampStart, +.timestampEnd { + color: var(--harmony-neutral); + font-size: var(--harmony-font-2xs); line-height: 12px; - font-family: var(--font-family); + font-family: var(--harmony-font-family); min-width: 40px; } @@ -22,5 +23,5 @@ .scrubber.isMobile .timestampStart, .scrubber.isMobile .timestampEnd { - font-size: var(--font-xs); + font-size: var(--harmony-font-xs); } diff --git a/packages/stems/src/components/Scrubber/Scrubber.tsx b/packages/harmony/src/components/scrubber/Scrubber.tsx similarity index 97% rename from packages/stems/src/components/Scrubber/Scrubber.tsx rename to packages/harmony/src/components/scrubber/Scrubber.tsx index 6add6f07db7..570b3cc8dea 100644 --- a/packages/stems/src/components/Scrubber/Scrubber.tsx +++ b/packages/harmony/src/components/scrubber/Scrubber.tsx @@ -24,6 +24,7 @@ const formatSeconds = (seconds: number) => { } /** + * @beta - This component was directly ported from stems and subject to change * Wraps the `` component and provides timestamp indicators. */ export const Scrubber = ({ diff --git a/packages/stems/src/components/Scrubber/Slider.module.css b/packages/harmony/src/components/scrubber/Slider.module.css similarity index 65% rename from packages/stems/src/components/Scrubber/Slider.module.css rename to packages/harmony/src/components/scrubber/Slider.module.css index 2114e6c9b0e..2590cc5eb36 100644 --- a/packages/stems/src/components/Scrubber/Slider.module.css +++ b/packages/harmony/src/components/scrubber/Slider.module.css @@ -4,23 +4,23 @@ display: flex; align-items: center; cursor: pointer; - margin: 0 var(--unit-3); + margin: 0 var(--harmony-unit-3); } .slider.isMobile { - margin: 0 var(--unit-4); + margin: 0 var(--harmony-unit-4); } .slider.isDisabled { - cursor: default + cursor: default; } /* Use a psuedo-element to "increase" the clickable area of the scrubber. */ .slider.expandedTargets:after { position: absolute; opacity: 0; - border-radius: var(--unit-half);; - content: ""; + border-radius: var(--harmony-unit-half); + content: ''; width: 100%; height: 500%; top: -300%; @@ -30,9 +30,9 @@ .rail { position: relative; width: 100%; - height: var(--unit); - border-radius: var(--unit-half); - background: var(--neutral-light-8); + height: var(--harmony-unit); + border-radius: var(--harmony-unit-half); + background: var(--harmony-n-100); overflow: hidden; /** Fixes Safari bug where overflow doesn't work with border radius during animation */ mask-image: -webkit-radial-gradient(white, black); @@ -51,14 +51,14 @@ position: absolute; width: 100%; height: 100%; - background: var(--neutral); + background: var(--harmony-neutral); } .track:before { - content: ""; + content: ''; position: absolute; - border-radius: var(--unit-half); - background: var(--scrubber-hover); + border-radius: var(--harmony-unit-half); + background: var(--harmony-primary-gradient); width: 100%; height: 100%; left: 0; @@ -85,24 +85,26 @@ } .handle { - margin-left: var(--negative-unit); - height: var(--unit-2); - width: var(--unit-2); + margin-left: var(--harmony-negative-unit); + height: var(--harmony-unit-2); + width: var(--harmony-unit-2); border-radius: 50%; - background: var(--white); - box-shadow: 0 0 2px 0 rgba(133,129,153,0.5), 0 2px 5px -1px rgba(133,129,153,0.5); + background: var(--harmony-white); + box-shadow: 0 0 2px 0 rgba(133, 129, 153, 0.5), + 0 2px 5px -1px rgba(133, 129, 153, 0.5); transition: transform 0.18s ease-in-out, opacity 0.18s ease-in-out; opacity: 0; transform: scale(0); } .slider.isMobile .handle { - height: var(--unit-4); - width: var(--unit-4); - margin-left: var(--negative-unit-2); + height: var(--harmony-unit-4); + width: var(--harmony-unit-4); + margin-left: calc(var(--harmony-negative-unit) * 2); } -.showHandle .handle, .slider:not(.showHandle):hover .handle { +.showHandle .handle, +.slider:not(.showHandle):hover .handle { opacity: 1; transform: scale(1); } diff --git a/packages/stems/src/components/Scrubber/Slider.tsx b/packages/harmony/src/components/scrubber/Slider.tsx similarity index 100% rename from packages/stems/src/components/Scrubber/Slider.tsx rename to packages/harmony/src/components/scrubber/Slider.tsx diff --git a/packages/stems/src/components/Scrubber/hooks.ts b/packages/harmony/src/components/scrubber/hooks.ts similarity index 100% rename from packages/stems/src/components/Scrubber/hooks.ts rename to packages/harmony/src/components/scrubber/hooks.ts diff --git a/packages/stems/src/components/Scrubber/index.ts b/packages/harmony/src/components/scrubber/index.ts similarity index 100% rename from packages/stems/src/components/Scrubber/index.ts rename to packages/harmony/src/components/scrubber/index.ts diff --git a/packages/stems/src/components/Scrubber/types.ts b/packages/harmony/src/components/scrubber/types.ts similarity index 100% rename from packages/stems/src/components/Scrubber/types.ts rename to packages/harmony/src/components/scrubber/types.ts diff --git a/packages/harmony/src/foundations/color/primitive.css b/packages/harmony/src/foundations/color/primitive.css index c5cc4769d6a..2c684775306 100644 --- a/packages/harmony/src/foundations/color/primitive.css +++ b/packages/harmony/src/foundations/color/primitive.css @@ -51,6 +51,7 @@ --harmony-dark-red: #bb0218; --harmony-green: #0f9e48; --harmony-light-green: #13c65a; + --harmony-primary-gradient: linear-gradient(135deg, #ee00ed 0%, #c514e0 100%); --harmony-gradient: linear-gradient(315deg, #5b23e1 0%, #a22feb 100%); } diff --git a/packages/stems/src/components/Button/Button.module.css b/packages/stems/src/components/Button/Button.module.css deleted file mode 100644 index fe7d9d9dfb7..00000000000 --- a/packages/stems/src/components/Button/Button.module.css +++ /dev/null @@ -1,544 +0,0 @@ -.button { - box-sizing: border-box; - cursor: pointer; - user-select: none; - text-align: center; - white-space: nowrap; - overflow: hidden; - transition: all var(--quick); - position: relative; - - display: inline-flex; - align-items: center; - justify-content: center; - padding-left: var(--unit-6); - padding-right: var(--unit-6); -} - -.button:focus { - outline: none !important; -} - -.button.noIcon { - padding-left: var(--unit-8); - padding-right: var(--unit-8); -} - -.button.medium { - height: var(--unit-12); -} - -.button.small { - height: var(--unit-8); -} - -.button.large { - padding: var(--unit-5) var(--unit-6); - height: var(--unit-15); - gap: var(--unit-2); -} - -.button.large .textLabel { - font-size: var(--font-xl); - font-weight: var(--font-bold); - letter-spacing: 0.25px; - line-height: var(--unit-5); - text-transform: uppercase; -} - -.button.large .icon, -.button.large .icon.left { - margin-right: 0; -} - -.button.tiny { - height: var(--unit-7); - padding-left: var(--unit-4); - padding-right: var(--unit-4); -} - -.button.medium .icon svg { - width: var(--unit-6); -} - -.button.small .icon svg { - width: var(--unit-4); -} - -.button.tiny .icon svg { - width: var(--unit-4); -} - -.button .icon path { - fill: var(--neutral); - transition: all var(--quick); -} - -.button .icon.left { - margin-right: var(--unit-3); -} - -.button.small .icon.left { - margin-right: var(--unit-2); -} - -.button .icon.left.noText { - margin: 0 !important; -} - -.button .icon.right { - margin-left: var(--unit-3); -} - -.button .icon.right.noText { - margin: 0 !important; -} - -.button .icon { - display: inline-flex; - align-items: center; - vertical-align: middle; -} - -.textLabel { - vertical-align: middle; - transition: all var(--quick); -} - -.button .overlay { - background-color: var(--overlay-color, transparent); - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - opacity: var(--overlay-opacity, 0); -} - -/* Primary Button */ - -.primary { - --button-color: var(--primary); - box-shadow: var(--shadow-near); - border: none; - border-radius: 4px; - background: var(--button-color); -} - -.primary .textLabel { - color: var(--primary-secondary-text); - font-size: var(--font-l); - font-weight: var(--font-bold); -} - -.primary .icon path, -.primary .icon use { - fill: var(--primary-secondary-text); -} - -.primary.includeHoverAnimations:hover.enabled { - --overlay-color: var(--static-white); - --overlay-opacity: 0.1; - box-shadow: var(--shadow-mid); - transform: var(--grow); - background: var(--button-color); -} - -.primary.includeHoverAnimations:active.enabled { - --overlay-color: var(--static-blck); - --overlay-opacity: 0.2; - box-shadow: none; - transform: perspective(1px) scale3d(0.99, 0.99, 0.99); - background: var(--button-color); -} - -/* PrimaryAlt Button */ - -.primaryAlt { - height: 46px; - border: none; - border-radius: 4px; - background: var(--primary); -} - -.primaryAlt .textLabel { - color: var(--primary-secondary-text); - font-size: var(--font-s); - font-weight: var(--font-bold); - letter-spacing: 0.5px; -} - -.primaryAlt .icon path, -.primaryAlt .icon use { - fill: var(--primary-secondary-text); -} - -.primaryAlt.includeHoverAnimations:hover.enabled { - transform: var(--grow); - background: var(--primary-light-1); -} - -.primaryAlt.includeHoverAnimations:active.enabled { - transform: perspective(1px) scale3d(0.99, 0.99, 0.99); - background: var(--primary-dark-1); -} - -/* Secondary Button */ - -.secondary { - border: 1px solid var(--primary-dark-1); - border-radius: 4px; - background: var(--white); -} - -.secondary .textLabel { - color: var(--primary); - font-size: var(--font-l); - font-weight: var(--font-bold); -} - -.secondary.small .textLabel { - font-size: var(--font-s); - letter-spacing: 0.5px; -} - -.secondary.tiny .textLabel { - font-size: 11px; - letter-spacing: 0.3px; -} - -.secondary .icon path, -.secondary .icon use { - fill: var(--primary); -} - -.secondary.includeHoverAnimations:hover.enabled { - transform: var(--grow); - border: 1px solid var(--primary-dark-2); - background: var(--primary); -} - -.secondary.includeHoverAnimations:hover.enabled .textLabel { - color: var(--primary-secondary-text); -} - -.secondary.includeHoverAnimations:hover.enabled .icon path, -.secondary.includeHoverAnimations:hover.enabled .icon use { - fill: var(--primary-secondary-text); -} - -.secondary.includeHoverAnimations:active.enabled { - transform: perspective(1px) scale3d(0.99, 0.99, 0.99); - border: 1px solid var(--primary-dark-2); - background: var(--primary-dark-2); -} - -/* Tertiary Button */ - -.tertiary { - background: var(--white); - border: 1px solid var(--neutral-light-7); - border-radius: 4px; -} - -.tertiary .textLabel { - color: var(--secondary); - font-family: var(--font-family); - font-size: var(--font-l); - font-weight: var(--font-bold); -} - -.tertiary .icon path, -.tertiary .icon use { - fill: var(--secondary); -} - -.tertiary.includeHoverAnimations:hover.enabled { - transform: var(--grow); - background-color: var(--static-white); -} - -.tertiary.includeHoverAnimations:active.enabled { - transform: perspective(1px) scale3d(0.99, 0.99, 0.99); -} - -/* Common Button */ - -.common { - border: 1px solid var(--neutral-light-6); - border-radius: 4px; - background: var(--white); -} - -.common.small { - padding: 0 var(--unit-4); -} - -.common .textLabel { - color: var(--neutral); - font-size: var(--font-s); - font-weight: var(--font-bold); - letter-spacing: 0.5px; -} - -.common.tiny .textLabel { - font-size: 11px; - letter-spacing: 0.3px; -} - -.common .icon path, -.common .icon use { - fill: var(--neutral); -} - -.common.includeHoverAnimations:hover.enabled { - transform: var(--grow); - border: 1px solid var(--primary-dark-2); - background: var(--primary); -} - -.common.includeHoverAnimations:hover.enabled .textLabel { - color: var(--primary-secondary-text); -} - -.common.includeHoverAnimations:hover.enabled .icon path, -.common.includeHoverAnimations:hover.enabled .icon use { - fill: var(--primary-secondary-text); -} - -.common.includeHoverAnimations:active.enabled { - transform: perspective(1px) scale3d(0.99, 0.99, 0.99); - border: 1px solid var(--primary-dark-2); - background: var(--primary-dark-2); -} - -.common.includeHoverAnimations:active.enabled .textLabel { - color: var(--primary-secondary-text); -} - -.common.includeHoverAnimations:active.enabled .icon path { - fill: var(--primary-secondary-text); -} - -/* Common Alt Button */ - -.commonAlt { - border: 1px solid var(--neutral-light-6); - border-radius: 4px; - background: var(--white); -} - -.commonAlt .textLabel { - color: var(--neutral); - font-size: var(--font-s); - font-weight: var(--font-bold); - letter-spacing: 0.5px; -} - -.commonAlt.small .textLabel { - font-size: var(--font-xs); -} - -.commonAlt .icon path, -.commonAlt .icon use { - fill: var(--neutral); -} - -.commonAlt:hover.enabled { - transform: var(--grow); - border: 1px solid var(--neutral-light-6); - background: var(--neutral-light-10); -} - -.commonAlt.includeHoverAnimations:active.enabled { - transform: perspective(1px) scale3d(0.99, 0.99, 0.99); - border: 1px solid var(--neutral-light-6); - background: var(--neutral-light-8); -} - -/* Glass Button */ - -.glass { - border: 1px solid var(--white); - border-radius: 4px; - background-color: rgba(255, 255, 255, 0.1); -} - -.glass .textLabel { - text-transform: uppercase; - color: var(--white); - font-size: var(--font-l); - font-weight: var(--font-bold); -} - -.glass .icon path, -.glass .icon use { - fill: var(--white); -} - -.glass.includeHoverAnimations:hover.enabled { - transform: var(--grow); - background-color: rgba(255, 255, 255, 0.2); -} - -.glass.includeHoverAnimations:active.enabled { - transform: perspective(1px) scale3d(1, 1, 1); - background-color: rgba(255, 255, 255, 0.05); -} - -/* Disabled Button */ - -.disabled { - box-shadow: none; - border-radius: 4px; - background-color: var(--neutral-light-7); - cursor: default; - transform: none; - border: none; - pointer-events: none; -} - -.disabled .textLabel { - font-size: var(--font-l); - font-weight: var(--font-bold); - color: var(--white); -} - -.disabled .icon path, -.disabled .icon use { - fill: var(--white); -} - -/* White Button */ - -.white { - border: none; - border-radius: 4px; - background-color: var(--static-neutral-light-10); - box-shadow: 0 1px 0 0 var(--neutral-light-4), - 0 4px 12px -4px rgba(0, 0, 0, 0.3); -} - -.white .textLabel { - color: var(--secondary); - font-family: var(--font-family); - font-size: var(--font-l); - font-weight: var(--font-demi-bold); -} - -.white .icon path, -.white .icon use { - fill: var(--secondary); -} - -.white.includeHoverAnimations:hover.enabled { - transform: var(--grow); - background-color: var(--static-white); - box-shadow: 0 1px 0 0 var(--neutral-light-5), - 0 5px 20px -3px rgba(0, 0, 0, 0.3); -} - -.white.includeHoverAnimations:active.enabled { - background-color: #eeeeee; - box-shadow: 0 1px 0 0 var(--neutral-light-4), - 0 4px 12px -4px rgba(0, 0, 0, 0.3); - transform: perspective(1px) scale3d(0.99, 0.99, 0.99); -} - -/* Text Button */ -.textButton { - background: none; - border: none; - outline: none; - padding: 8px 24px; - font-weight: var(--font-bold); -} - -.textButton.button.medium, -.textButton.button.small, -.textButton.button.tiny { - height: unset; -} - -.textButton.medium, -.textButton.medium .textLabel { - font-size: var(--font-m); -} -.textButton.small, -.textButton.small .textLabel { - font-size: var(--font-s); -} -.textButton.tiny, -.textButton.tiny .textLabel { - font-size: var(--font-xs); -} - -.textButton.button .icon svg { - width: calc(1em - 2px); - height: calc(1em - 2px); -} - -.textButton:hover .textLabel { - color: var(--secondary); -} - -.textButton .icon.left { - margin-right: var(--unit-1); -} - -.textButton .icon.right { - margin-left: var(--unit-1); -} - -.textButton .icon path { - transition: all var(--quick); -} - -.textButton:hover .icon path { - fill: var(--secondary); -} - -/** Destructive buttons **/ -.destructive { - background: transparent; - border: 1px solid var(--accent-red); - border-radius: var(--unit-1); -} - -.destructive .textLabel { - font-size: var(--font-l); - font-weight: var(--font-bold); - color: var(--accent-red); -} - -.destructive .icon path { - fill: var(--accent-red); -} - -/** destructive hover **/ -.destructive.includeHoverAnimations:hover.enabled { - transform: var(--grow); - background-color: var(--accent-red); -} - -.destructive.includeHoverAnimations:active.enabled { - transform: perspective(1px) scale3d(0.99, 0.99, 0.99); - background-color: var(--accent-red-dark-1); -} - -.destructive.includeHoverAnimations:hover.enabled .textLabel { - color: white; -} - -.destructive.includeHoverAnimations:hover.enabled .icon path { - fill: var(--static-white); -} - -/** destructive disabled **/ -.destructive:disabled { - opacity: 0.45; -} - -.fullWidth { - width: 100%; -} diff --git a/packages/stems/src/components/Button/Button.stories.tsx b/packages/stems/src/components/Button/Button.stories.tsx deleted file mode 100644 index dba601ead1a..00000000000 --- a/packages/stems/src/components/Button/Button.stories.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { Story } from '@storybook/react' - -import { Button } from './Button' -import { ButtonProps, Type } from './types' - -import { Size } from './index' - -export default { - component: Button, - title: 'Components/Button', - argTypes: { onClick: { action: 'clicked' } } -} - -const baseProps: ButtonProps = { - text: 'Click Me' -} - -const Template: Story = (args) => ( -
-
-) - -const BackgroundTemplate: Story = (args) => ( -
-
-) - -// Primary -export const Primary = Template.bind({}) - -// Disabled -export const Disabled = Template.bind({}) -Disabled.args = { disabled: true } - -// Primary Alt -export const PrimaryAlt = Template.bind({}) -PrimaryAlt.args = { type: Type.PRIMARY_ALT } - -// Primary w/ color -export const PrimaryWithColor = Template.bind({}) -PrimaryWithColor.args = { color: 'accentBlue' } - -// Secondary -export const Secondary = Template.bind({}) -Secondary.args = { type: Type.SECONDARY } - -// Common -export const Common = Template.bind({}) -Common.args = { type: Type.COMMON } - -// Common Alt -export const CommonAlt = Template.bind({}) -CommonAlt.args = { type: Type.COMMON_ALT } - -// Glass -export const Glass = BackgroundTemplate.bind({}) -Glass.args = { type: Type.GLASS } - -// White -export const White = Template.bind({}) -White.args = { type: Type.WHITE } - -// Text -export const Text = Template.bind({}) -Text.args = { type: Type.TEXT } - -// Destructive -export const Destructive = Template.bind({}) -Destructive.args = { type: Type.DESTRUCTIVE } diff --git a/packages/stems/src/components/Button/Button.tsx b/packages/stems/src/components/Button/Button.tsx deleted file mode 100644 index 9faa5ddad42..00000000000 --- a/packages/stems/src/components/Button/Button.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import { forwardRef, CSSProperties, ElementType, ForwardedRef } from 'react' - -import cn from 'classnames' - -import { useMediaQueryListener } from 'hooks/useMediaQueryListener' -import { CSSCustomProperties } from 'styles/types' -import { toCSSVariableName } from 'utils/styles' - -import styles from './Button.module.css' -import { ButtonProps, Type, Size } from './types' - -const SIZE_STYLE_MAP = { - [Size.TINY]: styles.tiny, - [Size.SMALL]: styles.small, - [Size.MEDIUM]: styles.medium, - [Size.LARGE]: styles.large -} - -const TYPE_STYLE_MAP = { - [Type.PRIMARY]: styles.primary, - [Type.PRIMARY_ALT]: styles.primaryAlt, - [Type.SECONDARY]: styles.secondary, - [Type.TERTIARY]: styles.tertiary, - [Type.COMMON]: styles.common, - [Type.COMMON_ALT]: styles.commonAlt, - [Type.DISABLED]: styles.disabled, - [Type.GLASS]: styles.glass, - [Type.WHITE]: styles.white, - [Type.TEXT]: styles.textButton, - [Type.DESTRUCTIVE]: styles.destructive -} - -/** - * @deprecated - * Deprecated: (use `Button` from \@audius/harmony) - * - * A common Button component. Includes a few variants and options to - * include and position icons. - */ -export const Button = forwardRef(function Button< - Component extends ElementType = 'button' ->(props: ButtonProps, ref: ForwardedRef) { - const { - color, - text, - type = Type.PRIMARY, - buttonType, - size = Size.MEDIUM, - leftIcon, - rightIcon, - isDisabled, - disabled: disabledProp, - includeHoverAnimations = true, - widthToHideText, - minWidth, - className, - iconClassName, - textClassName, - 'aria-label': ariaLabelProp, - fullWidth, - as, - ...other - } = props - const { isMatch: textIsHidden } = useMediaQueryListener( - `(max-width: ${widthToHideText}px)` - ) - const disabled = disabledProp ?? isDisabled - const isTextVisible = !!text && !textIsHidden - - const renderLeftIcon = () => - leftIcon && ( - - {leftIcon} - - ) - - const renderRightIcon = () => - rightIcon && ( - - {rightIcon} - - ) - - const getAriaLabel = () => { - if (ariaLabelProp) return ariaLabelProp - // Use the text prop as the aria-label if the text becomes hidden - // and no aria-label was provided to keep the button accessible. - else if (textIsHidden && typeof text === 'string') return text - return undefined - } - - const renderText = () => - isTextVisible && ( - {text} - ) - - const style: CSSCustomProperties = { - minWidth: minWidth && isTextVisible ? `${minWidth}px` : 'unset', - '--button-color': color ? `var(${toCSSVariableName(color)})` : undefined - } - - const RootComponent: ElementType = as ?? 'button' - - return ( - - {color ? : null} - {renderLeftIcon()} - {renderText()} - {renderRightIcon()} - - ) -}) diff --git a/packages/stems/src/components/Button/index.ts b/packages/stems/src/components/Button/index.ts deleted file mode 100644 index 1148be17d1d..00000000000 --- a/packages/stems/src/components/Button/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Button } from './Button' -export { ButtonProps, Type, Size } from './types' diff --git a/packages/stems/src/components/Button/test.ts b/packages/stems/src/components/Button/test.ts deleted file mode 100644 index f2d299fc54d..00000000000 --- a/packages/stems/src/components/Button/test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Button } from '.' - -describe('Button', () => { - it('is truthy', () => { - expect(Button).toBeTruthy() - }) -}) diff --git a/packages/stems/src/components/Button/types.ts b/packages/stems/src/components/Button/types.ts deleted file mode 100644 index 4a35e6a6e61..00000000000 --- a/packages/stems/src/components/Button/types.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react' - -import { ColorValue } from 'styles/colors' - -export enum Type { - PRIMARY = 'primary', - PRIMARY_ALT = 'primaryAlt', - SECONDARY = 'secondary', - TERTIARY = 'tertiary', - COMMON = 'common', - COMMON_ALT = 'commonAlt', - DISABLED = 'disabled', - GLASS = 'glass', - WHITE = 'white', - TEXT = 'text', - DESTRUCTIVE = 'destructive' -} - -export enum Size { - TINY = 'tiny', - SMALL = 'small', - MEDIUM = 'medium', - LARGE = 'large' -} - -type ButtonOwnProps = { - as?: Component - color?: ColorValue - /** - * The text of the button - */ - text: ReactNode - - /** - * The type of the button - */ - type?: Type - - /** - * The default behavior of the button. - */ - buttonType?: 'submit' | 'button' | 'reset' - - /** - * The button size - */ - size?: Size - - /** - * Optional icon element to include on the left side of the button - */ - leftIcon?: ReactNode | JSX.Element - - /** - * Optional icon element to include on the right side of the button - */ - rightIcon?: ReactNode | JSX.Element - - /** - * Whether or not the button is clickable - */ - isDisabled?: boolean - - /** - * Whether or not to include animations on hover - * Consider turning off animations in mobile-first experiences - */ - includeHoverAnimations?: boolean - - /** - * The max width at which text will still be shown - */ - widthToHideText?: number - - /** - * Optional min width - * Min width can be useful if the button is switching states and you want - * to keep a certain width while text length changes - */ - minWidth?: number - - /** - * If provided, allow button to take up full width of container - */ - fullWidth?: boolean - - /** - * Class name to apply to the icon - */ - iconClassName?: string - - /** - * Class name to apply to the text label - */ - textClassName?: string -} - -export type ButtonProps = - ButtonOwnProps & - Omit, keyof ButtonOwnProps> diff --git a/packages/stems/src/components/MarkdownViewer/MarkdownViewer.stories.tsx b/packages/stems/src/components/MarkdownViewer/MarkdownViewer.stories.tsx deleted file mode 100644 index b949a3260ed..00000000000 --- a/packages/stems/src/components/MarkdownViewer/MarkdownViewer.stories.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Story } from '@storybook/react' - -import { MarkdownViewer, MarkdownViewerProps } from '.' - -export default { - component: MarkdownViewer, - title: 'Components/MarkdownViewer' -} - -const defaultProps: MarkdownViewerProps = { - markdown: ` -# Hello -Good morning - -## Section 1 - -1. This -2. Is -3. An ordered list - 1. And - 2. A - 3. Sublist - -You can also **bold** and _italicize_ things. -And make - -* Bullet1 -* Bullet2 -* Bullet3 - -## Appendix - -Read more here: [link](https://example.com) - ` -} - -const Template: Story = (args) => { - return -} - -// Default -export const Default = Template.bind({}) diff --git a/packages/stems/src/components/PillButton/PillButton.module.css b/packages/stems/src/components/PillButton/PillButton.module.css deleted file mode 100644 index bd097f6848f..00000000000 --- a/packages/stems/src/components/PillButton/PillButton.module.css +++ /dev/null @@ -1,42 +0,0 @@ -.button { - height: unset !important; - padding: 10px 0; - border-radius: 100px; - border: 1px solid var(--neutral-light-4); - background: var(--white); -} -.buttonText { - display: flex; - align-items: center; - text-transform: uppercase; - font-size: var(--font-xs) !important; - color: var(--neutral) !important; - letter-spacing: unset !important; -} -.button:hover { - transform: scale3d(1.01, 1.01, 1.01) !important; - border: unset !important; -} -.button:active { - transform: scale3d(0.99, 0.99, 0.99) !important; -} -.button:hover .buttonText, -.button:active .buttonText { - color: var(--white) !important; -} -.button.primary:hover, -.button.primary:hover .buttonText { - background: var(--primary) !important; -} -.button.primary:active, -.button.primary:active .buttonText { - background: var(--primary-dark-2) !important; -} -.button.secondary:hover, -.button.secondary:hover .buttonText { - background: var(--secondary-light-2) !important; -} -.button.secondary:active, -.button.secondary:active .buttonText { - background: var(--secondary) !important; -} diff --git a/packages/stems/src/components/PillButton/PillButton.stories.tsx b/packages/stems/src/components/PillButton/PillButton.stories.tsx deleted file mode 100644 index 3f870193b2f..00000000000 --- a/packages/stems/src/components/PillButton/PillButton.stories.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Story } from '@storybook/react' - -import { PillButton, PillButtonProps } from './' - -export default { - component: PillButton, - title: 'Components/PillButton' -} - -const defaultProps: PillButtonProps = { - text: 'Pill Button' -} - -const Template: Story = (args) => { - return -} - -// Default -export const Default = Template.bind({}) - -// Disabled -export const Disabled = Template.bind({}) -Disabled.args = { disabled: true } diff --git a/packages/stems/src/components/PillButton/PillButton.tsx b/packages/stems/src/components/PillButton/PillButton.tsx deleted file mode 100644 index f54de607cb2..00000000000 --- a/packages/stems/src/components/PillButton/PillButton.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import cn from 'classnames' - -import { Button, Type as ButtonType } from 'components/Button' - -import styles from './PillButton.module.css' -import { PillButtonProps, Variant as PillButtonVariant } from './types' - -const VARIANT_STYLE_MAP = { - [PillButtonVariant.PRIMARY]: styles.primary, - [PillButtonVariant.SECONDARY]: styles.secondary -} -/** - * @deprecated Used in feed-tip-tile - */ -export const PillButton = (props: PillButtonProps) => { - const { - text, - onClick, - variant = PillButtonVariant.PRIMARY, - className, - textClassName, - ...other - } = props - return ( - ) } diff --git a/packages/stems/src/components/TokenValueSlider/TokenValueSlider.module.css b/packages/web/src/components/token-value-slider/TokenValueSlider.module.css similarity index 58% rename from packages/stems/src/components/TokenValueSlider/TokenValueSlider.module.css rename to packages/web/src/components/token-value-slider/TokenValueSlider.module.css index e4139f4a6d8..a01c792258b 100644 --- a/packages/stems/src/components/TokenValueSlider/TokenValueSlider.module.css +++ b/packages/web/src/components/token-value-slider/TokenValueSlider.module.css @@ -1,6 +1,15 @@ -:root, root { - --stems-token-value-slider-background: linear-gradient(315deg, #7652CC 2.04%, #B05CE6 100%); - --stems-token-value-slider-background-error: linear-gradient(180deg, #F15064 0%, #C03A4B 100%); +:root, +root { + --token-value-slider-background: linear-gradient( + 315deg, + #7652cc 2.04%, + #b05ce6 100% + ); + --token-value-slider-background-error: linear-gradient( + 180deg, + #f15064 0%, + #c03a4b 100% + ); } .container { @@ -10,13 +19,13 @@ width: 576px; /* Text styles */ - font-family: var(--font-family); - font-weight: var(--font-bold); - font-size: var(--font-s); + font-family: var(--harmony-font-family); + font-weight: var(--harmony-font-bold); + font-size: var(--harmony-font-s); line-height: 17px; letter-spacing: 1px; text-transform: uppercase; - color: #BEC5E0; + color: var(--harmony-neutral); } .slider { @@ -31,20 +40,20 @@ .newValueSlider { position: absolute; - background: var(--stems-token-value-slider-background); + background: var(--token-value-slider-background); height: 100%; transition: width 0.2s ease-in-out; } .initialValueSlider { position: absolute; - background: var(--stems-token-value-slider-background); + background: var(--token-value-slider-background); height: 100%; transition: width 0.2s ease-in-out; } .invalid { - background: var(--stems-token-value-slider-background-error); + background: var(--token-value-slider-background-error); z-index: 1; } @@ -58,16 +67,16 @@ display: inline-flex; justify-content: space-between; margin-bottom: 8px; - color: var(--neutral); + color: var(--harmony-neutral); } .minLabel { - color: var(--neutral-light-4); + color: var(--harmony-text-subdued); padding-right: 4px; } .maxLabel { - color: var(--neutral-light-4); + color: var(--harmony-text-subdued); padding-left: 4px; } diff --git a/packages/stems/src/components/TokenValueSlider/TokenValueSlider.tsx b/packages/web/src/components/token-value-slider/TokenValueSlider.tsx similarity index 93% rename from packages/stems/src/components/TokenValueSlider/TokenValueSlider.tsx rename to packages/web/src/components/token-value-slider/TokenValueSlider.tsx index e8717cfec0e..61f35b1a567 100644 --- a/packages/stems/src/components/TokenValueSlider/TokenValueSlider.tsx +++ b/packages/web/src/components/token-value-slider/TokenValueSlider.tsx @@ -1,10 +1,9 @@ import { useState, useRef, useEffect } from 'react' import * as React from 'react' +import BN from 'bn.js' import cn from 'classnames' -import { getBNPercentage } from 'utils/bnHelpers' - import styles from './TokenValueSlider.module.css' import { TokenValueSliderProps } from './types' @@ -14,6 +13,14 @@ const messages = { current: 'CURRENT' } +export function getBNPercentage(n1: BN, n2: BN): number { + if (n2.isZero()) return 0 + const thousand = new BN('1000') + const num = n1.mul(thousand).div(n2) + if (num.gte(thousand)) return 1 + return num.toNumber() / 1000 +} + export const TokenValueSlider: React.FC = ({ className, sliderClassName, diff --git a/packages/stems/src/components/TokenValueSlider/index.ts b/packages/web/src/components/token-value-slider/index.ts similarity index 52% rename from packages/stems/src/components/TokenValueSlider/index.ts rename to packages/web/src/components/token-value-slider/index.ts index a9d7f3ebd3a..60cbca9bac3 100644 --- a/packages/stems/src/components/TokenValueSlider/index.ts +++ b/packages/web/src/components/token-value-slider/index.ts @@ -1,2 +1 @@ export { TokenValueSlider } from './TokenValueSlider' -export { TokenValueSliderProps } from './types' diff --git a/packages/stems/src/components/TokenValueSlider/types.ts b/packages/web/src/components/token-value-slider/types.ts similarity index 100% rename from packages/stems/src/components/TokenValueSlider/types.ts rename to packages/web/src/components/token-value-slider/types.ts diff --git a/packages/web/src/components/track/GiantTrackTileProgressInfo.tsx b/packages/web/src/components/track/GiantTrackTileProgressInfo.tsx index ac403725d05..5ff12db1451 100644 --- a/packages/web/src/components/track/GiantTrackTileProgressInfo.tsx +++ b/packages/web/src/components/track/GiantTrackTileProgressInfo.tsx @@ -5,8 +5,7 @@ import { CommonState } from '@audius/common/store' import { formatLineupTileDuration } from '@audius/common/utils' -import { IconCheck } from '@audius/harmony' -import { ProgressBar } from '@audius/stems' +import { IconCheck, ProgressBar } from '@audius/harmony' import { useSelector } from 'react-redux' import styles from './GiantTrackTile.module.css' diff --git a/packages/web/src/components/track/desktop/TrackTile.tsx b/packages/web/src/components/track/desktop/TrackTile.tsx index 4bd462f22fe..2e213976948 100644 --- a/packages/web/src/components/track/desktop/TrackTile.tsx +++ b/packages/web/src/components/track/desktop/TrackTile.tsx @@ -22,9 +22,9 @@ import { IconVisibilityHidden, Text, Flex, - spacing + spacing, + ProgressBar } from '@audius/harmony' -import { ProgressBar } from '@audius/stems' import cn from 'classnames' import moment from 'moment' import { useSelector } from 'react-redux' diff --git a/packages/web/src/pages/audio-rewards-page/ChallengeRewardsTile.tsx b/packages/web/src/pages/audio-rewards-page/ChallengeRewardsTile.tsx index a4698f615a2..3b3ad92228f 100644 --- a/packages/web/src/pages/audio-rewards-page/ChallengeRewardsTile.tsx +++ b/packages/web/src/pages/audio-rewards-page/ChallengeRewardsTile.tsx @@ -24,9 +24,9 @@ import { Button, IconArrowRight as IconArrow, IconCheck, + ProgressBar, Text } from '@audius/harmony' -import { ProgressBar } from '@audius/stems' import cn from 'classnames' import { useDispatch, useSelector } from 'react-redux' diff --git a/packages/web/src/pages/audio-rewards-page/components/DashboardTokenValueSlider.tsx b/packages/web/src/pages/audio-rewards-page/components/DashboardTokenValueSlider.tsx index 31e599e4d3e..f069bead531 100644 --- a/packages/web/src/pages/audio-rewards-page/components/DashboardTokenValueSlider.tsx +++ b/packages/web/src/pages/audio-rewards-page/components/DashboardTokenValueSlider.tsx @@ -1,8 +1,9 @@ import { BNAudio } from '@audius/common/models' import { formatNumberCommas } from '@audius/common/utils' -import { TokenValueSlider } from '@audius/stems' import BN from 'bn.js' +import { TokenValueSlider } from 'components/token-value-slider' + import styles from './DashboardTokenValueSlider.module.css' type DashboardTokenValueSliderProps = { @@ -19,11 +20,8 @@ const MinMaxWrapper = ({ value }: { value: BN }) => { ) } -const DashboardTokenValueSlider = ({ - min, - max, - value -}: DashboardTokenValueSliderProps) => { +const DashboardTokenValueSlider = (props: DashboardTokenValueSliderProps) => { + const { min, max, value } = props return (