diff --git a/.changeset/config.json b/.changeset/config.json index a4ba8a296..6f539e3e3 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,5 +7,5 @@ "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": ["storybook", "web"] + "ignore": ["@/storybook", "@/web"] } diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 00926bafa..f2e06d8cc 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -5,9 +5,9 @@ runs: using: composite steps: - name: Setup Bun - uses: oven-sh/setup-bun@v1 + uses: oven-sh/setup-bun@v2 with: - bun-version: 1.1.21 + bun-version: 1.1.43 - name: Setup Node uses: actions/setup-node@v4 diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 7ceb3b627..24b72a549 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,11 +1,11 @@ { "recommendations": [ - "oven.bun-vscode", - "esbenp.prettier-vscode", - "dbaeumer.vscode-eslint", - "yoavbls.pretty-ts-errors", "bradlc.vscode-tailwindcss", + "DavidAnson.vscode-markdownlint", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "oven.bun-vscode", "unifiedjs.vscode-mdx", - "DavidAnson.vscode-markdownlint" + "yoavbls.pretty-ts-errors" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 8dbffc577..9d57ae826 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,15 +4,23 @@ }, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, - "eslint.workingDirectories": ["apps/web", "packages/ui"], + "editor.quickSuggestions": { + "strings": "on" + }, + "eslint.workingDirectories": [{ "mode": "auto" }], + "files.associations": { + "*.css": "tailwindcss" + }, "tailwindCSS.classAttributes": ["class", "className", "theme"], "tailwindCSS.experimental.classRegex": [ ["twMerge\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], - ["createTheme\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"] + ["createTheme(?:<\\w+>)?\\s*\\(([^)]*)\\)", "{?\\s?[\\w].*:\\s*?[\"'`]([^\"'`]*).*?,?\\s?}?"] ], "tailwindCSS.experimental.configFile": { + "apps/storybook/tailwind.config.cjs": "apps/storybook/**", "apps/web/tailwind.config.cjs": "apps/web/**", "packages/ui/tailwind.config.cjs": "packages/ui/**" }, + "typescript.preferences.preferTypeOnlyAutoImports": true, "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/apps/storybook/.eslintrc.cjs b/apps/storybook/.eslintrc.cjs new file mode 100644 index 000000000..5ffe5a97c --- /dev/null +++ b/apps/storybook/.eslintrc.cjs @@ -0,0 +1,44 @@ +/** @type {import("eslint").Linter.Config} */ +module.exports = { + root: true, + env: { + browser: true, + commonjs: true, + es2021: true, + }, + extends: [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:react/jsx-runtime", + "plugin:tailwindcss/recommended", + "prettier", + ], + overrides: [ + { + files: ["**/*.{ts,tsx}"], + plugins: ["@typescript-eslint"], + parser: "@typescript-eslint/parser", + extends: ["plugin:@typescript-eslint/recommended"], + }, + ], + parserOptions: { + ecmaVersion: "latest", + sourceType: "module", + }, + plugins: ["react-refresh"], + settings: { + react: { + version: "detect", + }, + tailwindcss: { + callees: ["twMerge", "createTheme"], + classRegex: "^(class(Name)|theme)?$", + }, + }, + ignorePatterns: ["storybook-static"], + rules: { + "react-refresh/only-export-components": ["warn", { allowConstantExport: true }], + "react/no-unescaped-entities": "off", + "react/prop-types": "off", + }, +}; diff --git a/apps/storybook/.storybook/main.ts b/apps/storybook/.storybook/main.ts index 2daa674b2..b049fa05f 100644 --- a/apps/storybook/.storybook/main.ts +++ b/apps/storybook/.storybook/main.ts @@ -10,7 +10,7 @@ function getAbsolutePath(value: string): any { return dirname(require.resolve(join(value, "package.json"))); } const config: StorybookConfig = { - stories: ["../../../packages/ui/**/*.stories.@(ts|tsx)"], + stories: ["../src/**/*.stories.{ts,tsx}"], addons: [ getAbsolutePath("@storybook/addon-links"), getAbsolutePath("@storybook/addon-essentials"), diff --git a/apps/storybook/package.json b/apps/storybook/package.json index 09201890d..891a9484a 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -1,5 +1,5 @@ { - "name": "storybook", + "name": "@/storybook", "version": "0.0.0", "private": true, "scripts": { @@ -8,11 +8,15 @@ "dev": "storybook dev -p 6006", "format": "prettier . --write", "format:check": "prettier . --check", + "lint": "eslint .", + "lint:fix": "eslint . --fix", "typecheck": "tsc --noEmit" }, "dependencies": { + "flowbite-react": "workspace:*", "react": "18.3.1", - "react-dom": "18.3.1" + "react-dom": "18.3.1", + "react-icons": "5.2.1" }, "devDependencies": { "@storybook/addon-essentials": "8.1.10", @@ -25,12 +29,18 @@ "@storybook/test": "8.1.10", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", - "@vitejs/plugin-react": "4.3.1", + "@typescript-eslint/eslint-plugin": "8.19.1", + "@typescript-eslint/parser": "8.19.1", + "@vitejs/plugin-react": "4.3.4", "autoprefixer": "10.4.20", - "postcss": "8.4.41", + "eslint-plugin-react": "7.37.3", + "eslint-plugin-react-refresh": "0.4.16", + "eslint-plugin-storybook": "0.11.1", + "eslint-plugin-vitest": "0.5.4", + "postcss": "8.4.49", "storybook": "8.1.10", - "tailwindcss": "3.4.7", - "typescript": "5.5.4", - "vite": "5.3.5" + "tailwindcss": "3.4.17", + "typescript": "5.6.3", + "vite": "6.0.7" } } diff --git a/apps/storybook/postcss.config.cjs b/apps/storybook/postcss.config.cjs index 12a703d90..1719dfd25 100644 --- a/apps/storybook/postcss.config.cjs +++ b/apps/storybook/postcss.config.cjs @@ -1,3 +1,4 @@ +/** @type {import('postcss-load-config').Config} */ module.exports = { plugins: { tailwindcss: {}, diff --git a/apps/storybook/prettier.config.cjs b/apps/storybook/prettier.config.cjs new file mode 100644 index 000000000..e9e08307f --- /dev/null +++ b/apps/storybook/prettier.config.cjs @@ -0,0 +1,10 @@ +const rootPrettier = require("../../prettier.config.cjs"); + +/** @type {import('prettier').Config} */ +module.exports = { + ...rootPrettier, + plugins: [...rootPrettier.plugins, "prettier-plugin-tailwindcss"], + // tailwindcss + tailwindAttributes: ["theme"], + tailwindFunctions: ["twMerge", "createTheme"], +}; diff --git a/packages/ui/src/components/Accordion/Accordion.stories.tsx b/apps/storybook/src/Accordion.stories.tsx similarity index 81% rename from packages/ui/src/components/Accordion/Accordion.stories.tsx rename to apps/storybook/src/Accordion.stories.tsx index 2a7a37e77..26bdbc550 100644 --- a/packages/ui/src/components/Accordion/Accordion.stories.tsx +++ b/apps/storybook/src/Accordion.stories.tsx @@ -1,8 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { ComponentProps, FC } from "react"; +import { Accordion, AccordionContent, AccordionPanel, AccordionTitle, type AccordionProps } from "flowbite-react"; import { HiChevronDown, HiOutlineArrowCircleDown } from "react-icons/hi"; -import type { AccordionProps } from "./Accordion"; -import { Accordion } from "./Accordion"; export default { title: "Components/Accordion", @@ -13,13 +11,11 @@ export default { }, } as Meta; -const icon: FC> = HiChevronDown; - const Template: StoryFn = (args) => ( - - - What is Flowbite? - + + + What is Flowbite? +

Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more. @@ -34,11 +30,11 @@ const Template: StoryFn = (args) => (  and start developing websites even faster with components on top of Tailwind CSS.

-
-
- - Is there a Figma file available? - + + + + Is there a Figma file available? +

Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file. @@ -50,11 +46,11 @@ const Template: StoryFn = (args) => (  based on the utility classes from Tailwind CSS and components from Flowbite.

-
-
- - What are the differences between Flowbite and Tailwind UI? - + + + + What are the differences between Flowbite and Tailwind UI? +

The main difference is that the core components from Flowbite are open source under the MIT license, whereas Tailwind UI is a paid product. Another difference is that Flowbite relies on smaller and standalone @@ -81,8 +77,8 @@ const Template: StoryFn = (args) => ( - - + + ); diff --git a/packages/ui/src/components/Alert/Alert.stories.tsx b/apps/storybook/src/Alert.stories.tsx similarity index 96% rename from packages/ui/src/components/Alert/Alert.stories.tsx rename to apps/storybook/src/Alert.stories.tsx index 9e7b4e331..4b8ab0be6 100644 --- a/packages/ui/src/components/Alert/Alert.stories.tsx +++ b/apps/storybook/src/Alert.stories.tsx @@ -1,15 +1,14 @@ import type { Meta, StoryFn } from "@storybook/react"; +import type { AlertProps } from "flowbite-react"; +import { Alert, alertTheme } from "flowbite-react"; import { HiEye, HiInformationCircle } from "react-icons/hi"; -import { theme } from "../../theme"; -import type { AlertProps } from "./Alert"; -import { Alert } from "./Alert"; export default { title: "Components/Alert", component: Alert, argTypes: { color: { - options: Object.keys(theme.alert.color), + options: Object.keys(alertTheme.color), control: { type: "inline-radio" }, }, }, diff --git a/packages/ui/src/components/Avatar/Avatar.stories.tsx b/apps/storybook/src/Avatar.stories.tsx similarity index 92% rename from packages/ui/src/components/Avatar/Avatar.stories.tsx rename to apps/storybook/src/Avatar.stories.tsx index c3b7a6fd7..b49c58405 100644 --- a/packages/ui/src/components/Avatar/Avatar.stories.tsx +++ b/apps/storybook/src/Avatar.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { AvatarProps } from "./Avatar"; -import { Avatar } from "./Avatar"; +import type { AvatarProps } from "flowbite-react"; +import { Avatar } from "flowbite-react"; export default { title: "Components/Avatar", diff --git a/packages/ui/src/components/Avatar/AvatarGroup.stories.tsx b/apps/storybook/src/AvatarGroup.stories.tsx similarity index 73% rename from packages/ui/src/components/Avatar/AvatarGroup.stories.tsx rename to apps/storybook/src/AvatarGroup.stories.tsx index f7c3b936b..f489e3356 100644 --- a/packages/ui/src/components/Avatar/AvatarGroup.stories.tsx +++ b/apps/storybook/src/AvatarGroup.stories.tsx @@ -1,20 +1,20 @@ import type { Meta, StoryFn } from "@storybook/react"; -import { Avatar } from "./Avatar"; -import type { AvatarGroupProps } from "./AvatarGroup"; +import type { AvatarGroupProps } from "flowbite-react"; +import { Avatar, AvatarGroup, AvatarGroupCounter } from "flowbite-react"; export default { title: "Components/Avatar", - component: Avatar.Group, + component: AvatarGroup, } as Meta; const Template: StoryFn = (args) => ( - + - - + + ); export const DefaultAvatarGroup = Template.bind({}); diff --git a/packages/ui/src/components/Badge/Badge.stories.tsx b/apps/storybook/src/Badge.stories.tsx similarity index 70% rename from packages/ui/src/components/Badge/Badge.stories.tsx rename to apps/storybook/src/Badge.stories.tsx index 70982e893..2e86b850c 100644 --- a/packages/ui/src/components/Badge/Badge.stories.tsx +++ b/apps/storybook/src/Badge.stories.tsx @@ -1,19 +1,18 @@ import type { Meta, StoryFn } from "@storybook/react"; +import type { BadgeProps } from "flowbite-react"; +import { Badge, badgeTheme } from "flowbite-react"; import { HiCheck } from "react-icons/hi"; -import { theme } from "../../theme"; -import type { BadgeProps } from "./Badge"; -import { Badge } from "./Badge"; export default { title: "Components/Badge", component: Badge, argTypes: { color: { - options: Object.keys(theme.badge.root.color), + options: Object.keys(badgeTheme.root.color), control: { type: "inline-radio" }, }, size: { - options: Object.keys(theme.badge.root.size), + options: Object.keys(badgeTheme.root.size), control: { type: "inline-radio" }, }, }, @@ -45,10 +44,3 @@ BadgeOnlyIcon.args = { color: "green", icon: HiCheck, }; - -export const BadgeAsLink = Template.bind({}); -BadgeAsLink.storyName = "As link"; -BadgeAsLink.args = { - href: "/badges", - children: "Read more →", -}; diff --git a/packages/ui/src/components/Banner/Banner.stories.tsx b/apps/storybook/src/Banner.stories.tsx similarity index 78% rename from packages/ui/src/components/Banner/Banner.stories.tsx rename to apps/storybook/src/Banner.stories.tsx index 77b295ba7..6c651b774 100644 --- a/packages/ui/src/components/Banner/Banner.stories.tsx +++ b/apps/storybook/src/Banner.stories.tsx @@ -1,15 +1,15 @@ import type { Meta, StoryFn } from "@storybook/react"; +import type { BannerProps } from "flowbite-react"; +import { Banner, BannerCollapseButton } from "flowbite-react"; import { HiX } from "react-icons/hi"; import { MdAnnouncement } from "react-icons/md"; -import type { BannerComponentProps } from "./Banner"; -import { Banner } from "./Banner"; export default { title: "Components/Banner", component: Banner, } as Meta; -const Template: StoryFn = (args) => ; +const Template: StoryFn = (args) => ; export const DefaultBanner = Template.bind({}); DefaultBanner.storyName = "Default"; @@ -30,9 +30,9 @@ DefaultBanner.args = {

- + - + ), }; diff --git a/packages/ui/src/components/Blockquote/Blockquote.stories.tsx b/apps/storybook/src/Blockquote.stories.tsx similarity index 84% rename from packages/ui/src/components/Blockquote/Blockquote.stories.tsx rename to apps/storybook/src/Blockquote.stories.tsx index ad3ba76d2..be7877ca3 100644 --- a/packages/ui/src/components/Blockquote/Blockquote.stories.tsx +++ b/apps/storybook/src/Blockquote.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { BlockquoteProps } from "./Blockquote"; -import { Blockquote } from "./Blockquote"; +import type { BlockquoteProps } from "flowbite-react"; +import { Blockquote } from "flowbite-react"; export default { title: "Components/Blockquote", diff --git a/packages/ui/src/components/Breadcrumb/Breadcrumb.stories.tsx b/apps/storybook/src/Breadcrumb.stories.tsx similarity index 57% rename from packages/ui/src/components/Breadcrumb/Breadcrumb.stories.tsx rename to apps/storybook/src/Breadcrumb.stories.tsx index b6ca37393..2ccb4d2cc 100644 --- a/packages/ui/src/components/Breadcrumb/Breadcrumb.stories.tsx +++ b/apps/storybook/src/Breadcrumb.stories.tsx @@ -1,20 +1,20 @@ import type { Meta, StoryFn } from "@storybook/react"; +import type { BreadcrumbProps } from "flowbite-react"; +import { Breadcrumb, BreadcrumbItem } from "flowbite-react"; import { HiHome } from "react-icons/hi"; -import type { BreadcrumbComponentProps } from "./Breadcrumb"; -import { Breadcrumb } from "./Breadcrumb"; export default { title: "Components/Breadcrumb", component: Breadcrumb, } as Meta; -const Template: StoryFn = (args) => ( +const Template: StoryFn = (args) => ( - + Home - - Projects - Flowbite React + + Projects + Flowbite React ); diff --git a/packages/ui/src/components/Button/Button.stories.tsx b/apps/storybook/src/Button.stories.tsx similarity index 78% rename from packages/ui/src/components/Button/Button.stories.tsx rename to apps/storybook/src/Button.stories.tsx index ab00a6b95..b04ee5a59 100644 --- a/packages/ui/src/components/Button/Button.stories.tsx +++ b/apps/storybook/src/Button.stories.tsx @@ -1,14 +1,13 @@ import type { Meta, StoryFn } from "@storybook/react"; -import { theme } from "../../theme"; -import type { ButtonProps } from "./Button"; -import { Button } from "./Button"; +import type { ButtonProps } from "flowbite-react"; +import { Button, buttonTheme } from "flowbite-react"; export default { title: "Components/Button", component: Button, argTypes: { color: { - options: Object.keys(theme.button.color), + options: Object.keys(buttonTheme.color), control: { type: "inline-radio" }, }, size: { diff --git a/packages/ui/src/components/Button/ButtonGroup.stories.tsx b/apps/storybook/src/ButtonGroup.stories.tsx similarity index 70% rename from packages/ui/src/components/Button/ButtonGroup.stories.tsx rename to apps/storybook/src/ButtonGroup.stories.tsx index 62b7e5e56..03f06da89 100644 --- a/packages/ui/src/components/Button/ButtonGroup.stories.tsx +++ b/apps/storybook/src/ButtonGroup.stories.tsx @@ -1,18 +1,18 @@ import type { Meta, StoryFn } from "@storybook/react"; -import { Button } from "."; -import type { ButtonGroupProps } from "./ButtonGroup"; +import type { ButtonGroupProps } from "flowbite-react"; +import { Button, ButtonGroup } from "flowbite-react"; export default { title: "Components/Button", - component: Button.Group, + component: ButtonGroup, } as Meta; const Template: StoryFn = (args) => ( - + - + ); export const DefaultAvatarGroup = Template.bind({}); diff --git a/packages/ui/src/components/Card/Card.stories.tsx b/apps/storybook/src/Card.stories.tsx similarity index 93% rename from packages/ui/src/components/Card/Card.stories.tsx rename to apps/storybook/src/Card.stories.tsx index 679adc94f..b1bed4091 100644 --- a/packages/ui/src/components/Card/Card.stories.tsx +++ b/apps/storybook/src/Card.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { CardProps } from "./Card"; -import { Card } from "./Card"; +import type { CardProps } from "flowbite-react"; +import { Card } from "flowbite-react"; export default { title: "Components/Card", diff --git a/packages/ui/src/components/Carousel/Carousel.stories.tsx b/apps/storybook/src/Carousel.stories.tsx similarity index 93% rename from packages/ui/src/components/Carousel/Carousel.stories.tsx rename to apps/storybook/src/Carousel.stories.tsx index d20313a58..5fb994eb3 100644 --- a/packages/ui/src/components/Carousel/Carousel.stories.tsx +++ b/apps/storybook/src/Carousel.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { CarouselProps } from "./Carousel"; -import { Carousel } from "./Carousel"; +import type { CarouselProps } from "flowbite-react"; +import { Carousel } from "flowbite-react"; export default { title: "Components/Carousel", diff --git a/packages/ui/src/components/Checkbox/Checkbox.stories.tsx b/apps/storybook/src/Checkbox.stories.tsx similarity index 77% rename from packages/ui/src/components/Checkbox/Checkbox.stories.tsx rename to apps/storybook/src/Checkbox.stories.tsx index 11c8ac677..8b91e5aaf 100644 --- a/packages/ui/src/components/Checkbox/Checkbox.stories.tsx +++ b/apps/storybook/src/Checkbox.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { CheckboxProps } from "./Checkbox"; -import { Checkbox } from "./Checkbox"; +import type { CheckboxProps } from "flowbite-react"; +import { Checkbox } from "flowbite-react"; export default { title: "Components/Checkbox", diff --git a/packages/ui/src/components/Clipboard/Clipboard.stories.tsx b/apps/storybook/src/Clipboard.stories.tsx similarity index 84% rename from packages/ui/src/components/Clipboard/Clipboard.stories.tsx rename to apps/storybook/src/Clipboard.stories.tsx index 7374f0f54..3382b4b36 100644 --- a/packages/ui/src/components/Clipboard/Clipboard.stories.tsx +++ b/apps/storybook/src/Clipboard.stories.tsx @@ -1,9 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -// import { FaClipboardList } from "react-icons/fa6"; -import type { ClipboardProps } from "./Clipboard"; -import { Clipboard } from "./Clipboard"; -import type { ClipboardWithIconProps } from "./ClipboardWithIcon"; -import type { ClipboardWithIconTextProps } from "./ClipboardWithIconText"; +import type { ClipboardProps, ClipboardWithIconProps, ClipboardWithIconTextProps } from "flowbite-react"; +import { Clipboard, ClipboardWithIcon, ClipboardWithIconText } from "flowbite-react"; export default { title: "Components/Clipboard", @@ -43,7 +40,7 @@ const CopyIconTemplate: StoryFn = () => ( disabled readOnly /> - + ); @@ -64,7 +61,7 @@ const CopyIconTextTemplate: StoryFn = () => ( disabled readOnly /> - + ); diff --git a/packages/ui/src/components/DarkThemeToggle/DarkThemeToggle.stories.tsx b/apps/storybook/src/DarkThemeToggle.stories.tsx similarity index 75% rename from packages/ui/src/components/DarkThemeToggle/DarkThemeToggle.stories.tsx rename to apps/storybook/src/DarkThemeToggle.stories.tsx index 7493367c1..8707c0b8c 100644 --- a/packages/ui/src/components/DarkThemeToggle/DarkThemeToggle.stories.tsx +++ b/apps/storybook/src/DarkThemeToggle.stories.tsx @@ -1,6 +1,5 @@ import type { Meta, StoryFn } from "@storybook/react"; -import { Flowbite } from "../Flowbite"; -import { DarkThemeToggle } from "./DarkThemeToggle"; +import { DarkThemeToggle, ThemeProvider } from "flowbite-react"; export default { title: "Components/DarkThemeToggle", @@ -8,9 +7,9 @@ export default { } as Meta; const Template: StoryFn = (args) => ( - + - + ); export const DefaultDarkThemeToggle = Template.bind({}); diff --git a/packages/ui/src/components/Datepicker/Datepicker.stories.tsx b/apps/storybook/src/Datepicker.stories.tsx similarity index 95% rename from packages/ui/src/components/Datepicker/Datepicker.stories.tsx rename to apps/storybook/src/Datepicker.stories.tsx index 354773947..084d98f06 100644 --- a/packages/ui/src/components/Datepicker/Datepicker.stories.tsx +++ b/apps/storybook/src/Datepicker.stories.tsx @@ -1,8 +1,7 @@ import type { Meta, StoryFn } from "@storybook/react"; +import type { DatepickerProps } from "flowbite-react"; +import { Datepicker, getFirstDateInRange, WeekStart } from "flowbite-react"; import { useEffect, useState } from "react"; -import type { DatepickerProps } from "./Datepicker"; -import { Datepicker } from "./Datepicker"; -import { getFirstDateInRange, WeekStart } from "./helpers"; export default { title: "Components/Datepicker", diff --git a/packages/ui/src/components/Drawer/Drawer.stories.tsx b/apps/storybook/src/Drawer.stories.tsx similarity index 91% rename from packages/ui/src/components/Drawer/Drawer.stories.tsx rename to apps/storybook/src/Drawer.stories.tsx index 3c1cad882..41587f1d0 100644 --- a/packages/ui/src/components/Drawer/Drawer.stories.tsx +++ b/apps/storybook/src/Drawer.stories.tsx @@ -1,7 +1,5 @@ import type { Meta, StoryFn } from "@storybook/react"; -import { Drawer, DrawerProps } from "./Drawer"; -import { DrawerHeader } from "./DrawerHeader"; -import { DrawerItems } from "./DrawerItems"; +import { Drawer, DrawerHeader, DrawerItems, type DrawerProps } from "flowbite-react"; export default { title: "Components/Drawer", @@ -33,7 +31,7 @@ const Template: StoryFn = (args) => ( > Get access  Bonnie Green + name@flowbite.com + + Dashboard + Settings + Earnings + + Sign out + + ), +}; + +export const WithUsableInputHeader = Template.bind({}); +WithUsableInputHeader.storyName = "With usable input header"; +WithUsableInputHeader.args = { + enableTypeAhead: false, + children: ( + <> + + + + Dashboard + Settings + Earnings + Sign out + + ), +}; + +export const Inline = Template.bind({}); +Inline.args = { + inline: true, + children: ( + <> + Dashboard + Settings + Earnings + Sign out + + ), +}; + +export const CustomTrigger = Template.bind({}); +CustomTrigger.args = { + renderTrigger: () => , + children: ( + <> + Dashboard + Settings + Earnings + Sign out + + ), +}; + +export const CustomItem = Template.bind({}); +CustomItem.args = { + children: ( + <> + Default button + As span + + + As link + + + ), +}; + +export const ItemClickHandler = Template.bind({}); +ItemClickHandler.storyName = "Item click handlers"; +ItemClickHandler.args = { + children: ( + <> + Dashboard + Settings + Earnings + Sign out + + ), +}; diff --git a/packages/ui/src/components/FileInput/FileInput.stories.tsx b/apps/storybook/src/FileInput.stories.tsx similarity index 77% rename from packages/ui/src/components/FileInput/FileInput.stories.tsx rename to apps/storybook/src/FileInput.stories.tsx index 92afe0fa5..4cdb403a8 100644 --- a/packages/ui/src/components/FileInput/FileInput.stories.tsx +++ b/apps/storybook/src/FileInput.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { FileInputProps } from "./FileInput"; -import { FileInput } from "./FileInput"; +import type { FileInputProps } from "flowbite-react"; +import { FileInput } from "flowbite-react"; export default { title: "Components/FileInput", diff --git a/packages/ui/src/components/FloatingLabel/FloatingLabel.stories.tsx b/apps/storybook/src/FloatingLabel.stories.tsx similarity index 88% rename from packages/ui/src/components/FloatingLabel/FloatingLabel.stories.tsx rename to apps/storybook/src/FloatingLabel.stories.tsx index 0c1081045..6eae6add6 100644 --- a/packages/ui/src/components/FloatingLabel/FloatingLabel.stories.tsx +++ b/apps/storybook/src/FloatingLabel.stories.tsx @@ -1,5 +1,5 @@ import type { Meta, StoryFn } from "@storybook/react"; -import { FloatingLabel, type FloatingLabelProps } from "./FloatingLabel"; +import { FloatingLabel, type FloatingLabelProps } from "flowbite-react"; export default { title: "Components/FloatingLabel", @@ -101,10 +101,3 @@ SmallStandard.args = { label: "Small Standard", sizing: "sm", }; - -export const HelperText = Template.bind({}); -HelperText.args = { - variant: "filled", - label: "Floating Helper", - helperText: "Remember, contributions to this topic should follow our Community Guidelines.", -}; diff --git a/apps/storybook/src/Footer.stories.tsx b/apps/storybook/src/Footer.stories.tsx new file mode 100644 index 000000000..f5590ef01 --- /dev/null +++ b/apps/storybook/src/Footer.stories.tsx @@ -0,0 +1,170 @@ +import type { Meta, StoryFn } from "@storybook/react"; +import { + Footer, + FooterBrand, + FooterCopyright, + FooterDivider, + FooterIcon, + FooterLink, + FooterLinkGroup, + FooterTitle, +} from "flowbite-react"; +import { BsDribbble, BsFacebook, BsGithub, BsInstagram, BsTwitter } from "react-icons/bs"; + +export default { + title: "Components/Footer", + component: Footer, +} as Meta; + +const Template: StoryFn = ({ children }) =>
{children}
; + +export const DefaultFooter = Template.bind({}); +DefaultFooter.storyName = "Default"; +DefaultFooter.args = { + children: ( +
+ + + About + Privacy Policy + Licensing + Contact + +
+ ), +}; + +export const WithLogoFooter = Template.bind({}); +WithLogoFooter.storyName = "With Logo"; +WithLogoFooter.args = { + children: ( +
+
+ + + About + Privacy Policy + Licensing + Contact + +
+ + +
+ ), +}; + +export const WithSocialMediaFooter = Template.bind({}); +WithSocialMediaFooter.storyName = "Social Media Icons"; +WithSocialMediaFooter.args = { + container: true, + children: ( +
+
+
+ +
+
+
+ + + Flowbite + Tailwind CSS + +
+
+ + + Github + Discord + +
+
+ + + Privacy Policy + Terms & Conditions + +
+
+
+ +
+ +
+ + + + + +
+
+
+ ), +}; + +export const SitemapLinksFooter = Template.bind({}); +SitemapLinksFooter.storyName = "Sitemap Links"; +SitemapLinksFooter.args = { + children: ( +
+
+
+ + + About + Careers + Brand Center + Blog + +
+
+ + + Discord Server + Twitter + Facebook + Contact Us + +
+
+ + + Privacy Policy + Licensing + Terms & Conditions + +
+
+ + + iOS + Android + Windows + MacOS + +
+
+
+ +
+ + + + + +
+
+
+ ), +}; diff --git a/packages/ui/src/components/HR/HR.stories.tsx b/apps/storybook/src/HR.stories.tsx similarity index 68% rename from packages/ui/src/components/HR/HR.stories.tsx rename to apps/storybook/src/HR.stories.tsx index 4ff5aef40..8454b79a8 100644 --- a/packages/ui/src/components/HR/HR.stories.tsx +++ b/apps/storybook/src/HR.stories.tsx @@ -1,14 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { HRProps } from "./HR"; -import { HR } from "./HR"; -import { HRIcon } from "./HRIcon"; -import type { HRIconProps } from "./HRIcon"; -import type { HRSquareProps } from "./HRSquare"; -import { HRSquare } from "./HRSquare"; -import { HRText } from "./HRText"; -import type { HRTextProps } from "./HRText"; -import type { HRTrimmedProps } from "./HRTrimmed"; -import { HRTrimmed } from "./HRTrimmed"; +import type { HRIconProps, HRProps, HRSquareProps, HRTextProps, HRTrimmedProps } from "flowbite-react"; +import { HR, HRIcon, HRSquare, HRText, HRTrimmed } from "flowbite-react"; export default { title: "Components/HR", diff --git a/packages/ui/src/components/Kbd/Kbd.stories.tsx b/apps/storybook/src/Kbd.stories.tsx similarity index 88% rename from packages/ui/src/components/Kbd/Kbd.stories.tsx rename to apps/storybook/src/Kbd.stories.tsx index c13053519..f4c8bed07 100644 --- a/packages/ui/src/components/Kbd/Kbd.stories.tsx +++ b/apps/storybook/src/Kbd.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryFn } from "@storybook/react"; +import type { KbdProps } from "flowbite-react"; +import { Kbd } from "flowbite-react"; import { MdKeyboardArrowDown, MdKeyboardCommandKey } from "react-icons/md"; -import type { KbdProps } from "./Kbd"; -import { Kbd } from "./Kbd"; export default { title: "Components/Kbd", diff --git a/packages/ui/src/components/Label/Label.stories.tsx b/apps/storybook/src/Label.stories.tsx similarity index 78% rename from packages/ui/src/components/Label/Label.stories.tsx rename to apps/storybook/src/Label.stories.tsx index a8e9ea77b..732509c22 100644 --- a/packages/ui/src/components/Label/Label.stories.tsx +++ b/apps/storybook/src/Label.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { LabelProps } from "./Label"; -import { Label } from "./Label"; +import type { LabelProps } from "flowbite-react"; +import { Label } from "flowbite-react"; export default { title: "Components/Label", diff --git a/packages/ui/src/components/List/List.stories.tsx b/apps/storybook/src/List.stories.tsx similarity index 65% rename from packages/ui/src/components/List/List.stories.tsx rename to apps/storybook/src/List.stories.tsx index fc2b72d22..7c39e12cd 100644 --- a/packages/ui/src/components/List/List.stories.tsx +++ b/apps/storybook/src/List.stories.tsx @@ -1,8 +1,7 @@ import type { Meta, StoryFn } from "@storybook/react"; +import { Avatar, List, ListItem } from "flowbite-react"; +import type { ListProps } from "flowbite-react"; import { HiCheckCircle } from "react-icons/hi"; -import { Avatar } from "../Avatar"; -import type { ListProps } from "./List"; -import { List } from "./List"; export default { title: "Components/List", @@ -16,9 +15,9 @@ DefaultList.storyName = "Default"; DefaultList.args = { children: ( <> - At least 10 characters (and up to 100 characters) - At least one lowercase character - Inclusion of at least one special character, e.g., ! @ # ? + At least 10 characters (and up to 100 characters) + At least one lowercase character + Inclusion of at least one special character, e.g., ! @ # ? ), }; @@ -29,9 +28,9 @@ UnstyledList.args = { unstyled: true, children: ( <> - At least 10 characters (and up to 100 characters) - At least one lowercase character - Inclusion of at least one special character, e.g., ! @ # ? + At least 10 characters (and up to 100 characters) + At least one lowercase character + Inclusion of at least one special character, e.g., ! @ # ? ), }; @@ -41,30 +40,30 @@ NestedList.storyName = "Nested"; NestedList.args = { children: ( <> - + List item one - You might feel like you are being really "organized" o - Nested navigation in UIs is a bad idea too, keep things as flat as possible. - Nesting tons of folders in your source code is also not helpful. + You might feel like you are being really "organized" o + Nested navigation in UIs is a bad idea too, keep things as flat as possible. + Nesting tons of folders in your source code is also not helpful. - - + + List item two - I'm not sure if we'll bother styling more than two levels deep. - Two is already too much, three is guaranteed to be a bad idea. - If you nest four levels deep you belong in prison. + I'm not sure if we'll bother styling more than two levels deep. + Two is already too much, three is guaranteed to be a bad idea. + If you nest four levels deep you belong in prison. - - + + List item three - Again please don't nest lists if you want - Nobody wants to look at this. - I'm upset that we even have to bother styling this. + Again please don't nest lists if you want + Nobody wants to look at this. + I'm upset that we even have to bother styling this. - + ), }; @@ -75,9 +74,9 @@ OrderedList.args = { ordered: true, children: ( <> - At least 10 characters (and up to 100 characters) - At least one lowercase character - Inclusion of at least one special character, e.g., ! @ # ? + At least 10 characters (and up to 100 characters) + At least one lowercase character + Inclusion of at least one special character, e.g., ! @ # ? ), }; @@ -88,13 +87,13 @@ HorizontalList.args = { horizontal: true, children: ( <> - About - Premium - Campaigns - Blog - Affiliate Program - FAQs - Contact + About + Premium + Campaigns + Blog + Affiliate Program + FAQs + Contact ), }; @@ -104,9 +103,9 @@ WithIconList.storyName = "With Icon"; WithIconList.args = { children: ( <> - At least 10 characters (and up to 100 characters) - At least one lowercase character - Inclusion of at least one special character, e.g., ! @ # ? + At least 10 characters (and up to 100 characters) + At least one lowercase character + Inclusion of at least one special character, e.g., ! @ # ? ), }; @@ -118,7 +117,7 @@ AdvancedList.args = { className: "max-w-md divide-y divide-gray-200 dark:divide-gray-700", children: ( <> - +
$320
-
- + +
$3467
-
- + +
$67
-
- + +
$2367
-
- + +
$367
-
+ ), }; diff --git a/apps/storybook/src/ListGroup.stories.tsx b/apps/storybook/src/ListGroup.stories.tsx new file mode 100644 index 000000000..e1c044307 --- /dev/null +++ b/apps/storybook/src/ListGroup.stories.tsx @@ -0,0 +1,69 @@ +import type { Meta, StoryFn } from "@storybook/react"; +import type { ListGroupProps } from "flowbite-react"; +import { ListGroup, ListGroupItem } from "flowbite-react"; +import { HiCloudDownload, HiInbox, HiOutlineAdjustments, HiUserCircle } from "react-icons/hi"; + +export default { + title: "Components/ListGroup", + component: ListGroup, +} as Meta; + +const Template: StoryFn = (args) => ; + +export const DefaultListGroup = Template.bind({}); +DefaultListGroup.storyName = "Default"; +DefaultListGroup.args = { + children: ( + <> + Profile + Settings + Messages + Download + + ), +}; + +export const WithLinks = Template.bind({}); +WithLinks.storyName = "With links"; +WithLinks.args = { + children: ( + <> + + Profile + + Settings + Messages + Download + + ), +}; + +export const WithButtons = Template.bind({}); +WithButtons.storyName = "With buttons"; +WithButtons.args = { + children: ( + <> + alert("Profile clicked!")}> + Profile + + Settings + Messages + Download + + ), +}; + +export const WithIcons = Template.bind({}); +WithIcons.storyName = "With icons"; +WithIcons.args = { + children: ( + <> + + Profile + + Settings + Messages + Download + + ), +}; diff --git a/packages/ui/src/components/MegaMenu/MegaMenu.stories.tsx b/apps/storybook/src/MegaMenu.stories.tsx similarity index 92% rename from packages/ui/src/components/MegaMenu/MegaMenu.stories.tsx rename to apps/storybook/src/MegaMenu.stories.tsx index 78149c704..771defff3 100644 --- a/packages/ui/src/components/MegaMenu/MegaMenu.stories.tsx +++ b/apps/storybook/src/MegaMenu.stories.tsx @@ -1,9 +1,14 @@ import type { Meta, StoryFn } from "@storybook/react"; -import { Button } from "../Button"; -import { NavbarBrand, NavbarCollapse, NavbarLink, NavbarToggle } from "../Navbar"; -import type { MegaMenuProps } from "./MegaMenu"; -import { MegaMenu } from "./MegaMenu"; -import { MegaMenuDropdown } from "./MegaMenuDropdown"; +import { + Button, + MegaMenu, + MegaMenuDropdown, + NavbarBrand, + NavbarCollapse, + NavbarLink, + NavbarToggle, +} from "flowbite-react"; +import type { MegaMenuProps } from "flowbite-react"; export default { title: "Components/MegaMenu", diff --git a/packages/ui/src/components/Modal/Modal.stories.tsx b/apps/storybook/src/Modal.stories.tsx similarity index 86% rename from packages/ui/src/components/Modal/Modal.stories.tsx rename to apps/storybook/src/Modal.stories.tsx index 975c5c805..5add410f4 100644 --- a/packages/ui/src/components/Modal/Modal.stories.tsx +++ b/apps/storybook/src/Modal.stories.tsx @@ -1,12 +1,8 @@ import { action } from "@storybook/addon-actions"; import type { Meta, StoryFn } from "@storybook/react"; +import { Button, Checkbox, Label, Modal, ModalBody, ModalFooter, ModalHeader, TextInput } from "flowbite-react"; +import type { ModalProps } from "flowbite-react"; import { HiOutlineExclamationCircle } from "react-icons/hi"; -import { Button } from "../Button"; -import { Checkbox } from "../Checkbox"; -import { Label } from "../Label"; -import { TextInput } from "../TextInput"; -import type { ModalProps } from "./Modal"; -import { Modal } from "./Modal"; export default { title: "Components/Modal", @@ -31,8 +27,8 @@ export const Default = Template.bind({}); Default.args = { children: ( <> - Terms of Service - + Terms of Service +

With less than a month to go before the European Union enacts new consumer privacy laws for its citizens, @@ -44,13 +40,13 @@ Default.args = { soon as possible of high-risk data breaches that could personally affect them.

-
- + + - + ), }; @@ -59,7 +55,7 @@ export const PopUp = Template.bind({}); PopUp.storyName = "Pop-up modal"; PopUp.args = { children: ( - +

@@ -74,7 +70,7 @@ PopUp.args = {

-
+ ), }; @@ -83,19 +79,19 @@ FormElements.storyName = "Form elements"; FormElements.args = { children: ( <> - - + +

Sign in to our platform

-
-
@@ -118,7 +114,7 @@ FormElements.args = {
-
+ ), }; diff --git a/apps/storybook/src/Navbar.stories.tsx b/apps/storybook/src/Navbar.stories.tsx new file mode 100644 index 000000000..015b50f4b --- /dev/null +++ b/apps/storybook/src/Navbar.stories.tsx @@ -0,0 +1,116 @@ +import type { Meta, StoryFn } from "@storybook/react"; +import { + Avatar, + Button, + Dropdown, + DropdownDivider, + DropdownHeader, + DropdownItem, + Navbar, + NavbarBrand, + NavbarCollapse, + NavbarLink, + NavbarToggle, + type NavbarProps, +} from "flowbite-react"; + +export default { + title: "Components/Navbar", + component: Navbar, +} as Meta; + +const Template: StoryFn = (args) => ( +
+ +
+); + +export const DefaultNavbar = Template.bind({}); +DefaultNavbar.storyName = "Default"; +DefaultNavbar.args = { + children: ( + <> + + Flowbite Logo + Flowbite + + + + + Home + + About + Services + Pricing + Contact + + + ), +}; + +export const WithCTA = Template.bind({}); +WithCTA.args = { + children: ( + <> + + Flowbite Logo + Flowbite + +
+ + +
+ + + Home + + About + Services + Pricing + Contact + + + ), +}; + +export const WithDropdown = Template.bind({}); +WithDropdown.storyName = "With dropdown"; +WithDropdown.args = { + children: ( + <> + + Flowbite Logo + Flowbite + +
+ + } + > + + Bonnie Green + name@flowbite.com + + Dashboard + Settings + Earnings + + Sign out + + +
+ + + Home + + About + Services + Pricing + Contact + + + ), +}; diff --git a/packages/ui/src/components/Pagination/Pagination.stories.tsx b/apps/storybook/src/Pagination.stories.tsx similarity index 93% rename from packages/ui/src/components/Pagination/Pagination.stories.tsx rename to apps/storybook/src/Pagination.stories.tsx index 21341e39a..2854e258d 100644 --- a/packages/ui/src/components/Pagination/Pagination.stories.tsx +++ b/apps/storybook/src/Pagination.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryFn } from "@storybook/react"; +import type { PaginationProps } from "flowbite-react"; +import { Pagination } from "flowbite-react"; import { useEffect, useState } from "react"; -import type { PaginationProps } from "./Pagination"; -import { Pagination } from "./Pagination"; export default { title: "Components/Pagination", diff --git a/packages/ui/src/components/Popover/Popover.stories.tsx b/apps/storybook/src/Popover.stories.tsx similarity index 96% rename from packages/ui/src/components/Popover/Popover.stories.tsx rename to apps/storybook/src/Popover.stories.tsx index ef84f6e44..b3fb37254 100644 --- a/packages/ui/src/components/Popover/Popover.stories.tsx +++ b/apps/storybook/src/Popover.stories.tsx @@ -1,7 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; +import { Button, Popover, type PopoverProps } from "flowbite-react"; import { useState } from "react"; -import { Button } from "../Button"; -import { Popover, type PopoverProps } from "./Popover"; export default { title: "Components/Popover", diff --git a/packages/ui/src/components/Progress/Progress.stories.tsx b/apps/storybook/src/Progress.stories.tsx similarity index 96% rename from packages/ui/src/components/Progress/Progress.stories.tsx rename to apps/storybook/src/Progress.stories.tsx index 2b5adf343..d6cdbcbb4 100644 --- a/packages/ui/src/components/Progress/Progress.stories.tsx +++ b/apps/storybook/src/Progress.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { ProgressProps } from "./Progress"; -import { Progress } from "./Progress"; +import type { ProgressProps } from "flowbite-react"; +import { Progress } from "flowbite-react"; export default { title: "Components/Progress", diff --git a/packages/ui/src/components/Radio/Radio.stories.tsx b/apps/storybook/src/Radio.stories.tsx similarity index 77% rename from packages/ui/src/components/Radio/Radio.stories.tsx rename to apps/storybook/src/Radio.stories.tsx index b3c28fe6e..e16a8d188 100644 --- a/packages/ui/src/components/Radio/Radio.stories.tsx +++ b/apps/storybook/src/Radio.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { RadioProps } from "./Radio"; -import { Radio } from "./Radio"; +import type { RadioProps } from "flowbite-react"; +import { Radio } from "flowbite-react"; export default { title: "Components/Radio", diff --git a/packages/ui/src/components/RangeSlider/RangeSlider.stories.tsx b/apps/storybook/src/RangeSlider.stories.tsx similarity index 75% rename from packages/ui/src/components/RangeSlider/RangeSlider.stories.tsx rename to apps/storybook/src/RangeSlider.stories.tsx index 8d392d94a..efd8ea2b9 100644 --- a/packages/ui/src/components/RangeSlider/RangeSlider.stories.tsx +++ b/apps/storybook/src/RangeSlider.stories.tsx @@ -1,7 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import { theme } from "../../theme"; -import type { RangeSliderProps } from "./RangeSlider"; -import { RangeSlider } from "./RangeSlider"; +import type { RangeSliderProps } from "flowbite-react"; +import { RangeSlider, rangeSliderTheme } from "flowbite-react"; export default { title: "Components/RangeSlider", @@ -15,7 +14,7 @@ export default { ], argTypes: { sizing: { - options: Object.keys(theme.rangeSlider.field.input.sizes), + options: Object.keys(rangeSliderTheme.field.input.sizes), control: { type: "select" }, }, disabled: { diff --git a/packages/ui/src/components/Rating/Rating.stories.tsx b/apps/storybook/src/Rating.stories.tsx similarity index 62% rename from packages/ui/src/components/Rating/Rating.stories.tsx rename to apps/storybook/src/Rating.stories.tsx index 79be81766..98df87d89 100644 --- a/packages/ui/src/components/Rating/Rating.stories.tsx +++ b/apps/storybook/src/Rating.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { RatingProps } from "./Rating"; -import { Rating } from "./Rating"; +import type { RatingProps } from "flowbite-react"; +import { Rating, RatingAdvanced, RatingStar } from "flowbite-react"; export default { title: "Components/Rating", @@ -14,11 +14,11 @@ DefaultRating.storyName = "Default"; DefaultRating.args = { children: ( <> - - - - - + + + + + ), }; @@ -28,11 +28,11 @@ WithText.storyName = "With text"; WithText.args = { children: ( <> - - - - - + + + + +

4.95 out of 5

), @@ -43,7 +43,7 @@ RatingCount.storyName = "With rating count"; RatingCount.args = { children: ( <> - +

4.95

@@ -56,18 +56,18 @@ RatingCount.args = { export const Advanced = (): JSX.Element => (
- - - - - + + + + +

4.95 out of 5

1,745 global ratings

- 5 star - 4 star - 3 star - 2 star - 1 star + 5 star + 4 star + 3 star + 2 star + 1 star
); diff --git a/packages/ui/src/components/Select/Select.stories.tsx b/apps/storybook/src/Select.stories.tsx similarity index 89% rename from packages/ui/src/components/Select/Select.stories.tsx rename to apps/storybook/src/Select.stories.tsx index 5eaa06e3a..16861fb64 100644 --- a/packages/ui/src/components/Select/Select.stories.tsx +++ b/apps/storybook/src/Select.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryFn } from "@storybook/react"; +import type { SelectProps } from "flowbite-react"; +import { Select } from "flowbite-react"; import { BsFlagFill } from "react-icons/bs"; -import type { SelectProps } from "./Select"; -import { Select } from "./Select"; export default { title: "Components/Select", diff --git a/apps/storybook/src/Sidebar.stories.tsx b/apps/storybook/src/Sidebar.stories.tsx new file mode 100644 index 000000000..1aa350ae0 --- /dev/null +++ b/apps/storybook/src/Sidebar.stories.tsx @@ -0,0 +1,298 @@ +import type { Meta, StoryFn } from "@storybook/react"; +import { + Badge, + Button, + Sidebar, + SidebarCollapse, + SidebarCTA, + SidebarItem, + SidebarItemGroup, + SidebarItems, + SidebarLogo, + type SidebarProps, +} from "flowbite-react"; +import { BiBuoy } from "react-icons/bi"; +import { HiArrowSmRight, HiChartPie, HiInbox, HiShoppingBag, HiTable, HiUser, HiViewBoards } from "react-icons/hi"; + +export default { + title: "Components/Sidebar", + component: Sidebar, +} as Meta; + +const Template: StoryFn = (props) => ; + +export const Default = Template.bind({}); +Default.args = { + children: ( + <> + + + + Dashboard + + + Kanban + + + Inbox + + + Users + + + Products + + + Sign In + + + Sign Up + + + + + ), + collapsed: false, +}; + +export const WithoutIcons = Template.bind({}); +WithoutIcons.storyName = "No icons"; +WithoutIcons.args = { + children: ( + <> + + + Dashboard + + Kanban + + + Inbox + + Users + Products + Sign In + Sign Up + + + + ), + collapsed: false, +}; + +export const MultiLevelDropdown = Template.bind({}); +MultiLevelDropdown.storyName = "Multi-level dropdown"; +MultiLevelDropdown.args = { + children: ( + <> + + + + Dashboard + + + Products + + + Inbox + + + Users + + + Products + + + Sign In + + + Sign Up + + + + + ), + collapsed: false, +}; + +export const DefaultExpandedDropdown = Template.bind({}); +DefaultExpandedDropdown.args = { + children: ( + <> + + + + Dashboard + + + Products + + + Usage Summary + + + Inbox + + + Users + + + Products + + + Sign In + + + Sign Up + + + + + ), + collapsed: false, +}; + +export const ContentSeparator = Template.bind({}); +ContentSeparator.storyName = "Content separator"; +ContentSeparator.args = { + children: ( + <> + + + + Dashboard + + + Kanban + + + Inbox + + + Users + + + Products + + + Sign In + + + Sign Up + + + + + Upgrade to Pro + + + Documentation + + + Help + + + + + ), + collapsed: false, +}; + +export const CTAButton = Template.bind({}); +CTAButton.storyName = "CTA button"; +CTAButton.args = { + children: ( + <> + + + + Dashboard + + + Kanban + + + Inbox + + + Users + + + Products + + + Sign In + + + Sign Up + + + + +
+ Beta +
+ +
+
+

+ Preview the new Flowbite dashboard navigation! You can turn the new navigation off for a limited time in your + profile. +

+
+ Turn new navigation off + + + + ), + collapsed: false, +}; + +export const LogoBranding = Template.bind({}); +LogoBranding.storyName = "Logo branding"; +LogoBranding.args = { + children: ( + <> + + Flowbite + + + + + Dashboard + + + Kanban + + + Inbox + + + Users + + + Products + + + Sign In + + + Sign Up + + + + + ), + collapsed: false, +}; diff --git a/packages/ui/src/components/Spinner/Spinner.stories.tsx b/apps/storybook/src/Spinner.stories.tsx similarity index 96% rename from packages/ui/src/components/Spinner/Spinner.stories.tsx rename to apps/storybook/src/Spinner.stories.tsx index d2a74b95e..da7a49df1 100644 --- a/packages/ui/src/components/Spinner/Spinner.stories.tsx +++ b/apps/storybook/src/Spinner.stories.tsx @@ -1,6 +1,5 @@ import type { Meta, StoryFn } from "@storybook/react"; -import { Button } from "../Button"; -import { Spinner } from "./Spinner"; +import { Button, Spinner } from "flowbite-react"; export default { title: "Components/Spinner", diff --git a/apps/storybook/src/Table.stories.tsx b/apps/storybook/src/Table.stories.tsx new file mode 100644 index 000000000..0366872df --- /dev/null +++ b/apps/storybook/src/Table.stories.tsx @@ -0,0 +1,90 @@ +import type { Meta, StoryFn } from "@storybook/react"; +import type { TableProps } from "flowbite-react"; +import { Table, TableBody, TableCell, TableHead, TableHeadCell, TableRow } from "flowbite-react"; + +export default { + title: "Components/Tables", + component: Table, +} as Meta; + +const Template: StoryFn = (args) => ( + + + + Product name + Color + Category + Price + + Edit + + + + + + + Apple MacBook Pro 17" + + Sliver + Laptop + $2999 + + + Edit + + + + + + Microsoft Surface Pro + + White + Laptop PC + $1999 + + + Edit + + + + + Magic Mouse 2 + Black + Accessories + $99 + + + Edit + + + + + + Google Pixel Phone + + Gray + Phone + $799 + + + Edit + + + + + Apple Watch 5 + Red + Wearables + $999 + + + Edit + + + + +
+); + +export const DefaultTable = Template.bind({}); +DefaultTable.storyName = "Default"; diff --git a/apps/storybook/src/Tabs.stories.tsx b/apps/storybook/src/Tabs.stories.tsx new file mode 100644 index 000000000..ea0635aa7 --- /dev/null +++ b/apps/storybook/src/Tabs.stories.tsx @@ -0,0 +1,105 @@ +import type { Meta } from "@storybook/react"; +import type { TabsProps } from "flowbite-react"; +import { TabItem, Tabs } from "flowbite-react"; +import { HiAdjustments, HiClipboardList, HiUserCircle } from "react-icons/hi"; +import { MdDashboard } from "react-icons/md"; + +export default { + title: "Components/Tabs", + component: Tabs, + args: { + className: "bg-white rounded-lg dark:bg-gray-800 dark:text-white", + }, + argTypes: { + className: { + control: "text", + }, + variant: { + control: "radio", + options: ["default", "underline", "pills", "fullWidth"], + }, + }, +} as Meta; + +export const Default = (args: TabsProps): JSX.Element => ( + + Profile content + Dashboard content + Settings content + Contacts content + + Disabled content + + +); + +export const WithUnderline = (args: TabsProps): JSX.Element => ( + + Profile content + Dashboard content + Settings content + Contacts content + + Disabled content + + +); +WithUnderline.args = { + variant: "underline", +}; +WithUnderline.storyName = "With underline"; + +export const WithIcons = (args: TabsProps): JSX.Element => ( + + + Profile content + + + Dashboard content + + + Settings content + + + Contacts content + + + Disabled content + + +); +WithIcons.args = { + variant: "underline", +}; +WithIcons.storyName = "With icons"; + +export const Pills = (args: TabsProps): JSX.Element => ( + + Profile content + Dashboard content + Settings content + Contacts content + + Disabled content + + +); +Pills.args = { + variant: "pills", +}; + +export const FullWidth = (args: TabsProps): JSX.Element => ( + + Profile content + Dashboard content + Settings content + Contacts content + + Disabled content + + +); +FullWidth.args = { + variant: "fullWidth", +}; +FullWidth.storyName = "Full width"; diff --git a/packages/ui/src/components/TextInput/TextInput.stories.tsx b/apps/storybook/src/TextInput.stories.tsx similarity index 64% rename from packages/ui/src/components/TextInput/TextInput.stories.tsx rename to apps/storybook/src/TextInput.stories.tsx index da05865ae..94f5349a5 100644 --- a/packages/ui/src/components/TextInput/TextInput.stories.tsx +++ b/apps/storybook/src/TextInput.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { TextInputProps } from "./TextInput"; -import { TextInput } from "./TextInput"; +import type { TextInputProps } from "flowbite-react"; +import { TextInput } from "flowbite-react"; export default { title: "Components/TextInput", @@ -11,4 +11,6 @@ const Template: StoryFn = (args) => ; export const Default = Template.bind({}); Default.storyName = "Text input"; -Default.args = {}; +Default.args = { + placeholder: "Write your thoughts here...", +}; diff --git a/packages/ui/src/components/Textarea/Textarea.stories.tsx b/apps/storybook/src/Textarea.stories.tsx similarity index 66% rename from packages/ui/src/components/Textarea/Textarea.stories.tsx rename to apps/storybook/src/Textarea.stories.tsx index b232a87f1..534678387 100644 --- a/packages/ui/src/components/Textarea/Textarea.stories.tsx +++ b/apps/storybook/src/Textarea.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryFn } from "@storybook/react"; -import type { TextareaProps } from "./Textarea"; -import { Textarea } from "./Textarea"; +import type { TextareaProps } from "flowbite-react"; +import { Textarea } from "flowbite-react"; export default { title: "Components/Textarea", @@ -12,5 +12,6 @@ const Template: StoryFn = (args) =>