diff --git a/.gitignore b/.gitignore index 2c4105f7..2db2c100 100644 --- a/.gitignore +++ b/.gitignore @@ -43,7 +43,6 @@ next-env.d.ts *storybook.log # Storybook -.storybook /storybook-static/ # Playwright diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 00000000..c4ed6878 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,57 @@ +import type { StorybookConfig } from '@storybook/nextjs' + +const config: StorybookConfig = { + stories: [ + '../src/components/**/*.mdx', + '../src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)' + ], + staticDirs: ['../public'], + addons: [ + '@storybook/addon-onboarding', + '@storybook/addon-links', + '@storybook/addon-essentials', + '@chromatic-com/storybook', + '@storybook/addon-interactions', + '@storybook/addon-styling-webpack', + + { + name: '@storybook/addon-styling-webpack', + options: { + rules: [ + { + test: /\.css$/, + sideEffects: true, + use: [ + require.resolve('style-loader'), + { + loader: require.resolve('css-loader'), + options: { + importLoaders: 1 + } + }, + { + loader: require.resolve('postcss-loader'), + options: { + implementation: require.resolve('postcss') + } + } + ] + } + ] + } + } + ], + + framework: { + name: '@storybook/nextjs', + options: {} + }, + typescript: { + reactDocgen: 'react-docgen-typescript' + }, + docs: { + autodocs: 'tag' + }, + build: {} +} +export default config diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 00000000..d7963faa --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,34 @@ +import type { Preview } from '@storybook/react' + +import '../src/app/globals.css' + +import React from 'react' +import { ThemeProvider } from '../src/lib/theme/theme-provider' +import { IntlProvider } from 'react-intl' + +const preview: Preview = { + parameters: { + backgrounds: { + values: [{ name: 'Light', value: '#f4f4f5' }], + default: 'Light' + }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i + } + } + } +} + +export const decorators = [ + (Story) => ( + + + + + + ) +] + +export default preview diff --git a/package.json b/package.json index efc5870d..969fbd6f 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "build": "next build", "start": "next start -p 8081", "lint": "next lint --fix", - "storybook": "storybook dev -p 6006", + "storybook": "storybook dev -p 6007", "build-storybook": "storybook build", "extract:i18n": "tsx ./scripts/i18n-extract.ts", "compile:i18n": "formatjs compile-folder \"./locales/extracted\" --format simple \"./locales/compiled\"", diff --git a/src/app/(auth-routes)/signin/page.tsx b/src/app/(auth-routes)/signin/page.tsx index 9cfbeb34..044c458e 100644 --- a/src/app/(auth-routes)/signin/page.tsx +++ b/src/app/(auth-routes)/signin/page.tsx @@ -16,6 +16,7 @@ import { ArrowRight } from 'lucide-react' import React from 'react' import LoadingScreen from '@/components/loading-screen' import MidazLogo from '@/images/midaz-login-screen.png' +import BackgroundImage from '@/images/login-wallpaper.jpg' import { Tooltip, TooltipContent, @@ -172,7 +173,13 @@ const SignInPage = () => { -
+
+ Login background image
Midaz Logo diff --git a/src/components/form/input-field/input-field.mdx b/src/components/form/input-field/input-field.mdx new file mode 100644 index 00000000..15d8a2e9 --- /dev/null +++ b/src/components/form/input-field/input-field.mdx @@ -0,0 +1,35 @@ +import { Meta, Controls, Primary, Canvas, Stories } from '@storybook/blocks' +import * as Story from './input-field.stories' + + + +# InputField + +An implementation for easy use of Input component. + +### Basic + + + +### Required + + + +### With Tooltip + + + +### With Label Extra + + + +### Read Only + + + +### Disabled + + + + + diff --git a/src/components/form/input-field/input-field.stories.tsx b/src/components/form/input-field/input-field.stories.tsx new file mode 100644 index 00000000..bfb7158d --- /dev/null +++ b/src/components/form/input-field/input-field.stories.tsx @@ -0,0 +1,69 @@ +import { Meta, StoryObj } from '@storybook/react' +import { InputField, InputFieldProps } from '.' +import { useForm } from 'react-hook-form' +import { Form } from '@/components/ui/form' + +const meta: Meta = { + title: 'Components/Form/InputField', + component: InputField, + argTypes: {} +} + +export default meta + +function BaseComponent(args: Omit) { + const form = useForm() + + return ( +
+
+ + +
+ ) +} + +export const Primary: StoryObj = { + render: (args) => BaseComponent(args) +} + +export const Required: StoryObj = { + args: { + required: true + }, + render: (args) => BaseComponent(args) +} + +export const WithTooltip: StoryObj = { + args: { + tooltip: 'This is a Tooltip!' + }, + render: (args) => BaseComponent(args) +} + +export const WithExtraLabel: StoryObj = { + args: { + labelExtra: Extra Label + }, + render: (args) => BaseComponent(args) +} + +export const ReadOnly: StoryObj = { + args: { + readOnly: true + }, + render: (args) => BaseComponent(args) +} + +export const Disabled: StoryObj = { + args: { + disabled: true + }, + render: (args) => BaseComponent(args) +} diff --git a/src/components/form/select-field/select-field.mdx b/src/components/form/select-field/select-field.mdx new file mode 100644 index 00000000..5bb5eb58 --- /dev/null +++ b/src/components/form/select-field/select-field.mdx @@ -0,0 +1,31 @@ +import { Meta, Controls, Primary, Canvas, Stories } from '@storybook/blocks' +import * as Story from './select-field.stories' + + + +# SelectField + +An implementation for easy use of Select component. + +### Basic + + + +### Required + + + +### With Tooltip + + + +### With Label Extra + + + +### Disabled + + + + + diff --git a/src/components/form/select-field/select-field.stories.tsx b/src/components/form/select-field/select-field.stories.tsx new file mode 100644 index 00000000..8ac87bb2 --- /dev/null +++ b/src/components/form/select-field/select-field.stories.tsx @@ -0,0 +1,67 @@ +import { Meta, StoryObj } from '@storybook/react' +import { SelectField, SelectFieldProps } from '.' +import { useForm } from 'react-hook-form' +import { Form } from '@/components/ui/form' +import { SelectItem } from '@/components/ui/select' + +const meta: Meta = { + title: 'Components/Form/SelectField', + component: SelectField, + argTypes: {} +} + +export default meta + +function BaseComponent(args: Omit) { + const form = useForm() + + return ( +
+
+ + Apple + Banana + Orange + +
+
+ ) +} + +export const Primary: StoryObj = { + render: (args) => BaseComponent(args) +} + +export const Required: StoryObj = { + args: { + required: true + }, + render: (args) => BaseComponent(args) +} + +export const WithTooltip: StoryObj = { + args: { + tooltip: 'This is a Tooltip!' + }, + render: (args) => BaseComponent(args) +} + +export const WithExtraLabel: StoryObj = { + args: { + labelExtra: Extra Label + }, + render: (args) => BaseComponent(args) +} + +export const Disabled: StoryObj = { + args: { + disabled: true + }, + render: (args) => BaseComponent(args) +} diff --git a/src/components/loading-screen.tsx b/src/components/loading-screen.tsx index 650f19b0..35dbc4cb 100644 --- a/src/components/loading-screen.tsx +++ b/src/components/loading-screen.tsx @@ -1,6 +1,8 @@ 'use client' import React from 'react' +import Image from 'next/image' +import LoadingImage from '@/images/loading-wallpaper.jpg' import midazLoading from '@/animations/midaz-loading.json' import { Lottie } from '@/lib/lottie' @@ -10,7 +12,8 @@ type LoadingScreenProps = { const LoadingScreen = ({ onComplete }: LoadingScreenProps) => { return ( -
+
+ Loading image
+ +# Alert + +Displays a callout for user attention. + +### Primary + + + +### Destructive + + + + + diff --git a/src/components/ui/alert/alert.stories.tsx b/src/components/ui/alert/alert.stories.tsx new file mode 100644 index 00000000..6506a80a --- /dev/null +++ b/src/components/ui/alert/alert.stories.tsx @@ -0,0 +1,36 @@ +import { Meta, StoryObj } from '@storybook/react' +import { Alert, AlertDescription, AlertProps, AlertTitle } from '.' +import { Terminal } from 'lucide-react' + +const meta: Meta = { + title: 'Primitives/Alert', + component: Alert, + argTypes: {} +} + +export default meta + +export const Primary: StoryObj = { + render: (args) => ( + + + Heads up! + This is an alert component + + ) +} + +export const Destructive: StoryObj = { + args: { + variant: 'destructive' + }, + render: (args) => ( + + + Error + + Your session has expired. Please log in again. + + + ) +} diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert/index.tsx similarity index 80% rename from src/components/ui/alert.tsx rename to src/components/ui/alert/index.tsx index 65019c6d..6fd7a005 100644 --- a/src/components/ui/alert.tsx +++ b/src/components/ui/alert/index.tsx @@ -19,17 +19,19 @@ const alertVariants = cva( } ) -const Alert = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes & VariantProps ->(({ className, variant, ...props }, ref) => ( -
-)) +export type AlertProps = React.HTMLAttributes & + VariantProps + +const Alert = React.forwardRef( + ({ className, variant, ...props }, ref) => ( +
+ ) +) Alert.displayName = 'Alert' const AlertTitle = React.forwardRef< diff --git a/src/components/ui/button/button.mdx b/src/components/ui/button/button.mdx index 17704d0e..9707f609 100644 --- a/src/components/ui/button/button.mdx +++ b/src/components/ui/button/button.mdx @@ -27,9 +27,17 @@ This is a button component. +### Full Width + + + ### With leading icon +### With leading icon at end + + + diff --git a/src/components/ui/button/button.stories.tsx b/src/components/ui/button/button.stories.tsx index 35f8a6cd..02744bb0 100644 --- a/src/components/ui/button/button.stories.tsx +++ b/src/components/ui/button/button.stories.tsx @@ -58,9 +58,26 @@ export const Outline: StoryObj = { } } +export const FullWidth: StoryObj = { + args: { + fullWidth: true, + children: 'Button' + }, + render: (args) => + + + + Edit profile + + Make changes to your profile here. Click save when you are done. + + + + + + + + ) +} diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog/index.tsx similarity index 100% rename from src/components/ui/dialog.tsx rename to src/components/ui/dialog/index.tsx diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover/index.tsx similarity index 100% rename from src/components/ui/popover.tsx rename to src/components/ui/popover/index.tsx diff --git a/src/components/ui/popover/popover.mdx b/src/components/ui/popover/popover.mdx new file mode 100644 index 00000000..cf9574be --- /dev/null +++ b/src/components/ui/popover/popover.mdx @@ -0,0 +1,12 @@ +import { Meta, Controls, Primary, Canvas } from '@storybook/blocks' +import * as Story from './popover.stories' + + + +# Popover + +Displays rich content in a portal, triggered by a button. + +### Primary + + diff --git a/src/components/ui/popover/popover.stories.tsx b/src/components/ui/popover/popover.stories.tsx new file mode 100644 index 00000000..3c556fd9 --- /dev/null +++ b/src/components/ui/popover/popover.stories.tsx @@ -0,0 +1,25 @@ +import { Popover, PopoverContent, PopoverTrigger } from '.' +import { Meta, StoryObj } from '@storybook/react' +import { Button } from '../button' +import { PopoverProps } from '@radix-ui/react-popover' + +const meta: Meta = { + title: 'Primitives/Popover', + component: Popover, + argTypes: {} +} + +export default meta + +export const Primary: StoryObj = { + render: (args) => ( + + + + + +

This is a Popover!

+
+
+ ) +} diff --git a/src/components/ui/sheet.tsx b/src/components/ui/sheet/index.tsx similarity index 100% rename from src/components/ui/sheet.tsx rename to src/components/ui/sheet/index.tsx diff --git a/src/components/ui/sheet/sheet.mdx b/src/components/ui/sheet/sheet.mdx new file mode 100644 index 00000000..0af9243b --- /dev/null +++ b/src/components/ui/sheet/sheet.mdx @@ -0,0 +1,20 @@ +import { Meta, Controls, Primary, Canvas } from '@storybook/blocks' +import * as Story from './sheet.stories' + + + +# Dialog + +Extends the Dialog component to display content that complements the main content of the screen. \ +[Docs](https://www.radix-ui.com/primitives/docs/components/dialog) + + + +### Sides + +Use the side property to SheetContent to indicate the edge of the screen where the component will appear. The values can be top, right, bottom or left. + + + + + diff --git a/src/components/ui/sheet/sheet.stories.tsx b/src/components/ui/sheet/sheet.stories.tsx new file mode 100644 index 00000000..694c8dd9 --- /dev/null +++ b/src/components/ui/sheet/sheet.stories.tsx @@ -0,0 +1,77 @@ +import { + Sheet, + SheetClose, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger +} from '.' +import { Meta, StoryObj } from '@storybook/react' +import { Button } from '../button' + +const meta: Meta = { + title: 'Primitives/Sheet', + component: Sheet, + argTypes: {} +} + +export default meta + +export const Primary: StoryObj = { + render: (args) => ( + + Open + + + Are you absolutely sure? + + This action cannot be undone. This will permanently delete your + account and remove your data from our servers. + + + + + ) +} + +const SHEET_SIDES = ['top', 'right', 'bottom', 'left'] as const + +type SheetSide = (typeof SHEET_SIDES)[number] + +export const SheetSide: StoryObj = { + render: (args) => { + return ( +
+ {SHEET_SIDES.map((side) => ( + + + + + + + Edit profile + + Make changes to your profile here. Click save when you are + done. + + +
+

Content

+

Content

+

Content

+

Content

+
+ + + + + +
+
+ ))} +
+ ) + } +} diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch/index.tsx similarity index 100% rename from src/components/ui/switch.tsx rename to src/components/ui/switch/index.tsx diff --git a/src/components/ui/switch/switch.mdx b/src/components/ui/switch/switch.mdx new file mode 100644 index 00000000..d9abc06c --- /dev/null +++ b/src/components/ui/switch/switch.mdx @@ -0,0 +1,20 @@ +import { Meta, Controls, Primary, Canvas } from '@storybook/blocks' +import * as Story from './switch.stories' + + + +# Switch + +A control that allows the user to toggle between checked and not checked. \ +[Docs](https://www.radix-ui.com/primitives/docs/components/switch) + +### Primary + + + +### With Text + + + + + diff --git a/src/components/ui/switch/switch.stories.tsx b/src/components/ui/switch/switch.stories.tsx new file mode 100644 index 00000000..86f5942b --- /dev/null +++ b/src/components/ui/switch/switch.stories.tsx @@ -0,0 +1,25 @@ +import { Meta, StoryObj } from '@storybook/react' +import { Switch } from '.' +import { SwitchProps } from '@radix-ui/react-switch' +import { Label } from '../label' + +const meta: Meta = { + title: 'Primitives/Switch', + component: Switch, + argTypes: {} +} + +export default meta + +export const Primary: StoryObj = { + render: (args) => +} + +export const WithText: StoryObj = { + render: (args) => ( +
+ + +
+ ) +} diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip/index.tsx similarity index 100% rename from src/components/ui/tooltip.tsx rename to src/components/ui/tooltip/index.tsx diff --git a/src/components/ui/tooltip/tooltip.mdx b/src/components/ui/tooltip/tooltip.mdx new file mode 100644 index 00000000..6dad9494 --- /dev/null +++ b/src/components/ui/tooltip/tooltip.mdx @@ -0,0 +1,29 @@ +import { Meta, Controls, Primary, Canvas } from '@storybook/blocks' +import * as Story from './tooltip.stories' + + + +# Tooltip + +A window overlaid on either the primary window or another dialog window, +rendering the content underneath inert. \ +[Docs](https://www.radix-ui.com/primitives/docs/components/tooltip) + +### Primary + + + +### Delay + +The delay can be changed to zero (instantly) too. + + + +### Position + +Tooltip can be displayed in all sides of the trigger component. + + + + + diff --git a/src/components/ui/tooltip/tooltip.stories.tsx b/src/components/ui/tooltip/tooltip.stories.tsx new file mode 100644 index 00000000..be57da36 --- /dev/null +++ b/src/components/ui/tooltip/tooltip.stories.tsx @@ -0,0 +1,92 @@ +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '.' +import { Meta, StoryObj } from '@storybook/react' +import { Button } from '../button' +import { TooltipProps } from '@radix-ui/react-tooltip' + +const meta: Meta = { + title: 'Primitives/Tooltip', + component: Tooltip, + argTypes: {} +} + +export default meta + +export const Primary: StoryObj = { + render: (args) => ( + + + + + + +

Add to library

+
+
+
+ ) +} + +export const WithoutDelay: StoryObj = { + args: { + delayDuration: 0 + }, + render: (args) => ( + + + + + + +

Add to library

+
+
+
+ ) +} + +export const WithSides: StoryObj = { + render: (args) => ( +
+ + + + + + +

This is a Tooltip!

+
+
+
+ + + + + + +

This is a Tooltip!

+
+
+
+ + + + + + +

This is a Tooltip!

+
+
+
+ + + + + + +

This is a Tooltip!

+
+
+
+
+ ) +} diff --git a/tailwind.config.ts b/tailwind.config.ts index d4d9ba6e..2cb799ef 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -29,10 +29,6 @@ const config = { entityBox: '0px 10px 20px rgba(0, 0, 0, 0.05), 0px 1px 2px rgba(0, 0, 0, 0.10)' }, - backgroundImage: { - 'login-wallpaper': "url('/images/login-wallpaper.jpg')", - 'loading-wallpaper': "url('/images/loading-wallpaper.jpg')" - }, colors: { sunglow: { '50': '#fefbe8',