Improvements for design integration
This commit is contained in:
parent
001d008a27
commit
3281ec5c9d
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@codex-storage/marketplace-ui-components",
|
"name": "@codex-storage/marketplace-ui-components",
|
||||||
"version": "0.0.40",
|
"version": "0.0.42",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@codex-storage/marketplace-ui-components",
|
"name": "@codex-storage/marketplace-ui-components",
|
||||||
"version": "0.0.40",
|
"version": "0.0.42",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lucide-react": "^0.453.0"
|
"lucide-react": "^0.453.0"
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/codex-storage/codex-marketplace-ui-components"
|
"url": "https://github.com/codex-storage/codex-marketplace-ui-components"
|
||||||
},
|
},
|
||||||
"version": "0.0.40",
|
"version": "0.0.41",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepack": "npm run build",
|
"prepack": "npm run build",
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M10.0001 8.93955L13.7126 5.22705L14.7731 6.28755L11.0606 10.0001L14.7731 13.7126L13.7126 14.7731L10.0001 11.0606L6.28755 14.7731L5.22705 13.7126L8.93955 10.0001L5.22705 6.28755L6.28755 5.22705L10.0001 8.93955Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 362 B |
|
@ -0,0 +1,12 @@
|
||||||
|
<svg
|
||||||
|
width="21"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 21 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M11.2958 9.99907L7.58325 6.28657L8.64375 5.22607L13.4168 9.99907L8.64375 14.7721L7.58325 13.7116L11.2958 9.99907Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 266 B |
|
@ -0,0 +1,12 @@
|
||||||
|
<svg
|
||||||
|
width="21"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 21 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M9.70425 9.99907L13.4168 13.7116L12.3563 14.7721L7.58325 9.99907L12.3563 5.22607L13.4168 6.28657L9.70425 9.99907Z"
|
||||||
|
fill="#969696"
|
||||||
|
/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 268 B |
|
@ -0,0 +1,16 @@
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M0 10C0 4.47715 4.47715 0 10 0C15.5228 0 20 4.47715 20 10C20 15.5228 15.5228 20 10 20C4.47715 20 0 15.5228 0 10Z"
|
||||||
|
fill="#1FC16B"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M15.0999 7.45336L8.72547 13.8202L4.8999 9.99973L6.17479 8.72654L8.72547 11.2738L13.825 6.18018L15.0999 7.45336Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 417 B |
|
@ -33,6 +33,8 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
Icon?: ComponentType;
|
Icon?: ComponentType;
|
||||||
|
|
||||||
|
IconAfter?: ComponentType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply custom classname.
|
* Apply custom classname.
|
||||||
*/
|
*/
|
||||||
|
@ -45,6 +47,7 @@ export function Button({
|
||||||
label,
|
label,
|
||||||
className = "",
|
className = "",
|
||||||
Icon,
|
Icon,
|
||||||
|
IconAfter,
|
||||||
onMouseEnter,
|
onMouseEnter,
|
||||||
onMouseLeave,
|
onMouseLeave,
|
||||||
size = "medium",
|
size = "medium",
|
||||||
|
@ -65,12 +68,9 @@ export function Button({
|
||||||
"aria-busy": fetching,
|
"aria-busy": fetching,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{Icon && (
|
{Icon && <Icon />}
|
||||||
<div>
|
|
||||||
<Icon />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<span>{label}</span>
|
<span>{label}</span>
|
||||||
|
{IconAfter && <IconAfter />}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
padding: var(--codex-button-padding);
|
padding: var(--codex-button-padding);
|
||||||
display: flex;
|
display: flex;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
gap: 8px;
|
gap: 2px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
position: relative;
|
position: relative;
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -61,8 +61,7 @@
|
||||||
|
|
||||||
&.button--primary:not(:disabled):hover {
|
&.button--primary:not(:disabled):hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: 0 0 0 3px
|
box-shadow: 0 0 0 3px var(--codex-button-color-box-shadow, #6fcb94cc);
|
||||||
var(--codex-button-color-box-shadow, var(--codex-color-primary-variant));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.button--outline:not(:disabled):hover {
|
&.button--outline:not(:disabled):hover {
|
||||||
|
@ -71,7 +70,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.button--primary {
|
&.button--primary {
|
||||||
background-color: var(--codex-color-primary);
|
background-color: #6fcb94;
|
||||||
color: var(--codex-color-on-primary);
|
color: var(--codex-color-on-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,8 @@ type Props = {
|
||||||
label: string;
|
label: string;
|
||||||
|
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
|
size?: "big" | "medium";
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Dropdown({
|
export function Dropdown({
|
||||||
|
@ -81,6 +83,7 @@ export function Dropdown({
|
||||||
onSelected,
|
onSelected,
|
||||||
value = "",
|
value = "",
|
||||||
className = "",
|
className = "",
|
||||||
|
size = "big",
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const lower = value.toLocaleLowerCase();
|
const lower = value.toLocaleLowerCase();
|
||||||
|
@ -119,12 +122,13 @@ export function Dropdown({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"dropdown " + className}>
|
<div className={"dropdown " + className}>
|
||||||
<label htmlFor={id}>{label}</label>
|
{label && <label htmlFor={id}>{label}</label>}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Backdrop onClose={onClose} open={focused} />
|
<Backdrop onClose={onClose} open={focused} />
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
|
autoComplete="off"
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
onFocus={onInternalFocus}
|
onFocus={onInternalFocus}
|
||||||
|
@ -136,12 +140,13 @@ export function Dropdown({
|
||||||
value={value}
|
value={value}
|
||||||
label={""}
|
label={""}
|
||||||
id={id}
|
id={id}
|
||||||
|
size={size as any}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ul {...attr}>
|
<ul {...attr}>
|
||||||
{filtered.length ? (
|
{filtered.length ? (
|
||||||
filtered.map((o) => (
|
filtered.map((o) => (
|
||||||
<li onClick={() => onSelect(o)} key={o.title}>
|
<li onClick={() => onSelect(o)} key={o.title + o.subtitle}>
|
||||||
{o.Icon && <o.Icon />}
|
{o.Icon && <o.Icon />}
|
||||||
<span>{o.title}</span>
|
<span>{o.title}</span>
|
||||||
{o.subtitle && <span>{o.subtitle}</span>}
|
{o.subtitle && <span>{o.subtitle}</span>}
|
||||||
|
|
|
@ -71,10 +71,7 @@
|
||||||
background-position: right 0.5rem center;
|
background-position: right 0.5rem center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 1.25em 1.25em;
|
background-size: 1.25em 1.25em;
|
||||||
|
z-index: 11;
|
||||||
&:focus {
|
|
||||||
z-index: 11;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { ReactNode, useEffect, useState } from "react";
|
import { ComponentType, ReactNode, useEffect, useState } from "react";
|
||||||
import { Backdrop } from "../Backdrop/Backdrop";
|
import { Backdrop } from "../Backdrop/Backdrop";
|
||||||
import { Button } from "../Button/Button";
|
import { Button } from "../Button/Button";
|
||||||
import { classnames } from "../utils/classnames";
|
import { classnames } from "../utils/classnames";
|
||||||
import "./modal.css";
|
import "./modal.css";
|
||||||
|
import CloseIcon from "../../assets/icons/close.svg?react";
|
||||||
|
import { ButtonIcon } from "../ButtonIcon/ButtonIcon";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
|
@ -55,6 +57,10 @@ type Props = {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
||||||
|
title?: string;
|
||||||
|
|
||||||
|
Icon?: ComponentType<{ width: number | string | undefined }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Modal({
|
export function Modal({
|
||||||
|
@ -68,6 +74,8 @@ export function Modal({
|
||||||
labelActionButton = "Action",
|
labelActionButton = "Action",
|
||||||
labelCloseButton = "Close",
|
labelCloseButton = "Close",
|
||||||
children,
|
children,
|
||||||
|
title,
|
||||||
|
Icon,
|
||||||
onAction,
|
onAction,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const [internalOpen, setInternalOpen] = useState(open);
|
const [internalOpen, setInternalOpen] = useState(open);
|
||||||
|
@ -94,26 +102,43 @@ export function Modal({
|
||||||
<Backdrop open={internalOpen} onClose={internalClose} />
|
<Backdrop open={internalOpen} onClose={internalClose} />
|
||||||
|
|
||||||
<dialog>
|
<dialog>
|
||||||
|
{title && (
|
||||||
|
<header>
|
||||||
|
<div>
|
||||||
|
{Icon && <Icon width={24}></Icon>}
|
||||||
|
<h6>{title}</h6>
|
||||||
|
</div>
|
||||||
|
<ButtonIcon
|
||||||
|
onClick={internalClose}
|
||||||
|
Icon={CloseIcon}
|
||||||
|
variant="small"
|
||||||
|
></ButtonIcon>
|
||||||
|
</header>
|
||||||
|
)}
|
||||||
|
|
||||||
<main>{open && children}</main>
|
<main>{open && children}</main>
|
||||||
|
|
||||||
<footer>
|
{displayCloseButton ||
|
||||||
{displayCloseButton && (
|
(displayActionButton && (
|
||||||
<Button
|
<footer>
|
||||||
label={labelCloseButton}
|
{displayCloseButton && (
|
||||||
variant="outline"
|
<Button
|
||||||
onClick={internalClose}
|
label={labelCloseButton}
|
||||||
disabled={disableCloseButton}
|
variant="outline"
|
||||||
/>
|
onClick={internalClose}
|
||||||
)}
|
disabled={disableCloseButton}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{displayActionButton && (
|
{displayActionButton && (
|
||||||
<Button
|
<Button
|
||||||
label={labelActionButton}
|
label={labelActionButton}
|
||||||
onClick={onAction}
|
onClick={onAction}
|
||||||
disabled={disableActionButton}
|
disabled={disableActionButton}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</footer>
|
</footer>
|
||||||
|
))}
|
||||||
</dialog>
|
</dialog>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
transition:
|
transition:
|
||||||
transform 0.25s,
|
transform 0.25s,
|
||||||
opacity 0.25s;
|
opacity 0.25s;
|
||||||
max-width: 800px;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
@ -15,16 +14,54 @@
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: var(--codex-background);
|
background: #232323;
|
||||||
padding: 1.5rem;
|
border-radius: 16px;
|
||||||
border-radius: var(--codex-border-radius);
|
|
||||||
border: none;
|
border: none;
|
||||||
width: calc(100% - 6rem);
|
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;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
margin-top: 1rem;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.modal--actions footer {
|
&.modal--actions footer {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,119 +1,124 @@
|
||||||
.step {
|
.step {
|
||||||
display: flex;
|
&:not(:last-child) {
|
||||||
align-items: center;
|
flex: 1;
|
||||||
gap: 0.5rem;
|
|
||||||
transition: opacity 0.35s;
|
|
||||||
|
|
||||||
&:not([disabled]):not(.step--active):hover {
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 801px) {
|
--codex-step-background-color: white;
|
||||||
&:not(:last-child) {
|
--codex-step-border-color: #e1e4ea;
|
||||||
flex: 1;
|
--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 {
|
> div:first-child {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.5rem;
|
|
||||||
transition: opacity 0.35s;
|
|
||||||
|
|
||||||
width: 1.75rem;
|
|
||||||
height: 1.75rem;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-radius: 50%;
|
gap: 16px;
|
||||||
transition: background-color 0.35s;
|
transition:
|
||||||
background-color: var(
|
box-shadow 0.35s,
|
||||||
--codex-stepper-background,
|
background-color 0.35s;
|
||||||
var(--codex-background-light)
|
flex: 1;
|
||||||
);
|
height: 20px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: 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 {
|
hr {
|
||||||
border: 0;
|
border: 0;
|
||||||
height: 1px;
|
height: 4px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background-color: var(
|
background-color: #969696;
|
||||||
--codex-stepper-background,
|
border-radius: 40px;
|
||||||
var(--codex-background-light)
|
|
||||||
);
|
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
&::before {
|
||||||
& {
|
background-color: var(--codex-step-hr-color);
|
||||||
display: none;
|
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 {
|
> div:nth-child(2) {
|
||||||
background-color: var(--codex-color-primary);
|
display: block;
|
||||||
height: 1px;
|
padding-left: 38px;
|
||||||
content: " ";
|
|
||||||
position: absolute;
|
small {
|
||||||
top: 8px;
|
font-family: Inter;
|
||||||
animation-duration: 1s;
|
font-size: 8px;
|
||||||
animation-name: step-back;
|
font-weight: 700;
|
||||||
animation-fill-mode: forwards;
|
line-height: 8px;
|
||||||
opacity: 0;
|
text-align: left;
|
||||||
/* animation-direction: reverse; */
|
color: var(--codex-step-small-color);
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
position: absolute;
|
font-family: Inter;
|
||||||
top: 10px;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
@media (max-width: 800px) {
|
line-height: 20px;
|
||||||
& {
|
letter-spacing: -0.006em;
|
||||||
display: none;
|
text-align: left;
|
||||||
}
|
color: var(--codex-step-label-color);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes step-back {
|
||||||
|
0% {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
width: 0%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes step {
|
||||||
|
0% {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { Check } from "lucide-react";
|
|
||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import { attributes } from "../utils/attributes";
|
import { attributes } from "../utils/attributes";
|
||||||
import { classnames } from "../utils/classnames";
|
import { classnames } from "../utils/classnames";
|
||||||
import "./Step.css";
|
import "./Step.css";
|
||||||
|
import ValidIcon from "../../assets/icons/valid.svg?react";
|
||||||
|
|
||||||
type StepProps = {
|
type StepProps = {
|
||||||
/**
|
/**
|
||||||
|
@ -34,6 +34,8 @@ type StepProps = {
|
||||||
* Event triggered when a step number is clicked on
|
* Event triggered when a step number is clicked on
|
||||||
*/
|
*/
|
||||||
onClick?: (step: number) => void;
|
onClick?: (step: number) => void;
|
||||||
|
|
||||||
|
index: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Step({
|
export function Step({
|
||||||
|
@ -42,6 +44,7 @@ export function Step({
|
||||||
isLast,
|
isLast,
|
||||||
isDone,
|
isDone,
|
||||||
title,
|
title,
|
||||||
|
index,
|
||||||
onClick,
|
onClick,
|
||||||
}: StepProps) {
|
}: StepProps) {
|
||||||
const mounted = useRef(false);
|
const mounted = useRef(false);
|
||||||
|
@ -62,12 +65,13 @@ export function Step({
|
||||||
{...attributes({ disabled: !onClick })}
|
{...attributes({ disabled: !onClick })}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<span>{isDone ? <Check size={"1.25rem"} /> : step + 1}</span>
|
<span>{isDone ? <ValidIcon /> : step + 1}</span>
|
||||||
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!isLast && (
|
{!isLast && (
|
||||||
<div>
|
<div>
|
||||||
<hr />
|
<small>STEP {index}</small>
|
||||||
<span>{title}</span>
|
<span>{title}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import { Spinner } from "../Spinner/Spinner";
|
||||||
import { Step } from "./Step";
|
import { Step } from "./Step";
|
||||||
import { StepperAction, StepperState } from "./useStepperReducer";
|
import { StepperAction, StepperState } from "./useStepperReducer";
|
||||||
import { classnames } from "../utils/classnames";
|
import { classnames } from "../utils/classnames";
|
||||||
|
import PreviousIcon from "../../assets/icons/previous.svg?react";
|
||||||
|
import NextIcon from "../../assets/icons/next.svg?react";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
/**
|
/**
|
||||||
|
@ -94,6 +96,7 @@ export function Stepper({
|
||||||
<header>
|
<header>
|
||||||
{titles.map((title, index) => (
|
{titles.map((title, index) => (
|
||||||
<Step
|
<Step
|
||||||
|
index={index + 1}
|
||||||
title={title}
|
title={title}
|
||||||
step={index}
|
step={index}
|
||||||
isActive={index === state.step}
|
isActive={index === state.step}
|
||||||
|
@ -115,11 +118,13 @@ export function Stepper({
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => onChangeStep(state.step - 1)}
|
onClick={() => onChangeStep(state.step - 1)}
|
||||||
disabled={!state.isBackEnable}
|
disabled={!state.isBackEnable}
|
||||||
|
Icon={PreviousIcon}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
label={nextLabel}
|
label={nextLabel}
|
||||||
onClick={() => onChangeStep(state.step + 1)}
|
onClick={() => onChangeStep(state.step + 1)}
|
||||||
disabled={!state.isNextEnable}
|
disabled={!state.isNextEnable}
|
||||||
|
IconAfter={NextIcon}
|
||||||
/>
|
/>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,34 +1,21 @@
|
||||||
.stepper {
|
.stepper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: var(--codex-background);
|
padding: 16px;
|
||||||
border-radius: var(--codex-border-radius);
|
|
||||||
|
|
||||||
header {
|
> header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
gap: 0.5rem;
|
gap: 16px;
|
||||||
transition: opacity 0.35s;
|
border-bottom: 1px solid #96969633;
|
||||||
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
> 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;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
min-height: 200px;
|
||||||
@media (min-width: 801px) {
|
min-width: 500px;
|
||||||
& {
|
|
||||||
min-width: 500px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.stepper--progress {
|
&.stepper--progress {
|
||||||
|
@ -42,25 +29,9 @@
|
||||||
footer {
|
footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
|
||||||
}
|
.button {
|
||||||
|
width: 105px;
|
||||||
@keyframes step {
|
}
|
||||||
0% {
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes step-back {
|
|
||||||
0% {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
width: 0%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
bottom: 140%;
|
bottom: 30px;
|
||||||
left: -140%;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes tooltip {
|
@keyframes tooltip {
|
||||||
|
|
|
@ -35,10 +35,32 @@ const Template = (props: Props) => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Icon = () => (
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="10"
|
||||||
|
viewBox="0 0 20 10"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g clipPath="url(#clip0_326_785)">
|
||||||
|
<path
|
||||||
|
d="M14.1666 7.91667L9.99992 3.75L5.83325 7.91667H14.1666ZM14.1666 12.0833L9.99992 16.25L5.83325 12.0833H14.1666Z"
|
||||||
|
fill="#969696"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_326_785">
|
||||||
|
<rect width="20" height="10" fill="white" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: "6rem" }}>
|
<div style={{ padding: "6rem" }}>
|
||||||
<button onClick={onOpen}>Make Modal</button>
|
<button onClick={onOpen}>Make Modal</button>
|
||||||
<Modal onClose={onClose} open={open}>
|
<Modal title="Title" Icon={Icon} onClose={onClose} open={open}>
|
||||||
<p>Hello world</p>
|
<p>Hello world</p>
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
.stepper-padding {
|
|
||||||
padding: 1.5rem;
|
|
||||||
}
|
|
Loading…
Reference in New Issue