Enhance toast component and update the dependencies
This commit is contained in:
parent
79cfe9755d
commit
2f3c51c7d3
16
README.md
16
README.md
|
@ -45,22 +45,6 @@ npm run preview
|
||||||
|
|
||||||
### Components
|
### Components
|
||||||
|
|
||||||
In order to build the components library you need for to clone the [Codex SDK](https://github.com/codex-storage/codex-js) (it's currently in early stage so it is not published yet to the npm registry).
|
|
||||||
|
|
||||||
Follow the instructions to install and build the SDK, then run this command in the SDK repository:
|
|
||||||
|
|
||||||
```
|
|
||||||
npm link
|
|
||||||
```
|
|
||||||
|
|
||||||
Now in the current repository, you'll we able to link your local SDK build by running:
|
|
||||||
|
|
||||||
```
|
|
||||||
npm link @codex/sdk-js
|
|
||||||
```
|
|
||||||
|
|
||||||
You can finally build the Components by running:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "@codex/marketplace-ui-components",
|
"name": "@codex-storage/marketplace-ui-components",
|
||||||
"description": "Marketplace UI components for Codex decentralized storage network.",
|
"description": "Marketplace UI components for Codex decentralized storage network.",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -35,14 +35,13 @@
|
||||||
"lucide-react": "^0.428.0"
|
"lucide-react": "^0.428.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@codex/sdk-js": "@codex/sdk-js#master",
|
"@codex-storage/sdk-js": "0.0.1",
|
||||||
"@tanstack/react-query": "^5.51.24",
|
"@tanstack/react-query": "^5.51.24",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1"
|
"react-dom": "^18.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@chromatic-com/storybook": "^1.6.1",
|
"@chromatic-com/storybook": "^1.6.1",
|
||||||
"@codex/sdk-js": "@codex/sdk-js#master",
|
|
||||||
"@storybook/addon-essentials": "^8.2.9",
|
"@storybook/addon-essentials": "^8.2.9",
|
||||||
"@storybook/addon-interactions": "^8.2.9",
|
"@storybook/addon-interactions": "^8.2.9",
|
||||||
"@storybook/addon-links": "^8.2.9",
|
"@storybook/addon-links": "^8.2.9",
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
import {
|
import { CSSProperties, useEffect, useRef, useState } from "react";
|
||||||
ComponentType,
|
|
||||||
CSSProperties,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from "react";
|
|
||||||
import { attributes } from "../utils/attributes";
|
import { attributes } from "../utils/attributes";
|
||||||
import "./toast.css";
|
import "./toast.css";
|
||||||
import { X } from "lucide-react";
|
import { CircleCheck, CircleX, Info, X } from "lucide-react";
|
||||||
import { ButtonIcon } from "../ButtonIcon/ButtonIcon";
|
import { ButtonIcon } from "../ButtonIcon/ButtonIcon";
|
||||||
|
|
||||||
interface CustomStyleCSS extends CSSProperties {
|
interface CustomStyleCSS extends CSSProperties {
|
||||||
|
@ -34,11 +28,6 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
duration?: number;
|
duration?: number;
|
||||||
|
|
||||||
/**
|
|
||||||
* Icon displayed on the left of the toast
|
|
||||||
*/
|
|
||||||
Icon: ComponentType;
|
|
||||||
|
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,13 +38,15 @@ type Props = {
|
||||||
* codex-toast-color
|
* codex-toast-color
|
||||||
*/
|
*/
|
||||||
style?: CustomStyleCSS;
|
style?: CustomStyleCSS;
|
||||||
|
|
||||||
|
variant: "success" | "error" | "default";
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Toast({
|
export function Toast({
|
||||||
message,
|
message,
|
||||||
time,
|
time,
|
||||||
Icon,
|
|
||||||
style,
|
style,
|
||||||
|
variant,
|
||||||
className = "",
|
className = "",
|
||||||
duration = 3000,
|
duration = 3000,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
|
@ -82,15 +73,23 @@ export function Toast({
|
||||||
setMsg("");
|
setMsg("");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const icons = {
|
||||||
|
success: CircleCheck,
|
||||||
|
error: CircleX,
|
||||||
|
default: Info,
|
||||||
|
};
|
||||||
|
const Icon = icons[variant];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`toast ${className}`}
|
className={`toast ${className} toast--${variant}`}
|
||||||
{...attributes({ "aria-hidden": time == 0 || msg === "" })}
|
{...attributes({ "aria-hidden": time == 0 || msg === "" })}
|
||||||
style={style}
|
style={style}
|
||||||
>
|
>
|
||||||
<Icon />
|
<Icon size="1.25rem" className="toast-icon" />
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
<b>Success ! </b>
|
<b className="toast-title">{variant} ! </b>
|
||||||
<span>{msg}</span>
|
<span>{msg}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
padding-left: 1.5rem;
|
padding-left: 1.5rem;
|
||||||
color: var(--codex-toast-color, --codex-color);
|
color: var(--codex-toast-color, --codex-color);
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
|
border: 1px solid rgb(var(--codex-toast-color));
|
||||||
|
background: rgba(var(--codex-toast-color), 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast-close {
|
.toast-close {
|
||||||
|
@ -24,3 +26,24 @@
|
||||||
.toast[aria-hidden] {
|
.toast[aria-hidden] {
|
||||||
transform: translateX(1000px);
|
transform: translateX(1000px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toast-title {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-icon {
|
||||||
|
fill: rgba(var(--codex-toast-color), 0.2);
|
||||||
|
stroke: rgb(var(--codex-toast-color));
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast--success {
|
||||||
|
--codex-toast-color: var(--codex-color-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast--error {
|
||||||
|
--codex-toast-color: var(--codex-color-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast--default {
|
||||||
|
--codex-toast-color: var(--codex-color-grey);
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { UploadFile } from "./UploadFile.tsx";
|
||||||
import { useUploadStategy } from "./useUploadStrategy.ts";
|
import { useUploadStategy } from "./useUploadStrategy.ts";
|
||||||
import { classnames } from "../utils/classnames.ts";
|
import { classnames } from "../utils/classnames.ts";
|
||||||
import { ButtonIcon } from "../ButtonIcon/ButtonIcon.tsx";
|
import { ButtonIcon } from "../ButtonIcon/ButtonIcon.tsx";
|
||||||
import { CodexData, UploadResponse } from "@codex/sdk-js";
|
import { CodexData, UploadResponse } from "@codex-storage/sdk-js";
|
||||||
import { SimpleText } from "../SimpleText/SimpleText.tsx";
|
import { SimpleText } from "../SimpleText/SimpleText.tsx";
|
||||||
|
|
||||||
interface CustomStyleCSS extends CSSProperties {
|
interface CustomStyleCSS extends CSSProperties {
|
||||||
|
|
|
@ -10,16 +10,10 @@ import { attributes } from "../utils/attributes";
|
||||||
import { PrettyBytes } from "../utils/bytes";
|
import { PrettyBytes } from "../utils/bytes";
|
||||||
import { Toast } from "../Toast/Toast";
|
import { Toast } from "../Toast/Toast";
|
||||||
import { UploadStatus } from "./types";
|
import { UploadStatus } from "./types";
|
||||||
import {
|
import { CircleCheck, TriangleAlert, CircleX, CircleStop } from "lucide-react";
|
||||||
CircleCheck,
|
|
||||||
TriangleAlert,
|
|
||||||
CircleX,
|
|
||||||
CircleStop,
|
|
||||||
Info,
|
|
||||||
} from "lucide-react";
|
|
||||||
import { Spinner } from "../Spinner/Spinner";
|
import { Spinner } from "../Spinner/Spinner";
|
||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import { CodexData } from "@codex/sdk-js";
|
import { CodexData } from "@codex-storage/sdk-js";
|
||||||
import { WebFileIcon } from "../WebFileIcon/WebFileIcon";
|
import { WebFileIcon } from "../WebFileIcon/WebFileIcon";
|
||||||
import { ButtonIcon } from "../ButtonIcon/ButtonIcon";
|
import { ButtonIcon } from "../ButtonIcon/ButtonIcon";
|
||||||
import { SimpleText } from "../SimpleText/SimpleText";
|
import { SimpleText } from "../SimpleText/SimpleText";
|
||||||
|
@ -361,7 +355,7 @@ export function UploadFile({
|
||||||
|
|
||||||
{error && <SimpleText variant="error">{error}</SimpleText>}
|
{error && <SimpleText variant="error">{error}</SimpleText>}
|
||||||
|
|
||||||
<Toast message={toast.message} time={toast.time} Icon={Info} />
|
<Toast message={toast.message} time={toast.time} variant="success" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Codex } from "@codex/sdk-js";
|
import { Codex } from "@codex-storage/sdk-js";
|
||||||
|
|
||||||
const codex = new Codex(import.meta.env.VITE_CODEX_API_URL);
|
const codex = new Codex(import.meta.env.VITE_CODEX_API_URL);
|
||||||
let abort: () => void;
|
let abort: () => void;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import type { Meta } from "@storybook/react";
|
import type { Meta } from "@storybook/react";
|
||||||
import { CircleCheck } from "lucide-react";
|
|
||||||
import { Toast } from "../src/components/Toast/Toast";
|
import { Toast } from "../src/components/Toast/Toast";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
|
@ -27,14 +26,7 @@ const Template = () => {
|
||||||
<div style={{ padding: "2rem" }}>
|
<div style={{ padding: "2rem" }}>
|
||||||
<button onClick={onClick}>Make Toast</button>
|
<button onClick={onClick}>Make Toast</button>
|
||||||
<Toast
|
<Toast
|
||||||
Icon={() => (
|
variant="success"
|
||||||
<CircleCheck
|
|
||||||
size="1.25rem"
|
|
||||||
fill="var(--codex-color-primary"
|
|
||||||
className="primary upload-progress-check"
|
|
||||||
stroke="var(--codex-background)"
|
|
||||||
></CircleCheck>
|
|
||||||
)}
|
|
||||||
message="Toast displayed with success"
|
message="Toast displayed with success"
|
||||||
time={time}
|
time={time}
|
||||||
/>
|
/>
|
||||||
|
@ -42,4 +34,38 @@ const Template = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Default = Template.bind({});
|
export const Success = Template.bind({});
|
||||||
|
|
||||||
|
const ErrorTemplate = () => {
|
||||||
|
const [time, setTime] = useState(0);
|
||||||
|
|
||||||
|
const onClick = () => setTime(Date.now());
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: "2rem" }}>
|
||||||
|
<button onClick={onClick}>Make Toast</button>
|
||||||
|
<Toast variant="error" message="Toast displayed with error" time={time} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Error = ErrorTemplate.bind({});
|
||||||
|
|
||||||
|
const DefaultTemplate = () => {
|
||||||
|
const [time, setTime] = useState(0);
|
||||||
|
|
||||||
|
const onClick = () => setTime(Date.now());
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: "2rem" }}>
|
||||||
|
<button onClick={onClick}>Make Toast</button>
|
||||||
|
<Toast
|
||||||
|
variant="default"
|
||||||
|
message="Toast displayed with default"
|
||||||
|
time={time}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Default = DefaultTemplate.bind({});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { Meta } from "@storybook/react";
|
import type { Meta } from "@storybook/react";
|
||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { UploadResponse } from "@codex/sdk-js";
|
import { UploadResponse } from "@codex-storage/sdk-js";
|
||||||
import { Upload } from "../src/components/Upload/Upload";
|
import { Upload } from "../src/components/Upload/Upload";
|
||||||
import { fn } from "@storybook/test";
|
import { fn } from "@storybook/test";
|
||||||
import "./Upload.stories.css";
|
import "./Upload.stories.css";
|
||||||
|
|
|
@ -6,10 +6,10 @@ export default defineConfig({
|
||||||
plugins: [react({ jsxRuntime: "automatic" })],
|
plugins: [react({ jsxRuntime: "automatic" })],
|
||||||
worker: {
|
worker: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: ["@codex/sdk-js"],
|
external: ["@codex-storage/sdk-js"],
|
||||||
output: {
|
output: {
|
||||||
globals: {
|
globals: {
|
||||||
"@codex/sdk-js": "codex-sdk-js",
|
"@codex-storage/sdk-js": "codex-sdk-js",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,10 +12,10 @@ const { glob } = pkg;
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
worker: {
|
worker: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: ["@codex/sdk-js", "@tanstack/react-query"],
|
external: ["@codex-storage/sdk-js", "@tanstack/react-query"],
|
||||||
output: {
|
output: {
|
||||||
globals: {
|
globals: {
|
||||||
"@codex/sdk-js": "codex-sdk-js",
|
"@codex-storage/sdk-js": "codex-sdk-js",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -37,7 +37,7 @@ export default defineConfig({
|
||||||
external: [
|
external: [
|
||||||
"react",
|
"react",
|
||||||
"react/jsx-runtime",
|
"react/jsx-runtime",
|
||||||
"@codex/sdk-js",
|
"@codex-storage/sdk-js",
|
||||||
"@tanstack/react-query",
|
"@tanstack/react-query",
|
||||||
],
|
],
|
||||||
input: Object.fromEntries(
|
input: Object.fromEntries(
|
||||||
|
@ -58,7 +58,7 @@ export default defineConfig({
|
||||||
assetFileNames: "assets/[name][extname]",
|
assetFileNames: "assets/[name][extname]",
|
||||||
entryFileNames: "[name].js",
|
entryFileNames: "[name].js",
|
||||||
globals: {
|
globals: {
|
||||||
"@codex/sdk-js": "codex-sdk-js",
|
"@codex-storage/sdk-js": "codex-sdk-js",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue