Merge pull request #2 from codex-storage/structure-refactoring

Normalize structure by moving components to src folder and update bui…
This commit is contained in:
Arnaud 2024-08-21 17:17:36 +02:00 committed by GitHub
commit d29ddc9a9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
87 changed files with 1225 additions and 156 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
node_modules node_modules
storybook-static storybook-static
dist

View File

@ -11,11 +11,14 @@ const config: StorybookConfig = {
"@storybook/addon-essentials", "@storybook/addon-essentials",
"@chromatic-com/storybook", "@chromatic-com/storybook",
"@storybook/addon-interactions", "@storybook/addon-interactions",
// 'storybook-dark-mode'
], ],
framework: { framework: {
name: "@storybook/react-vite", name: "@storybook/react-vite",
options: {}, options: {
builder: {
viteConfigPath: "./vite-storybook.config.ts",
},
},
}, },
}; };
export default config; export default config;

View File

@ -27,7 +27,9 @@ npm install
npm run storybook npm run storybook
``` ```
## Build (for deployment) ## Build
### Storybook
``` ```
npm run build-storybook npm run build-storybook
@ -40,3 +42,25 @@ You can preview by using the command:
``` ```
npm run preview npm run preview
``` ```
### 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
```

941
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,17 +3,26 @@
"description": "Marketplace UI components for Codex decentralized storage network.", "description": "Marketplace UI components for Codex decentralized storage network.",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/codex-storage/codex-marketplace-storybook" "url": "https://github.com/codex-storage/codex-marketplace-ui-components"
}, },
"private": true,
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"build": "tsc --p ./tsconfig.build.json && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "npx http-server ./storybook-static", "preview": "npx http-server ./storybook-static",
"format": "prettier --write ./src", "format": "prettier --write ./src",
"compile": "tsc --noEmit",
"storybook": "storybook dev -p 6006", "storybook": "storybook dev -p 6006",
"prepublishOnly": "npm run build",
"build-storybook": "storybook build" "build-storybook": "storybook build"
}, },
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"keywords": [ "keywords": [
"Codex", "Codex",
"Javascript", "Javascript",
@ -23,14 +32,17 @@
"React" "React"
], ],
"dependencies": { "dependencies": {
"lucide-react": "^0.428.0"
},
"peerDependencies": {
"@codex/sdk-js": "@codex/sdk-js#master",
"@tanstack/react-query": "^5.51.24", "@tanstack/react-query": "^5.51.24",
"lucide-react": "^0.428.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1"
"@codex/sdk-js": "@codex/marketplace-ui#master"
}, },
"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",
@ -39,11 +51,20 @@
"@storybook/react": "^8.2.9", "@storybook/react": "^8.2.9",
"@storybook/react-vite": "^8.2.9", "@storybook/react-vite": "^8.2.9",
"@storybook/test": "^8.2.9", "@storybook/test": "^8.2.9",
"@tanstack/react-query": "^5.51.24",
"@vitejs/plugin-react": "^4.3.1",
"glob": "^7.2.3",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"storybook": "^8.2.9", "storybook": "^8.2.9",
"storybook-dark-mode": "^4.0.2", "typescript": "^5.2.2",
"typescript": "^5.2.2" "vite-plugin-dts": "^4.0.3",
"vite-plugin-lib-inject-css": "^2.1.1"
}, },
"sideEffects": [
"**/*.css"
],
"engines": { "engines": {
"node": ">=18" "node": ">=18"
}, },

View File

@ -1,5 +1,5 @@
import "./alert.css"; import "./alert.css";
import React, { CSSProperties, ReactNode } from "react"; import { CSSProperties } from "react";
interface CustomStyleCSS extends CSSProperties { interface CustomStyleCSS extends CSSProperties {
"--codex-border-radius"?: string; "--codex-border-radius"?: string;

View File

@ -1,7 +1,6 @@
import { CSSProperties, useEffect } from "react"; import { CSSProperties, useEffect } from "react";
import { attributes } from "../../utils/attributes";
import "./backdrop.css"; import "./backdrop.css";
import React from "react"; import { attributes } from "../utils/attributes";
interface CustomStyleCSS extends CSSProperties { interface CustomStyleCSS extends CSSProperties {
"--codex-background-backdrop"?: string; "--codex-background-backdrop"?: string;
@ -16,14 +15,22 @@ type Props = {
* --codex-background-backdrop * --codex-background-backdrop
*/ */
style?: CustomStyleCSS; style?: CustomStyleCSS;
/**
* If true, it will remove the overflow scroll from the page when open.
* Default: true
*/
removeScroll?: boolean;
}; };
export function Backdrop({ open, onClose, style }: Props) { export function Backdrop({ open, onClose, style, removeScroll = true }: Props) {
const attr = attributes({ "aria-expanded": open }); const attr = attributes({ "aria-expanded": open });
useEffect(() => { useEffect(() => {
document.documentElement.classList.toggle("document-noOverflow"); if (removeScroll) {
}, [open]); document.documentElement.classList.toggle("document-noOverflow");
}
}, [open, removeScroll]);
return ( return (
<div {...attr} className="backdrop" onClick={onClose} style={style}></div> <div {...attr} className="backdrop" onClick={onClose} style={style}></div>

View File

@ -1,6 +1,6 @@
import React, { ComponentType, CSSProperties, ReactNode } from "react"; import { ComponentType, CSSProperties } from "react";
import "./button.css"; import "./button.css";
import { attributes } from "../../utils/attributes"; import { attributes } from "../utils/attributes";
interface CustomStyleCSS extends CSSProperties { interface CustomStyleCSS extends CSSProperties {
"--codex-color-primary"?: string; "--codex-color-primary"?: string;

View File

@ -13,6 +13,7 @@
opacity 0.35s; opacity 0.35s;
font-family: var(--codex-font-family); font-family: var(--codex-font-family);
border: 1px solid transparent; border: 1px solid transparent;
place-content: center;
} }
.button--primary { .button--primary {

View File

@ -1,6 +1,6 @@
import React, { ComponentType, CSSProperties } from "react"; import { ComponentType, CSSProperties } from "react";
import "./buttonIcon.css"; import "./buttonIcon.css";
import { attributes } from "../../utils/attributes"; import { attributes } from "../utils/attributes";
interface CustomStyleCSS extends CSSProperties { interface CustomStyleCSS extends CSSProperties {
"--codex-button-icon-background"?: string; "--codex-button-icon-background"?: string;

View File

@ -1,4 +1,4 @@
import React, { CSSProperties, ReactNode } from "react"; import { CSSProperties, ReactNode } from "react";
import "./card.css"; import "./card.css";
interface CustomStyleCSS extends CSSProperties { interface CustomStyleCSS extends CSSProperties {

View File

@ -10,5 +10,5 @@
} }
.card-body { .card-body {
padding: 0.75rem 1.5rem; padding: 1.5rem;
} }

View File

@ -1,8 +1,7 @@
import { ChangeEvent, ComponentType, useState } from "react"; import { ChangeEvent, ComponentType, useState } from "react";
import "./dropdown.css"; import "./dropdown.css";
import { attributes } from "../../utils/attributes"; import { attributes } from "../utils/attributes";
import { Backdrop } from "../Backdrop/Backdrop"; import { Backdrop } from "../Backdrop/Backdrop";
import React from "react";
import { Input, InputCustomStyleCSS } from "../Input/Input"; import { Input, InputCustomStyleCSS } from "../Input/Input";
interface CustomStyleCSS extends InputCustomStyleCSS { interface CustomStyleCSS extends InputCustomStyleCSS {

View File

@ -4,7 +4,7 @@
.dropdown-panel { .dropdown-panel {
position: absolute; position: absolute;
padding: 0.25rem; padding: 0.5rem;
background-color: var( background-color: var(
--codex-dropdown-panel-background, --codex-dropdown-panel-background,
var(--codex-background-secondary) var(--codex-background-secondary)
@ -44,7 +44,7 @@
} }
.dropdown-option { .dropdown-option {
padding: 0.75rem 0.25rem; padding: 0.5rem;
border-radius: var(--codex-border-radius); border-radius: var(--codex-border-radius);
transition: background-color 0.35s; transition: background-color 0.35s;
cursor: pointer; cursor: pointer;

View File

@ -1,6 +1,5 @@
import { Button } from "../Button/Button"; import { Button } from "../Button/Button";
import "./emptyPlaceholder.css"; import "./emptyPlaceholder.css";
import React from "react";
import { EmptyPlaceholderIcon } from "./EmptyPlaceholderIcon"; import { EmptyPlaceholderIcon } from "./EmptyPlaceholderIcon";
type Props = { type Props = {

View File

@ -1,4 +1,3 @@
import React from "react";
import "./emptyPlaceholderIcon.css"; import "./emptyPlaceholderIcon.css";
type Props = { type Props = {

View File

@ -1,6 +1,6 @@
import "./failure.css"; import "./failure.css";
import { Button } from "../Button/Button"; import { Button } from "../Button/Button";
import React from "react"; import { CSSProperties } from "react";
interface CustomStyleCSS extends CSSProperties { interface CustomStyleCSS extends CSSProperties {
"--codex-code-font-size"?: string; "--codex-code-font-size"?: string;

View File

@ -1,6 +1,6 @@
import React, { ChangeEvent, ComponentType, CSSProperties } from "react"; import { ChangeEvent, ComponentType, CSSProperties } from "react";
import { attributes } from "../../utils/attributes"; import { attributes } from "../utils/attributes";
import { classnames } from "../../utils/classnames"; import { classnames } from "../utils/classnames";
import "./input.css"; import "./input.css";
import { SimpleText } from "../SimpleText/SimpleText"; import { SimpleText } from "../SimpleText/SimpleText";

View File

@ -1,6 +1,5 @@
import { ChangeEvent, CSSProperties } from "react"; import { ChangeEvent, CSSProperties } from "react";
import "./inputGroup.css"; import "./inputGroup.css";
import React from "react";
import { Input } from "../Input/Input"; import { Input } from "../Input/Input";
import { Select } from "../Select/Select"; import { Select } from "../Select/Select";
@ -73,7 +72,7 @@ export function InputGroup({
<div className={`inputGroup ${className}`} style={style}> <div className={`inputGroup ${className}`} style={style}>
<div className="inputGroup-container"> <div className="inputGroup-container">
<div className="inputGroup-element"> <div className="inputGroup-element">
<div> <div className="inputGroup-inputContainer">
<Input <Input
label={label} label={label}
onChange={onChange} onChange={onChange}

View File

@ -26,5 +26,9 @@ select.inputGroup-select {
border-top-right-radius: var(--codex-border-radius); border-top-right-radius: var(--codex-border-radius);
border-bottom-right-radius: var(--codex-border-radius); border-bottom-right-radius: var(--codex-border-radius);
background-color: var(--codex-border-color); background-color: var(--codex-border-color);
padding: calc(0.5rem + 0.5px) 1rem; padding: 0.75rem;
}
.inputGroup-inputContainer {
flex: 1;
} }

View File

@ -1,4 +1,4 @@
import React, { ChangeEvent, CSSProperties } from "react"; import { ChangeEvent, CSSProperties } from "react";
import "./select.css"; import "./select.css";
interface CustomStyleCSS extends CSSProperties { interface CustomStyleCSS extends CSSProperties {

View File

@ -1,4 +1,4 @@
import React, { CSSProperties } from "react"; import { CSSProperties } from "react";
import "./simpleText.css"; import "./simpleText.css";
interface CustomStyleCSS extends CSSProperties { interface CustomStyleCSS extends CSSProperties {

View File

@ -1,6 +1,5 @@
import { PrettyBytes } from "../../utils/bytes"; import { PrettyBytes } from "../utils/bytes";
import "./spaceAllocation.css"; import "./spaceAllocation.css";
import React from "react";
type Props = { type Props = {
data: { data: {

View File

@ -1,5 +1,3 @@
import React from "react";
type Props = { type Props = {
width?: string; width?: string;
className?: string; className?: string;

View File

@ -1,7 +1,7 @@
import { Check } from "lucide-react"; import { Check } from "lucide-react";
import React, { 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";
type StepProps = { type StepProps = {
title: string; title: string;

View File

@ -1,6 +1,6 @@
import { Button } from "../Button/Button"; import { Button } from "../Button/Button";
import "./stepper.css"; import "./stepper.css";
import React, { CSSProperties } from "react"; import { CSSProperties } from "react";
import { Spinner } from "../Spinner/Spinner"; import { Spinner } from "../Spinner/Spinner";
import { Step } from "./Step"; import { Step } from "./Step";
@ -87,7 +87,7 @@ export function Stepper({
isLast={index === titles.length - 1} isLast={index === titles.length - 1}
isDone={index < step} isDone={index < step}
key={title} key={title}
onClick={step > index ? () => onMoveStep(step) : undefined} onClick={step > index ? () => onMoveStep(index) : undefined}
/> />
))} ))}
</div> </div>
@ -104,10 +104,10 @@ export function Stepper({
<div className="stepper-buttons"> <div className="stepper-buttons">
<Button <Button
label="Back" label={step ? "Back" : "Close"}
variant="outline" variant="outline"
onClick={() => onMoveStep(step - 1)} onClick={() => onMoveStep(step - 1)}
disabled={step === 0 || progress} disabled={progress}
/> />
<Button <Button
label={label} label={label}

View File

@ -4,7 +4,6 @@
background-color: var(--codex-background); background-color: var(--codex-background);
padding: 1.5rem; padding: 1.5rem;
border-radius: var(--codex-border-radius); border-radius: var(--codex-border-radius);
margin-bottom: 0.5rem;
} }
.stepper-progress, .stepper-progress,

View File

@ -5,10 +5,9 @@ import {
useRef, useRef,
useState, useState,
} from "react"; } from "react";
import { attributes } from "../../utils/attributes"; import { attributes } from "../utils/attributes";
import "./toast.css"; import "./toast.css";
import { X } from "lucide-react"; import { X } from "lucide-react";
import React from "react";
import { ButtonIcon } from "../ButtonIcon/ButtonIcon"; import { ButtonIcon } from "../ButtonIcon/ButtonIcon";
interface CustomStyleCSS extends CSSProperties { interface CustomStyleCSS extends CSSProperties {

View File

@ -1,12 +1,11 @@
import { FileStack, Upload as UploadIcon } from "lucide-react"; import { FileStack, Upload as UploadIcon } from "lucide-react";
import { ChangeEvent, CSSProperties, DragEventHandler, useRef } from "react"; import { ChangeEvent, CSSProperties, DragEventHandler, useRef } from "react";
import { attributes } from "../../utils/attributes.ts"; import { attributes } from "../utils/attributes.ts";
import "./upload.css"; import "./upload.css";
import { UploadFile } from "./UploadFile.tsx"; 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 React from "react"; import { ButtonIcon } from "../ButtonIcon/ButtonIcon.tsx";
import { ButtonIcon } from "../ButtonIcon/ButtonIcon";
import { CodexData, UploadResponse } from "@codex/sdk-js"; import { CodexData, UploadResponse } from "@codex/sdk-js";
import { SimpleText } from "../SimpleText/SimpleText.tsx"; import { SimpleText } from "../SimpleText/SimpleText.tsx";

View File

@ -1,6 +1,6 @@
import { useRef, useState, useReducer, Reducer, useEffect } from "react"; import { useRef, useState, useReducer, Reducer, useEffect } from "react";
import { attributes } from "../../utils/attributes"; 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 {
@ -11,7 +11,6 @@ import {
Info, Info,
} from "lucide-react"; } from "lucide-react";
import { Spinner } from "../Spinner/Spinner"; import { Spinner } from "../Spinner/Spinner";
import React from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQueryClient } from "@tanstack/react-query";
import { CodexData } from "@codex/sdk-js"; import { CodexData } from "@codex/sdk-js";
import { WebFileIcon } from "../WebFileIcon/WebFileIcon"; import { WebFileIcon } from "../WebFileIcon/WebFileIcon";
@ -210,7 +209,7 @@ export function UploadFile({
type: "module", type: "module",
}); });
provider().then((upload) => { provider().then(() => {
worker.current?.postMessage({ type: "init", upload: "" }); worker.current?.postMessage({ type: "init", upload: "" });
}); });

View File

@ -1,5 +1,3 @@
import React from "react";
type Props = { type Props = {
size?: number; size?: number;
}; };

View File

@ -1,5 +1,3 @@
import React from "react";
type Props = { type Props = {
size?: number; size?: number;
}; };

View File

@ -1,5 +1,3 @@
import React from "react";
type Props = { type Props = {
size?: number; size?: number;
}; };

View File

@ -1,5 +1,3 @@
import React from "react";
type Props = { type Props = {
size?: number; size?: number;
}; };

View File

@ -1,5 +1,3 @@
import React from "react";
type Props = { type Props = {
size?: number; size?: number;
}; };

View File

@ -1,5 +1,3 @@
import React from "react";
type Props = { type Props = {
size?: number; size?: number;
}; };

View File

@ -1,5 +1,3 @@
import React from "react";
type Props = { type Props = {
size?: number; size?: number;
}; };

View File

@ -5,7 +5,6 @@ import { PdfIcon } from "./PdfIcon";
import { ExcelIcon } from "./ExcelIcon"; import { ExcelIcon } from "./ExcelIcon";
import { DocIcon } from "./DocIcon"; import { DocIcon } from "./DocIcon";
import { AnyFileIcon } from "./AnyFileIcon"; import { AnyFileIcon } from "./AnyFileIcon";
import React from "react";
type Props = { type Props = {
type: string; type: string;

View File

@ -1,5 +1,3 @@
import * as React from "react";
export const ZipIcon = () => ( export const ZipIcon = () => (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"

18
src/components/index.ts Normal file
View File

@ -0,0 +1,18 @@
export { Button } from "../components/Button/Button";
export { ButtonIcon } from "../components/ButtonIcon/ButtonIcon";
export { Input } from "../components/Input/Input";
export { InputGroup } from "../components/InputGroup/InputGroup";
export { SimpleText } from "../components/SimpleText/SimpleText";
export { Upload } from "../components/Upload/Upload";
export { Card } from "../components/Card/Card";
export { Select } from "../components/Select/Select";
export { Toast } from "../components/Toast/Toast";
export { SpaceAllocation } from "../components/SpaceAllocation/SpaceAllocation";
export { EmptyPlaceholder } from "../components/EmptyPlaceholder/EmptyPlaceholder";
export { Dropdown, type DropdownOption } from "../components/Dropdown/Dropdown";
export { Failure } from "../components/Failure/Failure";
export { Alert } from "../components/Alert/Alert";
export { Spinner } from "../components/Spinner/Spinner";
export { WebFileIcon } from "../components/WebFileIcon/WebFileIcon";
export { Stepper } from "../components/Stepper/Stepper";
export { Backdrop } from "../components/Backdrop/Backdrop";

9
src/components/vite-env.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
/// <reference types='vite/client' />
interface ImportMetaEnv {
VITE_CODEX_API_URL: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

6
src/utils/attributes.ts Normal file
View File

@ -0,0 +1,6 @@
type Attributes = Record<string, unknown>;
export const attributes = (attributes: Attributes) =>
Object.keys(attributes)
.filter((key) => attributes[key] !== false)
.reduce((prev, key) => ({ ...prev, [key]: attributes[key] }), {});

14
src/utils/bytes.ts Normal file
View File

@ -0,0 +1,14 @@
export const PrettyBytes = (bytes: number) => {
const sizes = ["bytes", "KB", "MB", "GB", "TB"];
if (bytes == 0) {
return "0 b";
}
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)).toString());
if (i == 0) {
return bytes + " " + sizes[i];
}
return (bytes / Math.pow(1024, i)).toFixed(1) + " " + sizes[i];
};

7
src/utils/classnames.ts Normal file
View File

@ -0,0 +1,7 @@
export type Classname = [string, boolean?];
export const classnames = (...classnames: Classname[]) =>
classnames
.filter(([, visible = true]) => visible)
.map(([name]) => name)
.join(" ");

View File

@ -1,5 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { Alert } from "../components/Alert/Alert"; import { Alert } from "../src/components/Alert/Alert";
const meta = { const meta = {
title: "Overlays/Alert", title: "Overlays/Alert",

View File

@ -1,7 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta } from "@storybook/react";
import { Backdrop } from "../components/Backdrop/Backdrop"; import { Backdrop } from "../src/components/Backdrop/Backdrop";
import { useState } from "react"; import { useState } from "react";
import React from "react";
const meta = { const meta = {
title: "Overlays/Backdrop", title: "Overlays/Backdrop",
@ -14,7 +13,6 @@ const meta = {
} satisfies Meta<typeof Backdrop>; } satisfies Meta<typeof Backdrop>;
export default meta; export default meta;
type Story = StoryObj<typeof meta>;
const Template = () => { const Template = () => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
@ -29,4 +27,4 @@ const Template = () => {
); );
}; };
export const Default: Story = Template.bind({}); export const Default = Template.bind({});

View File

@ -1,6 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { fn } from "@storybook/test"; import { fn } from "@storybook/test";
import { Button } from "../components/Button/Button"; import { Button } from "../src/components/Button/Button";
import { Plus } from "lucide-react"; import { Plus } from "lucide-react";
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export

View File

@ -1,7 +1,7 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { fn } from "@storybook/test"; import { fn } from "@storybook/test";
import { Plus } from "lucide-react"; import { Plus } from "lucide-react";
import { ButtonIcon } from "../components/ButtonIcon/ButtonIcon"; import { ButtonIcon } from "../src/components/ButtonIcon/ButtonIcon";
const meta = { const meta = {
title: "Components/ButtonIcon", title: "Components/ButtonIcon",

View File

@ -1,8 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { fn } from "@storybook/test"; import { Card } from "../src/components/Card/Card";
import { Plus } from "lucide-react"; import React from "react";
import { Card } from "../components/Card/Card";
import React, { CSSProperties } from "react";
const meta = { const meta = {
title: "Components/Card", title: "Components/Card",

View File

@ -1,8 +1,8 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { Dropdown, DropdownOption } from "../components/Dropdown/Dropdown"; import { Dropdown, DropdownOption } from "../src/components/Dropdown/Dropdown";
import { PdfIcon } from "../components/WebFileIcon/PdfIcon"; import { PdfIcon } from "../src/components/WebFileIcon/PdfIcon";
import { ImageIcon } from "../components/WebFileIcon/ImageIcon"; import { ImageIcon } from "../src/components/WebFileIcon/ImageIcon";
import React, { ChangeEvent, useState } from "react"; import { ChangeEvent, useState } from "react";
const meta = { const meta = {
title: "Forms/Dropdown", title: "Forms/Dropdown",
@ -46,7 +46,7 @@ const Template = () => {
); );
}; };
export const Default: Story = Template.bind({}); export const Default = Template.bind({});
export const CustomStyle: Story = { export const CustomStyle: Story = {
args: { args: {

View File

@ -1,5 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { EmptyPlaceholder } from "../components/EmptyPlaceholder/EmptyPlaceholder"; import { EmptyPlaceholder } from "../src/components/EmptyPlaceholder/EmptyPlaceholder";
const meta = { const meta = {
title: "Content/EmptyPlaceholder", title: "Content/EmptyPlaceholder",

View File

@ -1,5 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { Failure } from "../components/Failure/Failure"; import { Failure } from "../src/components/Failure/Failure";
const meta = { const meta = {
title: "Content/Failure", title: "Content/Failure",

View File

@ -1,6 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { fn } from "@storybook/test"; import { fn } from "@storybook/test";
import { Input } from "../components/Input/Input"; import { Input } from "../src/components/Input/Input";
import { InputIcon } from "./InputIcon"; import { InputIcon } from "./InputIcon";
const meta = { const meta = {

View File

@ -1,6 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { fn } from "@storybook/test"; import { fn } from "@storybook/test";
import { InputGroup } from "../components/InputGroup/InputGroup"; import { InputGroup } from "../src/components/InputGroup/InputGroup";
const meta = { const meta = {
title: "Forms/InputGroup", title: "Forms/InputGroup",

View File

@ -1,5 +1,4 @@
import { User } from "lucide-react"; import { User } from "lucide-react";
import React from "react";
export function InputIcon() { export function InputIcon() {
return <User size="1.25rem" />; return <User size="1.25rem" />;

View File

@ -1,6 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { fn } from "@storybook/test"; import { fn } from "@storybook/test";
import { Select } from "../components/Select/Select"; import { Select } from "../src/components/Select/Select";
const meta = { const meta = {
title: "Forms/Select", title: "Forms/Select",

View File

@ -1,5 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { SimpleText } from "../components/SimpleText/SimpleText"; import { SimpleText } from "../src/components/SimpleText/SimpleText";
const meta = { const meta = {
title: "Components/SimpleText", title: "Components/SimpleText",

View File

@ -1,5 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { SpaceAllocation } from "../components/SpaceAllocation/SpaceAllocation"; import { SpaceAllocation } from "../src/components/SpaceAllocation/SpaceAllocation";
const meta = { const meta = {
title: "Advanced/SpaceAllocation", title: "Advanced/SpaceAllocation",

View File

@ -1,6 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { Spinner } from "../components/Spinner/Spinner"; import { Spinner } from "../src/components/Spinner/Spinner";
import React from "react";
const meta = { const meta = {
title: "Overlays/Spinner", title: "Overlays/Spinner",

View File

@ -1,6 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { Stepper } from "../components/Stepper/Stepper"; import { Stepper } from "../src/components/Stepper/Stepper";
import React, { CSSProperties, useState } from "react"; import React, { useState } from "react";
const meta = { const meta = {
title: "Advanced/Stepper", title: "Advanced/Stepper",
@ -45,4 +45,4 @@ const Template = () => {
); );
}; };
export const Default: Story = Template.bind({}); export const Default = Template.bind({});

View File

@ -1,8 +1,7 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { CircleCheck } from "lucide-react"; import { CircleCheck } from "lucide-react";
import { Toast } from "../components/Toast/Toast"; import { Toast } from "../src/components/Toast/Toast";
import { MouseEvent, useState } from "react"; import { MouseEvent, useState } from "react";
import React from "react";
const meta = { const meta = {
title: "Overlays/Toast", title: "Overlays/Toast",
@ -44,4 +43,4 @@ const Template = () => {
); );
}; };
export const Default: Story = Template.bind({}); export const Default = Template.bind({});

View File

@ -1,8 +1,7 @@
import type { Meta, StoryObj } from "@storybook/react"; import type { Meta, StoryObj } from "@storybook/react";
import { Upload } from "../components/Upload/Upload";
import React from "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/sdk-js";
import { Upload } from "../src/components/Upload/Upload";
const meta = { const meta = {
title: "Advanced/Upload", title: "Advanced/Upload",
@ -15,7 +14,6 @@ const meta = {
} satisfies Meta<typeof Upload>; } satisfies Meta<typeof Upload>;
export default meta; export default meta;
type Story = StoryObj<typeof meta>;
const queryClient = new QueryClient(); const queryClient = new QueryClient();
@ -27,13 +25,13 @@ const Template = () => {
); );
}; };
export const Multiple: Story = Template.bind({}); export const Multiple = Template.bind({});
const slowProvider = () => const slowProvider = () =>
Promise.resolve( Promise.resolve(
(_: File, onProgress: (loaded: number, total: number) => void) => { (_: File, onProgress: (loaded: number, total: number) => void) => {
return new Promise<UploadResponse>((resolve) => { return new Promise<UploadResponse>((resolve) => {
let timeout; let timeout: number;
resolve({ resolve({
abort: () => { abort: () => {
@ -41,7 +39,7 @@ const slowProvider = () =>
}, },
result: new Promise((resolve) => { result: new Promise((resolve) => {
let count = 0; let count = 0;
timeout = setInterval(() => { timeout = window.setInterval(() => {
count++; count++;
onProgress(500 * count, 1500); onProgress(500 * count, 1500);
@ -71,7 +69,7 @@ const SlowTemplate = () => {
); );
}; };
export const Slow: Story = SlowTemplate.bind({}); export const Slow = SlowTemplate.bind({});
const SingleTemplate = () => { const SingleTemplate = () => {
return ( return (
@ -90,4 +88,4 @@ const SingleTemplate = () => {
); );
}; };
export const Single: Story = SingleTemplate.bind({}); export const Single = SingleTemplate.bind({});

27
tsconfig.app.json Normal file
View File

@ -0,0 +1,27 @@
{
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src", "stories"]
}

4
tsconfig.build.json Normal file
View File

@ -0,0 +1,4 @@
{
"extends": "./tsconfig.app.json",
"include": ["src"],
}

11
tsconfig.json Normal file
View File

@ -0,0 +1,11 @@
{
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.node.json"
}
]
}

13
tsconfig.node.json Normal file
View File

@ -0,0 +1,13 @@
{
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"strict": true,
"noEmit": true
},
"include": ["vite.config.ts"]
}

17
vite-storybook.config.ts Normal file
View File

@ -0,0 +1,17 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react({ jsxRuntime: "automatic" })],
worker: {
rollupOptions: {
external: ["@codex/sdk-js"],
output: {
globals: {
"@codex/sdk-js": "codex-sdk-js",
},
},
},
},
});

View File

@ -1,10 +1,66 @@
import { defineConfig } from "vite"; import { defineConfig } from "vite";
import { resolve } from "path";
import dts from "vite-plugin-dts";
import react from "@vitejs/plugin-react";
import { libInjectCss } from "vite-plugin-lib-inject-css";
import { extname, relative } from "path";
import { fileURLToPath } from "node:url";
import pkg from "glob";
const { glob } = pkg;
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
worker: { worker: {
rollupOptions: { rollupOptions: {
external: ["@codex/sdk-js"], external: ["@codex/sdk-js"],
output: {
globals: {
"@codex/sdk-js": "codex-sdk-js",
},
},
},
},
plugins: [
react(),
libInjectCss(),
dts({
tsconfigPath: "./tsconfig.build.json",
rollupTypes: true,
}),
],
build: {
lib: {
entry: resolve(__dirname, "src/index.ts"),
formats: ["es"],
},
rollupOptions: {
external: [
"react",
"react/jsx-runtime",
"@codex/sdk-js",
"@tanstack/react-query",
],
input: Object.fromEntries(
glob
.sync("src/**/*.{ts,tsx}", {
ignore: ["src/**/*.d.ts"],
})
.map((file) => [
// The name of the entry point
// lib/nested/foo.ts becomes nested/foo
relative("src", file.slice(0, file.length - extname(file).length)),
// The absolute path to the entry file
// lib/nested/foo.ts becomes /project/lib/nested/foo.ts
fileURLToPath(new URL(file, import.meta.url)),
])
),
output: {
assetFileNames: "assets/[name][extname]",
entryFileNames: "[name].js",
globals: {
"@codex/sdk-js": "codex-sdk-js",
},
},
}, },
}, },
}); });