diff --git a/package-lock.json b/package-lock.json index 52b182e..bc6aab5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@codex-storage/marketplace-ui-components", - "version": "0.0.40", + "version": "0.0.42", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@codex-storage/marketplace-ui-components", - "version": "0.0.40", + "version": "0.0.42", "license": "MIT", "dependencies": { "lucide-react": "^0.453.0" diff --git a/package.json b/package.json index 7a17395..6f7a107 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "type": "git", "url": "https://github.com/codex-storage/codex-marketplace-ui-components" }, - "version": "0.0.40", + "version": "0.0.41", "type": "module", "scripts": { "prepack": "npm run build", diff --git a/src/assets/icons/close.svg b/src/assets/icons/close.svg new file mode 100644 index 0000000..67824be --- /dev/null +++ b/src/assets/icons/close.svg @@ -0,0 +1,12 @@ + + + diff --git a/src/assets/icons/next.svg b/src/assets/icons/next.svg new file mode 100644 index 0000000..2d7875e --- /dev/null +++ b/src/assets/icons/next.svg @@ -0,0 +1,12 @@ + + + diff --git a/src/assets/icons/previous.svg b/src/assets/icons/previous.svg new file mode 100644 index 0000000..9234e4b --- /dev/null +++ b/src/assets/icons/previous.svg @@ -0,0 +1,12 @@ + + + diff --git a/src/assets/icons/valid.svg b/src/assets/icons/valid.svg new file mode 100644 index 0000000..3de428c --- /dev/null +++ b/src/assets/icons/valid.svg @@ -0,0 +1,16 @@ + + + + diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index fee9dc6..55cb11a 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -33,6 +33,8 @@ type Props = { */ Icon?: ComponentType; + IconAfter?: ComponentType; + /** * Apply custom classname. */ @@ -45,6 +47,7 @@ export function Button({ label, className = "", Icon, + IconAfter, onMouseEnter, onMouseLeave, size = "medium", @@ -65,12 +68,9 @@ export function Button({ "aria-busy": fetching, })} > - {Icon && ( -
- -
- )} + {Icon && } {label} + {IconAfter && } ); } diff --git a/src/components/Button/button.css b/src/components/Button/button.css index b75536b..bd470a3 100644 --- a/src/components/Button/button.css +++ b/src/components/Button/button.css @@ -13,7 +13,7 @@ padding: var(--codex-button-padding); display: flex; place-items: center; - gap: 8px; + gap: 2px; font-weight: 500; position: relative; border: none; @@ -61,8 +61,7 @@ &.button--primary:not(:disabled):hover { cursor: pointer; - box-shadow: 0 0 0 3px - var(--codex-button-color-box-shadow, var(--codex-color-primary-variant)); + box-shadow: 0 0 0 3px var(--codex-button-color-box-shadow, #6fcb94cc); } &.button--outline:not(:disabled):hover { @@ -71,7 +70,7 @@ } &.button--primary { - background-color: var(--codex-color-primary); + background-color: #6fcb94; color: var(--codex-color-on-primary); } diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx index d04182f..65d685f 100644 --- a/src/components/Dropdown/Dropdown.tsx +++ b/src/components/Dropdown/Dropdown.tsx @@ -66,6 +66,8 @@ type Props = { label: string; id: string; + + size?: "big" | "medium"; }; export function Dropdown({ @@ -81,6 +83,7 @@ export function Dropdown({ onSelected, value = "", className = "", + size = "big", }: Props) { const inputRef = useRef(null); const lower = value.toLocaleLowerCase(); @@ -119,12 +122,13 @@ export function Dropdown({ return (
- + {label && }
    {filtered.length ? ( filtered.map((o) => ( -
  • onSelect(o)} key={o.title}> +
  • onSelect(o)} key={o.title + o.subtitle}> {o.Icon && } {o.title} {o.subtitle && {o.subtitle}} diff --git a/src/components/Dropdown/dropdown.css b/src/components/Dropdown/dropdown.css index 87db971..621bfb0 100644 --- a/src/components/Dropdown/dropdown.css +++ b/src/components/Dropdown/dropdown.css @@ -71,10 +71,7 @@ background-position: right 0.5rem center; background-repeat: no-repeat; background-size: 1.25em 1.25em; - - &:focus { - z-index: 11; - } + z-index: 11; } p { diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx index 3c93922..e40b574 100644 --- a/src/components/Modal/Modal.tsx +++ b/src/components/Modal/Modal.tsx @@ -1,8 +1,10 @@ -import { ReactNode, useEffect, useState } from "react"; +import { ComponentType, ReactNode, useEffect, useState } from "react"; import { Backdrop } from "../Backdrop/Backdrop"; import { Button } from "../Button/Button"; import { classnames } from "../utils/classnames"; import "./modal.css"; +import CloseIcon from "../../assets/icons/close.svg?react"; +import { ButtonIcon } from "../ButtonIcon/ButtonIcon"; type Props = { open: boolean; @@ -55,6 +57,10 @@ type Props = { children: ReactNode; className?: string; + + title?: string; + + Icon?: ComponentType<{ width: number | string | undefined }>; }; export function Modal({ @@ -68,6 +74,8 @@ export function Modal({ labelActionButton = "Action", labelCloseButton = "Close", children, + title, + Icon, onAction, }: Props) { const [internalOpen, setInternalOpen] = useState(open); @@ -94,26 +102,43 @@ export function Modal({ + {title && ( +
    +
    + {Icon && } +
    {title}
    +
    + +
    + )} +
    {open && children}
    -
    - {displayCloseButton && ( -
    + {displayActionButton && ( +
); diff --git a/src/components/Modal/modal.css b/src/components/Modal/modal.css index 3105790..eca071f 100644 --- a/src/components/Modal/modal.css +++ b/src/components/Modal/modal.css @@ -3,7 +3,6 @@ transition: transform 0.25s, opacity 0.25s; - max-width: 800px; overflow-y: auto; overflow-x: hidden; opacity: 0; @@ -15,16 +14,54 @@ position: fixed; display: flex; flex-direction: column; - background-color: var(--codex-background); - padding: 1.5rem; - border-radius: var(--codex-border-radius); + background: #232323; + border-radius: 16px; border: none; width: calc(100% - 6rem); - @media (min-width: 801px) { - & { - min-width: 500px; + & { + min-width: 500px; + } + + > header { + padding: 16px; + display: flex; + align-items: center; + justify-content: space-between; + + > div { + display: flex; + gap: 8px; + align-items: center; } + + .button-icon { + background-color: transparent; + border: 1px solid #96969633; + } + + svg { + min-width: 20px; + } + + h6 { + margin: 0; + font-family: Inter; + font-size: 16px; + font-weight: 500; + line-height: 24px; + letter-spacing: -0.011em; + } + } + + > main { + flex: 1; + } + + > footer { + margin-top: 1rem; + display: flex; + justify-content: center; } } @@ -37,16 +74,6 @@ z-index: 10; } - main { - flex: 1; - } - - footer { - margin-top: 1rem; - display: flex; - justify-content: center; - } - &.modal--actions footer { margin-top: 1rem; display: flex; diff --git a/src/components/Stepper/Step.css b/src/components/Stepper/Step.css index 8b2f116..b373553 100644 --- a/src/components/Stepper/Step.css +++ b/src/components/Stepper/Step.css @@ -1,119 +1,124 @@ .step { - display: flex; - align-items: center; - gap: 0.5rem; - transition: opacity 0.35s; - - &:not([disabled]):not(.step--active):hover { - cursor: pointer; - opacity: 0.8; + &:not(:last-child) { + flex: 1; } - @media (min-width: 801px) { - &:not(:last-child) { - flex: 1; - } + --codex-step-background-color: white; + --codex-step-border-color: #e1e4ea; + --codex-step-label-color: #969696; + --codex-step-small-color: #96969699; + --codex-step-hr-color: #96969699; + --codex-step-animation: step-back; + + &.step--done { + --codex-step-background-color: transparent; + --codex-step-border-color: transparent; + --codex-step-small-color: #1fc16b99; + --codex-step-label-color: #1fc16b; + --codex-step-hr-color: #1fc16b; + --codex-step-animation: step; } > div:first-child { - display: flex; - align-items: center; - gap: 0.5rem; - transition: opacity 0.35s; - - width: 1.75rem; - height: 1.75rem; display: flex; align-items: center; justify-content: center; - border-radius: 50%; - transition: background-color 0.35s; - background-color: var( - --codex-stepper-background, - var(--codex-background-light) - ); + gap: 16px; + transition: + box-shadow 0.35s, + background-color 0.35s; + flex: 1; + height: 20px; + position: relative; span { display: flex; align-items: center; justify-content: center; - mix-blend-mode: difference; + background-color: var(--codex-step-background-color); + border: 1px solid var(--codex-step-border-color); + border-radius: 50%; + width: 20px; + height: 20px; + color: #525866; + font-family: Inter; + font-size: 12px; + font-weight: 500; + line-height: 16px; + text-align: center; + cursor: pointer; + transition: box-shadow 0.35s; + + &:hover { + box-shadow: 0 0 0 2px var(--codex-border-color); + } } - } - - &.step--active > div:first-child, - &.step--done > div:first-child { - background-color: var(--codex-color-primary); - } - - div:nth-child(2) { - display: flex; - flex: 1; - position: relative; - place-items: center; hr { border: 0; - height: 1px; + height: 4px; flex: 1; - background-color: var( - --codex-stepper-background, - var(--codex-background-light) - ); + background-color: #969696; + border-radius: 40px; position: relative; margin-bottom: 8px; - @media (max-width: 800px) { - & { - display: none; - } + &::before { + background-color: var(--codex-step-hr-color); + height: 4px; + content: " "; + position: absolute; + z-index: 1; + animation-duration: 1s; + animation-name: var(--codex-step-animation); + animation-fill-mode: forwards; + border-radius: 40px; } } + } - &::before { - background-color: var(--codex-color-primary); - height: 1px; - content: " "; - position: absolute; - top: 8px; - animation-duration: 1s; - animation-name: step-back; - animation-fill-mode: forwards; - opacity: 0; - /* animation-direction: reverse; */ + > div:nth-child(2) { + display: block; + padding-left: 38px; + + small { + font-family: Inter; + font-size: 8px; + font-weight: 700; + line-height: 8px; + text-align: left; + color: var(--codex-step-small-color); + display: block; } span { - position: absolute; - top: 10px; + font-family: Inter; font-size: 14px; - - @media (max-width: 800px) { - & { - display: none; - } - } - } - } - - &.step--done { - div:nth-child(2) { - &::before { - background-color: var(--codex-color-primary); - display: inline-block; - animation-duration: 1s; - animation-name: step; - animation-fill-mode: forwards; - opacity: 1; - } - } - } - - &.step--mounted { - div:nth-child(2) { - &::before { - opacity: 1; - } + font-weight: 400; + line-height: 20px; + letter-spacing: -0.006em; + text-align: left; + color: var(--codex-step-label-color); } } } + +@keyframes step-back { + 0% { + width: 100%; + } + + 100% { + width: 0%; + } +} + +@keyframes step { + 0% { + width: 0; + } + + 100% { + width: 100%; + } +} diff --git a/src/components/Stepper/Step.tsx b/src/components/Stepper/Step.tsx index 2a557e9..3721283 100644 --- a/src/components/Stepper/Step.tsx +++ b/src/components/Stepper/Step.tsx @@ -1,8 +1,8 @@ -import { Check } from "lucide-react"; import { useEffect, useRef } from "react"; import { attributes } from "../utils/attributes"; import { classnames } from "../utils/classnames"; import "./Step.css"; +import ValidIcon from "../../assets/icons/valid.svg?react"; type StepProps = { /** @@ -34,6 +34,8 @@ type StepProps = { * Event triggered when a step number is clicked on */ onClick?: (step: number) => void; + + index: number; }; export function Step({ @@ -42,6 +44,7 @@ export function Step({ isLast, isDone, title, + index, onClick, }: StepProps) { const mounted = useRef(false); @@ -62,12 +65,13 @@ export function Step({ {...attributes({ disabled: !onClick })} >
- {isDone ? : step + 1} + {isDone ? : step + 1} +
{!isLast && (
-
+ STEP {index} {title}
)} diff --git a/src/components/Stepper/Stepper.tsx b/src/components/Stepper/Stepper.tsx index cbbf783..ba1f6bb 100644 --- a/src/components/Stepper/Stepper.tsx +++ b/src/components/Stepper/Stepper.tsx @@ -5,6 +5,8 @@ import { Spinner } from "../Spinner/Spinner"; import { Step } from "./Step"; import { StepperAction, StepperState } from "./useStepperReducer"; import { classnames } from "../utils/classnames"; +import PreviousIcon from "../../assets/icons/previous.svg?react"; +import NextIcon from "../../assets/icons/next.svg?react"; type Props = { /** @@ -94,6 +96,7 @@ export function Stepper({
{titles.map((title, index) => ( onChangeStep(state.step - 1)} disabled={!state.isBackEnable} + Icon={PreviousIcon} />
diff --git a/src/components/Stepper/stepper.css b/src/components/Stepper/stepper.css index ba6e342..4a06af1 100644 --- a/src/components/Stepper/stepper.css +++ b/src/components/Stepper/stepper.css @@ -1,34 +1,21 @@ .stepper { display: flex; flex-direction: column; - background-color: var(--codex-background); - border-radius: var(--codex-border-radius); + padding: 16px; - header { + > header { display: flex; - align-items: center; - gap: 0.5rem; - transition: opacity 0.35s; + align-items: flex-start; + gap: 16px; + border-bottom: 1px solid #96969633; + padding-bottom: 16px; } - main { - margin: 1.5rem 0; - border: 1px dashed var(--codex-border-color); - border-radius: var(--codex-border-radius); - background-color: var( - --codex-stepper-background, - var(--codex-background-light) - ); - min-height: 200px; - padding: 1.5rem; + > main { display: flex; flex-direction: column; - - @media (min-width: 801px) { - & { - min-width: 500px; - } - } + min-height: 200px; + min-width: 500px; } &.stepper--progress { @@ -42,25 +29,9 @@ footer { display: flex; justify-content: space-between; - } -} - -@keyframes step { - 0% { - width: 0; - } - - 100% { - width: 100%; - } -} - -@keyframes step-back { - 0% { - width: 100%; - } - - 100% { - width: 0%; + + .button { + width: 105px; + } } } diff --git a/src/components/Tooltip/Tooltip.css b/src/components/Tooltip/Tooltip.css index 87e3fc3..1c18c17 100644 --- a/src/components/Tooltip/Tooltip.css +++ b/src/components/Tooltip/Tooltip.css @@ -18,8 +18,8 @@ text-align: center; font-size: 0.85rem; padding: 0.5rem; - bottom: 140%; - left: -140%; + bottom: 30px; + right: 0; } @keyframes tooltip { diff --git a/stories/Modal.stories.tsx b/stories/Modal.stories.tsx index ab03f93..5937f61 100644 --- a/stories/Modal.stories.tsx +++ b/stories/Modal.stories.tsx @@ -35,10 +35,32 @@ const Template = (props: Props) => { setOpen(false); }; + const Icon = () => ( + + + + + + + + + + + ); + return (
- +

Hello world

diff --git a/stories/Stepper.stories.css b/stories/Stepper.stories.css index 71c8a7c..e69de29 100644 --- a/stories/Stepper.stories.css +++ b/stories/Stepper.stories.css @@ -1,3 +0,0 @@ -.stepper-padding { - padding: 1.5rem; -}