From fe5fb080a314423ec7a9c8c9424be490c82da861 Mon Sep 17 00:00:00 2001 From: Victor Zanivan Monteiro Date: Fri, 8 Mar 2024 10:30:20 -0300 Subject: [PATCH] [material-ui] Refine checkout template (#40967) --- .../templates/checkout/AddressForm.js | 223 +++--- .../templates/checkout/AddressForm.tsx | 223 +++--- .../templates/checkout/Checkout.js | 433 ++++++++++-- .../templates/checkout/Checkout.tsx | 431 ++++++++++-- .../templates/checkout/Info.js | 63 ++ .../templates/checkout/Info.tsx | 60 ++ .../templates/checkout/InfoMobile.js | 53 ++ .../templates/checkout/InfoMobile.tsx | 50 ++ .../templates/checkout/InfoMobile.tsx.preview | 10 + .../templates/checkout/PaymentForm.js | 308 +++++++-- .../templates/checkout/PaymentForm.tsx | 309 +++++++-- .../templates/checkout/Review.js | 107 ++- .../templates/checkout/Review.tsx | 106 ++- .../templates/checkout/ToggleColorMode.js | 30 + .../templates/checkout/ToggleColorMode.tsx | 30 + .../templates/checkout/getCheckoutTheme.js | 632 +++++++++++++++++ .../templates/checkout/getCheckoutTheme.tsx | 651 ++++++++++++++++++ .../static/images/templates/checkout.png | Bin 29337 -> 21469 bytes .../MaterialFreeTemplatesCollection.js | 14 +- test/regressions/index.js | 1 + 20 files changed, 3147 insertions(+), 587 deletions(-) create mode 100644 docs/data/material/getting-started/templates/checkout/Info.js create mode 100644 docs/data/material/getting-started/templates/checkout/Info.tsx create mode 100644 docs/data/material/getting-started/templates/checkout/InfoMobile.js create mode 100644 docs/data/material/getting-started/templates/checkout/InfoMobile.tsx create mode 100644 docs/data/material/getting-started/templates/checkout/InfoMobile.tsx.preview create mode 100644 docs/data/material/getting-started/templates/checkout/ToggleColorMode.js create mode 100644 docs/data/material/getting-started/templates/checkout/ToggleColorMode.tsx create mode 100644 docs/data/material/getting-started/templates/checkout/getCheckoutTheme.js create mode 100644 docs/data/material/getting-started/templates/checkout/getCheckoutTheme.tsx diff --git a/docs/data/material/getting-started/templates/checkout/AddressForm.js b/docs/data/material/getting-started/templates/checkout/AddressForm.js index 53e2faa294e4cb..07858cc4647161 100644 --- a/docs/data/material/getting-started/templates/checkout/AddressForm.js +++ b/docs/data/material/getting-started/templates/checkout/AddressForm.js @@ -1,109 +1,128 @@ import * as React from 'react'; -import Grid from '@mui/material/Grid'; -import Typography from '@mui/material/Typography'; -import TextField from '@mui/material/TextField'; -import FormControlLabel from '@mui/material/FormControlLabel'; + import Checkbox from '@mui/material/Checkbox'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormLabel from '@mui/material/FormLabel'; +import Grid from '@mui/material/Grid'; +import OutlinedInput from '@mui/material/OutlinedInput'; +import { styled } from '@mui/system'; + +const FormGrid = styled(Grid)(() => ({ + display: 'flex', + flexDirection: 'column', +})); export default function AddressForm() { return ( - - - Shipping address - - - - - - - - - - - - - - - - - - - - - - - - - - - - } - label="Use this address for payment details" - /> - - - + + + + First name + + + + + + Last name + + + + + + Address line 1 + + + + + Address line 2 + + + + + City + + + + + + State + + + + + + Zip / Postal code + + + + + + Country + + + + + } + label="Use this address for payment details" + /> + + ); } diff --git a/docs/data/material/getting-started/templates/checkout/AddressForm.tsx b/docs/data/material/getting-started/templates/checkout/AddressForm.tsx index 53e2faa294e4cb..07858cc4647161 100644 --- a/docs/data/material/getting-started/templates/checkout/AddressForm.tsx +++ b/docs/data/material/getting-started/templates/checkout/AddressForm.tsx @@ -1,109 +1,128 @@ import * as React from 'react'; -import Grid from '@mui/material/Grid'; -import Typography from '@mui/material/Typography'; -import TextField from '@mui/material/TextField'; -import FormControlLabel from '@mui/material/FormControlLabel'; + import Checkbox from '@mui/material/Checkbox'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormLabel from '@mui/material/FormLabel'; +import Grid from '@mui/material/Grid'; +import OutlinedInput from '@mui/material/OutlinedInput'; +import { styled } from '@mui/system'; + +const FormGrid = styled(Grid)(() => ({ + display: 'flex', + flexDirection: 'column', +})); export default function AddressForm() { return ( - - - Shipping address - - - - - - - - - - - - - - - - - - - - - - - - - - - - } - label="Use this address for payment details" - /> - - - + + + + First name + + + + + + Last name + + + + + + Address line 1 + + + + + Address line 2 + + + + + City + + + + + + State + + + + + + Zip / Postal code + + + + + + Country + + + + + } + label="Use this address for payment details" + /> + + ); } diff --git a/docs/data/material/getting-started/templates/checkout/Checkout.js b/docs/data/material/getting-started/templates/checkout/Checkout.js index c1dc100ce09f2b..d87b040ac4259a 100644 --- a/docs/data/material/getting-started/templates/checkout/Checkout.js +++ b/docs/data/material/getting-started/templates/checkout/Checkout.js @@ -1,35 +1,86 @@ import * as React from 'react'; -import CssBaseline from '@mui/material/CssBaseline'; -import AppBar from '@mui/material/AppBar'; +import PropTypes from 'prop-types'; + import Box from '@mui/material/Box'; -import Container from '@mui/material/Container'; -import Toolbar from '@mui/material/Toolbar'; -import Paper from '@mui/material/Paper'; -import Stepper from '@mui/material/Stepper'; +import Button from '@mui/material/Button'; +import Card from '@mui/material/Card'; +import CardContent from '@mui/material/CardContent'; +import CssBaseline from '@mui/material/CssBaseline'; +import Grid from '@mui/material/Grid'; +import Stack from '@mui/material/Stack'; import Step from '@mui/material/Step'; import StepLabel from '@mui/material/StepLabel'; -import Button from '@mui/material/Button'; -import Link from '@mui/material/Link'; +import Stepper from '@mui/material/Stepper'; +import ToggleButton from '@mui/material/ToggleButton'; +import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import Typography from '@mui/material/Typography'; + +import { createTheme, ThemeProvider } from '@mui/material/styles'; + +import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded'; +import AutoAwesomeRoundedIcon from '@mui/icons-material/AutoAwesomeRounded'; +import ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded'; +import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded'; + import AddressForm from './AddressForm'; +import getCheckoutTheme from './getCheckoutTheme'; +import Info from './Info'; +import InfoMobile from './InfoMobile'; import PaymentForm from './PaymentForm'; import Review from './Review'; +import ToggleColorMode from './ToggleColorMode'; -function Copyright() { +function ToggleCustomTheme({ showCustomTheme, toggleCustomTheme }) { return ( - - {'Copyright © '} - - Your Website - {' '} - {new Date().getFullYear()} - {'.'} - + + + + + Custom theme + + Material Design 2 + + ); } +ToggleCustomTheme.propTypes = { + showCustomTheme: PropTypes.shape({ + valueOf: PropTypes.func.isRequired, + }).isRequired, + toggleCustomTheme: PropTypes.func.isRequired, +}; + const steps = ['Shipping address', 'Payment details', 'Review your order']; +const logoStyle = { + width: '140px', + height: '56px', + marginLeft: '-4px', + marginRight: '-8px', +}; + function getStepContent(step) { switch (step) { case 0: @@ -44,8 +95,20 @@ function getStepContent(step) { } export default function Checkout() { + const [mode, setMode] = React.useState('light'); + const [showCustomTheme, setShowCustomTheme] = React.useState(true); + const checkoutTheme = createTheme(getCheckoutTheme(mode)); + const defaultTheme = createTheme({ palette: { mode } }); const [activeStep, setActiveStep] = React.useState(0); + const toggleColorMode = () => { + setMode((prev) => (prev === 'dark' ? 'light' : 'dark')); + }; + + const toggleCustomTheme = () => { + setShowCustomTheme((prev) => !prev); + }; + const handleNext = () => { setActiveStep(activeStep + 1); }; @@ -55,69 +118,287 @@ export default function Checkout() { }; return ( - + - `1px solid ${t.palette.divider}`, - }} - > - - - Company name - - - - - - - Checkout - - - {steps.map((label) => ( - - {label} - - ))} - - {activeStep === steps.length ? ( - - - Thank you for your order. - - - Your order number is #2001539. We have emailed your order - confirmation, and will send you an update when your order has - shipped. - - - ) : ( - - {getStepContent(activeStep)} - - {activeStep !== 0 && ( - - )} - + + + + + + + = 2 ? '$144.97' : '$134.98'} /> + + + + + + + + + + + + {steps.map((label) => ( + + {label} + + ))} + + + + + +
+ + Selected products + + + {activeStep >= 2 ? '$144.97' : '$134.98'} + +
+ = 2 ? '$144.97' : '$134.98'} /> +
+
+ + + {steps.map((label) => ( + + + {label} + + + ))} + + {activeStep === steps.length ? ( + + 📦 + Thank you for your order! + + Your order number is +  #140396. We have emailed your order + confirmation and will update you once its shipped. + - -
- )} -
- -
-
+ + ) : ( + + {getStepContent(activeStep)} + + {activeStep !== 0 && ( + + )} + + {activeStep !== 0 && ( + + )} + + + + + )} + + + + + ); } diff --git a/docs/data/material/getting-started/templates/checkout/Checkout.tsx b/docs/data/material/getting-started/templates/checkout/Checkout.tsx index 97c15f8bff8f4d..f89270bc220afc 100644 --- a/docs/data/material/getting-started/templates/checkout/Checkout.tsx +++ b/docs/data/material/getting-started/templates/checkout/Checkout.tsx @@ -1,35 +1,87 @@ import * as React from 'react'; -import CssBaseline from '@mui/material/CssBaseline'; -import AppBar from '@mui/material/AppBar'; + import Box from '@mui/material/Box'; -import Container from '@mui/material/Container'; -import Toolbar from '@mui/material/Toolbar'; -import Paper from '@mui/material/Paper'; -import Stepper from '@mui/material/Stepper'; +import Button from '@mui/material/Button'; +import Card from '@mui/material/Card'; +import CardContent from '@mui/material/CardContent'; +import CssBaseline from '@mui/material/CssBaseline'; +import Grid from '@mui/material/Grid'; +import Stack from '@mui/material/Stack'; import Step from '@mui/material/Step'; import StepLabel from '@mui/material/StepLabel'; -import Button from '@mui/material/Button'; -import Link from '@mui/material/Link'; +import Stepper from '@mui/material/Stepper'; +import ToggleButton from '@mui/material/ToggleButton'; +import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import Typography from '@mui/material/Typography'; + +import { createTheme, ThemeProvider } from '@mui/material/styles'; +import { PaletteMode } from '@mui/material'; + +import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded'; +import AutoAwesomeRoundedIcon from '@mui/icons-material/AutoAwesomeRounded'; +import ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded'; +import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded'; + import AddressForm from './AddressForm'; +import getCheckoutTheme from './getCheckoutTheme'; +import Info from './Info'; +import InfoMobile from './InfoMobile'; import PaymentForm from './PaymentForm'; import Review from './Review'; +import ToggleColorMode from './ToggleColorMode'; -function Copyright() { +interface ToggleCustomThemeProps { + showCustomTheme: Boolean; + toggleCustomTheme: () => void; +} + +function ToggleCustomTheme({ + showCustomTheme, + toggleCustomTheme, +}: ToggleCustomThemeProps) { return ( - - {'Copyright © '} - - Your Website - {' '} - {new Date().getFullYear()} - {'.'} - + + + + + Custom theme + + Material Design 2 + + ); } const steps = ['Shipping address', 'Payment details', 'Review your order']; +const logoStyle = { + width: '140px', + height: '56px', + marginLeft: '-4px', + marginRight: '-8px', +}; + function getStepContent(step: number) { switch (step) { case 0: @@ -44,8 +96,20 @@ function getStepContent(step: number) { } export default function Checkout() { + const [mode, setMode] = React.useState('light'); + const [showCustomTheme, setShowCustomTheme] = React.useState(true); + const checkoutTheme = createTheme(getCheckoutTheme(mode)); + const defaultTheme = createTheme({ palette: { mode } }); const [activeStep, setActiveStep] = React.useState(0); + const toggleColorMode = () => { + setMode((prev) => (prev === 'dark' ? 'light' : 'dark')); + }; + + const toggleCustomTheme = () => { + setShowCustomTheme((prev) => !prev); + }; + const handleNext = () => { setActiveStep(activeStep + 1); }; @@ -55,68 +119,285 @@ export default function Checkout() { }; return ( - + - `1px solid ${t.palette.divider}`, - }} - > - - - Company name - - - - - - - Checkout - - - {steps.map((label) => ( - - {label} - - ))} - - {activeStep === steps.length ? ( - - - Thank you for your order. - - - Your order number is #2001539. We have emailed your order - confirmation, and will send you an update when your order has - shipped. - - - ) : ( - - {getStepContent(activeStep)} - - {activeStep !== 0 && ( - - )} + + + + + + + = 2 ? '$144.97' : '$134.98'} /> + + + + + + + + + + + + {steps.map((label) => ( + + {label} + + ))} + + + + + +
+ + Selected products + + + {activeStep >= 2 ? '$144.97' : '$134.98'} + +
+ = 2 ? '$144.97' : '$134.98'} /> +
+
+ + + {steps.map((label) => ( + + + {label} + + + ))} + + {activeStep === steps.length ? ( + + 📦 + Thank you for your order! + + Your order number is +  #140396. We have emailed your order + confirmation and will update you once its shipped. + - -
- )} -
- -
-
+ + ) : ( + + {getStepContent(activeStep)} + + {activeStep !== 0 && ( + + )} + {activeStep !== 0 && ( + + )} + + + + )} + + + + + ); } diff --git a/docs/data/material/getting-started/templates/checkout/Info.js b/docs/data/material/getting-started/templates/checkout/Info.js new file mode 100644 index 00000000000000..9595c53c250a2b --- /dev/null +++ b/docs/data/material/getting-started/templates/checkout/Info.js @@ -0,0 +1,63 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; + +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemText from '@mui/material/ListItemText'; +import Typography from '@mui/material/Typography'; + +const products = [ + { + name: 'Professional plan', + desc: 'Monthly subscription', + price: '$15.00', + }, + { + name: 'Dedicated support', + desc: 'Included in the Professional plan', + price: 'Free', + }, + { + name: 'Hardware', + desc: 'Devices needed for development', + price: '$69.99', + }, + { + name: 'Landing page template', + desc: 'License', + price: '$49.99', + }, +]; + +function Info({ totalPrice }) { + return ( + + + Total + + + {totalPrice} + + + {products.map((product) => ( + + + + {product.price} + + + ))} + + + ); +} + +Info.propTypes = { + totalPrice: PropTypes.string.isRequired, +}; + +export default Info; diff --git a/docs/data/material/getting-started/templates/checkout/Info.tsx b/docs/data/material/getting-started/templates/checkout/Info.tsx new file mode 100644 index 00000000000000..3250b59d3c2568 --- /dev/null +++ b/docs/data/material/getting-started/templates/checkout/Info.tsx @@ -0,0 +1,60 @@ +import * as React from 'react'; + +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemText from '@mui/material/ListItemText'; +import Typography from '@mui/material/Typography'; + +const products = [ + { + name: 'Professional plan', + desc: 'Monthly subscription', + price: '$15.00', + }, + { + name: 'Dedicated support', + desc: 'Included in the Professional plan', + price: 'Free', + }, + { + name: 'Hardware', + desc: 'Devices needed for development', + price: '$69.99', + }, + { + name: 'Landing page template', + desc: 'License', + price: '$49.99', + }, +]; + +interface InfoProps { + totalPrice: string; +} + +export default function Info({ totalPrice }: InfoProps) { + return ( + + + Total + + + {totalPrice} + + + {products.map((product) => ( + + + + {product.price} + + + ))} + + + ); +} diff --git a/docs/data/material/getting-started/templates/checkout/InfoMobile.js b/docs/data/material/getting-started/templates/checkout/InfoMobile.js new file mode 100644 index 00000000000000..c7afd0e28c0cb6 --- /dev/null +++ b/docs/data/material/getting-started/templates/checkout/InfoMobile.js @@ -0,0 +1,53 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; + +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Drawer from '@mui/material/Drawer'; +import IconButton from '@mui/material/IconButton'; + +import CloseIcon from '@mui/icons-material/Close'; +import ExpandMoreRoundedIcon from '@mui/icons-material/ExpandMoreRounded'; + +import Info from './Info'; + +function InfoMobile({ totalPrice }) { + const [open, setOpen] = React.useState(false); + + const toggleDrawer = (newOpen) => () => { + setOpen(newOpen); + }; + + const DrawerList = ( + + + + + + + ); + + return ( +
+ + + {DrawerList} + +
+ ); +} + +InfoMobile.propTypes = { + totalPrice: PropTypes.string.isRequired, +}; + +export default InfoMobile; diff --git a/docs/data/material/getting-started/templates/checkout/InfoMobile.tsx b/docs/data/material/getting-started/templates/checkout/InfoMobile.tsx new file mode 100644 index 00000000000000..758c9546a40ff5 --- /dev/null +++ b/docs/data/material/getting-started/templates/checkout/InfoMobile.tsx @@ -0,0 +1,50 @@ +import * as React from 'react'; + +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Drawer from '@mui/material/Drawer'; +import IconButton from '@mui/material/IconButton'; + +import CloseIcon from '@mui/icons-material/Close'; +import ExpandMoreRoundedIcon from '@mui/icons-material/ExpandMoreRounded'; + +import Info from './Info'; + +interface InfoProps { + totalPrice: string; +} + +export default function InfoMobile({ totalPrice }: InfoProps) { + const [open, setOpen] = React.useState(false); + + const toggleDrawer = (newOpen: boolean) => () => { + setOpen(newOpen); + }; + + const DrawerList = ( + + + + + + + ); + + return ( +
+ + + {DrawerList} + +
+ ); +} diff --git a/docs/data/material/getting-started/templates/checkout/InfoMobile.tsx.preview b/docs/data/material/getting-started/templates/checkout/InfoMobile.tsx.preview new file mode 100644 index 00000000000000..792471f0f401c7 --- /dev/null +++ b/docs/data/material/getting-started/templates/checkout/InfoMobile.tsx.preview @@ -0,0 +1,10 @@ + + + {DrawerList} + \ No newline at end of file diff --git a/docs/data/material/getting-started/templates/checkout/PaymentForm.js b/docs/data/material/getting-started/templates/checkout/PaymentForm.js index 9116fd0a907477..219a48e8cade76 100644 --- a/docs/data/material/getting-started/templates/checkout/PaymentForm.js +++ b/docs/data/material/getting-started/templates/checkout/PaymentForm.js @@ -1,65 +1,263 @@ import * as React from 'react'; -import Typography from '@mui/material/Typography'; -import Grid from '@mui/material/Grid'; -import TextField from '@mui/material/TextField'; -import FormControlLabel from '@mui/material/FormControlLabel'; + +import Alert from '@mui/material/Alert'; +import Box from '@mui/material/Box'; +import Card from '@mui/material/Card'; +import CardActionArea from '@mui/material/CardActionArea'; +import CardContent from '@mui/material/CardContent'; import Checkbox from '@mui/material/Checkbox'; +import FormControl from '@mui/material/FormControl'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormLabel from '@mui/material/FormLabel'; +import OutlinedInput from '@mui/material/OutlinedInput'; +import RadioGroup from '@mui/material/RadioGroup'; +import Stack from '@mui/material/Stack'; +import Typography from '@mui/material/Typography'; + +import AccountBalanceRoundedIcon from '@mui/icons-material/AccountBalanceRounded'; +import CreditCardRoundedIcon from '@mui/icons-material/CreditCardRounded'; +import SimCardRoundedIcon from '@mui/icons-material/SimCardRounded'; +import WarningRoundedIcon from '@mui/icons-material/WarningRounded'; + +import { styled } from '@mui/system'; + +const FormGrid = styled('div')(() => ({ + display: 'flex', + flexDirection: 'column', +})); export default function PaymentForm() { + const [paymentType, setPaymentType] = React.useState('creditCard'); + const [cardNumber, setCardNumber] = React.useState(''); + const [cvv, setCvv] = React.useState(''); + const [expirationDate, setExpirationDate] = React.useState(''); + + const handlePaymentTypeChange = (event) => { + setPaymentType(event.target.value); + }; + + const handleCardNumberChange = (event) => { + const value = event.target.value.replace(/\D/g, ''); + const formattedValue = value.replace(/(\d{4})(?=\d)/g, '$1 '); + if (value.length <= 16) { + setCardNumber(formattedValue); + } + }; + + const handleCvvChange = (event) => { + const value = event.target.value.replace(/\D/g, ''); + if (value.length <= 3) { + setCvv(value); + } + }; + + const handleExpirationDateChange = (event) => { + const value = event.target.value.replace(/\D/g, ''); + const formattedValue = value.replace(/(\d{2})(?=\d{2})/, '$1/'); + if (value.length <= 4) { + setExpirationDate(formattedValue); + } + }; + return ( - - - Payment method - - - - - - - - - - - - - - - + + + + + setPaymentType('creditCard')}> + + + Card + + + + + setPaymentType('bankTransfer')}> + + + Bank account + + + + + + {paymentType === 'creditCard' && ( + + + + Credit card + + + + + + + Card number + + + + + + CVV + + + + + + + + Name + + + + + + Expiration date + + + + + } + control={} label="Remember credit card details for next time" /> - - - + + )} + + {paymentType === 'bankTransfer' && ( + + }> + Your order will be processed once we receive the funds. + + + Bank account + + + Please transfer the payment to the bank account details shown below. + + + + Bank: + + + Mastercredit + + + + + Account number: + + + 123456789 + + + + + Routing number: + + + 987654321 + + + + )} + ); } diff --git a/docs/data/material/getting-started/templates/checkout/PaymentForm.tsx b/docs/data/material/getting-started/templates/checkout/PaymentForm.tsx index 9116fd0a907477..86bd90611d6ec9 100644 --- a/docs/data/material/getting-started/templates/checkout/PaymentForm.tsx +++ b/docs/data/material/getting-started/templates/checkout/PaymentForm.tsx @@ -1,65 +1,264 @@ import * as React from 'react'; -import Typography from '@mui/material/Typography'; -import Grid from '@mui/material/Grid'; -import TextField from '@mui/material/TextField'; -import FormControlLabel from '@mui/material/FormControlLabel'; + +import Alert from '@mui/material/Alert'; +import Box from '@mui/material/Box'; +import Card from '@mui/material/Card'; +import CardActionArea from '@mui/material/CardActionArea'; +import CardContent from '@mui/material/CardContent'; import Checkbox from '@mui/material/Checkbox'; +import FormControl from '@mui/material/FormControl'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormLabel from '@mui/material/FormLabel'; +import OutlinedInput from '@mui/material/OutlinedInput'; +import RadioGroup from '@mui/material/RadioGroup'; +import Stack from '@mui/material/Stack'; +import Typography from '@mui/material/Typography'; + +import AccountBalanceRoundedIcon from '@mui/icons-material/AccountBalanceRounded'; +import CreditCardRoundedIcon from '@mui/icons-material/CreditCardRounded'; +import SimCardRoundedIcon from '@mui/icons-material/SimCardRounded'; +import WarningRoundedIcon from '@mui/icons-material/WarningRounded'; + +import { styled } from '@mui/system'; + +const FormGrid = styled('div')(() => ({ + display: 'flex', + flexDirection: 'column', +})); export default function PaymentForm() { + const [paymentType, setPaymentType] = React.useState('creditCard'); + const [cardNumber, setCardNumber] = React.useState(''); + const [cvv, setCvv] = React.useState(''); + const [expirationDate, setExpirationDate] = React.useState(''); + + const handlePaymentTypeChange = (event: { + target: { value: React.SetStateAction }; + }) => { + setPaymentType(event.target.value); + }; + + const handleCardNumberChange = (event: { target: { value: string } }) => { + const value = event.target.value.replace(/\D/g, ''); + const formattedValue = value.replace(/(\d{4})(?=\d)/g, '$1 '); + if (value.length <= 16) { + setCardNumber(formattedValue); + } + }; + + const handleCvvChange = (event: { target: { value: string } }) => { + const value = event.target.value.replace(/\D/g, ''); + if (value.length <= 3) { + setCvv(value); + } + }; + + const handleExpirationDateChange = (event: { target: { value: string } }) => { + const value = event.target.value.replace(/\D/g, ''); + const formattedValue = value.replace(/(\d{2})(?=\d{2})/, '$1/'); + if (value.length <= 4) { + setExpirationDate(formattedValue); + } + }; + return ( - - - Payment method - - - - - - - - - - - - - - - + + + + + setPaymentType('creditCard')}> + + + Card + + + + + setPaymentType('bankTransfer')}> + + + Bank account + + + + + + {paymentType === 'creditCard' && ( + + + + Credit card + + + + + + + Card number + + + + + + CVV + + + + + + + + Name + + + + + + Expiration date + + + + + } + control={} label="Remember credit card details for next time" /> - - - + + )} + {paymentType === 'bankTransfer' && ( + + }> + Your order will be processed once we receive the funds. + + + Bank account + + + Please transfer the payment to the bank account details shown below. + + + + Bank: + + + Mastercredit + + + + + Account number: + + + 123456789 + + + + + Routing number: + + + 987654321 + + + + )} + ); } diff --git a/docs/data/material/getting-started/templates/checkout/Review.js b/docs/data/material/getting-started/templates/checkout/Review.js index ad827af533470e..ac7ecf17f92c44 100644 --- a/docs/data/material/getting-started/templates/checkout/Review.js +++ b/docs/data/material/getting-started/templates/checkout/Review.js @@ -1,88 +1,79 @@ import * as React from 'react'; -import Typography from '@mui/material/Typography'; + +import Divider from '@mui/material/Divider'; +import Grid from '@mui/material/Grid'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemText from '@mui/material/ListItemText'; -import Grid from '@mui/material/Grid'; - -const products = [ - { - name: 'Product 1', - desc: 'A nice thing', - price: '$9.99', - }, - { - name: 'Product 2', - desc: 'Another thing', - price: '$3.45', - }, - { - name: 'Product 3', - desc: 'Something else', - price: '$6.51', - }, - { - name: 'Product 4', - desc: 'Best thing of all', - price: '$14.11', - }, - { name: 'Shipping', desc: '', price: 'Free' }, -]; +import Stack from '@mui/material/Stack'; +import Typography from '@mui/material/Typography'; const addresses = ['1 MUI Drive', 'Reactville', 'Anytown', '99999', 'USA']; const payments = [ - { name: 'Card type', detail: 'Visa' }, - { name: 'Card holder', detail: 'Mr John Smith' }, - { name: 'Card number', detail: 'xxxx-xxxx-xxxx-1234' }, - { name: 'Expiry date', detail: '04/2024' }, + { name: 'Card type:', detail: 'Visa' }, + { name: 'Card holder:', detail: 'Mr. John Smith' }, + { name: 'Card number:', detail: 'xxxx-xxxx-xxxx-1234' }, + { name: 'Expiry date:', detail: '04/2024' }, ]; export default function Review() { return ( - - - Order summary - + - {products.map((product) => ( - - - {product.price} - - ))} + + + $134.98 + + + + $9.99 + - $34.06 + $144.97 - - - - Shipping + + } + spacing={2} + sx={{ my: 2 }} + > +
+ + Shipment details John Smith - {addresses.join(', ')} - - - + + {addresses.join(', ')} + +
+
+ Payment details {payments.map((payment) => ( - - {payment.name} - - - {payment.detail} - + + + {payment.name} + + {payment.detail} + ))} - - - +
+
+
); } diff --git a/docs/data/material/getting-started/templates/checkout/Review.tsx b/docs/data/material/getting-started/templates/checkout/Review.tsx index 60544307917a7c..ac7ecf17f92c44 100644 --- a/docs/data/material/getting-started/templates/checkout/Review.tsx +++ b/docs/data/material/getting-started/templates/checkout/Review.tsx @@ -1,87 +1,79 @@ import * as React from 'react'; -import Typography from '@mui/material/Typography'; + +import Divider from '@mui/material/Divider'; +import Grid from '@mui/material/Grid'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemText from '@mui/material/ListItemText'; -import Grid from '@mui/material/Grid'; +import Stack from '@mui/material/Stack'; +import Typography from '@mui/material/Typography'; -const products = [ - { - name: 'Product 1', - desc: 'A nice thing', - price: '$9.99', - }, - { - name: 'Product 2', - desc: 'Another thing', - price: '$3.45', - }, - { - name: 'Product 3', - desc: 'Something else', - price: '$6.51', - }, - { - name: 'Product 4', - desc: 'Best thing of all', - price: '$14.11', - }, - { name: 'Shipping', desc: '', price: 'Free' }, -]; const addresses = ['1 MUI Drive', 'Reactville', 'Anytown', '99999', 'USA']; const payments = [ - { name: 'Card type', detail: 'Visa' }, - { name: 'Card holder', detail: 'Mr John Smith' }, - { name: 'Card number', detail: 'xxxx-xxxx-xxxx-1234' }, - { name: 'Expiry date', detail: '04/2024' }, + { name: 'Card type:', detail: 'Visa' }, + { name: 'Card holder:', detail: 'Mr. John Smith' }, + { name: 'Card number:', detail: 'xxxx-xxxx-xxxx-1234' }, + { name: 'Expiry date:', detail: '04/2024' }, ]; export default function Review() { return ( - - - Order summary - + - {products.map((product) => ( - - - {product.price} - - ))} + + + $134.98 + + + + $9.99 + - $34.06 + $144.97 - - - - Shipping + + } + spacing={2} + sx={{ my: 2 }} + > +
+ + Shipment details John Smith - {addresses.join(', ')} - - - + + {addresses.join(', ')} + +
+
+ Payment details {payments.map((payment) => ( - - {payment.name} - - - {payment.detail} - + + + {payment.name} + + {payment.detail} + ))} - - - +
+
+
); } diff --git a/docs/data/material/getting-started/templates/checkout/ToggleColorMode.js b/docs/data/material/getting-started/templates/checkout/ToggleColorMode.js new file mode 100644 index 00000000000000..7e4305a7698c28 --- /dev/null +++ b/docs/data/material/getting-started/templates/checkout/ToggleColorMode.js @@ -0,0 +1,30 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; + +import IconButton from '@mui/material/IconButton'; + +import ModeNightRoundedIcon from '@mui/icons-material/ModeNightRounded'; +import WbSunnyRoundedIcon from '@mui/icons-material/WbSunnyRounded'; + +function ToggleColorMode({ mode, toggleColorMode }) { + return ( + + {mode === 'dark' ? ( + + ) : ( + + )} + + ); +} + +ToggleColorMode.propTypes = { + mode: PropTypes.oneOf(['dark', 'light']).isRequired, + toggleColorMode: PropTypes.func.isRequired, +}; + +export default ToggleColorMode; diff --git a/docs/data/material/getting-started/templates/checkout/ToggleColorMode.tsx b/docs/data/material/getting-started/templates/checkout/ToggleColorMode.tsx new file mode 100644 index 00000000000000..3783eb9d80714d --- /dev/null +++ b/docs/data/material/getting-started/templates/checkout/ToggleColorMode.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; + +import { PaletteMode } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; + +import ModeNightRoundedIcon from '@mui/icons-material/ModeNightRounded'; +import WbSunnyRoundedIcon from '@mui/icons-material/WbSunnyRounded'; + +interface ToggleColorModeProps { + mode: PaletteMode; + toggleColorMode: () => void; +} + +function ToggleColorMode({ mode, toggleColorMode }: ToggleColorModeProps) { + return ( + + {mode === 'dark' ? ( + + ) : ( + + )} + + ); +} + +export default ToggleColorMode; diff --git a/docs/data/material/getting-started/templates/checkout/getCheckoutTheme.js b/docs/data/material/getting-started/templates/checkout/getCheckoutTheme.js new file mode 100644 index 00000000000000..ba208dfca5bb32 --- /dev/null +++ b/docs/data/material/getting-started/templates/checkout/getCheckoutTheme.js @@ -0,0 +1,632 @@ +import { alpha } from '@mui/material/styles'; +import { red } from '@mui/material/colors'; + +export const brand = { + 50: '#F0F7FF', + 100: '#CEE5FD', + 200: '#9CCCFC', + 300: '#55A6F6', + 400: '#0A66C2', + 500: '#0959AA', + 600: '#064079', + 700: '#033363', + 800: '#02294F', + 900: '#021F3B', +}; + +export const secondary = { + 50: '#F9F0FF', + 100: '#E9CEFD', + 200: '#D49CFC', + 300: '#B355F6', + 400: '#750AC2', + 500: '#6709AA', + 600: '#490679', + 700: '#3B0363', + 800: '#2F024F', + 900: '#23023B', +}; + +export const gray = { + 50: '#FBFCFE', + 100: '#EAF0F5', + 200: '#D6E2EB', + 300: '#BFCCD9', + 400: '#94A6B8', + 500: '#5B6B7C', + 600: '#4C5967', + 700: '#364049', + 800: '#131B20', + 900: '#090E10', +}; + +export const green = { + 50: '#F6FEF6', + 100: '#E3FBE3', + 200: '#C7F7C7', + 300: '#A1E8A1', + 400: '#51BC51', + 500: '#1F7A1F', + 600: '#136C13', + 700: '#0A470A', + 800: '#042F04', + 900: '#021D02', +}; + +export const orange = { + 50: '#FFFBF0', + 100: '#FDF1CE', + 200: '#FCE49C', + 300: '#F6CE55', + 400: '#C2940A', + 500: '#AA8109', + 600: '#795C06', + 700: '#634B03', + 800: '#4F3C02', + 900: '#3B2D02', +}; + +const getDesignTokens = (mode) => ({ + palette: { + mode, + primary: { + light: brand[200], + main: brand[500], + dark: brand[800], + contrastText: brand[50], + ...(mode === 'dark' && { + contrastText: brand[100], + light: brand[300], + main: brand[400], + dark: brand[800], + }), + }, + secondary: { + light: secondary[300], + main: secondary[500], + dark: secondary[800], + ...(mode === 'dark' && { + light: secondary[400], + main: secondary[500], + dark: secondary[900], + }), + }, + warning: { + main: '#F7B538', + dark: '#F79F00', + ...(mode === 'dark' && { main: '#F7B538', dark: '#F79F00' }), + }, + error: { + light: red[50], + main: red[500], + dark: red[700], + ...(mode === 'dark' && { light: '#D32F2F', main: '#D32F2F', dark: '#B22A2A' }), + }, + success: { + light: green[300], + main: green[400], + dark: green[800], + ...(mode === 'dark' && { + light: green[400], + main: green[500], + dark: green[700], + }), + }, + grey: { + 50: gray[50], + 100: gray[100], + 200: gray[200], + 300: gray[300], + 400: gray[400], + 500: gray[500], + 600: gray[600], + 700: gray[700], + 800: gray[800], + 900: gray[900], + }, + divider: mode === 'dark' ? alpha(gray[600], 0.3) : alpha(gray[300], 0.5), + background: { + default: '#fff', + paper: gray[50], + ...(mode === 'dark' && { default: gray[900], paper: gray[800] }), + }, + text: { + primary: gray[800], + secondary: gray[600], + ...(mode === 'dark' && { primary: '#fff', secondary: gray[400] }), + }, + action: { + selected: `${alpha(brand[200], 0.2)}`, + ...(mode === 'dark' && { + selected: alpha(brand[800], 0.2), + }), + }, + }, + typography: { + fontFamily: ['"Inter", "sans-serif"'].join(','), + h1: { + fontSize: 60, + fontWeight: 600, + lineHeight: 78 / 70, + letterSpacing: -0.2, + }, + h2: { + fontSize: 48, + fontWeight: 600, + lineHeight: 1.2, + }, + h3: { + fontSize: 42, + lineHeight: 1.2, + }, + h4: { + fontSize: 36, + fontWeight: 500, + lineHeight: 1.5, + }, + h5: { + fontSize: 20, + fontWeight: 600, + }, + h6: { + fontSize: 18, + }, + subtitle1: { + fontSize: 18, + }, + subtitle2: { + fontSize: 16, + }, + body1: { + fontWeight: 400, + fontSize: 15, + }, + body2: { + fontWeight: 400, + fontSize: 14, + }, + caption: { + fontWeight: 400, + fontSize: 12, + }, + }, +}); + +export default function getCheckoutTheme(mode) { + return { + ...getDesignTokens(mode), + components: { + MuiAlert: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: 10, + backgroundColor: orange[100], + color: theme.palette.text.primary, + border: `1px solid ${alpha(orange[300], 0.5)}`, + '& .MuiAlert-icon': { + color: orange[500], + }, + ...(theme.palette.mode === 'dark' && { + backgroundColor: `${alpha(orange[900], 0.5)}`, + border: `1px solid ${alpha(orange[800], 0.5)}`, + }), + }), + }, + }, + MuiToggleButtonGroup: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: '10px', + boxShadow: `0 4px 16px ${alpha(gray[400], 0.2)}`, + '& .Mui-selected': { + color: brand[500], + }, + ...(theme.palette.mode === 'dark' && { + '& .Mui-selected': { + color: '#fff', + }, + boxShadow: `0 4px 16px ${alpha(brand[700], 0.5)}`, + }), + }), + }, + }, + MuiToggleButton: { + styleOverrides: { + root: ({ theme }) => ({ + padding: '12px 16px', + textTransform: 'none', + borderRadius: '10px', + fontWeight: 500, + ...(theme.palette.mode === 'dark' && { + color: gray[400], + boxShadow: '0 4px 16px rgba(0, 0, 0, 0.5)', + '&.Mui-selected': { color: brand[300] }, + }), + }), + }, + }, + MuiButtonBase: { + defaultProps: { + disableTouchRipple: true, + disableRipple: true, + }, + styleOverrides: { + root: { + boxSizing: 'border-box', + transition: 'all 100ms ease-in', + '&:focus-visible': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + boxShadow: 'none', + borderRadius: '10px', + textTransform: 'none', + ...(ownerState.size === 'small' && { + maxHeight: '32px', + }), + ...(ownerState.size === 'medium' && { + height: '40px', + }), + ...(ownerState.variant === 'contained' && + ownerState.color === 'primary' && { + color: brand[50], + backgroundColor: brand[500], + backgroundImage: `linear-gradient(to bottom, ${brand[400]}, ${brand[500]})`, + boxShadow: `inset 0 1px ${alpha( + brand[300], + 0.5, + )}, inset 0 -2px ${alpha(brand[700], 0.5)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[400], + backgroundImage: 'none', + boxShadow: `0 0 0 1px ${alpha(brand[300], 0.5)}`, + }, + }), + ...(ownerState.variant === 'outlined' && { + backgroundColor: alpha(brand[300], 0.1), + borderColor: brand[300], + color: brand[500], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + borderColor: brand[200], + }, + }), + ...(ownerState.variant === 'text' && { + color: brand[500], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + borderColor: brand[200], + }, + }), + ...(theme.palette.mode === 'dark' && { + ...(ownerState.variant === 'contained' && + ownerState.color === 'primary' && { + border: `1px solid ${brand[600]}`, + backgroundImage: 'none', + backgroundColor: brand[500], + '&:hover': { + background: brand[600], + backgroundImage: 'none', + boxShadow: `0 0 0 1px ${alpha(brand[700], 0.5)}`, + }, + }), + ...(ownerState.variant === 'outlined' && { + backgroundColor: alpha(brand[600], 0.1), + borderColor: brand[700], + color: brand[300], + '&:hover': { + backgroundColor: alpha(brand[600], 0.3), + borderColor: brand[700], + }, + }), + ...(ownerState.variant === 'text' && { + color: brand[300], + '&:hover': { + backgroundColor: alpha(brand[600], 0.3), + borderColor: brand[700], + }, + }), + }), + }), + }, + }, + MuiCard: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + backgroundColor: gray[50], + borderRadius: 10, + outline: `1px solid ${alpha(gray[200], 0.8)}`, + boxShadow: 'none', + transition: 'background-color, border, 80ms ease', + ...(ownerState.variant === 'outlined' && { + boxSizing: 'border-box', + background: `linear-gradient(to bottom, #FFF, ${gray[50]})`, + '&:hover': { + borderColor: brand[300], + boxShadow: `0 0 24px ${brand[100]}`, + }, + }), + ...(theme.palette.mode === 'dark' && { + backgroundColor: alpha(gray[800], 0.6), + outline: `1px solid ${alpha(gray[700], 0.3)}`, + ...(ownerState.variant === 'outlined' && { + boxSizing: 'border-box', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + '&:hover': { + borderColor: brand[700], + boxShadow: `0 0 24px ${brand[800]}`, + }, + }), + }), + }), + }, + }, + MuiDivider: { + styleOverrides: { + root: ({ theme }) => ({ + borderColor: `${alpha(gray[200], 0.8)}`, + ...(theme.palette.mode === 'dark' && { + borderColor: `${alpha(gray[700], 0.4)}`, + }), + }), + }, + }, + MuiPaper: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundImage: 'none', + backgroundColor: gray[100], + ...(theme.palette.mode === 'dark' && { + backgroundColor: gray[800], + }), + }), + }, + }, + MuiOutlinedInput: { + styleOverrides: { + notchedOutline: { + border: 'none', + }, + root: ({ theme }) => ({ + '& .MuiInputBase-input': { + '&::placeholder': { + opacity: 0.7, + color: gray[500], + }, + }, + boxSizing: 'border-box', + flexGrow: 1, + maxHeight: 40, + height: '100%', + borderRadius: '10px', + border: '1px solid', + borderColor: gray[200], + boxShadow: '0px 1px 1px rgba(0, 0, 0, 0.1)', + transition: 'border-color 120ms ease-in', + backgroundColor: alpha(gray[100], 0.4), + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: brand[200], + }, + ...(theme.palette.mode === 'dark' && { + '& .MuiInputBase-input': { + '&::placeholder': { + opacity: 1, + color: gray[500], + }, + }, + boxSizing: 'border-box', + flexGrow: 1, + minHeight: 40, + height: '100%', + borderRadius: '10px', + border: '1px solid', + borderColor: gray[700], + boxShadow: '0px 2px 2px rgb(0, 0, 0)', + backgroundColor: alpha(gray[800], 0.4), + transition: 'border-color 120ms ease-in', + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: alpha(brand[500], 0.5), + }, + }), + }), + input: { + paddingLeft: 10, + }, + }, + }, + MuiFormLabel: { + styleOverrides: { + root: ({ theme }) => ({ + typography: theme.typography.caption, + marginBottom: 8, + }), + }, + }, + MuiInputBase: { + styleOverrides: { + root: { + border: 'none', + }, + }, + }, + MuiTextField: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + '& label .Mui-focused': { + color: 'white', + }, + '& .MuiInputBase-input': { + '&::placeholder': { + opacity: 0.7, + color: gray[500], + }, + }, + '& .MuiOutlinedInput-root': { + boxSizing: 'border-box', + minWidth: 280, + minHeight: 40, + height: '100%', + borderRadius: '10px', + '& fieldset': { + border: 'none', + boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)', + background: `${alpha('#FFF', 0.3)}`, + }, + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: brand[200], + }, + }, + ...(ownerState.variant === 'standard' && { + '&.MuiTextField-root': { + '& .MuiInput-root:hover:not(.Mui-disabled, .Mui-error):before': { + borderColor: brand[200], + }, + }, + '& :before': { + borderBottom: '1px solid', + borderColor: gray[200], + }, + '&:hover': { + '& :before': { + borderColor: brand[300], + }, + }, + }), + ...(theme.palette.mode === 'dark' && { + '& .MuiInputBase-input': { + '&::placeholder': { + opacity: 1, + color: gray[500], + }, + }, + '& .MuiOutlinedInput-root': { + boxSizing: 'border-box', + minWidth: 280, + minHeight: 40, + height: '100%', + borderRadius: '10px', + transition: 'border-color 120ms ease-in', + '& fieldset': { + border: 'none', + boxShadow: ' 0px 2px 4px rgba(0, 0, 0, 0.4)', + background: `${alpha(gray[800], 0.4)}`, + }, + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: alpha(brand[500], 0.5), + }, + }, + ...(ownerState.variant === 'standard' && { + '&.MuiTextField-root': { + '& .MuiInput-root:hover:not(.Mui-disabled, .Mui-error):before': { + borderColor: brand[200], + }, + }, + '& :before': { + borderBottom: '1px solid', + borderColor: gray[700], + }, + '&:hover': { + '& :before': { + borderColor: brand[300], + }, + }, + }), + }), + }), + }, + }, + MuiStepConnector: { + styleOverrides: { + line: ({ theme }) => ({ + borderTop: '1px solid', + borderColor: theme.palette.divider, + flex: 1, + borderRadius: '99px', + }), + }, + }, + MuiStepLabel: { + styleOverrides: { + label: ({ theme }) => ({ + '&.Mui-completed': { + opacity: 0.4, + ...(theme.palette.mode === 'dark' && { opacity: 0.3 }), + }, + }), + }, + }, + MuiStepIcon: { + variants: [ + { + props: { completed: true }, + style: () => ({ + width: 12, + height: 12, + }), + }, + ], + styleOverrides: { + root: ({ theme }) => ({ + color: 'transparent', + border: `1px solid ${gray[400]}`, + width: 12, + height: 12, + borderRadius: '50%', + '& text': { + display: 'none', + }, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.main, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.main, + }, + ...(theme.palette.mode === 'dark' && { + border: `1px solid ${gray[700]}`, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.light, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.light, + }, + }), + }), + }, + }, + }, + }; +} diff --git a/docs/data/material/getting-started/templates/checkout/getCheckoutTheme.tsx b/docs/data/material/getting-started/templates/checkout/getCheckoutTheme.tsx new file mode 100644 index 00000000000000..507e386b5627e9 --- /dev/null +++ b/docs/data/material/getting-started/templates/checkout/getCheckoutTheme.tsx @@ -0,0 +1,651 @@ +import type {} from '@mui/material/themeCssVarsAugmentation'; +import { ThemeOptions, alpha } from '@mui/material/styles'; +import { red } from '@mui/material/colors'; +import { PaletteMode } from '@mui/material'; + +declare module '@mui/material/styles/createPalette' { + interface ColorRange { + 50: string; + 100: string; + 200: string; + 300: string; + 400: string; + 500: string; + 600: string; + 700: string; + 800: string; + 900: string; + } + + interface PaletteColor extends ColorRange {} +} + +export const brand = { + 50: '#F0F7FF', + 100: '#CEE5FD', + 200: '#9CCCFC', + 300: '#55A6F6', + 400: '#0A66C2', + 500: '#0959AA', + 600: '#064079', + 700: '#033363', + 800: '#02294F', + 900: '#021F3B', +}; + +export const secondary = { + 50: '#F9F0FF', + 100: '#E9CEFD', + 200: '#D49CFC', + 300: '#B355F6', + 400: '#750AC2', + 500: '#6709AA', + 600: '#490679', + 700: '#3B0363', + 800: '#2F024F', + 900: '#23023B', +}; + +export const gray = { + 50: '#FBFCFE', + 100: '#EAF0F5', + 200: '#D6E2EB', + 300: '#BFCCD9', + 400: '#94A6B8', + 500: '#5B6B7C', + 600: '#4C5967', + 700: '#364049', + 800: '#131B20', + 900: '#090E10', +}; + +export const green = { + 50: '#F6FEF6', + 100: '#E3FBE3', + 200: '#C7F7C7', + 300: '#A1E8A1', + 400: '#51BC51', + 500: '#1F7A1F', + 600: '#136C13', + 700: '#0A470A', + 800: '#042F04', + 900: '#021D02', +}; + +export const orange = { + 50: '#FFFBF0', + 100: '#FDF1CE', + 200: '#FCE49C', + 300: '#F6CE55', + 400: '#C2940A', + 500: '#AA8109', + 600: '#795C06', + 700: '#634B03', + 800: '#4F3C02', + 900: '#3B2D02', +}; + +const getDesignTokens = (mode: PaletteMode) => ({ + palette: { + mode, + primary: { + light: brand[200], + main: brand[500], + dark: brand[800], + contrastText: brand[50], + ...(mode === 'dark' && { + contrastText: brand[100], + light: brand[300], + main: brand[400], + dark: brand[800], + }), + }, + secondary: { + light: secondary[300], + main: secondary[500], + dark: secondary[800], + ...(mode === 'dark' && { + light: secondary[400], + main: secondary[500], + dark: secondary[900], + }), + }, + warning: { + main: '#F7B538', + dark: '#F79F00', + ...(mode === 'dark' && { main: '#F7B538', dark: '#F79F00' }), + }, + error: { + light: red[50], + main: red[500], + dark: red[700], + ...(mode === 'dark' && { light: '#D32F2F', main: '#D32F2F', dark: '#B22A2A' }), + }, + success: { + light: green[300], + main: green[400], + dark: green[800], + ...(mode === 'dark' && { + light: green[400], + main: green[500], + dark: green[700], + }), + }, + grey: { + 50: gray[50], + 100: gray[100], + 200: gray[200], + 300: gray[300], + 400: gray[400], + 500: gray[500], + 600: gray[600], + 700: gray[700], + 800: gray[800], + 900: gray[900], + }, + divider: mode === 'dark' ? alpha(gray[600], 0.3) : alpha(gray[300], 0.5), + background: { + default: '#fff', + paper: gray[50], + ...(mode === 'dark' && { default: gray[900], paper: gray[800] }), + }, + text: { + primary: gray[800], + secondary: gray[600], + ...(mode === 'dark' && { primary: '#fff', secondary: gray[400] }), + }, + action: { + selected: `${alpha(brand[200], 0.2)}`, + ...(mode === 'dark' && { + selected: alpha(brand[800], 0.2), + }), + }, + }, + typography: { + fontFamily: ['"Inter", "sans-serif"'].join(','), + h1: { + fontSize: 60, + fontWeight: 600, + lineHeight: 78 / 70, + letterSpacing: -0.2, + }, + h2: { + fontSize: 48, + fontWeight: 600, + lineHeight: 1.2, + }, + h3: { + fontSize: 42, + lineHeight: 1.2, + }, + h4: { + fontSize: 36, + fontWeight: 500, + lineHeight: 1.5, + }, + h5: { + fontSize: 20, + fontWeight: 600, + }, + h6: { + fontSize: 18, + }, + subtitle1: { + fontSize: 18, + }, + subtitle2: { + fontSize: 16, + }, + body1: { + fontWeight: 400, + fontSize: 15, + }, + body2: { + fontWeight: 400, + fontSize: 14, + }, + caption: { + fontWeight: 400, + fontSize: 12, + }, + }, +}); + +export default function getCheckoutTheme(mode: PaletteMode): ThemeOptions { + return { + ...getDesignTokens(mode), + components: { + MuiAlert: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: 10, + backgroundColor: orange[100], + color: theme.palette.text.primary, + border: `1px solid ${alpha(orange[300], 0.5)}`, + '& .MuiAlert-icon': { + color: orange[500], + }, + ...(theme.palette.mode === 'dark' && { + backgroundColor: `${alpha(orange[900], 0.5)}`, + border: `1px solid ${alpha(orange[800], 0.5)}`, + }), + }), + }, + }, + MuiToggleButtonGroup: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: '10px', + boxShadow: `0 4px 16px ${alpha(gray[400], 0.2)}`, + '& .Mui-selected': { + color: brand[500], + }, + ...(theme.palette.mode === 'dark' && { + '& .Mui-selected': { + color: '#fff', + }, + boxShadow: `0 4px 16px ${alpha(brand[700], 0.5)}`, + }), + }), + }, + }, + MuiToggleButton: { + styleOverrides: { + root: ({ theme }) => ({ + padding: '12px 16px', + textTransform: 'none', + borderRadius: '10px', + fontWeight: 500, + ...(theme.palette.mode === 'dark' && { + color: gray[400], + boxShadow: '0 4px 16px rgba(0, 0, 0, 0.5)', + '&.Mui-selected': { color: brand[300] }, + }), + }), + }, + }, + MuiButtonBase: { + defaultProps: { + disableTouchRipple: true, + disableRipple: true, + }, + styleOverrides: { + root: { + boxSizing: 'border-box', + transition: 'all 100ms ease-in', + '&:focus-visible': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + boxShadow: 'none', + borderRadius: '10px', + textTransform: 'none', + ...(ownerState.size === 'small' && { + maxHeight: '32px', + }), + ...(ownerState.size === 'medium' && { + height: '40px', + }), + ...(ownerState.variant === 'contained' && + ownerState.color === 'primary' && { + color: brand[50], + backgroundColor: brand[500], + backgroundImage: `linear-gradient(to bottom, ${brand[400]}, ${brand[500]})`, + boxShadow: `inset 0 1px ${alpha( + brand[300], + 0.5, + )}, inset 0 -2px ${alpha(brand[700], 0.5)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[400], + backgroundImage: 'none', + boxShadow: `0 0 0 1px ${alpha(brand[300], 0.5)}`, + }, + }), + ...(ownerState.variant === 'outlined' && { + backgroundColor: alpha(brand[300], 0.1), + borderColor: brand[300], + color: brand[500], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + borderColor: brand[200], + }, + }), + ...(ownerState.variant === 'text' && { + color: brand[500], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + borderColor: brand[200], + }, + }), + ...(theme.palette.mode === 'dark' && { + ...(ownerState.variant === 'contained' && + ownerState.color === 'primary' && { + border: `1px solid ${brand[600]}`, + backgroundImage: 'none', + backgroundColor: brand[500], + '&:hover': { + background: brand[600], + backgroundImage: 'none', + boxShadow: `0 0 0 1px ${alpha(brand[700], 0.5)}`, + }, + }), + ...(ownerState.variant === 'outlined' && { + backgroundColor: alpha(brand[600], 0.1), + borderColor: brand[700], + color: brand[300], + '&:hover': { + backgroundColor: alpha(brand[600], 0.3), + borderColor: brand[700], + }, + }), + ...(ownerState.variant === 'text' && { + color: brand[300], + '&:hover': { + backgroundColor: alpha(brand[600], 0.3), + borderColor: brand[700], + }, + }), + }), + }), + }, + }, + MuiCard: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + backgroundColor: gray[50], + borderRadius: 10, + outline: `1px solid ${alpha(gray[200], 0.8)}`, + boxShadow: 'none', + transition: 'background-color, border, 80ms ease', + ...(ownerState.variant === 'outlined' && { + boxSizing: 'border-box', + background: `linear-gradient(to bottom, #FFF, ${gray[50]})`, + '&:hover': { + borderColor: brand[300], + boxShadow: `0 0 24px ${brand[100]}`, + }, + }), + ...(theme.palette.mode === 'dark' && { + backgroundColor: alpha(gray[800], 0.6), + outline: `1px solid ${alpha(gray[700], 0.3)}`, + ...(ownerState.variant === 'outlined' && { + boxSizing: 'border-box', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + '&:hover': { + borderColor: brand[700], + boxShadow: `0 0 24px ${brand[800]}`, + }, + }), + }), + }), + }, + }, + MuiDivider: { + styleOverrides: { + root: ({ theme }) => ({ + borderColor: `${alpha(gray[200], 0.8)}`, + ...(theme.palette.mode === 'dark' && { + borderColor: `${alpha(gray[700], 0.4)}`, + }), + }), + }, + }, + MuiPaper: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundImage: 'none', + backgroundColor: gray[100], + ...(theme.palette.mode === 'dark' && { + backgroundColor: gray[800], + }), + }), + }, + }, + MuiOutlinedInput: { + styleOverrides: { + notchedOutline: { + border: 'none', + }, + root: ({ theme }) => ({ + '& .MuiInputBase-input': { + '&::placeholder': { + opacity: 0.7, + color: gray[500], + }, + }, + boxSizing: 'border-box', + flexGrow: 1, + maxHeight: 40, + height: '100%', + borderRadius: '10px', + border: '1px solid', + borderColor: gray[200], + boxShadow: '0px 1px 1px rgba(0, 0, 0, 0.1)', + transition: 'border-color 120ms ease-in', + backgroundColor: alpha(gray[100], 0.4), + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: brand[200], + }, + ...(theme.palette.mode === 'dark' && { + '& .MuiInputBase-input': { + '&::placeholder': { + opacity: 1, + color: gray[500], + }, + }, + boxSizing: 'border-box', + flexGrow: 1, + minHeight: 40, + height: '100%', + borderRadius: '10px', + border: '1px solid', + borderColor: gray[700], + boxShadow: '0px 2px 2px rgb(0, 0, 0)', + backgroundColor: alpha(gray[800], 0.4), + transition: 'border-color 120ms ease-in', + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: alpha(brand[500], 0.5), + }, + }), + }), + input: { + paddingLeft: 10, + }, + }, + }, + MuiFormLabel: { + styleOverrides: { + root: ({ theme }) => ({ + typography: theme.typography.caption, + marginBottom: 8, + }), + }, + }, + MuiInputBase: { + styleOverrides: { + root: { + border: 'none', + }, + }, + }, + MuiTextField: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + '& label .Mui-focused': { + color: 'white', + }, + '& .MuiInputBase-input': { + '&::placeholder': { + opacity: 0.7, + color: gray[500], + }, + }, + '& .MuiOutlinedInput-root': { + boxSizing: 'border-box', + minWidth: 280, + minHeight: 40, + height: '100%', + borderRadius: '10px', + '& fieldset': { + border: 'none', + boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)', + background: `${alpha('#FFF', 0.3)}`, + }, + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: brand[200], + }, + }, + ...(ownerState.variant === 'standard' && { + '&.MuiTextField-root': { + '& .MuiInput-root:hover:not(.Mui-disabled, .Mui-error):before': { + borderColor: brand[200], + }, + }, + '& :before': { + borderBottom: '1px solid', + borderColor: gray[200], + }, + '&:hover': { + '& :before': { + borderColor: brand[300], + }, + }, + }), + ...(theme.palette.mode === 'dark' && { + '& .MuiInputBase-input': { + '&::placeholder': { + opacity: 1, + color: gray[500], + }, + }, + '& .MuiOutlinedInput-root': { + boxSizing: 'border-box', + minWidth: 280, + minHeight: 40, + height: '100%', + borderRadius: '10px', + transition: 'border-color 120ms ease-in', + '& fieldset': { + border: 'none', + boxShadow: ' 0px 2px 4px rgba(0, 0, 0, 0.4)', + background: `${alpha(gray[800], 0.4)}`, + }, + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: alpha(brand[500], 0.5), + }, + }, + ...(ownerState.variant === 'standard' && { + '&.MuiTextField-root': { + '& .MuiInput-root:hover:not(.Mui-disabled, .Mui-error):before': { + borderColor: brand[200], + }, + }, + '& :before': { + borderBottom: '1px solid', + borderColor: gray[700], + }, + '&:hover': { + '& :before': { + borderColor: brand[300], + }, + }, + }), + }), + }), + }, + }, + MuiStepConnector: { + styleOverrides: { + line: ({ theme }) => ({ + borderTop: '1px solid', + borderColor: theme.palette.divider, + flex: 1, + borderRadius: '99px', + }), + }, + }, + MuiStepLabel: { + styleOverrides: { + label: ({ theme }) => ({ + '&.Mui-completed': { + opacity: 0.4, + ...(theme.palette.mode === 'dark' && { opacity: 0.3 }), + }, + }), + }, + }, + MuiStepIcon: { + variants: [ + { + props: { completed: true }, + style: () => ({ + width: 12, + height: 12, + }), + }, + ], + styleOverrides: { + root: ({ theme }) => ({ + color: 'transparent', + border: `1px solid ${gray[400]}`, + width: 12, + height: 12, + borderRadius: '50%', + '& text': { + display: 'none', + }, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.main, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.main, + }, + ...(theme.palette.mode === 'dark' && { + border: `1px solid ${gray[700]}`, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.light, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.light, + }, + }), + }), + }, + }, + }, + }; +} diff --git a/docs/public/static/images/templates/checkout.png b/docs/public/static/images/templates/checkout.png index 0b4e218a001ba734bbe8688e4d9bd493bb39bf0f..577daf8192714413b1a858184b46db085d5be2b2 100644 GIT binary patch literal 21469 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 l3nFm!WVL1(53+5Si&C({FbIA1Z(<&c)dlDR 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 diff --git a/docs/src/modules/components/MaterialFreeTemplatesCollection.js b/docs/src/modules/components/MaterialFreeTemplatesCollection.js index 91be4ebb3a5050..21f2434fa55110 100644 --- a/docs/src/modules/components/MaterialFreeTemplatesCollection.js +++ b/docs/src/modules/components/MaterialFreeTemplatesCollection.js @@ -31,6 +31,13 @@ function layouts(t) { href: '/material-ui/getting-started/templates/landing-page/', source: `${sourcePrefix}/docs/data/material/getting-started/templates/landing-page`, }, + { + title: t('checkoutTitle'), + description: t('checkoutDescr'), + src: '/static/images/templates/checkout.png', + href: '/material-ui/getting-started/templates/checkout/', + source: `${sourcePrefix}/docs/data/material/getting-started/templates/checkout`, + }, { title: t('signInTitle'), description: t('signInDescr'), @@ -59,13 +66,6 @@ function layouts(t) { href: '/material-ui/getting-started/templates/blog/', source: `${sourcePrefix}/docs/data/material/getting-started/templates/blog`, }, - { - title: t('checkoutTitle'), - description: t('checkoutDescr'), - src: '/static/images/templates/checkout.png', - href: '/material-ui/getting-started/templates/checkout/', - source: `${sourcePrefix}/docs/data/material/getting-started/templates/checkout`, - }, { title: t('stickyFooterTitle'), description: t('stickyFooterDescr'), diff --git a/test/regressions/index.js b/test/regressions/index.js index f67b071dad5771..3591aae89c78ec 100644 --- a/test/regressions/index.js +++ b/test/regressions/index.js @@ -27,6 +27,7 @@ importRegressionFixtures.keys().forEach((path) => { }, []); const blacklist = [ + 'docs-getting-started-templates-checkout/getCheckoutTheme.png', // Theme file 'docs-getting-started-templates-landing-page/getLPTheme.png', // Theme file 'docs-joy-getting-started-templates/TemplateCollection.png', // No public components 'docs-joy-core-features-automatic-adjustment/ListThemes.png', // No public components