@pautena/react-design-system 0.1.2 → 0.2.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.
- package/README.md +4 -0
- package/dist/cjs/index.js +4 -259
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/generators/model-router/screens/add-screen.d.ts +1 -1
- package/dist/cjs/types/generators/model-router/screens/list-screen.d.ts +1 -1
- package/dist/cjs/types/generators/model-router/screens/screens.types.d.ts +20 -0
- package/dist/cjs/types/generators/model-router/screens/update-screen.d.ts +1 -1
- package/dist/cjs/types/index.d.ts +1 -0
- package/dist/esm/index.js +4 -259
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/generators/model-router/screens/add-screen.d.ts +1 -1
- package/dist/esm/types/generators/model-router/screens/list-screen.d.ts +1 -1
- package/dist/esm/types/generators/model-router/screens/screens.types.d.ts +20 -0
- package/dist/esm/types/generators/model-router/screens/update-screen.d.ts +1 -1
- package/dist/esm/types/index.d.ts +1 -0
- package/dist/index.d.ts +52 -3
- package/package.json +13 -2
- package/src/components/app-bar/app-bar.stories.tsx +54 -0
- package/src/components/app-bar/app-bar.test.tsx +142 -0
- package/src/components/app-bar/app-bar.tsx +150 -0
- package/src/components/app-bar/app-bar.types.ts +17 -0
- package/src/components/app-bar/index.ts +3 -0
- package/src/components/app-bar/mini-app-bar/index.ts +1 -0
- package/src/components/app-bar/mini-app-bar/mini-app-bar.tsx +31 -0
- package/src/components/bullet/bullet.stories.tsx +43 -0
- package/src/components/bullet/bullet.test.tsx +24 -0
- package/src/components/bullet/bullet.tsx +30 -0
- package/src/components/bullet/index.ts +1 -0
- package/src/components/center-container/center-container.stories.tsx +50 -0
- package/src/components/center-container/center-container.test.tsx +16 -0
- package/src/components/center-container/center-container.tsx +32 -0
- package/src/components/center-container/index.ts +1 -0
- package/src/components/content/content.stories.tsx +23 -0
- package/src/components/content/content.test.tsx +26 -0
- package/src/components/content/content.tsx +11 -0
- package/src/components/content/content.types.ts +5 -0
- package/src/components/content/index.ts +2 -0
- package/src/components/drawer/__snapshots__/drawer.test.tsx.snap +20 -0
- package/src/components/drawer/drawer.context.ts +20 -0
- package/src/components/drawer/drawer.mixins.ts +24 -0
- package/src/components/drawer/drawer.mock.tsx +100 -0
- package/src/components/drawer/drawer.provider.tsx +23 -0
- package/src/components/drawer/drawer.test.tsx +97 -0
- package/src/components/drawer/drawer.tsx +30 -0
- package/src/components/drawer/drawer.types.ts +53 -0
- package/src/components/drawer/index.ts +5 -0
- package/src/components/drawer/mini-drawer/index.ts +1 -0
- package/src/components/drawer/mini-drawer/mini-drawer.stories.tsx +34 -0
- package/src/components/drawer/mini-drawer/mini-drawer.tsx +67 -0
- package/src/components/drawer-content/drawer-content.stories.tsx +29 -0
- package/src/components/drawer-content/drawer-content.test.tsx +34 -0
- package/src/components/drawer-content/drawer-content.tsx +18 -0
- package/src/components/drawer-content/index.ts +1 -0
- package/src/components/drawer-item/drawer-item.stories.tsx +62 -0
- package/src/components/drawer-item/drawer-item.test.tsx +119 -0
- package/src/components/drawer-item/drawer-item.tsx +71 -0
- package/src/components/drawer-item/index.ts +1 -0
- package/src/components/drawer-section/drawer-section.mock.tsx +39 -0
- package/src/components/drawer-section/drawer-section.stories.tsx +28 -0
- package/src/components/drawer-section/drawer-section.test.tsx +44 -0
- package/src/components/drawer-section/drawer-section.tsx +40 -0
- package/src/components/drawer-section/index.ts +1 -0
- package/src/components/header/header.dummy.ts +55 -0
- package/src/components/header/header.stories.tsx +116 -0
- package/src/components/header/header.test.tsx +159 -0
- package/src/components/header/header.tsx +121 -0
- package/src/components/header/header.types.ts +61 -0
- package/src/components/header/index.ts +2 -0
- package/src/components/index.ts +18 -0
- package/src/components/label/index.ts +1 -0
- package/src/components/label/label.stories.tsx +49 -0
- package/src/components/label/label.test.tsx +30 -0
- package/src/components/label/label.tsx +60 -0
- package/src/components/link/index.ts +1 -0
- package/src/components/link/link.tsx +17 -0
- package/src/components/loading-area/index.ts +1 -0
- package/src/components/loading-area/loading-area.stories.tsx +17 -0
- package/src/components/loading-area/loading-area.test.tsx +11 -0
- package/src/components/loading-area/loading-area.tsx +13 -0
- package/src/components/placeholder/index.ts +1 -0
- package/src/components/placeholder/placeholder.mock.ts +15 -0
- package/src/components/placeholder/placeholder.stories.tsx +44 -0
- package/src/components/placeholder/placeholder.test.tsx +76 -0
- package/src/components/placeholder/placeholder.tsx +75 -0
- package/src/components/query-container/index.ts +1 -0
- package/src/components/query-container/query-container.stories.tsx +68 -0
- package/src/components/query-container/query-container.test.tsx +95 -0
- package/src/components/query-container/query-container.tsx +71 -0
- package/src/components/sign-in/index.ts +1 -0
- package/src/components/sign-in/sign-in.stories.tsx +36 -0
- package/src/components/sign-in/sign-in.test.tsx +95 -0
- package/src/components/sign-in/sign-in.tsx +97 -0
- package/src/components/tab/index.ts +2 -0
- package/src/components/tab/tab-card/index.ts +1 -0
- package/src/components/tab/tab-card/tab-card.dummy.tsx +30 -0
- package/src/components/tab/tab-card/tab-card.stories.tsx +22 -0
- package/src/components/tab/tab-card/tab-card.test.tsx +53 -0
- package/src/components/tab/tab-card/tab-card.tsx +27 -0
- package/src/components/tab/tab-panel/index.ts +1 -0
- package/src/components/tab/tab-panel/tab-panel.test.tsx +26 -0
- package/src/components/tab/tab-panel/tab-panel.tsx +27 -0
- package/src/components/table/enhanced-remote-table/enhanced-remote-table.mock.tsx +27 -0
- package/src/components/table/enhanced-remote-table/enhanced-remote-table.stories.tsx +24 -0
- package/src/components/table/enhanced-remote-table/enhanced-remote-table.test.tsx +77 -0
- package/src/components/table/enhanced-remote-table/enhanced-remote-table.tsx +74 -0
- package/src/components/table/enhanced-remote-table/index.ts +1 -0
- package/src/components/table/enhanced-table/enhanced-table-head.tsx +58 -0
- package/src/components/table/enhanced-table/enhanced-table.mock.tsx +93 -0
- package/src/components/table/enhanced-table/enhanced-table.stories.tsx +21 -0
- package/src/components/table/enhanced-table/enhanced-table.test.tsx +107 -0
- package/src/components/table/enhanced-table/enhanced-table.tsx +136 -0
- package/src/components/table/enhanced-table/index.ts +2 -0
- package/src/components/table/index.ts +2 -0
- package/src/components/table-list/index.ts +1 -0
- package/src/components/table-list/table-list.stories.tsx +75 -0
- package/src/components/table-list/table-list.test.tsx +291 -0
- package/src/components/table-list/table-list.tsx +127 -0
- package/src/components/value-displays/group-value-card/group-value-card.mock.tsx +35 -0
- package/src/components/value-displays/group-value-card/group-value-card.stories.tsx +26 -0
- package/src/components/value-displays/group-value-card/group-value-card.test.tsx +58 -0
- package/src/components/value-displays/group-value-card/group-value-card.tsx +63 -0
- package/src/components/value-displays/group-value-card/index.ts +1 -0
- package/src/components/value-displays/index.ts +4 -0
- package/src/components/value-displays/value-boolean/index.ts +1 -0
- package/src/components/value-displays/value-boolean/value-boolean.stories.tsx +25 -0
- package/src/components/value-displays/value-boolean/value-boolean.test.tsx +27 -0
- package/src/components/value-displays/value-boolean/value-boolean.tsx +33 -0
- package/src/components/value-displays/value-card/index.ts +1 -0
- package/src/components/value-displays/value-card/value-card.stories.tsx +22 -0
- package/src/components/value-displays/value-card/value-card.test.tsx +18 -0
- package/src/components/value-displays/value-card/value-card.tsx +12 -0
- package/src/components/value-displays/value-text/index.ts +1 -0
- package/src/components/value-displays/value-text/value-test.test.tsx +21 -0
- package/src/components/value-displays/value-text/value-text.stories.tsx +26 -0
- package/src/components/value-displays/value-text/value-text.tsx +32 -0
- package/src/generators/generators.mock.ts +238 -0
- package/src/generators/generators.model.ts +46 -0
- package/src/generators/index.ts +4 -0
- package/src/generators/model-form/index.ts +1 -0
- package/src/generators/model-form/model-form.stories.tsx +30 -0
- package/src/generators/model-form/model-form.test.tsx +100 -0
- package/src/generators/model-form/model-form.tsx +97 -0
- package/src/generators/model-router/index.ts +1 -0
- package/src/generators/model-router/model-router.test.tsx +831 -0
- package/src/generators/model-router/model-router.tsx +30 -0
- package/src/generators/model-router/model-router.types.ts +14 -0
- package/src/generators/model-router/screens/add-screen.tsx +70 -0
- package/src/generators/model-router/screens/details-screen.tsx +62 -0
- package/src/generators/model-router/screens/index.ts +4 -0
- package/src/generators/model-router/screens/list-screen.tsx +125 -0
- package/src/generators/model-router/screens/screens.types.ts +38 -0
- package/src/generators/model-router/screens/update-screen.tsx +97 -0
- package/src/generators/model-router/stories/details-screen.stories.tsx +38 -0
- package/src/generators/model-router/stories/list-screen.stories.tsx +96 -0
- package/src/generators/model-router/stories/model-router.stories.tsx +176 -0
- package/src/generators/model-router/stories/templates.tsx +39 -0
- package/src/generators/object-details/index.ts +1 -0
- package/src/generators/object-details/object-details.stories.tsx +20 -0
- package/src/generators/object-details/object-details.test.tsx +21 -0
- package/src/generators/object-details/object-details.tsx +76 -0
- package/src/index.ts +5 -0
- package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.stories.tsx +28 -0
- package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.test.tsx +30 -0
- package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.tsx +37 -0
- package/src/layouts/app-bar-with-drawer-layout/index.ts +1 -0
- package/src/layouts/header-layout/header-layout.stories.tsx +204 -0
- package/src/layouts/header-layout/header-layout.test.tsx +37 -0
- package/src/layouts/header-layout/header-layout.tsx +23 -0
- package/src/layouts/header-layout/index.ts +1 -0
- package/src/layouts/index.ts +2 -0
- package/src/providers/index.ts +2 -0
- package/src/providers/notification-center/index.ts +2 -0
- package/src/providers/notification-center/notification-center.context.ts +37 -0
- package/src/providers/notification-center/notification-center.provider.tsx +51 -0
- package/src/providers/notification-center/notification-center.stories.tsx +52 -0
- package/src/providers/notification-center/notification-center.test.tsx +112 -0
- package/src/providers/tab-provider/index.ts +2 -0
- package/src/providers/tab-provider/tab-provider.context.ts +8 -0
- package/src/providers/tab-provider/tab-provider.provider.tsx +13 -0
- package/src/storybook.tsx +90 -0
- package/src/tests/assertions.ts +76 -0
- package/src/tests/components.tsx +60 -0
- package/src/tests/content-placeholder.stories.tsx +16 -0
- package/src/tests/index.ts +3 -0
- package/src/tests/skeleton-card.stories.tsx +18 -0
- package/src/tests/testing-library.tsx +65 -0
- package/src/utils/arrays.test.ts +9 -0
- package/src/utils/arrays.ts +7 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/theme.ts +11 -0
- package/.prettierrc.js +0 -5
|
@@ -13,4 +13,4 @@ export interface AddScreenProps<T extends BasicModelInstance> extends BaseScreen
|
|
|
13
13
|
*/
|
|
14
14
|
newItemRequest: RequestState;
|
|
15
15
|
}
|
|
16
|
-
export declare const AddScreen: <T extends BasicModelInstance>({ model, modelName, onSubmitNewItem, newItemRequest, }: AddScreenProps<T>) => JSX.Element;
|
|
16
|
+
export declare const AddScreen: <T extends BasicModelInstance>({ model, modelName, basePath, onSubmitNewItem, newItemRequest, }: AddScreenProps<T>) => JSX.Element;
|
|
@@ -27,4 +27,4 @@ export interface ListScreenProps<T extends BasicModelInstance> extends BaseScree
|
|
|
27
27
|
*/
|
|
28
28
|
deleteRequest: RequestState;
|
|
29
29
|
}
|
|
30
|
-
export declare const ListScreen: <T extends BasicModelInstance>({ model, modelName, listData,
|
|
30
|
+
export declare const ListScreen: <T extends BasicModelInstance>({ model, modelName, listData, listRequest, deleteRequest, basePath, deleteFeature, updateFeature, addFeature, detailsFeature, onRequestList, onClickDeleteItem, }: ListScreenProps<T>) => JSX.Element;
|
|
@@ -8,4 +8,24 @@ export interface BaseScreenProps {
|
|
|
8
8
|
* Structure that represents the fields of the model
|
|
9
9
|
*/
|
|
10
10
|
model: Model;
|
|
11
|
+
/**
|
|
12
|
+
* Path to attach before each internal ModelRouter path
|
|
13
|
+
*/
|
|
14
|
+
basePath?: string;
|
|
15
|
+
/**
|
|
16
|
+
* If true delete features are enabled
|
|
17
|
+
*/
|
|
18
|
+
deleteFeature?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* If true update features are enabled
|
|
21
|
+
*/
|
|
22
|
+
updateFeature?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* If true add features are enabled
|
|
25
|
+
*/
|
|
26
|
+
addFeature?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* If true details features are enabled
|
|
29
|
+
*/
|
|
30
|
+
detailsFeature?: boolean;
|
|
11
31
|
}
|
|
@@ -26,4 +26,4 @@ export interface UpdateScreenProps<T extends BasicModelInstance> extends BaseScr
|
|
|
26
26
|
*/
|
|
27
27
|
updateItem?: T;
|
|
28
28
|
}
|
|
29
|
-
export declare const UpdateScreen: <T extends BasicModelInstance>({ model, modelName, submitUpdateItemRequest, updateItemRequest, updateItem, onSubmitUpdateItem, onRequestUpdateItem, }: UpdateScreenProps<T>) => JSX.Element;
|
|
29
|
+
export declare const UpdateScreen: <T extends BasicModelInstance>({ model, modelName, basePath, submitUpdateItemRequest, updateItemRequest, updateItem, onSubmitUpdateItem, onRequestUpdateItem, }: UpdateScreenProps<T>) => JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import * as _mui_material from '@mui/material';
|
|
3
|
-
import { PropTypes, LinkProps as LinkProps$1, AppBarProps as AppBarProps$1, DrawerProps as DrawerProps$1, SxProps, Theme, GridProps, Color } from '@mui/material';
|
|
3
|
+
import { PropTypes, LinkProps as LinkProps$1, AppBarProps as AppBarProps$1, DrawerProps as DrawerProps$1, SxProps, Theme, GridProps, Color, AlertColor } from '@mui/material';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import React__default, { FunctionComponent, ReactElement, PropsWithChildren, ReactNode } from 'react';
|
|
5
|
+
import React__default, { FunctionComponent, ReactElement, PropsWithChildren, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
6
6
|
import * as _mui_material_OverridableComponent from '@mui/material/OverridableComponent';
|
|
7
7
|
import { LinkProps } from 'react-router-dom';
|
|
8
8
|
import * as _emotion_styled from '@emotion/styled';
|
|
@@ -519,6 +519,26 @@ interface BaseScreenProps {
|
|
|
519
519
|
* Structure that represents the fields of the model
|
|
520
520
|
*/
|
|
521
521
|
model: Model;
|
|
522
|
+
/**
|
|
523
|
+
* Path to attach before each internal ModelRouter path
|
|
524
|
+
*/
|
|
525
|
+
basePath?: string;
|
|
526
|
+
/**
|
|
527
|
+
* If true delete features are enabled
|
|
528
|
+
*/
|
|
529
|
+
deleteFeature?: boolean;
|
|
530
|
+
/**
|
|
531
|
+
* If true update features are enabled
|
|
532
|
+
*/
|
|
533
|
+
updateFeature?: boolean;
|
|
534
|
+
/**
|
|
535
|
+
* If true add features are enabled
|
|
536
|
+
*/
|
|
537
|
+
addFeature?: boolean;
|
|
538
|
+
/**
|
|
539
|
+
* If true details features are enabled
|
|
540
|
+
*/
|
|
541
|
+
detailsFeature?: boolean;
|
|
522
542
|
}
|
|
523
543
|
|
|
524
544
|
interface UpdateScreenProps<T extends BasicModelInstance$1> extends BaseScreenProps {
|
|
@@ -615,4 +635,33 @@ interface ModelFormProps<T extends BasicModelInstance> {
|
|
|
615
635
|
}
|
|
616
636
|
declare const ModelForm: <T extends BasicModelInstance>({ model, saveButtonText, onSubmit, initialValues, }: ModelFormProps<T>) => JSX.Element;
|
|
617
637
|
|
|
618
|
-
|
|
638
|
+
declare type NotificationCenterProviderProps = PropsWithChildren<{
|
|
639
|
+
autoHideDuration?: number;
|
|
640
|
+
}>;
|
|
641
|
+
declare const NotificationCenterProvider: ({ children, autoHideDuration, }: NotificationCenterProviderProps) => JSX.Element;
|
|
642
|
+
|
|
643
|
+
declare const NotificationCenterProviderUndefinedError: Error;
|
|
644
|
+
declare type SnackbarContentType = React__default.ReactElement<any, any> | ((key: string) => React__default.ReactElement<any, any>);
|
|
645
|
+
declare type SnackbarActionType = React__default.ReactNode | ((key: string) => React__default.ReactNode);
|
|
646
|
+
interface Notification {
|
|
647
|
+
severity: AlertColor;
|
|
648
|
+
title?: string;
|
|
649
|
+
message: string;
|
|
650
|
+
}
|
|
651
|
+
interface NotificationCenterProps {
|
|
652
|
+
show(notification: Notification): void;
|
|
653
|
+
hide(): void;
|
|
654
|
+
}
|
|
655
|
+
declare const NotificationCenterContext: React__default.Context<NotificationCenterProps | undefined>;
|
|
656
|
+
declare const useNotificationCenter: () => NotificationCenterProps;
|
|
657
|
+
|
|
658
|
+
declare const TabContext: React.Context<[number, Dispatch<SetStateAction<number>>]>;
|
|
659
|
+
declare const TabContextProvider: React.Provider<[number, Dispatch<SetStateAction<number>>]>;
|
|
660
|
+
declare const useTab: () => [number, Dispatch<SetStateAction<number>>];
|
|
661
|
+
|
|
662
|
+
declare type TabProviderProps = PropsWithChildren<{
|
|
663
|
+
initialValue?: number;
|
|
664
|
+
}>;
|
|
665
|
+
declare const TabProvider: ({ children, initialValue }: TabProviderProps) => JSX.Element;
|
|
666
|
+
|
|
667
|
+
export { AppBarComponent, AppBarElement, AppBarProfile, AppBarProps, AppBarWithDrawerLayout, AppBarWithDrawerLayoutProps, BasicModelInstance, Bullet, BulletProps, BulletVariant, CenterContainer, CenterContainerProps, Content, ContentComponent, ContentElement, ContentProps, Drawer, DrawerComponent, DrawerContent, DrawerContentComponent, DrawerContentElement, DrawerContentProps, DrawerContext, DrawerContextProps, DrawerElement, DrawerItem, DrawerItemProps, DrawerProps, DrawerProvider, DrawerSection, DrawerSectionProps, EnhancedRemoteTable, EnhancedTable, EnhancedTableHead, GroupField, GroupValueCard, GroupValueCardProps, GroupValueItem, GroupValueItemComponent, GroupValueItemElement, GroupValueItemProps, HeadCell, Header, HeaderAction, HeaderActionVariant, HeaderBreadcrumb, HeaderComponent, HeaderElement, HeaderLayout, HeaderPreset, HeaderProps, HeaderTab, Label, LabelProps, LabelVariant, Link, LinkBehaviour, MiniAppBar, MiniDrawer, Model, ModelField, ModelForm, ModelFormProps, ModelRouter, ModelRouterProps, Nav, NavItem, NavItemAvatar, NavItemBullet, NavItemLabel, NavSection, Notification, NotificationCenterContext, NotificationCenterProps, NotificationCenterProvider, NotificationCenterProviderProps, NotificationCenterProviderUndefinedError, ObjectDetails, ObjectDetailsProps, Order, Placeholder, PlaceholderAction, PlaceholderIconArgs, PlaceholderProps, QueryContainer, QueryContainerError, QueryContainerProps, QueryContainerSuccess, SignIn, SnackbarActionType, SnackbarContentType, TabCard, TabContext, TabContextProvider, TabPanel, TabProvider, TableList, TableListProps, TableRowOption, UndefinedProvider, ValueBoolean, ValueBooleanProps, ValueCard, ValueCardProps, ValueText, ValueTextProps, bulletClasses, getRandomItem, groupValueItemClasses, labelClasses, newArrayWithSize, useDrawer, useGetDefaultThemeColor, useNotificationCenter, useTab };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pautena/react-design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "My custom design system on top of MUI",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -86,10 +86,21 @@
|
|
|
86
86
|
"rollup-plugin-dts": "^4.2.2",
|
|
87
87
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
88
88
|
"rollup-plugin-terser": "^7.0.2",
|
|
89
|
-
"storybook-addon-react-router-v6": "^0.1.10",
|
|
90
89
|
"tslib": "^2.4.0",
|
|
91
90
|
"typescript": "^4.7.4"
|
|
92
91
|
},
|
|
92
|
+
"peerDependencies": {
|
|
93
|
+
"@emotion/react": "^11.5.0",
|
|
94
|
+
"@emotion/styled": "^11.3.0",
|
|
95
|
+
"@mui/icons-material": "^5.0.0",
|
|
96
|
+
"@mui/lab": "^5.0.0",
|
|
97
|
+
"@mui/material": "^5.0.0",
|
|
98
|
+
"@mui/x-data-grid": "^5.13.0",
|
|
99
|
+
"@types/react": "^17.0.0 || ^18.0.0",
|
|
100
|
+
"react": "^17.0.0 || ^18.0.0",
|
|
101
|
+
"react-dom": "^17.0.0 || ^18.0.0",
|
|
102
|
+
"react-router-dom": "^6.0.0"
|
|
103
|
+
},
|
|
93
104
|
"repository": {
|
|
94
105
|
"type": "git",
|
|
95
106
|
"url": "git+https://github.com/pautena/react-design-system.git"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ComponentMeta } from "@storybook/react";
|
|
3
|
+
import { createTemplate } from "../../storybook";
|
|
4
|
+
import { AppBar } from "./app-bar";
|
|
5
|
+
import { DrawerProvider } from "../drawer";
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: "AppBars/AppBar",
|
|
9
|
+
component: AppBar,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "fullscreen",
|
|
12
|
+
},
|
|
13
|
+
} as ComponentMeta<typeof AppBar>;
|
|
14
|
+
|
|
15
|
+
const Template = createTemplate((args) => {
|
|
16
|
+
return (
|
|
17
|
+
<DrawerProvider>
|
|
18
|
+
<AppBar {...args} />
|
|
19
|
+
</DrawerProvider>
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const Default = Template.bind({});
|
|
24
|
+
Default.args = {
|
|
25
|
+
title: "Lorem ipsum",
|
|
26
|
+
menu: true,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const WithSearch = Template.bind({});
|
|
30
|
+
WithSearch.args = {
|
|
31
|
+
title: "Lorem ipsum",
|
|
32
|
+
search: true,
|
|
33
|
+
menu: true,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const WithoutTitle = Template.bind({});
|
|
37
|
+
WithoutTitle.args = {
|
|
38
|
+
menu: true,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const WihtoutMenu = Template.bind({});
|
|
42
|
+
WihtoutMenu.args = {
|
|
43
|
+
title: "Lorem ipsum",
|
|
44
|
+
menu: false,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const WithProfile = Template.bind({});
|
|
48
|
+
WithProfile.args = {
|
|
49
|
+
title: "Lorem ipsum",
|
|
50
|
+
menu: true,
|
|
51
|
+
profile: {
|
|
52
|
+
name: "Test user",
|
|
53
|
+
},
|
|
54
|
+
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { fireEvent, render, screen } from "../../tests";
|
|
3
|
+
import { AppBar } from "./app-bar";
|
|
4
|
+
import { DrawerProvider } from "../drawer";
|
|
5
|
+
import { AppBarProfile } from "./app-bar.types";
|
|
6
|
+
import userEvent from "@testing-library/user-event";
|
|
7
|
+
|
|
8
|
+
const profile: AppBarProfile = {
|
|
9
|
+
name: "John Smith",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
describe("AppBar", () => {
|
|
13
|
+
const renderComponent = ({
|
|
14
|
+
search,
|
|
15
|
+
title,
|
|
16
|
+
menu,
|
|
17
|
+
initialOpen,
|
|
18
|
+
profile,
|
|
19
|
+
}: {
|
|
20
|
+
title?: string;
|
|
21
|
+
search?: boolean;
|
|
22
|
+
menu?: boolean;
|
|
23
|
+
initialOpen?: boolean;
|
|
24
|
+
profile?: AppBarProfile;
|
|
25
|
+
} = {}) => {
|
|
26
|
+
const onClickSignOut = jest.fn();
|
|
27
|
+
const instance = render(
|
|
28
|
+
<DrawerProvider initialOpen={initialOpen}>
|
|
29
|
+
<AppBar
|
|
30
|
+
title={title}
|
|
31
|
+
menu={menu}
|
|
32
|
+
search={search}
|
|
33
|
+
profile={profile}
|
|
34
|
+
onClickSignOut={onClickSignOut}
|
|
35
|
+
/>
|
|
36
|
+
</DrawerProvider>,
|
|
37
|
+
);
|
|
38
|
+
return { ...instance, onClickSignOut };
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const clickOutsideProfileMenu = () => {
|
|
42
|
+
const child = screen.getByRole("presentation").firstChild;
|
|
43
|
+
expect(child).toBeDefined();
|
|
44
|
+
child && fireEvent.click(child);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
describe("title", () => {
|
|
48
|
+
it("wouldn't render a title if it's not defined", () => {
|
|
49
|
+
renderComponent({ title: undefined });
|
|
50
|
+
|
|
51
|
+
expect(screen.queryByRole("heading", { level: 1 })).not.toBeInTheDocument();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("would render a title if it's defined", () => {
|
|
55
|
+
renderComponent({ title: "Lorem ipsum" });
|
|
56
|
+
|
|
57
|
+
expect(screen.queryByRole("heading", { level: 1, name: /lorem ipsum/i })).toBeInTheDocument();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("menu", () => {
|
|
62
|
+
it("wouldn't render a menu button if menu is not defined", () => {
|
|
63
|
+
renderComponent();
|
|
64
|
+
|
|
65
|
+
expect(screen.queryByRole("button", { name: /open drawer/i })).not.toBeInTheDocument();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("wouldn't render a menu button if menu is false", () => {
|
|
69
|
+
renderComponent({ menu: false });
|
|
70
|
+
|
|
71
|
+
expect(screen.queryByRole("button", { name: /open drawer/i })).not.toBeInTheDocument();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("would render a menu button if menu is true", () => {
|
|
75
|
+
renderComponent({ menu: true });
|
|
76
|
+
|
|
77
|
+
expect(screen.getByRole("button", { name: /open drawer/i })).toBeInTheDocument();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("search", () => {
|
|
82
|
+
it("wouldn't render a search box by default", () => {
|
|
83
|
+
renderComponent();
|
|
84
|
+
|
|
85
|
+
expect(screen.queryByRole("search")).not.toBeInTheDocument();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("wouldn't render a search box if search is false", () => {
|
|
89
|
+
renderComponent({ search: false });
|
|
90
|
+
|
|
91
|
+
expect(screen.queryByRole("search")).not.toBeInTheDocument();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("would render a search box if search is true", () => {
|
|
95
|
+
renderComponent({ search: true });
|
|
96
|
+
|
|
97
|
+
expect(screen.getByRole("search")).toBeInTheDocument();
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe("profile", () => {
|
|
102
|
+
it("wouldn't render the user profile if it's not set", () => {
|
|
103
|
+
renderComponent({ profile: undefined });
|
|
104
|
+
|
|
105
|
+
expect(screen.queryByRole("button", { name: /menu button/i })).not.toBeInTheDocument();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("would render the user profile if the profile is defined", () => {
|
|
109
|
+
renderComponent({ profile });
|
|
110
|
+
|
|
111
|
+
expect(screen.getByRole("button", { name: /menu button/i })).toBeInTheDocument();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe("the user click the profile button", () => {
|
|
115
|
+
it("would open the menu", async () => {
|
|
116
|
+
renderComponent({ profile });
|
|
117
|
+
|
|
118
|
+
await userEvent.click(screen.getByRole("button", { name: /menu button/i }));
|
|
119
|
+
|
|
120
|
+
expect(screen.getByRole("menu")).toBeInTheDocument();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("would call onClickSignOut if the user press the sign out button", async () => {
|
|
125
|
+
const { onClickSignOut } = renderComponent({ profile });
|
|
126
|
+
|
|
127
|
+
await userEvent.click(screen.getByRole("button", { name: /menu button/i }));
|
|
128
|
+
await userEvent.click(screen.getByRole("menuitem", { name: /sign out/i }));
|
|
129
|
+
|
|
130
|
+
expect(onClickSignOut).toHaveBeenCalledTimes(1);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("would hide the menu if the focus changes to an external element", async () => {
|
|
134
|
+
renderComponent({ profile, title: "lorem ipsum" });
|
|
135
|
+
|
|
136
|
+
await userEvent.click(screen.getByRole("button", { name: /menu button/i }));
|
|
137
|
+
clickOutsideProfileMenu();
|
|
138
|
+
|
|
139
|
+
expect(screen.queryByRole("menu")).not.toBeInTheDocument();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { styled, alpha } from "@mui/material/styles";
|
|
3
|
+
import MuiAppBar from "@mui/material/AppBar";
|
|
4
|
+
import Box from "@mui/material/Box";
|
|
5
|
+
import Toolbar from "@mui/material/Toolbar";
|
|
6
|
+
import IconButton from "@mui/material/IconButton";
|
|
7
|
+
import Typography from "@mui/material/Typography";
|
|
8
|
+
import InputBase from "@mui/material/InputBase";
|
|
9
|
+
import MenuItem from "@mui/material/MenuItem";
|
|
10
|
+
import Menu from "@mui/material/Menu";
|
|
11
|
+
import MenuIcon from "@mui/icons-material/Menu";
|
|
12
|
+
import SearchIcon from "@mui/icons-material/Search";
|
|
13
|
+
import AccountCircle from "@mui/icons-material/AccountCircle";
|
|
14
|
+
import { AppBarComponent, AppBarProps } from "./app-bar.types";
|
|
15
|
+
import { useDrawer } from "../drawer/drawer.context";
|
|
16
|
+
|
|
17
|
+
const Search = styled("div")(({ theme }) => ({
|
|
18
|
+
position: "relative",
|
|
19
|
+
borderRadius: theme.shape.borderRadius,
|
|
20
|
+
backgroundColor: alpha(theme.palette.common.white, 0.15),
|
|
21
|
+
"&:hover": {
|
|
22
|
+
backgroundColor: alpha(theme.palette.common.white, 0.25),
|
|
23
|
+
},
|
|
24
|
+
marginRight: theme.spacing(2),
|
|
25
|
+
marginLeft: 0,
|
|
26
|
+
width: "100%",
|
|
27
|
+
[theme.breakpoints.up("sm")]: {
|
|
28
|
+
marginLeft: theme.spacing(3),
|
|
29
|
+
width: "auto",
|
|
30
|
+
},
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
const SearchIconWrapper = styled("div")(({ theme }) => ({
|
|
34
|
+
padding: theme.spacing(0, 2),
|
|
35
|
+
height: "100%",
|
|
36
|
+
position: "absolute",
|
|
37
|
+
pointerEvents: "none",
|
|
38
|
+
display: "flex",
|
|
39
|
+
alignItems: "center",
|
|
40
|
+
justifyContent: "center",
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
const StyledInputBase = styled(InputBase)(({ theme }) => ({
|
|
44
|
+
color: "inherit",
|
|
45
|
+
"& .MuiInputBase-input": {
|
|
46
|
+
padding: theme.spacing(1, 1, 1, 0),
|
|
47
|
+
// vertical padding + font size from searchIcon
|
|
48
|
+
paddingLeft: `calc(1em + ${theme.spacing(4)})`,
|
|
49
|
+
transition: theme.transitions.create("width"),
|
|
50
|
+
width: "100%",
|
|
51
|
+
[theme.breakpoints.up("md")]: {
|
|
52
|
+
width: "20ch",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
}));
|
|
56
|
+
|
|
57
|
+
export const AppBar: AppBarComponent = ({
|
|
58
|
+
search = false,
|
|
59
|
+
title,
|
|
60
|
+
menu = false,
|
|
61
|
+
profile,
|
|
62
|
+
onClickSignOut,
|
|
63
|
+
...rest
|
|
64
|
+
}: AppBarProps) => {
|
|
65
|
+
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
|
66
|
+
const { isOpen, open } = useDrawer();
|
|
67
|
+
|
|
68
|
+
const handleMenu = (event: React.MouseEvent<HTMLElement>) => {
|
|
69
|
+
setAnchorEl(event.currentTarget);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const handleClose = () => {
|
|
73
|
+
setAnchorEl(null);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<MuiAppBar {...rest}>
|
|
78
|
+
<Toolbar>
|
|
79
|
+
{menu && (
|
|
80
|
+
<IconButton
|
|
81
|
+
color="inherit"
|
|
82
|
+
aria-label="open drawer"
|
|
83
|
+
onClick={open}
|
|
84
|
+
edge="start"
|
|
85
|
+
sx={{
|
|
86
|
+
marginRight: 5,
|
|
87
|
+
...(isOpen && { display: "none" }),
|
|
88
|
+
}}
|
|
89
|
+
>
|
|
90
|
+
<MenuIcon />
|
|
91
|
+
</IconButton>
|
|
92
|
+
)}
|
|
93
|
+
{title && (
|
|
94
|
+
<Typography
|
|
95
|
+
variant="h6"
|
|
96
|
+
component="h1"
|
|
97
|
+
role="heading"
|
|
98
|
+
aria-level={1}
|
|
99
|
+
noWrap
|
|
100
|
+
sx={{ display: { xs: "none", sm: "block" } }}
|
|
101
|
+
>
|
|
102
|
+
{title}
|
|
103
|
+
</Typography>
|
|
104
|
+
)}
|
|
105
|
+
{search && (
|
|
106
|
+
<Search role="search">
|
|
107
|
+
<SearchIconWrapper>
|
|
108
|
+
<SearchIcon />
|
|
109
|
+
</SearchIconWrapper>
|
|
110
|
+
<StyledInputBase placeholder="Search…" inputProps={{ "aria-label": "search" }} />
|
|
111
|
+
</Search>
|
|
112
|
+
)}
|
|
113
|
+
<Box sx={{ flexGrow: 1 }} />
|
|
114
|
+
{profile && (
|
|
115
|
+
<Box sx={{ display: { xs: "none", md: "flex" } }}>
|
|
116
|
+
<IconButton
|
|
117
|
+
size="large"
|
|
118
|
+
aria-controls="menu-appbar"
|
|
119
|
+
aria-haspopup="true"
|
|
120
|
+
aria-label="menu button"
|
|
121
|
+
role="button"
|
|
122
|
+
aria-expanded={Boolean(anchorEl)}
|
|
123
|
+
onClick={handleMenu}
|
|
124
|
+
color="inherit"
|
|
125
|
+
>
|
|
126
|
+
<AccountCircle />
|
|
127
|
+
</IconButton>
|
|
128
|
+
<Menu
|
|
129
|
+
id="menu-appbar"
|
|
130
|
+
anchorEl={anchorEl}
|
|
131
|
+
anchorOrigin={{
|
|
132
|
+
vertical: "top",
|
|
133
|
+
horizontal: "right",
|
|
134
|
+
}}
|
|
135
|
+
keepMounted
|
|
136
|
+
transformOrigin={{
|
|
137
|
+
vertical: "top",
|
|
138
|
+
horizontal: "right",
|
|
139
|
+
}}
|
|
140
|
+
open={Boolean(anchorEl)}
|
|
141
|
+
onClose={handleClose}
|
|
142
|
+
>
|
|
143
|
+
<MenuItem onClick={onClickSignOut}>Sign out</MenuItem>
|
|
144
|
+
</Menu>
|
|
145
|
+
</Box>
|
|
146
|
+
)}
|
|
147
|
+
</Toolbar>
|
|
148
|
+
</MuiAppBar>
|
|
149
|
+
);
|
|
150
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FunctionComponent, ReactElement } from "react";
|
|
2
|
+
import { AppBarProps as MuiAppBarProps } from "@mui/material";
|
|
3
|
+
|
|
4
|
+
export interface AppBarProfile {
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface AppBarProps extends MuiAppBarProps {
|
|
9
|
+
menu?: boolean;
|
|
10
|
+
title?: string;
|
|
11
|
+
search?: boolean;
|
|
12
|
+
profile?: AppBarProfile;
|
|
13
|
+
onClickSignOut: () => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type AppBarComponent = FunctionComponent<AppBarProps>;
|
|
17
|
+
export type AppBarElement = ReactElement<AppBarProps, AppBarComponent>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./mini-app-bar";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { styled } from "@mui/material/styles";
|
|
2
|
+
import { AppBar } from "../app-bar";
|
|
3
|
+
import { AppBarProps } from "@mui/material";
|
|
4
|
+
import { drawerWidth } from "../../drawer/drawer.mixins";
|
|
5
|
+
import { AppBarComponent } from "../app-bar.types";
|
|
6
|
+
import { useDrawer } from "../../drawer/drawer.context";
|
|
7
|
+
|
|
8
|
+
export const MiniAppBar: AppBarComponent = styled(AppBar)<AppBarProps>(({ theme }) => {
|
|
9
|
+
const { isOpen } = useDrawer();
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
zIndex: theme.zIndex.drawer + 1,
|
|
13
|
+
transition: theme.transitions.create(["width", "margin"], {
|
|
14
|
+
easing: theme.transitions.easing.sharp,
|
|
15
|
+
duration: theme.transitions.duration.leavingScreen,
|
|
16
|
+
}),
|
|
17
|
+
...(isOpen && {
|
|
18
|
+
marginLeft: drawerWidth,
|
|
19
|
+
width: `calc(100% - ${drawerWidth}px)`,
|
|
20
|
+
transition: theme.transitions.create(["width", "margin"], {
|
|
21
|
+
easing: theme.transitions.easing.sharp,
|
|
22
|
+
duration: theme.transitions.duration.enteringScreen,
|
|
23
|
+
}),
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
MiniAppBar.defaultProps = {
|
|
29
|
+
position: "fixed",
|
|
30
|
+
menu: true,
|
|
31
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ComponentMeta } from "@storybook/react";
|
|
2
|
+
import { createTemplate } from "../../storybook";
|
|
3
|
+
import { Bullet } from "./bullet";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: "Data Display/Bullet",
|
|
7
|
+
component: Bullet,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
},
|
|
11
|
+
} as ComponentMeta<typeof Bullet>;
|
|
12
|
+
|
|
13
|
+
const Template = createTemplate(Bullet);
|
|
14
|
+
|
|
15
|
+
export const Primary = Template.bind({});
|
|
16
|
+
Primary.args = {
|
|
17
|
+
variant: "primary",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const Secondary = Template.bind({});
|
|
21
|
+
Secondary.args = {
|
|
22
|
+
variant: "secondary",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Default = Template.bind({});
|
|
26
|
+
Default.args = {
|
|
27
|
+
variant: "default",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const Info = Template.bind({});
|
|
31
|
+
Info.args = {
|
|
32
|
+
variant: "info",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const Warning = Template.bind({});
|
|
36
|
+
Warning.args = {
|
|
37
|
+
variant: "warning",
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const Error = Template.bind({});
|
|
41
|
+
Error.args = {
|
|
42
|
+
variant: "error",
|
|
43
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Bullet, BulletVariant } from "./bullet";
|
|
3
|
+
import { render, screen } from "../../tests";
|
|
4
|
+
|
|
5
|
+
describe("Bullet", () => {
|
|
6
|
+
const renderComponent = (variant: BulletVariant | undefined = undefined) => {
|
|
7
|
+
return render(<Bullet variant={variant} />);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
it("renders as primary without a variant", () => {
|
|
11
|
+
renderComponent(undefined);
|
|
12
|
+
|
|
13
|
+
expect(screen.getByRole("bullet")).toHaveAttribute("aria-describedby", "primary");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it.each([["primary"], ["secondary"], ["default"], ["info"], ["warning"], ["error"]])(
|
|
17
|
+
"renders correctly with variant %s",
|
|
18
|
+
(variant: string) => {
|
|
19
|
+
renderComponent(variant as BulletVariant);
|
|
20
|
+
|
|
21
|
+
expect(screen.getByRole("bullet")).toHaveAttribute("aria-describedby", variant);
|
|
22
|
+
},
|
|
23
|
+
);
|
|
24
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Badge } from "@mui/material";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
export type BulletVariant = "primary" | "secondary" | "default" | "info" | "warning" | "error";
|
|
5
|
+
|
|
6
|
+
export const bulletClasses = {
|
|
7
|
+
root: "RdsBullet-root",
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export interface BulletProps {
|
|
11
|
+
/**
|
|
12
|
+
* Color palette used to draw the component
|
|
13
|
+
*/
|
|
14
|
+
variant?: BulletVariant;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Dot to attract the user attention
|
|
19
|
+
*/
|
|
20
|
+
export const Bullet = ({ variant = "primary" }: BulletProps) => {
|
|
21
|
+
return (
|
|
22
|
+
<Badge
|
|
23
|
+
color={variant}
|
|
24
|
+
variant="dot"
|
|
25
|
+
className={bulletClasses.root}
|
|
26
|
+
role="bullet"
|
|
27
|
+
aria-describedby={variant}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./bullet";
|