From 5767d4e52f47a4637bc33d2823f78d4441bbd869 Mon Sep 17 00:00:00 2001 From: Sean Ryan Date: Fri, 3 May 2024 10:12:26 -0700 Subject: [PATCH] added state to iframe; fixed rendering for Modal, Popover, Popper, Transition, Backdrop, and Dialog components --- app/src/components/left/DragDropPanel.tsx | 27 - app/src/components/main/DemoRender.tsx | 819 ++++++++++++++-------- app/src/redux/MUITypes.ts | 530 ++++++++++---- vite.config.ts | 9 +- 4 files changed, 925 insertions(+), 460 deletions(-) diff --git a/app/src/components/left/DragDropPanel.tsx b/app/src/components/left/DragDropPanel.tsx index 22546e0a..4e08aba2 100644 --- a/app/src/components/left/DragDropPanel.tsx +++ b/app/src/components/left/DragDropPanel.tsx @@ -101,33 +101,6 @@ const DragDropPanel = (props): JSX.Element => { - {/* MUI Components */} - {/* - } - aria-controls="panel2a-content" - id="panel2a-header" - className={classes.accordionSummary} - > -

MUI Components

-
- - - {muiTypesToRender.map((option) => { - return ( - - ); - })} - - -
*/} - {/* React Router */} { function logToParentConsole(...args) { const cache = new Set(); // Set to keep track of all objects being stringified const payload = args.map(arg => { - if (typeof arg === 'object' && arg !== null) { - return JSON.stringify(arg, (key, value) => { - if (typeof value === 'object' && value !== null) { - if (cache.has(value)) { - // Duplicate reference found, discard key - return; - } - // Store value in our collection - cache.add(value); - } - return value; - }); - } - return arg; + if (typeof arg === 'function') { + return arg.toString(); // Serialize function as its source code + } else if (typeof arg === 'object' && arg !== null) { + return JSON.stringify(arg, (key, value) => { + if (typeof value === 'object' && value !== null) { + if (cache.has(value)) { + // Duplicate reference found, discard key + return; + } + // Store value in our collection + cache.add(value); + } + return value; + }); + } + return arg; }); window.parent.postMessage({ type: 'log', data: payload }, '*'); cache.clear(); // Clear cache after serialization - } + } console.log = logToParentConsole; - const top100Films = [ - { label: 'The Shawshank Redemption', year: 1994 }, - { label: 'The Godfather', year: 1972 }, - { label: 'The Godfather: Part II', year: 1974 }, - { label: 'The Dark Knight', year: 2008 }, - { label: '12 Angry Men', year: 1957 }, - ]; - - function createData(name, calories, fat, carbs, protein) { - return { name, calories, fat, carbs, protein }; - } - - const rows = [ - createData('Frozen yoghurt', 159, 6.0, 24, 4.0), - createData('Ice cream sandwich', 237, 9.0, 37, 4.3), - createData('Eclair', 262, 16.0, 24, 6.0), - createData('Cupcake', 305, 3.7, 67, 4.3), - createData('Gingerbread', 356, 16.0, 49, 3.9), - ]; - const MaterialUI = window.MaterialUI; const ReactRouterDOM = window.ReactRouterDOM; const React = window.React; + const { useState, createContext, useContext } = React; const ReactDOM = window.ReactDOM; console.log('MaterialUI:', MaterialUI); @@ -106,35 +89,19 @@ const DemoRender = (): JSX.Element => { return; } - const isJsonString = (str) => { - try { - return JSON.parse(str); - } catch (e) { - return false; - } - }; - - const createComponentFromData = (data) => { - const { type, props } = data; - let { children } = data; - const Component = MaterialUI[type] || 'div'; - - let newProps = { ...props }; - if (Component === undefined) { - console.error(\`Component type \${type} is undefined.\`); - return null; - } + function createData(name, calories, fat, carbs, protein) { + return { name, calories, fat, carbs, protein }; + } - if (type === 'Autocomplete' && props.renderInput && typeof props.renderInput === 'string') { - newProps.renderInput = (params) => React.createElement(MaterialUI.TextField, {...params, label: 'Movie'}); - newProps.options = top100Films; - } - - if (type === 'FormControlLabel' && props.control && props.control.type === 'Radio') { - newProps.control = React.createElement(MaterialUI.Radio); - } - - // if (type === 'TableBody') { + const rows = [ + createData('Frozen yoghurt', 159, 6.0, 24, 4.0), + createData('Ice cream sandwich', 237, 9.0, 37, 4.3), + createData('Eclair', 262, 16.0, 24, 6.0), + createData('Cupcake', 305, 3.7, 67, 4.3), + createData('Gingerbread', 356, 16.0, 49, 3.9), + ]; + + // if (type === 'TableBody') { // console.log('Processing TableBody with rows:', rows); // children = rows.map(row => { // console.log('Processing row:', row); @@ -153,24 +120,466 @@ const DemoRender = (): JSX.Element => { // } // console.log('post tableBody check', children); - const processChildren = (child) => { - if (typeof child === 'string') { - if (isJsonString(child)) { - return createComponentFromData(JSON.parse(child)); + const PopoverContext = createContext(); + + const PopoverProvider = ({ children }) => { + const [anchorEl, setAnchorEl] = useState(null); + + const handleOpen = (event) => setAnchorEl(event.currentTarget); + const handleClose = () => setAnchorEl(null); + + const value = { + anchorEl, + handleOpen, + handleClose + }; + + const providerCheck = React.createElement( + PopoverContext.Provider, + { value: value }, + children + ); + return providerCheck; + }; + + const usePopover = () => useContext(PopoverContext); + + const PopperContext = createContext(); + + const PopperProvider = ({ children }) => { + const [anchorEl, setAnchorEl] = useState(null); + const handleClick = (event) => { + setAnchorEl(anchorEl ? null : event.currentTarget); + }; + + const value = { + anchorEl, + handleClick + }; + + const providerCheck = React.createElement( + PopperContext.Provider, + { value: value }, + children + ); + return providerCheck; + }; + + const usePopper = () => useContext(PopperContext); + + const ModalContext = createContext(); + + const ModalProvider = ({ children }) => { + const [open, setOpen] = React.useState(false); + + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + const value = { + open, + handleOpen, + handleClose + }; + + const providerCheck = React.createElement( + ModalContext.Provider, + { value: value }, + children + ); + return providerCheck; + }; + + const useModal = () => useContext(ModalContext); + + const TransferListContext = createContext(); + + const TransferListProvider = ({ children }) => { + const [checked, setChecked] = React.useState([]); + const [left, setLeft] = React.useState([0, 1, 2, 3]); + const [right, setRight] = React.useState([4, 5, 6, 7]); + + const handleToggle = (value) => () => { + const currentIndex = checked.indexOf(value); + const newChecked = [...checked]; + + if (currentIndex === -1) { + newChecked.push(value); + } else { + newChecked.splice(currentIndex, 1); + } + + setChecked(newChecked); + }; + + const handleCheckedRight = () => { + setRight(right.concat(leftChecked(checked, left))); + setLeft(not(left, leftChecked(checked, left))); + setChecked(not(checked, leftChecked(checked, left))); + }; + + const handleCheckedLeft = () => { + setLeft(left.concat(rightChecked(checked, right))); + setRight(not(right, rightChecked(checked, right))); + setChecked(not(checked, rightChecked(checked, right))); + }; + + const handleAllLeft = () => { + setLeft(left.concat(right)); + setRight([]); + }; + + const handleAllRight = () => { + setRight(right.concat(left)); + setLeft([]); + }; + + const value = { + checked, + setChecked, + left, + setLeft, + right, + setRight, + handleToggle, + handleAllRight, + handleCheckedRight, + handleCheckedLeft, + handleAllLeft, + }; + + const providerCheck = React.createElement( + TransferListContext.Provider, + { value: value }, + children + ); + return providerCheck; + }; + + const useTransferList = () => useContext(TransferListContext); + + const TransitionContext = createContext(); + + // Provider for Transition + const TransitionProvider = ({ children }) => { + const [checked, setChecked] = useState(false); + + const handleChange = () => { + setChecked((prev) => !prev); + }; + + const value = { + checked, + handleChange, + }; + + const providerCheck = React.createElement( + TransitionContext.Provider, + { value: value }, + children + ); + return providerCheck; + }; + + const useTransition = () => useContext(TransitionContext); + + const componentConfigs = { + Backdrop: (props, useState, useContext) => { + if (props.role === 'backDrop') { + const { open, handleClose } = useModal(); + + return { + ...props, + open: Boolean(open), + onClick: handleClose, + }; + } + }, + Box: (props, useState, useContext) => { + if (props.role === 'modalTrigger') { + const style = { + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + width: 400, + bgcolor: 'background.paper', + border: '2px solid #000', + boxShadow: 24, + p: 4, + }; + return { + ...props, + sx: style + }; + } + // Check if the role is 'collapseBox' and apply it to the children if needed + if (props.role === 'collapseBox') { + const updatedChildren = Array.isArray(props.children) ? props.children.map(child => { + // Check if the child is a div with the role 'collapseDiv' + if (child.type === 'div' && child.props && child.props.role === 'collapseDiv') { + // Replace 'icon' children with the SVG icon + const updatedChildChildren = Array.isArray(child.children) ? child.children.map(grandChild => { + if (grandChild.type === 'Collapse' && grandChild.children === 'icon') { + const icon = React.createElement( + 'svg', + null, + React.createElement( + 'polygon', + { + points: '0,100 50,0 100,100', + fill: 'white', + stroke: 'black', + strokeWidth: '1' + } + ) + ); + return icon; + } + return grandChild; + }) : child.children; + + return { + ...child, + children: updatedChildChildren + }; + } + return child; + }) : props.children; + + return { + ...props, + children: updatedChildren + }; + } + + // If the role is not 'collapseBox', return the original props + return props; + }, + Button: (props, useState, useContext) => { + + if (props.role === 'popoverTrigger') { + const { handleOpen } = usePopover(); + return { + ...props, + onClick: handleOpen + }; + } + if (props.role === 'popperTrigger') { + const { handleClick } = usePopper(); + return { + ...props, + onClick: handleClick + }; + } + if (props.role === 'modalTrigger') { + const { handleOpen } = useModal(); + return { + ...props, + onClick: handleOpen + }; } - return child; - } else if (typeof child === 'object' && child !== null) { - return createComponentFromData(child); + if (props.role === 'dialog') { + const { handleClose } = useModal(); + return { + ...props, + onClick: handleClose + }; + } + if (props.role === 'rightAll') { + return { + ...props, + onClick: handleAllRight, + disabled: left.length === 0 + }; + } + if (props.role === 'right') { + return { + ...props, + onClick: handleCheckedRight, + disabled: left.filter(item => checked.includes(item)).length === 0 + }; + } + + if (props.role === 'left') { + return { + ...props, + onClick: handleCheckedLeft, + disabled: right.filter(item => checked.includes(item)).length === 0 + }; + } + + if (props.role === 'leftAll') { + return { + ...props, + onClick: handleAllLeft, + disabled: right.length === 0 + }; + } + return props; + }, + Dialog: (props, useState, useContext) => { + if (props.role === 'dialog') { + const { open, handleClose } = useModal(); + + return { + ...props, + open: Boolean(open), + onClose: handleClose, + }; } - return null; - }; - - const processedChildren = Array.isArray(children) ? - children.map(processChildren) : - [processChildren(children)]; + }, + Modal: (props, useState, useContext) => { + const { open, handleClose } = useModal(); + + return { + ...props, + open: Boolean(open), + onClose: handleClose, + }; + }, + Popover: (props, useState, useContext) => { + const { anchorEl, handleClose } = usePopover(); + + return { + ...props, + open: Boolean(anchorEl), + anchorEl: anchorEl, + onClose: handleClose, + id: anchorEl ? 'simple-popover' : undefined, + }; + }, + Popper: (props) => { + const { anchorEl } = usePopper(); + + return { + ...props, + open: Boolean(anchorEl), + anchorEl: anchorEl, + id: open ? "simple-popper" : undefined, + }; + }, + Autocomplete: (props, useState) => { + // Assuming renderInput needs to be a function creating a TextField with specific props + if (typeof props.renderInput === 'string') { + props.renderInput = (params) => React.createElement(MaterialUI.TextField, { + ...params, + label: props.renderInput // Use the string as label, or customize as needed + }); + } + props.options = [ + { label: 'The Shawshank Redemption', year: 1994 }, + { label: 'The Godfather', year: 1972 }, + { label: 'The Godfather: Part II', year: 1974 }, + { label: 'The Dark Knight', year: 2008 }, + { label: '12 Angry Men', year: 1957 }, + ]; + + return props; + }, + FormControlLabel: (props, useState) => { + // Handle the case where the control needs to be a specific MUI component + if (props.control && props.control.type === 'Radio') { + props.control = React.createElement(MaterialUI.Radio); + } + if (props.role === 'transition') { + const { checked, handleChange } = useTransition(); + + const switchComponent = React.createElement(MaterialUI.Switch, { checked: checked, onChange: handleChange }); + return { + ...props, + control: switchComponent + }; + } + return props; + }, + TransferList: (props, useState, useContext) => { + // Access context values and functions from the TransferListProvider + const { checked, left, right, handleToggle, handleAllRight, handleCheckedRight, handleCheckedLeft, handleAllLeft } = useTransferList(); + + // Modify props accordingly based on context values and functions + const modifiedProps = { + ...props, + checked, + left, + right, + handleToggle, + handleAllRight, + handleCheckedRight, + handleCheckedLeft, + handleAllLeft + } + + return modifiedProps; + }, + Collapse: (props, useState, useContext) => { + const { checked } = useTransition(); + if (props.role === 'collapse') { + + return { + ...props, + in: Boolean(checked) + }; + } + return props; + } + // Additional components can be configured similarly + }; - return React.createElement(Component, newProps, ...processedChildren); + const isJsonString = (str) => { + try { + return JSON.parse(str); + } catch (e) { + return false; + } }; + + const createComponentFromData = (data) => { + const { type, props } = data; + let { children } = data; + const Component = MaterialUI[type] || 'div'; + + console.log('createComponentFromData Component', Component) + + if (Component === undefined) { + console.error(\`Component type \${type} is undefined.\`); + return null; + } + + // Dynamic component using configurations + const DynamicComponent = () => { + let configuredProps = {...props}; + + // Apply specific configuration if exists + if (componentConfigs[type]) { + configuredProps = componentConfigs[type](configuredProps, useState); + console.log('configuredProps', configuredProps) + } + + // Process children components recursively + const processChildren = (child) => { + if (typeof child === 'string') { + // Check if child is a JSON string to parse and create a component + if (/^\s*\{.*\}\s*$/.test(child)) { + return createComponentFromData(JSON.parse(child)); + } + return child; + } else if (typeof child === 'object' && child !== null) { + return createComponentFromData(child); + } + return null; + }; + + console.log('Final props for component:', type, configuredProps); + + const processedChildren = Array.isArray(children) ? + children.map(processChildren) : + [processChildren(children)].filter(child => child !== null); + + return React.createElement(Component, configuredProps, ...processedChildren); + }; + + return React.createElement(DynamicComponent); + }; window.addEventListener('message', (event) => { const dataArr = event.data.replace(/}{/g, '}|||{').replace(/}{/g, '>|||{').split('|||'); @@ -180,7 +589,7 @@ const DemoRender = (): JSX.Element => { if(segment.trim().startsWith('{') && segment.trim().endsWith('}')) { try { const jsonData = JSON.parse(segment); - // console.log('jsonData', jsonData); + console.log('jsonData', jsonData); if (jsonData.props && jsonData.props.children) { jsonData.children = jsonData.children || []; // console.log('jsonData.props.children', jsonData.props.children); @@ -189,7 +598,54 @@ const DemoRender = (): JSX.Element => { const componentContainer = document.createElement('div'); container.appendChild(componentContainer); const component = createComponentFromData(jsonData); - ReactDOM.render(component, componentContainer); + console.log('component', component) + let correctProvider; + // variable to hold the correct provider + if (Array.isArray(jsonData.children) && jsonData.children.some(child => child.type === 'Modal' || child.type === 'Backdrop' || child.type === 'Dialog')) { + correctProvider = ModalProvider + console.log('correctProvider', correctProvider) + } + if (Array.isArray(jsonData.children) && jsonData.children.some(child => child.type === 'Popover')) { + correctProvider = PopoverProvider + console.log('correctProvider', correctProvider) + } + if (Array.isArray(jsonData.children) && jsonData.children.some(child => child.type === 'Popper')) { + correctProvider = PopperProvider + console.log('correctProvider', correctProvider) + } + if ( + jsonData.children && + Array.isArray(jsonData.children) && + jsonData.children.length > 0 && + jsonData.children[0].type === 'FormControlLabel' && + jsonData.children[0].props && + jsonData.children[0].props.role === 'transition' + ) { + correctProvider = TransitionProvider + console.log('correctProvider', correctProvider) + } + + if (jsonData.type === 'Grid' && + Array.isArray(jsonData.children) && + jsonData.children.some(child => + child.type === 'customList' && + child.props.items && + (child.props.items === 'left' || child.props.items === 'right') + ) + ) { + correctProvider = TransferListProvider; + console.log('correctProvider', correctProvider); + } + + if(!correctProvider) { + console.log('div check') + ReactDOM.render(component, componentContainer); + } else { + ReactDOM.render( + React.createElement(correctProvider, null, component), // Wrap the component with the correctProvider + componentContainer + ); + } } catch (err) { console.error("Error parsing JSON:", err); } @@ -204,211 +660,6 @@ const DemoRender = (): JSX.Element => { `; - // const html = ` - // - // - // - // - // - // - // - // - // - // - // - //
- // - // - // - // `; - window.onmessage = (event) => { // If event.data or event.data.data is undefined, return early if (!event.data || typeof event.data.data !== 'string') return; diff --git a/app/src/redux/MUITypes.ts b/app/src/redux/MUITypes.ts index f62a2a59..7749b516 100644 --- a/app/src/redux/MUITypes.ts +++ b/app/src/redux/MUITypes.ts @@ -24,14 +24,14 @@ DATA DISPLAY 38. Icons 39. Material Icons 40. List -41. Table //not working -42. Tooltip +41. Table // is working now. how? +42. Tooltip // not working 43. Typography FEEDBACK 44. Alert //working but icon needed -45. Backdrop //not working -46. Dialog //not working +45. Backdrop +46. Dialog 47. Progress //not working 48. Skeleton //not working 49. Snackbar //not working @@ -65,14 +65,14 @@ LAYOUT UTILS 71. Click-Away Listener - not included 72. CSS Baseline - not included -73. Modal //not working +73. Modal 74. No SSR - not included -75. Popover - //not working +75. Popover 76. Popper //not working (no state) -77. Portal - //not working -78. Textarea Autosize -79. Transitions //not working -80. useMediaQuery */ +77. Portal - not included +78. Textarea Autosize - not included +79. Transitions // not working +80. useMediaQuery - not included */ const MUITypes: MUIType[] = [ { @@ -1033,29 +1033,88 @@ const MUITypes: MUIType[] = [ { type: 'Grid', props: { item: true }, - children: 'customList(left)' // Placeholder for dynamic list function + children: { + type: 'customList', + props: { items: 'left' }, + children: null // No children for customList + } }, { type: 'Grid', props: { item: true }, - children: [ - { - type: 'Grid', - props: { - container: true, - direction: 'column', - alignItems: 'center' + children: { + type: 'Grid', + props: { + container: true, + direction: 'column', + alignItems: 'center' + }, + children: [ + { + type: 'Button', + props: { + sx: { my: 0.5 }, + variant: 'outlined', + size: 'small', + onClick: '{handleAllRight}', + disabled: '{left.length === 0}', + 'aria-label': 'move all right', + role: 'rightAll' + }, + children: '≫' // Moves all items from left to right }, - children: [ - // Detailed button components here with onClick handlers etc. - ] - } - ] + { + type: 'Button', + props: { + sx: { my: 0.5 }, + variant: 'outlined', + size: 'small', + onClick: '{handleCheckedRight}', + disabled: + '{left.filter(item => checked.includes(item)).length === 0}', + 'aria-label': 'move selected right', + role: 'right' + }, + children: '>' // Moves selected items from left to right + }, + { + type: 'Button', + props: { + sx: { my: 0.5 }, + variant: 'outlined', + size: 'small', + onClick: '{handleCheckedLeft}', + disabled: + '{right.filter(item => checked.includes(item)).length === 0}', + 'aria-label': 'move selected left', + role: 'left' + }, + children: '<' // Moves selected items from right to left + }, + { + type: 'Button', + props: { + sx: { my: 0.5 }, + variant: 'outlined', + size: 'small', + onClick: '{handleAllLeft}', + disabled: '{right.length === 0}', + 'aria-label': 'move all left', + role: 'leftAll' + }, + children: '≪' // Moves all items from right to left + } + ] + } }, { type: 'Grid', props: { item: true }, - children: 'customList(right)' // Placeholder for dynamic list function + children: { + type: 'customList', + props: { items: 'right' }, + children: null // No children for customList + } } ] }, @@ -1515,7 +1574,7 @@ const MUITypes: MUIType[] = [ props: { disablePadding: true }, children: { type: 'ListItemButton', - props: { component: 'a', href: '#simple-list' }, + props: {}, children: [ { type: 'ListItemText', props: { primary: 'Spam' } } ] @@ -1867,9 +1926,8 @@ const MUITypes: MUIType[] = [ { type: 'Button', props: { - color: 'primary', // This sets the button color to the primary theme color sx: { - bgcolor: 'primary.main', // This sets the background color to the primary color + backgroundColor: 'primary.main', // This sets the background color to the primary color color: 'white', // This sets the text color to white m: 1 } @@ -1984,8 +2042,18 @@ const MUITypes: MUIType[] = [ "import CircularProgress from '@mui/material/CircularProgress'", "import Button from '@mui/material/Button'" ], - stateAndEventHandlers: [], - defaultProps: ['open={open}'], + stateAndEventHandlers: [ + 'const [open, setOpen] = React.useState(false);', + '\nconst handleClose = () => {', + ' setOpen(false);', + '};', + '\nconst handleOpen = () => {', + ' setOpen(true);', + '};\n' + ], + defaultProps: [ + 'sx={{ color: "#fff", zIndex: (theme) => theme.zIndex.drawer + 1 }} open={open} onClick={handleClose}' + ], propOptions: [ 'children', 'classes', @@ -2000,22 +2068,38 @@ const MUITypes: MUIType[] = [ 'transitionDuration' ], jsx: [ - ' theme.zIndex.drawer + 1 }}', - ' open={open}', - ' onClick={handleClose}', - '>', - ' ', - '' + '
', + ' ', + ' ', + ' ', + ' ', + '
' ], + componentData: { - type: 'Backdrop', - props: { - sx: { color: '#fff', zIndex: '(theme) => theme.zIndex.drawer + 1' }, - open: '{open}', - onClick: '{handleClose}' - }, - children: '' + type: 'div', + props: {}, + children: [ + { + type: 'Button', + props: { onClick: '{handleOpen}', role: 'modalTrigger' }, //used 'modalTrigger' here because it is requires the same handleOpen function already created + children: 'Show backdrop' + }, + { + type: 'Backdrop', + props: { + sx: { color: '#fff', zIndex: '(theme) => theme.zIndex.drawer + 1' }, + open: '{open}', + onClick: '{handleClose}', + role: 'backDrop' + }, + children: { + type: 'CircularProgress', + props: { color: 'inherit' }, + children: [] + } + } + ] }, children: [] }, @@ -2030,22 +2114,25 @@ const MUITypes: MUIType[] = [ framework: 'reactClassic', nestable: false, imports: [ - "import Dialog from '@mui/material/Dialog'", "import Button from '@mui/material/Button'", - "import Avatar from '@mui/material/Avatar'", - "import List from '@mui/material/List'", - "import ListItem from '@mui/material/ListItem'", - "import ListItemAvatar from '@mui/material/ListItemAvatar'", - "import ListItemButton from '@mui/material/ListItemButton'", - "import ListItemText from '@mui/material/ListItemText'", - "import DialogTitle from '@mui/material/DialogTitle'", - "import PersonIcon from '@mui/icons-material/Person'", - "import AddIcon from '@mui/icons-material/Add'", - "import Typography from '@mui/material/Typography'", - "{ blue } from '@mui/material/colors'" + "import Dialog from '@mui/material/Dialog'", + "import DialogActions from '@mui/material/DialogActions'", + "import DialogContent from '@mui/material/DialogContent'", + "import DialogContentText from '@mui/material/DialogContentText'", + "import DialogTitle from '@mui/material/DialogTitle'" + ], + stateAndEventHandlers: [ + 'const [open, setOpen] = React.useState(false);', + '\nconst handleClickOpen = () => {', + ' setOpen(true);', + '};', + '\nconst handleClose = () => {', + ' setOpen(false);', + '};\n' + ], + defaultProps: [ + 'open={open} onClose={handleClose} aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description"' ], - stateAndEventHandlers: [], - defaultProps: ['open={open}'], propOptions: [ 'aria-describedby', 'aria-labelledby', @@ -2067,71 +2154,90 @@ const MUITypes: MUIType[] = [ 'TransitionProps' ], jsx: [ - '', - ' Set backup account', - ' ', - ' {emails.map((email) => (', - ' ', - ' handleListItemClick(email)}>', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ))}', - ' ', - ' handleListItemClick("addAccount")}>', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - '' + '', + ' ', + ' ', + ' ', + ' {"Use Google\'s location service?"}', + ' ', + ' ', + ' ', + ' Let Google help apps determine location. This means sending anonymous', + ' location data to Google, even when no apps are running.', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + '' ], + componentData: { - type: 'Dialog', - props: { - onClose: '{handleClose}', - open: '{open}' - }, + type: 'React.Fragment', + props: {}, children: [ { - type: 'DialogTitle', - children: 'Set backup account' + type: 'Button', + props: { + variant: 'outlined', + onClick: '{handleClickOpen}', + role: 'modalTrigger' //used 'modalTrigger' here because it is requires the same handleOpen function already created + }, + children: 'Open alert dialog' }, { - type: 'List', - props: { sx: { pt: 0 } }, + type: 'Dialog', + props: { + open: '{open}', + onClose: '{handleClose}', + 'aria-labelledby': '"alert-dialog-title"', + 'aria-describedby': '"alert-dialog-description"', + role: 'dialog' + }, children: [ - '{emails.map((email) => (', - ' ', - ' handleListItemClick(email)}>', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - '))}', - ' ', - ' handleListItemClick("addAccount")}>', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ' + { + type: 'DialogTitle', + props: { id: '"alert-dialog-title"' }, + children: '"Use Google\'s location service?"' + }, + { + type: 'DialogContent', + props: {}, + children: [ + { + type: 'DialogContentText', + props: { id: '"alert-dialog-description"' }, + children: + 'Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.' + } + ] + }, + { + type: 'DialogActions', + props: {}, + children: [ + { + type: 'Button', + props: { onClick: '{handleClose}', role: 'dialog' }, + children: 'Disagree' + }, + { + type: 'Button', + props: { + onClick: '{handleClose}', + autoFocus: true, + role: 'dialog' + }, + children: 'Agree' + } + ] + } ] } ] @@ -2808,7 +2914,7 @@ const MUITypes: MUIType[] = [ ' console.info("You clicked a breadcrumb.");', '}; \n' ], - defaultProps: [], + defaultProps: ['aria-label="breadcrumb"'], propOptions: [ 'children', 'classes', @@ -2824,10 +2930,10 @@ const MUITypes: MUIType[] = [ ], jsx: [ "
", - " ", - " MUI", - " Core", - " Breadcrumbs", + ' ', + " MUI", + " Core", + " Breadcrumbs", ' ', '
' ], @@ -2850,7 +2956,7 @@ const MUITypes: MUIType[] = [ props: { underline: 'hover', color: 'inherit', - href: '/' + onClick: 'event => event.preventDefault()' }, children: 'MUI' }, @@ -2859,7 +2965,7 @@ const MUITypes: MUIType[] = [ props: { underline: 'hover', color: 'inherit', - href: '/material-ui/getting-started/installation/' + onClick: 'event => event.preventDefault()' }, children: 'Core' }, @@ -2868,7 +2974,7 @@ const MUITypes: MUIType[] = [ props: { underline: 'hover', color: 'text.primary', - href: '/material-ui/react-breadcrumbs/', + onClick: 'event => event.preventDefault()', 'aria-current': 'page' }, children: 'Breadcrumbs' @@ -3161,7 +3267,7 @@ const MUITypes: MUIType[] = [ ], jsx: [ " :not(style) ~ :not(style)': { ml: 2 } }} onClick={preventDefault}>", - " Link", + " Link", " {'color=\"inherit\"'}", " {'variant=\"body2\"'}", '' @@ -3181,15 +3287,12 @@ const MUITypes: MUIType[] = [ children: [ { type: 'Link', - props: { - href: '#' - }, + props: {}, children: 'Link' }, { type: 'Link', props: { - href: '#', color: 'inherit' }, children: 'color="inherit"' @@ -3197,7 +3300,6 @@ const MUITypes: MUIType[] = [ { type: 'Link', props: { - href: '#', variant: 'body2' }, children: 'variant="body2"' @@ -4054,12 +4156,13 @@ const MUITypes: MUIType[] = [ ], componentData: { type: 'div', - props: {}, + props: { sx: { m: 1 } }, children: [ { type: 'Button', props: { - onClick: 'handleOpen' + onClick: 'handleOpen', + role: 'modalTrigger' }, children: 'Open modal' }, @@ -4075,7 +4178,8 @@ const MUITypes: MUIType[] = [ { type: 'Box', props: { - sx: '{style}' + sx: '{style}', + role: 'modalTrigger' }, children: [ { @@ -4121,8 +4225,8 @@ const MUITypes: MUIType[] = [ ], stateAndEventHandlers: [ 'const [anchorEl, setAnchorEl] = React.useState(null);', - 'const handleClick = (event) => { setAnchorEl(event.currentTarget); };', - '\nconst handleClose = () => { setAnchorEl(null); };', + 'const handleClick = (event) => { setAnchorEl(event.currentTarget) };', + '\nconst handleClose = () => { setAnchorEl(null) };', '\nconst open = Boolean(anchorEl);', "\nconst id = open ? 'simple-popover' : undefined;\n" ], @@ -4163,12 +4267,13 @@ const MUITypes: MUIType[] = [ ], componentData: { type: 'div', - props: {}, + props: { sx: { m: 1 } }, children: [ { type: 'Button', props: { 'aria-describedby': '{id}', + role: 'popoverTrigger', // added to differentiate from other buttons variant: 'contained', onClick: 'handleClick' }, @@ -4214,8 +4319,15 @@ const MUITypes: MUIType[] = [ "import Box from '@mui/material/Box'", "import Popper from '@mui/material/Popper'" ], - stateAndEventHandlers: [], - defaultProps: [], + stateAndEventHandlers: [ + 'const [anchorEl, setAnchorEl] = React.useState(null);', + '\nconst handleClick = (event) => {', + ' setAnchorEl(anchorEl ? null : event.currentTarget);', + '};', + '\nconst open = Boolean(anchorEl);', + '\nconst id = open ? "simple-popper" : undefined;\n' + ], + defaultProps: ['id={id} open={open} anchorEl={anchorEl}'], propOptions: [ 'open', 'anchorEl', @@ -4240,7 +4352,7 @@ const MUITypes: MUIType[] = [ ` `, - ` `, + ` `, ` `, ` The content of the Popper.`, ` `, @@ -4248,13 +4360,30 @@ const MUITypes: MUIType[] = [ `` ], componentData: { - type: 'Popper', - props: {}, + type: 'div', + props: { sx: { m: 1 } }, children: [ { - type: 'Box', - props: { sx: { border: 1, p: 1, bgcolor: 'background.paper' } }, - children: 'The content of the Popper.' + type: 'Button', + props: { + 'aria-describedby': '{id}', + type: 'button', + onClick: '{handleClick}', + role: 'popperTrigger' + }, + children: 'Toggle Popper' + }, + { + type: 'Popper', + children: [ + { + type: 'Box', + props: { + sx: { border: 1, p: 1, bgcolor: 'background.paper' } + }, + children: 'The content of the Popper.' + } + ] } ] }, @@ -4275,9 +4404,29 @@ const MUITypes: MUIType[] = [ "import FormControlLabel from '@mui/material/FormControlLabel'", "import Box from '@mui/material/Box'", "import Switch from '@mui/material/Switch'", - "import Paper from '@mui/material/Paper'" + "import Paper from '@mui/material/Paper'", + '\nconst icon = (', + ' ', + ' ', + ' theme.palette.common.white,', + ' stroke: (theme) => theme.palette.divider,', + ' strokeWidth: 1,', + ' }}', + ' />', + ' ', + ' ', + ');' + ], + stateAndEventHandlers: [ + 'const [checked, setChecked] = React.useState(false);', + '\nconst handleChange = () => {', + ' setChecked((prev) => !prev);', + ' };' ], - stateAndEventHandlers: [], defaultProps: [], propOptions: [ 'addEndListener', @@ -4324,9 +4473,94 @@ const MUITypes: MUIType[] = [ '' ], componentData: { - type: 'Transition', - props: {}, - children: null + type: 'Box', + props: { + sx: { height: 300 } + }, + children: [ + { + type: 'FormControlLabel', + props: { + control: { + type: 'Switch', + props: {}, + children: [] + }, + label: 'Show', + role: 'transition' + } + }, + { + type: 'Box', + props: { + sx: { + '& > :not(style)': { + display: 'flex', + justifyContent: 'space-around', + height: 120, + width: 250 + } + }, + role: 'collapseBox' + }, + children: [ + { + type: 'div', + children: [ + { + type: 'Collapse', + props: { + in: '{checked}', + role: 'collapse' + }, + children: 'icon' + }, + { + type: 'Collapse', + props: { + in: '{checked}', + collapsedSize: 40, + role: 'collapse' + }, + children: 'icon' + } + ] + }, + { + type: 'div', + children: [ + { + type: 'Box', + props: { sx: { width: '50%' } }, + children: { + type: 'Collapse', + props: { + orientation: 'horizontal', + in: '{checked}', + role: 'collapse' + }, + children: 'icon' + } + }, + { + type: 'Box', + props: { sx: { width: '50%' } }, + children: { + type: 'Collapse', + props: { + orientation: 'horizontal', + in: '{checked}', + collapsedSize: 40, + role: 'collapse' + }, + children: 'icon' + } + } + ] + } + ] + } + ] }, children: [] } diff --git a/vite.config.ts b/vite.config.ts index e26eb78d..881a7b7b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -19,5 +19,12 @@ export default defineConfig({ // ...svgr options (https://react-svgr.com/docs/options/) } }) - ] + ], + optimizeDeps: { + include: [ + '@mui/material', + '@mui/icons-material' // Assuming you use icons too + // Any other specific parts of MUI or related dependencies + ] + } });