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 0b4e218a001ba7..577daf81927144 100644 Binary files a/docs/public/static/images/templates/checkout.png and b/docs/public/static/images/templates/checkout.png differ 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