diff --git a/CHANGELOG.md b/CHANGELOG.md index 105071165..06e6e2364 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Not released +- AppBar: Add support for custom branding [#792](https://github.com/CartoDB/carto-react/pull/792) + ## 2.2 ### 2.2.13 (2023-10-16) diff --git a/packages/react-ui/src/components/organisms/AppBar/AppBar.d.ts b/packages/react-ui/src/components/organisms/AppBar/AppBar.d.ts index fac6ebd29..072a2ac1c 100644 --- a/packages/react-ui/src/components/organisms/AppBar/AppBar.d.ts +++ b/packages/react-ui/src/components/organisms/AppBar/AppBar.d.ts @@ -9,6 +9,8 @@ export type AppBarTypeMap = 'header'> = MuiAppB secondaryText?: React.ReactNode; onClickMenu?: (event: React.MouseEvent) => void; showBurgerMenu?: boolean; + backgroundColor?: string; + textColor?: string; }, D >; diff --git a/packages/react-ui/src/components/organisms/AppBar/AppBar.js b/packages/react-ui/src/components/organisms/AppBar/AppBar.js index 591f99a9a..e4dde2bed 100644 --- a/packages/react-ui/src/components/organisms/AppBar/AppBar.js +++ b/packages/react-ui/src/components/organisms/AppBar/AppBar.js @@ -3,11 +3,24 @@ import PropTypes from 'prop-types'; import { AppBar as MuiAppBar, Toolbar } from '@mui/material'; import { styled } from '@mui/material/styles'; -import BurguerMenu from './BurguerMenu'; +import BurgerMenu from './BurgerMenu'; import BrandLogo from './BrandLogo'; import BrandText from './BrandText'; import SecondaryText from './SecondaryText'; +const Root = styled(MuiAppBar, { + shouldForwardProp: (prop) => !['backgroundColor', 'textColor'].includes(prop) +})(({ backgroundColor, textColor, theme }) => ({ + backgroundColor: backgroundColor || theme.palette.brand.navyBlue, + + '& .MuiTypography-root': { + color: textColor || theme.palette.common.white + }, + '& .MuiIconButton-root path': { + fill: textColor || theme.palette.common.white + } +})); + const BrandElements = styled('div')(({ theme }) => ({ display: 'flex', alignItems: 'center', @@ -34,21 +47,25 @@ const AppBar = ({ secondaryText, showBurgerMenu, onClickMenu, + backgroundColor, + textColor, ...otherProps }) => { return ( - + - {showBurgerMenu && } + {showBurgerMenu && ( + + )} {brandLogo && } - {brandText && } - {secondaryText && } + {brandText && } + {secondaryText && } {children} - + ); }; @@ -61,7 +78,9 @@ AppBar.propTypes = { brandText: PropTypes.oneOfType([PropTypes.element, PropTypes.string]), secondaryText: PropTypes.oneOfType([PropTypes.element, PropTypes.string]), onClickMenu: PropTypes.func, - showBurgerMenu: PropTypes.bool + showBurgerMenu: PropTypes.bool, + backgroundColor: PropTypes.string, + textColor: PropTypes.string }; export default AppBar; diff --git a/packages/react-ui/src/components/organisms/AppBar/BrandText.js b/packages/react-ui/src/components/organisms/AppBar/BrandText.js index e337174cf..374adf4ae 100644 --- a/packages/react-ui/src/components/organisms/AppBar/BrandText.js +++ b/packages/react-ui/src/components/organisms/AppBar/BrandText.js @@ -1,5 +1,5 @@ import React from 'react'; -import { styled } from '@mui/material/styles'; +import { styled, useTheme } from '@mui/material/styles'; import Typography from '../../atoms/Typography'; @@ -9,9 +9,15 @@ const Text = styled(Typography)({ whiteSpace: 'nowrap' }); -export default function BrandText({ text }) { +export default function BrandText({ text, textColor }) { + const theme = useTheme(); + return ( - + {text} ); diff --git a/packages/react-ui/src/components/organisms/AppBar/BurgerMenu.js b/packages/react-ui/src/components/organisms/AppBar/BurgerMenu.js new file mode 100644 index 000000000..a6750a268 --- /dev/null +++ b/packages/react-ui/src/components/organisms/AppBar/BurgerMenu.js @@ -0,0 +1,44 @@ +import React from 'react'; +import { Divider, Hidden, IconButton } from '@mui/material'; +import { alpha, styled } from '@mui/material/styles'; +import { MenuOutlined } from '@mui/icons-material'; + +import { APPBAR_SIZE } from '../../../theme/themeConstants'; + +const Menu = styled('div')(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + height: APPBAR_SIZE, + marginRight: theme.spacing(1.5) +})); + +const MenuButton = styled(IconButton, { + shouldForwardProp: (prop) => prop !== 'iconColor' +})(({ iconColor, theme }) => ({ + marginRight: theme.spacing(1), + + '&.MuiButtonBase-root svg path': { + fill: iconColor || theme.palette.background.paper + } +})); + +const MenuDivider = styled(Divider, { + shouldForwardProp: (prop) => prop !== 'color' +})(({ color, theme }) => ({ + ...(color && { + borderColor: alpha(color, 0.12) + }) +})); + +export default function BurgerMenu({ onClickMenu, iconColor }) { + return ( + + + + + + + + + ); +} diff --git a/packages/react-ui/src/components/organisms/AppBar/BurguerMenu.js b/packages/react-ui/src/components/organisms/AppBar/BurguerMenu.js deleted file mode 100644 index 110cd971a..000000000 --- a/packages/react-ui/src/components/organisms/AppBar/BurguerMenu.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import { Divider, Hidden, IconButton } from '@mui/material'; -import { styled } from '@mui/material/styles'; -import { MenuOutlined } from '@mui/icons-material'; - -import { APPBAR_SIZE } from '../../../theme/themeConstants'; - -const Menu = styled('div')(({ theme }) => ({ - display: 'flex', - alignItems: 'center', - height: APPBAR_SIZE, - marginRight: theme.spacing(1.5) -})); - -const MenuButton = styled(IconButton)(({ theme }) => ({ - marginRight: theme.spacing(1), - - '&.MuiButtonBase-root svg path': { - fill: theme.palette.background.paper - } -})); - -export default function BurguerMenu({ onClickMenu }) { - return ( - - - - - - - - - ); -} diff --git a/packages/react-ui/src/components/organisms/AppBar/SecondaryText.js b/packages/react-ui/src/components/organisms/AppBar/SecondaryText.js index fe3e5c91a..de224eb07 100644 --- a/packages/react-ui/src/components/organisms/AppBar/SecondaryText.js +++ b/packages/react-ui/src/components/organisms/AppBar/SecondaryText.js @@ -1,21 +1,32 @@ import React from 'react'; -import { styled } from '@mui/material/styles'; +import { styled, useTheme } from '@mui/material/styles'; import Typography from '../../atoms/Typography'; -const Text = styled(Typography)(({ theme }) => ({ +const Text = styled(Typography, { + shouldForwardProp: (prop) => prop !== 'textColor' +})(({ textColor, theme }) => ({ display: 'flex', alignItems: 'center', + '&::before': { content: '"/"', margin: theme.spacing(0, 1), - color: theme.palette.white[60] + opacity: 0.6, + color: textColor || theme.palette.common.white } })); -export default function SecondaryText({ text }) { +export default function SecondaryText({ text, textColor }) { + const theme = useTheme(); + return ( - + {text} ); diff --git a/packages/react-ui/src/theme/sections/components/surfaces.js b/packages/react-ui/src/theme/sections/components/surfaces.js index b134c1c37..1d94adb19 100644 --- a/packages/react-ui/src/theme/sections/components/surfaces.js +++ b/packages/react-ui/src/theme/sections/components/surfaces.js @@ -21,12 +21,6 @@ export const surfacesOverrides = { padding: theme.spacing(0, 1), minHeight: APPBAR_SIZE }, - '& .MuiTypography-root': { - color: theme.palette.common.white - }, - '& .MuiIconButton-root path': { - fill: theme.palette.common.white - }, '& .MuiAvatar-root': { width: theme.spacing(4), height: theme.spacing(4) diff --git a/packages/react-ui/storybook/assets/carto-logo-dark.svg b/packages/react-ui/storybook/assets/carto-logo-dark.svg new file mode 100644 index 000000000..66e7d0654 --- /dev/null +++ b/packages/react-ui/storybook/assets/carto-logo-dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/react-ui/storybook/stories/molecules/Table.stories.js b/packages/react-ui/storybook/stories/molecules/Table.stories.js index 7523be687..842fd841c 100644 --- a/packages/react-ui/storybook/stories/molecules/Table.stories.js +++ b/packages/react-ui/storybook/stories/molecules/Table.stories.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Box, Chip, @@ -11,7 +11,9 @@ import { TableBody, Table, IconButton, - MenuItem + MenuItem, + TableFooter, + TablePagination } from '@mui/material'; import SelectField from '../../../src/components/atoms/SelectField'; import { MoreVertOutlined } from '@mui/icons-material'; @@ -52,7 +54,15 @@ const rows = [ const options = { title: 'Molecules/Table', component: Table, - argTypes: {}, + argTypes: { + size: { + defaultValue: 'medium', + control: { + type: 'select', + options: ['medium', 'small'] + } + } + }, parameters: { design: { type: 'figma', @@ -69,7 +79,7 @@ export default options; const PlaygroundTemplate = (args) => { return ( - +
# @@ -145,7 +155,7 @@ const PlaygroundTemplate = (args) => { const ScrollTemplate = (args) => ( -
+
# @@ -218,8 +228,110 @@ const ScrollTemplate = (args) => ( ); +const PaginationTemplate = (args) => { + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + return ( + +
+ + + # + Name + Type + Mode + Description + Actions + + + + {rows.map((row, index) => ( + + + {index + 1} + + + {index === 1 ? ( + + + {row.name} + + + ) : ( + row.name + )} + + + + + + void 0} + value={[]} + > + {[...Array(3)].map((item, index) => { + const itemText = `${index + 1}`; + + return ( + + {itemText} + + ); + })} + + + + {index === 3 ? ( + + + {row.description} + + + ) : ( + row.description + )} + + + + + + + + ))} + + + + + + +
+
+ ); +}; + export const Playground = PlaygroundTemplate.bind({}); Playground.args = {}; export const Scroll = ScrollTemplate.bind({}); ScrollTemplate.args = {}; + +export const WithPagination = PaginationTemplate.bind({}); +PaginationTemplate.args = {}; diff --git a/packages/react-ui/storybook/stories/organisms/AppBar.stories.js b/packages/react-ui/storybook/stories/organisms/AppBar.stories.js index 96ffff376..177e73abf 100644 --- a/packages/react-ui/storybook/stories/organisms/AppBar.stories.js +++ b/packages/react-ui/storybook/stories/organisms/AppBar.stories.js @@ -73,7 +73,7 @@ const CustomTemplate = (args) => { - + Profile @@ -129,4 +129,12 @@ Basic.args = { ...commonArgs }; export const Composition = CustomTemplate.bind({}); Composition.args = { ...commonArgs }; +export const CustomBranding = Template.bind({}); +CustomBranding.args = { + ...commonArgs, + brandLogo: , + backgroundColor: '#e1e3e4', + textColor: '#024D9E' +}; + export const Guide = DocTemplate.bind({});