| "@emotion/styled": "^11.3.0", | "@emotion/styled": "^11.3.0", | ||||
| "@mui/icons-material": "^5.0.5", | "@mui/icons-material": "^5.0.5", | ||||
| "@mui/material": "^5.0.6", | "@mui/material": "^5.0.6", | ||||
| "@mui/x-data-grid": "^5.0.1", | |||||
| "@reduxjs/toolkit": "^1.5.1", | "@reduxjs/toolkit": "^1.5.1", | ||||
| "@testing-library/jest-dom": "^5.13.0", | "@testing-library/jest-dom": "^5.13.0", | ||||
| "@testing-library/react": "^11.2.7", | "@testing-library/react": "^11.2.7", |
| import { Backdrop, CircularProgress } from '@mui/material'; | import { Backdrop, CircularProgress } from '@mui/material'; | ||||
| import { alpha } from '@mui/system'; | import { alpha } from '@mui/system'; | ||||
| const CustomBackdrop = ({ position = 'fixed', isLoading }) => ( | |||||
| const BackdropComponent = ({ position = 'fixed', isLoading }) => ( | |||||
| <Backdrop | <Backdrop | ||||
| sx={{ | sx={{ | ||||
| // 'fixed' takes whole page, 'fixed' takes whole space of the parent element which needs to have 'relative' position | // 'fixed' takes whole page, 'fixed' takes whole space of the parent element which needs to have 'relative' position | ||||
| </Backdrop> | </Backdrop> | ||||
| ); | ); | ||||
| CustomBackdrop.propTypes = { | |||||
| BackdropComponent.propTypes = { | |||||
| position: PropTypes.oneOf(['fixed', 'absolute']), | position: PropTypes.oneOf(['fixed', 'absolute']), | ||||
| isLoading: PropTypes.bool.isRequired, | isLoading: PropTypes.bool.isRequired, | ||||
| }; | }; | ||||
| export default CustomBackdrop; | |||||
| export default BackdropComponent; |
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||
| import { Typography } from '@mui/material'; | import { Typography } from '@mui/material'; | ||||
| const CustomErrorMessage = ({ error }) => ( | |||||
| const ErrorMessageComponent = ({ error }) => ( | |||||
| <Typography variant="body1" color="error" my={2}> | <Typography variant="body1" color="error" my={2}> | ||||
| {error} | {error} | ||||
| </Typography> | </Typography> | ||||
| ); | ); | ||||
| CustomErrorMessage.propTypes = { | |||||
| ErrorMessageComponent.propTypes = { | |||||
| error: PropTypes.string.isRequired, | error: PropTypes.string.isRequired, | ||||
| }; | }; | ||||
| export default CustomErrorMessage; | |||||
| export default ErrorMessageComponent; |
| import React from 'react'; | |||||
| import { Paper, Typography } from '@mui/material'; | |||||
| import { DataGrid } from '@mui/x-data-grid'; | |||||
| // Use these values from REDUX? | |||||
| const rows = [ | |||||
| { id: 1, col1: 'Example', col2: 'Row', col3: '1' }, | |||||
| { id: 2, col1: 'Row', col2: 'Example', col3: '2' }, | |||||
| { id: 3, col1: '3', col2: 'Row', col3: 'Example' }, | |||||
| ]; | |||||
| const columns = [ | |||||
| { field: 'col1', headerName: 'Column 1', flex: 1 }, | |||||
| { field: 'col2', headerName: 'Column 2', flex: 1 }, | |||||
| { field: 'col3', headerName: 'Column 2', flex: 1 }, | |||||
| ]; | |||||
| const DataGridExample = () => { | |||||
| return ( | |||||
| <Paper sx={{ p: 2 }} elevation={5}> | |||||
| <Typography variant="h4" gutterBottom align="center"> | |||||
| DataGrid Example | |||||
| </Typography> | |||||
| <DataGrid autoHeight rows={rows} columns={columns} /> | |||||
| </Paper> | |||||
| ); | |||||
| }; | |||||
| export default DataGridExample; |
| import React, { useState } from 'react'; | import React, { useState } from 'react'; | ||||
| import { Box, Button, Divider, Paper, Typography } from '@mui/material'; | |||||
| import { Button, Divider, Paper, Typography } from '@mui/material'; | |||||
| import DialogComponent from '../DialogComponent'; | import DialogComponent from '../DialogComponent'; | ||||
| import DrawerComponent from '../DrawerComponent'; | import DrawerComponent from '../DrawerComponent'; | ||||
| import PopoverComponent from '../PopoverComponent'; | import PopoverComponent from '../PopoverComponent'; | ||||
| const [anchorEl, setAnchorEl] = useState(null); | const [anchorEl, setAnchorEl] = useState(null); | ||||
| return ( | return ( | ||||
| <Box | |||||
| <Paper | |||||
| sx={{ | sx={{ | ||||
| mt: 4, | |||||
| ml: 4, | |||||
| p: 2, | |||||
| display: 'flex', | display: 'flex', | ||||
| flexGrow: 1, | |||||
| flexDirection: 'column', | |||||
| }} | }} | ||||
| elevation={5} | |||||
| > | > | ||||
| <Paper | |||||
| sx={{ | |||||
| p: 4, | |||||
| display: 'flex', | |||||
| flexDirection: 'column', | |||||
| <Typography variant="h4" gutterBottom align="center"> | |||||
| Modals Example | |||||
| </Typography> | |||||
| <Divider /> | |||||
| <Button onClick={() => setDialogOpen(true)}>Open Dialog</Button> | |||||
| <Button onClick={() => setDrawerOpen(true)}>Open Drawer</Button> | |||||
| <Button | |||||
| onClick={(e) => { | |||||
| setPopoverOpen(true); | |||||
| setAnchorEl(e.currentTarget); | |||||
| }} | }} | ||||
| > | > | ||||
| <Typography variant="h4" gutterBottom align="center"> | |||||
| Modals | |||||
| </Typography> | |||||
| <Divider /> | |||||
| <Button onClick={() => setDialogOpen(true)}>Open Dialog</Button> | |||||
| <Button onClick={() => setDrawerOpen(true)}>Open Drawer</Button> | |||||
| <Button | |||||
| onClick={(e) => { | |||||
| setPopoverOpen(true); | |||||
| setAnchorEl(e.currentTarget); | |||||
| }} | |||||
| > | |||||
| Open Popover | |||||
| </Button> | |||||
| </Paper> | |||||
| Open Popover | |||||
| </Button> | |||||
| <DialogComponent | <DialogComponent | ||||
| title="Dialog Title" | title="Dialog Title" | ||||
| content={<Typography>Dialog Content</Typography>} | content={<Typography>Dialog Content</Typography>} | ||||
| }} | }} | ||||
| content={<Typography sx={{ p: 2 }}>Popover Content</Typography>} | content={<Typography sx={{ p: 2 }}>Popover Content</Typography>} | ||||
| /> | /> | ||||
| </Box> | |||||
| </Paper> | |||||
| ); | ); | ||||
| }; | }; | ||||
| /*eslint-disable*/ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { | |||||
| Paper, | |||||
| Box, | |||||
| Grid, | |||||
| Typography, | |||||
| Divider, | |||||
| TablePagination, | |||||
| } from '@mui/material'; | |||||
| import { useTranslation } from 'react-i18next'; | |||||
| import { useDispatch, useSelector, batch } from 'react-redux'; | |||||
| import { | |||||
| itemsSelector, | |||||
| pageSelector, | |||||
| itemsPerPageSelector, | |||||
| countSelector, | |||||
| } from '../../../store/selectors/randomDataSelectors'; | |||||
| import { | |||||
| loadData, | |||||
| updatePage, | |||||
| updateItemsPerPage, | |||||
| } from '../../../store/actions/randomData/randomDataActions'; | |||||
| const PagingSortingFilteringExample = () => { | |||||
| const dispatch = useDispatch(); | |||||
| const { t } = useTranslation(); | |||||
| const items = useSelector(itemsSelector); | |||||
| const currentPage = useSelector(pageSelector); | |||||
| const itemsPerPage = useSelector(itemsPerPageSelector); | |||||
| const totalCount = useSelector(countSelector); | |||||
| useEffect(() => { | |||||
| dispatch(loadData(30)); | |||||
| }, []); | |||||
| const handlePageChange = (event, newPage) => { | |||||
| dispatch(updatePage(newPage)); | |||||
| }; | |||||
| const handleItemsPerPageChange = (event) => { | |||||
| const itemsPerPage = parseInt(event.target.value); | |||||
| batch(() => { | |||||
| dispatch(updateItemsPerPage(itemsPerPage)); | |||||
| dispatch(updatePage(0)); | |||||
| }); | |||||
| }; | |||||
| return ( | |||||
| <Paper | |||||
| sx={{ | |||||
| display: 'flex', | |||||
| flexDirection: 'column', | |||||
| justifyContent: 'center', | |||||
| }} | |||||
| elevation={5} | |||||
| > | |||||
| <Typography sx={{ my: 4 }} variant="h4" gutterBottom align="center"> | |||||
| Pagination, Filtering and Sorting Example | |||||
| </Typography> | |||||
| <Box sx={{ display: 'flex', justifyContent: 'space-between' }}> | |||||
| <Box> | |||||
| <TablePagination | |||||
| component="div" | |||||
| count={totalCount} | |||||
| page={currentPage} | |||||
| onPageChange={handlePageChange} | |||||
| rowsPerPage={itemsPerPage} | |||||
| onRowsPerPageChange={handleItemsPerPageChange} | |||||
| rowsPerPageOptions={[12, 24, 48, 96]} | |||||
| labelRowsPerPage="Items per page" | |||||
| showFirstButton | |||||
| showLastButton | |||||
| /> | |||||
| </Box> | |||||
| </Box> | |||||
| <Grid container> | |||||
| {items && | |||||
| items.length > 0 && | |||||
| items | |||||
| .slice( | |||||
| currentPage * itemsPerPage, | |||||
| currentPage * itemsPerPage + itemsPerPage | |||||
| ) | |||||
| .map((product, index) => ( | |||||
| // ! DON'T USE index for key, this is for example only | |||||
| <Grid item sx={{ p: 2 }} xs={12} sm={6} md={4} lg={3} key={index}> | |||||
| {/* TODO separate into component */} | |||||
| <Paper sx={{ p: 3, height: '100%' }} elevation={3}> | |||||
| <Typography sx={{ fontWeight: 600 }}>Name: </Typography> | |||||
| <Typography display="inline"> {product.name}</Typography> | |||||
| <Divider /> | |||||
| <Typography sx={{ fontWeight: 600 }}>Designer: </Typography> | |||||
| <Typography display="inline"> {product.designer}</Typography> | |||||
| <Divider /> | |||||
| <Typography sx={{ fontWeight: 600 }}>Type: </Typography> | |||||
| <Typography display="inline"> {product.type}</Typography> | |||||
| <Divider /> | |||||
| <Typography sx={{ fontWeight: 600 }}>Price: </Typography> | |||||
| <Typography display="inline"> ${product.price}</Typography> | |||||
| </Paper> | |||||
| </Grid> | |||||
| ))} | |||||
| </Grid> | |||||
| </Paper> | |||||
| ); | |||||
| }; | |||||
| export default PagingSortingFilteringExample; |
| import React, { useState } from 'react'; | import React, { useState } from 'react'; | ||||
| import { Button, Menu, MenuItem } from '@mui/material'; | import { Button, Menu, MenuItem } from '@mui/material'; | ||||
| const MenuList = () => { | |||||
| const MenuListComponent = () => { | |||||
| const [anchorEl, setAnchorEl] = useState(null); | const [anchorEl, setAnchorEl] = useState(null); | ||||
| const open = Boolean(anchorEl); | const open = Boolean(anchorEl); | ||||
| const handleClick = (event) => { | const handleClick = (event) => { | ||||
| ); | ); | ||||
| }; | }; | ||||
| export default MenuList; | |||||
| export default MenuListComponent; |
| import ShoppingBasketIcon from '@mui/icons-material/ShoppingBasket'; | import ShoppingBasketIcon from '@mui/icons-material/ShoppingBasket'; | ||||
| import Brightness4Icon from '@mui/icons-material/Brightness4'; | import Brightness4Icon from '@mui/icons-material/Brightness4'; | ||||
| import Brightness7Icon from '@mui/icons-material/Brightness7'; | import Brightness7Icon from '@mui/icons-material/Brightness7'; | ||||
| import MenuList from './MenuList'; | |||||
| import MenuList from './MenuListComponent'; | |||||
| import Drawer from './DrawerComponent'; | import Drawer from './DrawerComponent'; | ||||
| import { ColorModeContext } from '../../context/ColorModeContext'; | import { ColorModeContext } from '../../context/ColorModeContext'; | ||||
| const Navbar = () => { | |||||
| const NavbarComponent = () => { | |||||
| const [openDrawer, setOpenDrawer] = useState(false); | const [openDrawer, setOpenDrawer] = useState(false); | ||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const matches = useMediaQuery(theme.breakpoints.down('sm')); | const matches = useMediaQuery(theme.breakpoints.down('sm')); | ||||
| ); | ); | ||||
| }; | }; | ||||
| export default Navbar; | |||||
| export default NavbarComponent; |
| labelUsername: 'Username', | labelUsername: 'Username', | ||||
| labelPassword: 'Password', | labelPassword: 'Password', | ||||
| next: 'Next', | next: 'Next', | ||||
| nextPage: 'Next page', | |||||
| previousPage: 'Previous page', | |||||
| back: 'Back', | back: 'Back', | ||||
| goBack: 'Go Back', | goBack: 'Go Back', | ||||
| ok: 'Ok', | ok: 'Ok', |
| Link, | Link, | ||||
| Grid, | Grid, | ||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| import Backdrop from '../../components/MUI/CustomBackdrop'; | |||||
| import Backdrop from '../../components/MUI/BackdropComponent'; | |||||
| import { LOGIN_PAGE } from '../../constants/pages'; | import { LOGIN_PAGE } from '../../constants/pages'; | ||||
| import { NavLink } from 'react-router-dom'; | import { NavLink } from 'react-router-dom'; | ||||
| import React from 'react'; | import React from 'react'; | ||||
| import Navbar from '../../components/MUI/Navbar'; | |||||
| import Modals from '../../components/MUI/Examples/Modals'; | |||||
| import { Box, Grid } from '@mui/material'; | |||||
| import Navbar from '../../components/MUI/NavbarComponent'; | |||||
| import Modals from '../../components/MUI/Examples/ModalsExample'; | |||||
| import DataGrid from '../../components/MUI/Examples/DataGridExample'; | |||||
| import PagingSortingFiltering from '../../components/MUI/Examples/PagingSortingFilteringExample'; | |||||
| const HomePage = () => { | const HomePage = () => { | ||||
| return ( | return ( | ||||
| <> | <> | ||||
| <Navbar /> | <Navbar /> | ||||
| <Modals /> | |||||
| <Box sx={{ mt: 4, mx: 4 }}> | |||||
| <Grid container spacing={2} justifyContent="center"> | |||||
| <Grid item xs={12} md={3}> | |||||
| <Modals /> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={6}> | |||||
| <DataGrid /> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={9}> | |||||
| <PagingSortingFiltering /> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </Box> | |||||
| </> | </> | ||||
| ); | ); | ||||
| }; | }; |
| Typography, | Typography, | ||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| import { Visibility, VisibilityOff } from '@mui/icons-material'; | import { Visibility, VisibilityOff } from '@mui/icons-material'; | ||||
| import Backdrop from '../../components/MUI/CustomBackdrop'; | |||||
| import ErrorMessage from '../../components/MUI/CustomErrorMessage'; | |||||
| import Backdrop from '../../components/MUI/BackdropComponent'; | |||||
| import ErrorMessage from '../../components/MUI/ErrorMessageComponent'; | |||||
| import { selectIsLoadingByActionType } from '../../store/selectors/loadingSelectors'; | import { selectIsLoadingByActionType } from '../../store/selectors/loadingSelectors'; | ||||
| import { LOGIN_USER_LOADING } from '../../store/actions/login/loginActionConstants'; | import { LOGIN_USER_LOADING } from '../../store/actions/login/loginActionConstants'; | ||||
| export const LOAD_DATA = 'LOAD_DATA'; | |||||
| export const UPDATE_PAGE = 'UPDATE_PAGE'; | |||||
| export const UPDATE_ITEMS_PER_PAGE = 'UPDATE_ITEMS_PER_PAGE'; |
| import { | |||||
| LOAD_DATA, | |||||
| UPDATE_PAGE, | |||||
| UPDATE_ITEMS_PER_PAGE, | |||||
| } from './randomDataActionConstants'; | |||||
| export const loadData = (payload) => ({ | |||||
| type: LOAD_DATA, | |||||
| payload, | |||||
| }); | |||||
| export const updatePage = (payload) => ({ | |||||
| type: UPDATE_PAGE, | |||||
| payload, | |||||
| }); | |||||
| export const updateItemsPerPage = (payload) => ({ | |||||
| type: UPDATE_ITEMS_PER_PAGE, | |||||
| payload, | |||||
| }); |
| import loginReducer from './login/loginReducer'; | import loginReducer from './login/loginReducer'; | ||||
| import loadingReducer from './loading/loadingReducer'; | import loadingReducer from './loading/loadingReducer'; | ||||
| import userReducer from './user/userReducer'; | import userReducer from './user/userReducer'; | ||||
| import randomDataReducer from './randomData/randomDataReducer'; | |||||
| export default combineReducers({ | export default combineReducers({ | ||||
| login: loginReducer, | login: loginReducer, | ||||
| user: userReducer, | user: userReducer, | ||||
| loading:loadingReducer | |||||
| loading:loadingReducer, | |||||
| randomData: randomDataReducer | |||||
| }); | }); |
| import createReducer from '../../utils/createReducer'; | |||||
| import { | |||||
| LOAD_DATA, | |||||
| UPDATE_PAGE, | |||||
| UPDATE_ITEMS_PER_PAGE, | |||||
| } from '../../actions/randomData/randomDataActionConstants.js'; | |||||
| import generate from '../../../util/helpers/randomData'; | |||||
| const initialState = { | |||||
| items: [], | |||||
| count: 0, | |||||
| page: 0, | |||||
| itemsPerPage: 12, | |||||
| }; | |||||
| export default createReducer( | |||||
| { | |||||
| [LOAD_DATA]: loadRandomData, | |||||
| [UPDATE_PAGE]: updatePage, | |||||
| [UPDATE_ITEMS_PER_PAGE]: updateItemsPerPage, | |||||
| }, | |||||
| initialState | |||||
| ); | |||||
| function loadRandomData(state, action) { | |||||
| const count = action.payload; | |||||
| const items = generate(count); | |||||
| return { | |||||
| ...state, | |||||
| items, | |||||
| count: items.length, | |||||
| }; | |||||
| } | |||||
| function updatePage(state, action) { | |||||
| const page = action.payload; | |||||
| return { | |||||
| ...state, | |||||
| page, | |||||
| }; | |||||
| } | |||||
| function updateItemsPerPage(state, action) { | |||||
| const itemsPerPage = action.payload; | |||||
| return { | |||||
| ...state, | |||||
| itemsPerPage, | |||||
| }; | |||||
| } |
| import { createSelector } from 'reselect'; | |||||
| const randomDataSelector = (state) => state.randomData; | |||||
| export const itemsSelector = createSelector( | |||||
| randomDataSelector, | |||||
| (state) => state.items | |||||
| ); | |||||
| export const pageSelector = createSelector( | |||||
| randomDataSelector, | |||||
| (state) => state.page | |||||
| ); | |||||
| export const itemsPerPageSelector = createSelector( | |||||
| randomDataSelector, | |||||
| (state) => state.itemsPerPage | |||||
| ); | |||||
| export const countSelector = createSelector( | |||||
| randomDataSelector, | |||||
| (state) => state.count | |||||
| ); |
| const random = (arr) => { | |||||
| return arr[Math.floor(Math.random() * arr.length)]; | |||||
| }; | |||||
| const size = () => { | |||||
| return random(['Extra Small', 'Small', 'Medium', 'Large', 'Extra Large']); | |||||
| }; | |||||
| const color = () => { | |||||
| return random(['Red', 'Green', 'Blue', 'Orange', 'Yellow']); | |||||
| }; | |||||
| const designer = () => { | |||||
| return random([ | |||||
| 'Ralph Lauren', | |||||
| 'Alexander Wang', | |||||
| 'Grayse', | |||||
| 'Marc NY Performance', | |||||
| 'Scrapbook', | |||||
| 'J Brand Ready to Wear', | |||||
| 'Vintage Havana', | |||||
| 'Neiman Marcus Cashmere Collection', | |||||
| 'Derek Lam 10 Crosby', | |||||
| 'Jordan', | |||||
| ]); | |||||
| }; | |||||
| const type = () => { | |||||
| return random([ | |||||
| 'Cashmere', | |||||
| 'Cardigans', | |||||
| 'Crew and Scoop', | |||||
| 'V-Neck', | |||||
| 'Shoes', | |||||
| 'Cowl & Turtleneck', | |||||
| ]); | |||||
| }; | |||||
| const price = () => { | |||||
| return (Math.random() * 100).toFixed(2); | |||||
| }; | |||||
| function generate(count) { | |||||
| const data = []; | |||||
| for (let i = 0; i < count; i++) { | |||||
| const currentColor = color(); | |||||
| const currentSize = size(); | |||||
| const currentType = type(); | |||||
| const currentDesigner = designer(); | |||||
| const currentPrice = price(); | |||||
| data.push({ | |||||
| name: `${currentDesigner} ${currentType} ${currentColor} ${currentSize}`, | |||||
| color: currentColor, | |||||
| size: currentSize, | |||||
| designer: currentDesigner, | |||||
| type: currentType, | |||||
| price: currentPrice, | |||||
| salesPrice: currentPrice | |||||
| }); | |||||
| } | |||||
| return data; | |||||
| } | |||||
| export default generate; |
| dependencies: | dependencies: | ||||
| regenerator-runtime "^0.13.4" | regenerator-runtime "^0.13.4" | ||||
| "@babel/runtime@^7.16.3": | |||||
| version "7.16.3" | |||||
| resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" | |||||
| integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== | |||||
| dependencies: | |||||
| regenerator-runtime "^0.13.4" | |||||
| "@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3": | "@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3": | ||||
| version "7.12.13" | version "7.12.13" | ||||
| resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" | ||||
| prop-types "^15.7.2" | prop-types "^15.7.2" | ||||
| react-is "^17.0.2" | react-is "^17.0.2" | ||||
| "@mui/utils@^5.1.0": | |||||
| version "5.1.1" | |||||
| resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.1.1.tgz#3cb2c049731dacb3830336bc8011141e84434aad" | |||||
| integrity sha512-rqakHf0IMaasDo1EcYqkx13VTxeoQoGf/3RxQuazQFKzF7d2uylFwNyb6bnUJGNe2/akiIMk/qiub58sYrwxVQ== | |||||
| dependencies: | |||||
| "@babel/runtime" "^7.16.3" | |||||
| "@types/prop-types" "^15.7.4" | |||||
| "@types/react-is" "^16.7.1 || ^17.0.0" | |||||
| prop-types "^15.7.2" | |||||
| react-is "^17.0.2" | |||||
| "@mui/x-data-grid@^5.0.1": | |||||
| version "5.0.1" | |||||
| resolved "https://registry.yarnpkg.com/@mui/x-data-grid/-/x-data-grid-5.0.1.tgz#bace714fca342b6401bebb8861c4a0b09a4f1604" | |||||
| integrity sha512-F1IhkxNiI7A/VoRT0vTs7PP4E8E/K6e5WLrjXFzxeWmvOBaAfmwvf3Wq8o/8ouQ9MFy92M/lAgviOMp1gduOtw== | |||||
| dependencies: | |||||
| "@mui/utils" "^5.1.0" | |||||
| clsx "^1.1.1" | |||||
| prop-types "^15.7.2" | |||||
| reselect "^4.1.1" | |||||
| "@nodelib/fs.scandir@2.1.5": | "@nodelib/fs.scandir@2.1.5": | ||||
| version "2.1.5" | version "2.1.5" | ||||
| resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" | ||||
| resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" | resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" | ||||
| integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== | integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== | ||||
| reselect@^4.1.1: | |||||
| version "4.1.4" | |||||
| resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.4.tgz#66df0aff41b6ee0f51e2cc17cfaf2c1995916f32" | |||||
| integrity sha512-i1LgXw8DKSU5qz1EV0ZIKz4yIUHJ7L3bODh+Da6HmVSm9vdL/hG7IpbgzQ3k2XSirzf8/eI7OMEs81gb1VV2fQ== | |||||
| resolve-cwd@^2.0.0: | resolve-cwd@^2.0.0: | ||||
| version "2.0.0" | version "2.0.0" | ||||
| resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" | resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" |