pixelize-design-library 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/. prettierrc +14 -0
  2. package/.eslintcache +1 -0
  3. package/.husky/pre-commit +4 -0
  4. package/.storybook/main.ts +19 -0
  5. package/.storybook/preview.ts +14 -0
  6. package/README.md +48 -0
  7. package/build/favicon.ico +0 -0
  8. package/build/logo192.png +0 -0
  9. package/build/logo512.png +0 -0
  10. package/build/manifest.json +25 -0
  11. package/build/robots.txt +3 -0
  12. package/eslint.config.mjs +20 -0
  13. package/exposedComponents.json +26 -0
  14. package/package.json +105 -0
  15. package/public/favicon.ico +0 -0
  16. package/public/index.html +43 -0
  17. package/public/logo192.png +0 -0
  18. package/public/logo512.png +0 -0
  19. package/public/manifest.json +25 -0
  20. package/public/robots.txt +3 -0
  21. package/rsbuild.config.ts +49 -0
  22. package/src/App.tsx +10 -0
  23. package/src/Components/Apexcharts/ApexBarChart/ApexBarChart.stories.tsx +39 -0
  24. package/src/Components/Apexcharts/ApexBarChart/ApexBarChart.tsx +80 -0
  25. package/src/Components/Apexcharts/ApexBarChart/ApexBarChartProps.tsx +20 -0
  26. package/src/Components/Apexcharts/ApexPieChart/ApexPieChart.stories.tsx +33 -0
  27. package/src/Components/Apexcharts/ApexPieChart/ApexPieChart.tsx +42 -0
  28. package/src/Components/Apexcharts/ApexPieChart/ApexPieChartProps.tsx +17 -0
  29. package/src/Components/Breadcrumbs/Breadcrumbs.stories.tsx +26 -0
  30. package/src/Components/Breadcrumbs/Breadcrumbs.tsx +25 -0
  31. package/src/Components/Breadcrumbs/BreadcrumbsProps.tsx +12 -0
  32. package/src/Components/Button/Button.stories.tsx +32 -0
  33. package/src/Components/Button/Button.tsx +26 -0
  34. package/src/Components/Button/ButtonProps.tsx +10 -0
  35. package/src/Components/ButtonGroupIcon/ButtonGoupIconProps.tsx +14 -0
  36. package/src/Components/ButtonGroupIcon/ButtonGroupIcon.stories.tsx +37 -0
  37. package/src/Components/ButtonGroupIcon/ButtonGroupIcon.tsx +25 -0
  38. package/src/Components/Checkbox/Checkbox.stories.tsx +45 -0
  39. package/src/Components/Checkbox/Checkbox.tsx +29 -0
  40. package/src/Components/Checkbox/CheckboxProps.tsx +9 -0
  41. package/src/Components/Input/TextInput.stories.tsx +44 -0
  42. package/src/Components/Input/TextInput.tsx +70 -0
  43. package/src/Components/Input/TextInputProps.tsx +27 -0
  44. package/src/Components/InputTextArea/InputTextArea.stories.tsx +48 -0
  45. package/src/Components/InputTextArea/InputTextArea.tsx +36 -0
  46. package/src/Components/InputTextArea/InputTextAreaProps.tsx +11 -0
  47. package/src/Components/Loading/Loading.stories.tsx +25 -0
  48. package/src/Components/Loading/Loading.tsx +37 -0
  49. package/src/Components/Loading/LoadingProps.tsx +1 -0
  50. package/src/Components/Modal/Modal.stories.tsx +106 -0
  51. package/src/Components/Modal/Modal.tsx +44 -0
  52. package/src/Components/Modal/ModalProps.tsx +12 -0
  53. package/src/Components/NavigationBar/NavBar.stories.tsx +26 -0
  54. package/src/Components/NavigationBar/NavigationBar.tsx +55 -0
  55. package/src/Components/NavigationBar/NavigationBarProps.tsx +13 -0
  56. package/src/Components/NumberInput/NumberInput.stories.tsx +31 -0
  57. package/src/Components/NumberInput/NumberInput.tsx +55 -0
  58. package/src/Components/NumberInput/NumberInputProps.tsx +28 -0
  59. package/src/Components/PinInput/PinInput.stories.tsx +40 -0
  60. package/src/Components/PinInput/PinInput.tsx +48 -0
  61. package/src/Components/PinInput/PinInputProps.tsx +33 -0
  62. package/src/Components/ProfileCard/ProfileCard.stories.tsx +30 -0
  63. package/src/Components/ProfileCard/ProfileCard.tsx +58 -0
  64. package/src/Components/ProfileCard/ProfileCardProps.tsx +41 -0
  65. package/src/Components/ProfilePhotoViewer/ProfilePhotoViewer.stories.tsx +25 -0
  66. package/src/Components/ProfilePhotoViewer/ProfilePhotoViewer.tsx +68 -0
  67. package/src/Components/ProfilePhotoViewer/ProfilePhotoViewerProps.tsx +14 -0
  68. package/src/Components/ProgressBar/ProgressBar.stories.tsx +46 -0
  69. package/src/Components/ProgressBar/ProgressBar.tsx +32 -0
  70. package/src/Components/ProgressBar/ProgressBarProps.tsx +7 -0
  71. package/src/Components/RadioButton/RadioButton.stories.tsx +46 -0
  72. package/src/Components/RadioButton/RadioButton.tsx +63 -0
  73. package/src/Components/RadioButton/RadioButtonProps.tsx +10 -0
  74. package/src/Components/Select/Select.stories.tsx +56 -0
  75. package/src/Components/Select/Select.tsx +45 -0
  76. package/src/Components/Select/SelectProps.tsx +15 -0
  77. package/src/Components/SideBar/SideBar.tsx +143 -0
  78. package/src/Components/SideBar/SideBarProps.tsx +18 -0
  79. package/src/Components/SideBar/Sidebar.stories.tsx +80 -0
  80. package/src/Components/Skeletons/Skeleton.stories.tsx +63 -0
  81. package/src/Components/Skeletons/SkeletonProps.tsx +23 -0
  82. package/src/Components/Skeletons/Skeletons.tsx +51 -0
  83. package/src/Components/Table/Table.stories.tsx +47 -0
  84. package/src/Components/Table/Table.tsx +516 -0
  85. package/src/Components/Table/TableProps.tsx +36 -0
  86. package/src/Components/Toaster/Toaster.stories.tsx +58 -0
  87. package/src/Components/Toaster/Toaster.tsx +34 -0
  88. package/src/Components/Toaster/ToasterProps.tsx +15 -0
  89. package/src/Components/ToolTip/ToolTip.stories.tsx +39 -0
  90. package/src/Components/ToolTip/ToolTip.tsx +61 -0
  91. package/src/Components/ToolTip/ToolTipProps.tsx +45 -0
  92. package/src/Layout.tsx +499 -0
  93. package/src/Theme/Dark/theme.ts +278 -0
  94. package/src/Theme/Default/theme.ts +301 -0
  95. package/src/Theme/index.ts +4 -0
  96. package/src/bootstrap.tsx +13 -0
  97. package/src/index.tsx +22 -0
  98. package/src/stories/Configure.mdx +364 -0
  99. package/src/stories/assets/accessibility.png +0 -0
  100. package/src/stories/assets/accessibility.svg +5 -0
  101. package/src/stories/assets/addon-library.png +0 -0
  102. package/src/stories/assets/assets.png +0 -0
  103. package/src/stories/assets/avif-test-image.avif +0 -0
  104. package/src/stories/assets/context.png +0 -0
  105. package/src/stories/assets/discord.svg +15 -0
  106. package/src/stories/assets/docs.png +0 -0
  107. package/src/stories/assets/figma-plugin.png +0 -0
  108. package/src/stories/assets/github.svg +3 -0
  109. package/src/stories/assets/share.png +0 -0
  110. package/src/stories/assets/styling.png +0 -0
  111. package/src/stories/assets/testing.png +0 -0
  112. package/src/stories/assets/theming.png +0 -0
  113. package/src/stories/assets/tutorials.svg +12 -0
  114. package/src/stories/assets/youtube.svg +4 -0
  115. package/src/stories/header.css +32 -0
  116. package/tsconfig.json +20 -0
@@ -0,0 +1,68 @@
1
+ import { Box, Image, IconButton, Input, ChakraProvider } from "@chakra-ui/react";
2
+ import { ChangeEvent, useRef, useState } from "react";
3
+ import { EditIcon } from "@chakra-ui/icons"; // Ensure you have @chakra-ui/icons installed
4
+ import { ProfilePhotoViewerProps } from "./ProfilePhotoViewerProps";
5
+
6
+ export default function ProfilePhotoViewer({
7
+ photoUrl,
8
+ onPhotoChange,
9
+ imageWidth = "100px",
10
+ imageAlt = "Profile Photo",
11
+ imageObjectFit = "cover",
12
+ imageBorderRadius = "full",
13
+ editIconSize = "sm",
14
+ editIconPositionRight = "5px",
15
+ editIconPositionBottom = "5px",
16
+ isRound = true,
17
+ boxStyle
18
+ }: ProfilePhotoViewerProps) {
19
+ const [photo, setPhoto] = useState<string>(photoUrl);
20
+ const fileInputRef = useRef<HTMLInputElement>(null);
21
+
22
+ const handlePhotoChange = (event: ChangeEvent<HTMLInputElement>) => {
23
+ const file = event.target.files?.[0];
24
+ if (file) {
25
+ const reader = new FileReader();
26
+ reader.onload = () => {
27
+ const photoUrl = reader.result as string;
28
+ setPhoto(photoUrl);
29
+ onPhotoChange(file);
30
+ };
31
+ reader.readAsDataURL(file);
32
+ }
33
+ };
34
+ const handleClick = () => {
35
+ fileInputRef.current?.click();
36
+ };
37
+ return (
38
+ <ChakraProvider>
39
+ <Box position="relative" display="inline-block" style={boxStyle}>
40
+ <Image
41
+ src={photo}
42
+ alt={imageAlt}
43
+ boxSize={imageWidth}
44
+ objectFit={imageObjectFit}
45
+ borderRadius={imageBorderRadius}
46
+
47
+ />
48
+ <IconButton
49
+ icon={<EditIcon />}
50
+ isRound={isRound}
51
+ size={editIconSize}
52
+ position="absolute"
53
+ right={editIconPositionRight}
54
+ bottom={editIconPositionBottom}
55
+ onClick={handleClick}
56
+ aria-label="Edit photo"
57
+ />
58
+ <Input
59
+ type="file"
60
+ accept="image/*"
61
+ onChange={handlePhotoChange}
62
+ hidden
63
+ ref={fileInputRef}
64
+ />
65
+ </Box>
66
+ </ChakraProvider>
67
+ );
68
+ }
@@ -0,0 +1,14 @@
1
+
2
+ export type ProfilePhotoViewerProps = {
3
+ photoUrl: string,
4
+ onPhotoChange: (photoUrl: File) => void,
5
+ imageWidth?: string,
6
+ imageAlt?: string,
7
+ imageObjectFit?: "cover" | "contain" | "fill" | "none" | "scale-down",
8
+ imageBorderRadius?: string,
9
+ editIconSize?: string,
10
+ editIconPositionRight?: string,
11
+ editIconPositionBottom?: string,
12
+ isRound?: boolean,
13
+ boxStyle?: React.CSSProperties
14
+ }
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import { Meta, StoryFn } from '@storybook/react';
3
+ import { ChakraProvider } from '@chakra-ui/react';
4
+ import ProgressBar from './ProgressBar'; // Adjust the import path and component type if needed
5
+ import { ProgressBarProps } from "./ProgressBarProps";
6
+
7
+ export default {
8
+ title: 'Components/ProgressBar/ProgressBar',
9
+ component: ProgressBar,
10
+ argTypes: {
11
+ size: { control: { type: 'select', options: ['sm', 'md', 'lg'] } },
12
+ variant: {
13
+ control: { type: 'select', options: ["solid","outline","ghost","link"] },
14
+ defaultValue: 'solid'
15
+ },
16
+ color: {
17
+ control: { type: 'select', options: ["gray" ,"red" ,"orange" ,"yellow" ,"green" ,"teal" ,"blue" ,"cyan" ,"purple" ,"pink" ,"whiteAlpha" ,"blackAlpha"] },
18
+ defaultValue: 'blue'
19
+ },
20
+ height: { control: { type: 'text' } },
21
+ value: { control: { type: 'range', min: 0, max: 100, step: 1 } },
22
+ max: { control: { type: 'number' } },
23
+ min: { control: { type: 'number' } },
24
+ },
25
+ } as Meta;
26
+
27
+ const Template: StoryFn<ProgressBarProps> = (args) => (
28
+ <ChakraProvider>
29
+ <ProgressBar {...args} />
30
+ </ChakraProvider>
31
+ );
32
+
33
+ // Default Story
34
+ export const Default = Template.bind({});
35
+ Default.args = {
36
+ size: 'md', // Provide appropriate size
37
+ isIndeterminate: false, // Provide appropriate value
38
+ color: 'blue', // Provide appropriate color scheme
39
+ hasStripe: true, // Provide appropriate value
40
+ height: '12px', // Provide appropriate height
41
+ value: 50, // Provide appropriate value
42
+ isAnimated: true, // Provide appropriate value
43
+ max: 100, // Provide appropriate value
44
+ min: 0, // Provide appropriate value
45
+ variant: 'solid', // Provide appropriate variant
46
+ };
@@ -0,0 +1,32 @@
1
+ import { ChakraProvider, Progress } from "@chakra-ui/react";
2
+ import { ProgressBarProps } from "./ProgressBarProps";
3
+
4
+ export default function ProgressBar({
5
+ size,
6
+ isIndeterminate,
7
+ color,
8
+ hasStripe,
9
+ height,
10
+ value,
11
+ isAnimated,
12
+ max,
13
+ min,
14
+ variant,
15
+ }: ProgressBarProps) {
16
+ return (
17
+ <ChakraProvider>
18
+ <Progress
19
+ size={size}
20
+ isIndeterminate={isIndeterminate}
21
+ colorScheme={color}
22
+ hasStripe={hasStripe}
23
+ height={height}
24
+ value={value}
25
+ isAnimated={isAnimated}
26
+ max={max}
27
+ min={min}
28
+ variant={variant}
29
+ />
30
+ </ChakraProvider>
31
+ );
32
+ }
@@ -0,0 +1,7 @@
1
+ import { ProgressProps } from "@chakra-ui/react";
2
+
3
+ export type ProgressBarProps =Pick<ProgressProps,"size"|"isIndeterminate"|"value"|"height"|"hasStripe"|"isAnimated"|"max"|"min">&{
4
+ color?: "gray" | "red" | "orange" | "yellow" | "green" | "teal" | "blue" | "cyan" | "purple" | "pink" | "whiteAlpha" | "blackAlpha",
5
+ variant?: "solid" | "outline" | "ghost" | "link" | "unstyled",
6
+ size?: "lg" | "md" | "sm" | "xs",
7
+ }
@@ -0,0 +1,46 @@
1
+ import React, { useState } from 'react';
2
+ import { Meta, StoryFn } from '@storybook/react';
3
+ import { ChakraProvider } from '@chakra-ui/react';
4
+ import { RadioButton, RadioButtonGroup } from './RadioButton';
5
+ import { ChakraRadioProps, ChakraRadioGroupProps } from './RadioButtonProps';
6
+
7
+ export default {
8
+ title: 'Components/RadioButton/RadioButton',
9
+ component: RadioButton,
10
+ decorators: [(Story:any) => <ChakraProvider><Story /></ChakraProvider>],
11
+ } as Meta<typeof RadioButton>;
12
+
13
+ const RadioButtonTemplate: StoryFn<typeof RadioButton> = (args: ChakraRadioProps) => <RadioButton {...args} />;
14
+
15
+ export const SingleRadioButton = RadioButtonTemplate.bind({});
16
+ SingleRadioButton.args = {
17
+ label: 'Option 1',
18
+ value: '1',
19
+ colorScheme: 'blue',
20
+ size: 'md',
21
+ };
22
+
23
+ const RadioButtonGroupTemplate: StoryFn<typeof RadioButtonGroup> = (args: ChakraRadioGroupProps) => {
24
+ const [selectedValue, setSelectedValue] = useState<string>(args.value as string);
25
+
26
+ const handleChange = (value: string) => {
27
+ setSelectedValue(value);
28
+ if (args.onChange) {
29
+ args.onChange(value);
30
+ }
31
+ };
32
+
33
+ return <RadioButtonGroup {...args} value={selectedValue} onChange={handleChange} />;
34
+ };
35
+
36
+ export const RadioButtonGroupStory = RadioButtonGroupTemplate.bind({});
37
+ RadioButtonGroupStory.args = {
38
+ options: [
39
+ { label: 'Option 1', value: '1' },
40
+ { label: 'Option 2', value: '2' },
41
+ { label: 'Option 3', value: '3' },
42
+ ],
43
+ value: '1',
44
+ colorScheme: 'blue',
45
+ size: 'md',
46
+ };
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import { Radio as ChakraRadio, RadioGroup as ChakraRadioGroup, Box, Stack, ChakraProvider } from '@chakra-ui/react';
3
+ import { ChakraRadioProps, ChakraRadioGroupProps } from './RadioButtonProps';
4
+
5
+ const RadioButton = ({
6
+ label,
7
+ colorScheme,
8
+ isChecked,
9
+ onChange,
10
+ isDisabled,
11
+ size,
12
+ value,
13
+ defaultChecked,
14
+ }:ChakraRadioProps) => {
15
+ return (
16
+ <ChakraProvider>
17
+ <ChakraRadio
18
+ colorScheme={colorScheme}
19
+ isChecked={isChecked}
20
+ onChange={onChange}
21
+ isDisabled={isDisabled}
22
+ size={size}
23
+ value={value}
24
+ defaultChecked={defaultChecked}
25
+ >
26
+ <Box as="span">
27
+ {label}
28
+ </Box>
29
+ </ChakraRadio>
30
+ </ChakraProvider>
31
+ );
32
+ };
33
+
34
+ const RadioButtonGroup = ({
35
+ options,
36
+ onChange,
37
+ value,
38
+ defaultValue,
39
+ isDisabled,
40
+ size,
41
+ colorScheme,
42
+ }:ChakraRadioGroupProps) => {
43
+ return (
44
+ <ChakraProvider>
45
+ <ChakraRadioGroup onChange={onChange} value={value} defaultValue={defaultValue}>
46
+ <Stack direction="row" spacing={4}>
47
+ {options.map((option) => (
48
+ <RadioButton
49
+ key={option.value}
50
+ label={option.label}
51
+ value={option.value}
52
+ isDisabled={isDisabled}
53
+ size={size}
54
+ colorScheme={colorScheme}
55
+ />
56
+ ))}
57
+ </Stack>
58
+ </ChakraRadioGroup>
59
+ </ChakraProvider>
60
+ );
61
+ };
62
+
63
+ export { RadioButton, RadioButtonGroup };
@@ -0,0 +1,10 @@
1
+
2
+ import { RadioProps , RadioGroupProps } from '@chakra-ui/react';
3
+
4
+ export type ChakraRadioProps= Pick<RadioProps,|"size"|"colorScheme"|"isChecked"|"onChange"|"isDisabled"|"value"|"defaultChecked">&{
5
+ label: string;
6
+ }
7
+ export type ChakraRadioGroupProps = Pick<RadioGroupProps,|"size"|"colorScheme"|"isDisabled"|"defaultValue"|"value">&{
8
+ options: { label: string; value: string }[];
9
+ onChange?: (value: string) => void;
10
+ }
@@ -0,0 +1,56 @@
1
+ import { Meta, StoryFn } from '@storybook/react';
2
+ import { ChakraProvider } from "@chakra-ui/react";
3
+ import { useState } from 'react';
4
+ import Select from './Select';
5
+ import { chakraSelectProps } from './SelectProps';
6
+
7
+ const meta: Meta<typeof Select> = {
8
+ title: 'Components/Input/Select',
9
+ component: Select,
10
+ parameters: {
11
+ layout: 'centered',
12
+ },
13
+ tags: ['autodocs'],
14
+ };
15
+
16
+ export default meta;
17
+
18
+ const SelectTemplate: StoryFn<chakraSelectProps> = (args) => {
19
+ const [value, setValue] = useState("");
20
+
21
+ const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
22
+ setValue(e.target.value);
23
+ if (args.onChange) {
24
+ args.onChange(e);
25
+ }
26
+ };
27
+
28
+ return (
29
+ <ChakraProvider>
30
+ <Select {...args} onChange={handleChange} value={value} />
31
+ </ChakraProvider>
32
+ );
33
+ };
34
+
35
+ export const Primary = SelectTemplate.bind({});
36
+ Primary.args = {
37
+ placeholder: "Select an option",
38
+ size: "md",
39
+ variant: "outline",
40
+ icon: undefined,
41
+ bg: undefined,
42
+ borderColor: undefined,
43
+ color: undefined,
44
+ error: false,
45
+ isRequired: false,
46
+ label: 'Select Input',
47
+ errorMessage: "",
48
+ helperText: "",
49
+ options: [
50
+ { id: '1', label: 'Option 1' },
51
+ { id: '2', label: 'Option 2' },
52
+ { id: '3', label: 'Option 3' },
53
+ ],
54
+ value: "",
55
+ width: 500,
56
+ };
@@ -0,0 +1,45 @@
1
+ import { ChakraProvider, Select as ChakraSelect, FormControl, FormErrorMessage, FormHelperText, FormLabel } from "@chakra-ui/react";
2
+ import { OptionProp, chakraSelectProps } from "./SelectProps";
3
+ import { useCallback } from "react";
4
+
5
+ export default function Select({
6
+ placeholder = "Select Option",
7
+ size = "md",
8
+ variant = "outline",
9
+ icon,
10
+ bg,
11
+ borderColor,
12
+ color,
13
+ error,
14
+ isRequired,
15
+ label,
16
+ errorMessage,
17
+ helperText,
18
+ options = [],
19
+ value = "",
20
+ onChange,
21
+ width = 500,
22
+ }: chakraSelectProps) {
23
+
24
+ const getOptionsList = useCallback(() => {
25
+ if (!options.length) return <option value="">No Options</option>;
26
+ return options.map((option: OptionProp) => <option key={option.id} value={option.id}>{option.label}</option>);
27
+ }, [options]);
28
+
29
+ return (
30
+ <ChakraProvider>
31
+
32
+ <FormControl isRequired={isRequired} isInvalid={error} >
33
+ {label && <FormLabel mb="0.25rem">{label}</FormLabel>}
34
+
35
+ <ChakraSelect placeholder={placeholder} size={size} variant={variant} icon={icon} bg={bg} borderColor={borderColor} color={color} isInvalid={error} value={value} onChange={onChange} width={width}>
36
+ {getOptionsList()}
37
+ </ChakraSelect>
38
+ {error && (
39
+ <FormErrorMessage pl={4}>{errorMessage}</FormErrorMessage>
40
+ )}
41
+ {helperText && !error && <FormHelperText pl={4}>{helperText}</FormHelperText>}
42
+ </FormControl>
43
+ </ChakraProvider>
44
+ );
45
+ }
@@ -0,0 +1,15 @@
1
+ import { SelectProps } from "@chakra-ui/react";
2
+
3
+ export type chakraSelectProps = Pick<SelectProps, "placeholder" | "size" | "variant" | "icon" | "bg" | "borderColor" | "color" | "onChange" | "onBlur" | "onFocus" | "errorBorderColor" | "isDisabled" | "isReadOnly" | "isRequired" | "value"> & {
4
+ label?: string;
5
+ error?: boolean;
6
+ errorMessage?: string;
7
+ helperText?: string;
8
+ options: OptionProp[];
9
+ width?: string | number;
10
+ }
11
+
12
+ export type OptionProp = {
13
+ id: string | number,
14
+ label: string | number
15
+ }
@@ -0,0 +1,143 @@
1
+ import React from 'react'
2
+ import {
3
+ Flex,
4
+ Text,
5
+ IconButton,
6
+ Menu,
7
+ Link,
8
+ MenuButton,
9
+ Icon,
10
+ MenuList,
11
+ Image,
12
+ MenuItem,
13
+ ChakraProvider
14
+ } from '@chakra-ui/react'
15
+ import {
16
+ FiChevronLeft,
17
+ FiChevronRight,
18
+ } from 'react-icons/fi'
19
+ import { SidebarProps } from './SideBarProps'
20
+ export default function Sidebar({
21
+ menus,
22
+ activeMenu,
23
+ handleMenuClick,
24
+ toggle,
25
+ changeToggle,
26
+ logo,
27
+ companyName
28
+ }: SidebarProps) {
29
+ return (
30
+ <ChakraProvider>
31
+ <Flex
32
+ pos="sticky"
33
+ h="100vh"
34
+ boxShadow="0 4px 12px 0 rgba(0, 0, 0, 0.05)"
35
+ w={toggle ? "75px" : "200px"}
36
+ flexDir="column"
37
+ justifyContent="space-between"
38
+ background={"#ffffff"}
39
+ >
40
+ <Flex
41
+ pl={toggle ? "22%" : "8%"}
42
+ flexDir="column"
43
+ w="100%"
44
+ alignItems={"flex-start"}
45
+ as="nav"
46
+ h="100vh"
47
+ >
48
+ <Flex
49
+ mt={5}
50
+ align="center"
51
+ >
52
+ <Image
53
+ borderRadius='full'
54
+ boxSize={'45px'}
55
+ src={logo}
56
+ alt='Company Logo'
57
+ />
58
+ <Text ml={4} display={toggle ? "none" : "flex"}>{companyName}</Text>
59
+ </Flex>
60
+ <Flex position={"absolute"} left={toggle ? "55px" : "180px"} top={"60px"} background={"#3182CE"} borderRadius={"23px"}>
61
+ <IconButton
62
+ background={"none"}
63
+ icon={toggle ? <FiChevronRight color={"#ffffff"} /> : <FiChevronLeft color={"#ffffff"} />}
64
+ _hover={{ background: "none" }}
65
+ onClick={changeToggle}
66
+ aria-label='Toggle Navigation'
67
+ />
68
+ </Flex>
69
+ <Flex
70
+ mt={30}
71
+ flexDir="column"
72
+ w="100%"
73
+ alignItems={toggle ? "center" : "flex-start"}
74
+ h="100vh"
75
+ overflow="scroll"
76
+ css={{
77
+
78
+ '&::-webkit-scrollbar': {
79
+ width: '3px',
80
+ },
81
+ '&::-webkit-scrollbar-track': {
82
+ background: 'transparent',
83
+ },
84
+ '&::-webkit-scrollbar-thumb': {
85
+ background: 'transparent',
86
+ transition: 'background 0.5s',
87
+ },
88
+ '&:hover::-webkit-scrollbar-thumb': {
89
+ background: '#888',
90
+ },
91
+ }}
92
+ ml={toggle ? "-8px":"0px"}
93
+ >
94
+ {menus.map((menu: any) => (
95
+ <Menu key={menu.title} placement="right">
96
+ <Link
97
+ backgroundColor={activeMenu === menu.title ? "#3182CE" : "none"}
98
+ borderRadius={8}
99
+ _hover={{ textDecor: 'none', backgroundColor: "#3182CE", color: "#ffffff" }}
100
+ _active={{ color: "#ffffff" }}
101
+ w={"98%"}
102
+ onClick={() => handleMenuClick(menu?.title, menu?.url)}
103
+ mt={"5px"}
104
+ className='custom-link'
105
+ width={toggle ? "80%" : "90%"}
106
+ >
107
+ <MenuButton w="100%" p={"13px 12px 13px 13px"}>
108
+ <Flex>
109
+ <Icon as={menu.icon} fontSize="xl" color={activeMenu === menu.title ? "#ffff" : ""} />
110
+ <Text ml={5} display={toggle ? "none" : "flex"} color={activeMenu === menu.title ? "#ffff" : ""}>{menu.title}</Text>
111
+ </Flex>
112
+ </MenuButton>
113
+ </Link>
114
+ {
115
+ menu.subMenu &&
116
+ <MenuList py={0}
117
+ border="none"
118
+ ml={toggle ? 3 : 6}
119
+ boxShadow="0 4px 12px 0 rgba(0, 0, 0, 0.05)"
120
+ >
121
+ <Flex
122
+ pos="absolute"
123
+ mt="calc(100px - 70px)"
124
+ ml={"-10px"}
125
+ width={0}
126
+ height={0}
127
+ borderTop="10px solid transparent"
128
+ borderBottom="10px solid transparent"
129
+ borderRight="10px solid #3182CE"
130
+ />
131
+ {menu.subMenu.map((subMenuItem: any) => (
132
+ <MenuItem key={subMenuItem.title}>{subMenuItem.title}</MenuItem>
133
+ ))}
134
+ </MenuList>
135
+ }
136
+ </Menu>
137
+ ))}
138
+ </Flex>
139
+ </Flex>
140
+ </Flex >
141
+ </ChakraProvider >
142
+ )
143
+ }
@@ -0,0 +1,18 @@
1
+ import { IconType } from "react-icons";
2
+
3
+ export type SidebarProps = {
4
+ menus: Menu[];
5
+ activeMenu: string;
6
+ handleMenuClick: (title: string, url: string) => void;
7
+ toggle: boolean;
8
+ changeToggle: () => void;
9
+ logo: string;
10
+ companyName: string;
11
+ };
12
+
13
+ type Menu = {
14
+ title: string;
15
+ icon: IconType;
16
+ url: string;
17
+ subMenu?: { title: string; url: string }[];
18
+ }
@@ -0,0 +1,80 @@
1
+ import React, { useState } from 'react';
2
+ import { StoryFn, Meta } from '@storybook/react/types-6-0';
3
+ import Sidebar from './SideBar';
4
+ import { SidebarProps } from './SideBarProps';
5
+ import { FiBriefcase, FiCalendar, FiDollarSign, FiHome, FiSettings, FiUser } from 'react-icons/fi';
6
+ import { fn } from '@storybook/test';
7
+
8
+ export default {
9
+ title: 'Components/Sidebar/Sidebar',
10
+ component: Sidebar,
11
+ } as Meta;
12
+
13
+ const Template: StoryFn<SidebarProps> = (args) => {
14
+
15
+ const [toggle, changeToggle] = useState(true)
16
+ const [activeMenu, setActiveMenu] = useState("")
17
+
18
+ const handleMenuClick = (title: string, url: string) => {
19
+ setActiveMenu(title)
20
+ }
21
+
22
+ return (<Sidebar {...args} activeMenu={activeMenu} handleMenuClick={handleMenuClick} toggle={toggle} changeToggle={() => changeToggle(!toggle)} />)
23
+ };
24
+
25
+ const menus = [
26
+ {
27
+ title: "Dashboard",
28
+ icon: FiHome,
29
+ url: "dashboard"
30
+ },
31
+ {
32
+ title: "Calendar",
33
+ icon: FiCalendar,
34
+ url: "description"
35
+ },
36
+ {
37
+ title: "Clients",
38
+ icon: FiUser,
39
+ url: "description"
40
+ }, {
41
+ title: "Animals",
42
+ icon: FiCalendar,
43
+ url: "description"
44
+ },
45
+ {
46
+ title: "Stock's",
47
+ icon: FiDollarSign,
48
+ url: "description"
49
+ }, {
50
+ title: "Reports",
51
+ icon: FiBriefcase,
52
+ url: "description"
53
+ }, {
54
+ title: "Settings",
55
+ icon: FiSettings,
56
+ url: "description",
57
+ subMenu: [
58
+ {
59
+ title: "Submenu Item 1",
60
+ url: "Submenu item 1 description"
61
+ },
62
+ {
63
+ title: "Submenu Item 2",
64
+ url: "Submenu item 2 description"
65
+ }
66
+ ]
67
+ },
68
+ ];
69
+
70
+ export const Primary = Template.bind({});
71
+
72
+ Primary.args = {
73
+ menus: menus,
74
+ activeMenu: '',
75
+ handleMenuClick: fn(),
76
+ toggle: false,
77
+ changeToggle: fn(),
78
+ logo: 'https://bit.ly/dan-abramov',
79
+ companyName: 'PIXELIZE'
80
+ };