From 961c74aa0b625c1d5d2aa42222ec8135cba63797 Mon Sep 17 00:00:00 2001 From: Rodrigo Dias Date: Tue, 16 Jul 2024 12:49:17 -0300 Subject: [PATCH] feat: storybook - add Autocomplete / changes in Avatar and App Bar --- stories/AppBar.stories.tsx | 6 +- stories/AutocompleteField.stories.tsx | 132 ++++++++++++++++++++++++++ stories/Avatar.stories.tsx | 6 ++ stories/assets/rockets.svg | 1 + 4 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 stories/AutocompleteField.stories.tsx create mode 100644 stories/assets/rockets.svg diff --git a/stories/AppBar.stories.tsx b/stories/AppBar.stories.tsx index 83c734a3..43148792 100644 --- a/stories/AppBar.stories.tsx +++ b/stories/AppBar.stories.tsx @@ -3,16 +3,14 @@ import React from 'react'; import { AppBar } from '@concepta/react-material-ui'; import { Box, MenuItem } from '@mui/material'; -import RocketIcon from '@mui/icons-material/RocketOutlined'; import PersonIcon from '@mui/icons-material/PersonOutlineOutlined'; import HomeIcon from '@mui/icons-material/HomeOutlined'; +import rockets from './assets/rockets.svg'; const Component = (args) => ( - } + logo={rockets} items={[ { icon: , diff --git a/stories/AutocompleteField.stories.tsx b/stories/AutocompleteField.stories.tsx new file mode 100644 index 00000000..744c4f66 --- /dev/null +++ b/stories/AutocompleteField.stories.tsx @@ -0,0 +1,132 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { fn } from '@storybook/test'; +import { http, HttpResponse } from 'msw'; + +import { AutocompleteField } from '@concepta/react-material-ui'; + +const meta = { + component: AutocompleteField, + tags: ['autodocs'], + argTypes: {}, + args: { + label: 'Autocomplete Field', + }, + parameters: { + msw: { + handlers: [ + http.get('/food', ({ request }) => { + const url = new URL(request.url); + const sort = url.searchParams.get('sort'); + const sortField = sort?.split(',')[0]; + const sortOrder = sort?.split(',')[1]; + const filters = url.searchParams.get('filters[]'); + const type = filters?.split('||$eq||')[1]; + + const foodArray = [ + { id: 1, name: 'Carrot', type: 'fruit' }, + { id: 2, name: 'Cesar Salad', type: 'healthy' }, + { id: 3, name: 'Apple', type: 'fruit' }, + { id: 4, name: 'Pizza', type: 'junk' }, + { id: 5, name: 'Banana', type: 'fruit' }, + { id: 6, name: 'Hamburguer', type: 'junk' }, + { id: 7, name: 'Sardines', type: 'healthy' }, + ]; + + return HttpResponse.json( + foodArray + .sort((a, b) => { + if (!sortField || !a[sortField] || !b[sortField]) return 0; + + if (sortField === 'id') { + return sortOrder === 'ASC' ? a.id - b.id : b.id - a.id; + } + + if (sortOrder === 'ASC') { + return a[sortField]?.localeCompare(b[sortField]); + } + + if (sortOrder === 'DESC') { + return b[sortField]?.localeCompare(a[sortField]); + } + + return 0; + }) + .filter((food) => { + return type ? food.type === type : true; + }), + ); + }), + ], + }, + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + options: [ + { value: '1', label: 'Option 1' }, + { value: '2', label: 'Option 2' }, + { value: '3', label: 'Option 3' }, + ], + label: 'Autocomplete Field', + isLoading: false, + onChange: fn(), + }, +}; + +export const WithOptions: Story = { + args: { + options: [ + { value: '1', label: 'Option 1' }, + { value: '2', label: 'Option 2' }, + { value: '3', label: 'Option 3' }, + ], + }, +}; + +export const Loading: Story = { + args: { + isLoading: true, + }, +}; + +/** + * If you provide a "resource" prop, the component will fetch the data from the provided path. + * + * The "resourceLabel" and "resourceValue" props are used to define the label and value of the options. + */ +export const ResourceData: Story = { + args: { + label: 'Food', + resource: 'food', + resourceLabel: 'name', + resourceValue: 'id', + }, +}; + +/** + * You can also provide filters and sort options to the resource. + */ +export const ResourceDataWithFilters: Story = { + args: { + label: 'Junk food', + resource: 'food', + resourceLabel: 'name', + resourceValue: 'id', + filters: { 'type||$eq||': 'junk' }, + }, +}; + +export const ResourceDataWithSort: Story = { + args: { + label: 'Sorted by name', + resource: 'food', + resourceLabel: 'name', + resourceValue: 'id', + sort: 'name,ASC', + }, +}; diff --git a/stories/Avatar.stories.tsx b/stories/Avatar.stories.tsx index eb8c2ea4..51fdc2df 100644 --- a/stories/Avatar.stories.tsx +++ b/stories/Avatar.stories.tsx @@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { fn } from '@storybook/test'; import { Avatar } from '@concepta/react-material-ui'; +import rockets from './assets/rockets.svg'; const meta = { component: Avatar, @@ -46,8 +47,13 @@ export const CustomSize: Story = { }, }; +/** + * Background color will only be visible for images with transparency. + */ + export const CustomBackgroundColor: Story = { args: { + src: rockets, backgroundColor: '#00bbff', }, }; diff --git a/stories/assets/rockets.svg b/stories/assets/rockets.svg new file mode 100644 index 00000000..ced9d07d --- /dev/null +++ b/stories/assets/rockets.svg @@ -0,0 +1 @@ + \ No newline at end of file