diff --git a/CHANGELOG.md b/CHANGELOG.md index 324751073..abcb7a85c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Not released +- LegendCategories: support for custom markers [#451](https://github.com/CartoDB/carto-react/pull/451) + +## 1.4 ## 1.3 ### 1.3.0 (2022-07-11) diff --git a/packages/react-ui/__tests__/widgets/legend/LegendCategories.test.js b/packages/react-ui/__tests__/widgets/legend/LegendCategories.test.js index 59d43d768..0f66ca9dc 100644 --- a/packages/react-ui/__tests__/widgets/legend/LegendCategories.test.js +++ b/packages/react-ui/__tests__/widgets/legend/LegendCategories.test.js @@ -20,7 +20,7 @@ describe('LegendCategories', () => { }); test('renders colors (CARTOColors) correctly', () => { render(); - const elements = document.querySelectorAll('[class*="circle"]'); + const elements = document.querySelectorAll('[class*="marker"]'); getPalette(COLOR, 2).forEach((color, idx) => expect(elements[idx]).toHaveStyle(`background-color: ${color}`) ); @@ -28,15 +28,27 @@ describe('LegendCategories', () => { test('renders colors (hex) correctly', () => { render(); const [firstCategory, secondCategory] = - document.querySelectorAll('[class*="circle"]'); + document.querySelectorAll('[class*="marker"]'); expect(firstCategory).toHaveStyle('background-color: #000;'); expect(secondCategory).toHaveStyle('background-color: #fff;'); }); test('renders stroked colors correctly', () => { render(); - const elements = document.querySelectorAll('[class*="circle"]'); + const elements = document.querySelectorAll('[class*="marker"]'); getPalette(COLOR, 2).forEach((color, idx) => expect(elements[idx]).toHaveStyle(`border-color: ${color}`) ); }); + test('renders icons correctly', () => { + render( + + ); + const elements = document.querySelectorAll('[class*="marker"]'); + getPalette(COLOR, 2).forEach((color, idx) => { + expect(elements[idx]).toHaveStyle(`mask-image: url(https://xyz.com/x.png)`); + expect(elements[idx]).toHaveStyle(`background-color: ${color}`); + }); + }); }); diff --git a/packages/react-ui/src/widgets/legend/LegendCategories.js b/packages/react-ui/src/widgets/legend/LegendCategories.js index 38c87f998..bd52ac742 100644 --- a/packages/react-ui/src/widgets/legend/LegendCategories.js +++ b/packages/react-ui/src/widgets/legend/LegendCategories.js @@ -4,7 +4,7 @@ import { getPalette } from '../../utils/palette'; import PropTypes from 'prop-types'; function LegendCategories({ legend }) { - const { labels = [], colors = [], isStrokeColor = false } = legend; + const { labels = [], colors = [], isStrokeColor = false, customMarkers } = legend; const palette = getPalette(colors, labels.length); @@ -14,6 +14,9 @@ function LegendCategories({ legend }) { isMax={false} label={label} color={palette[idx]} + icon={ + customMarkers && Array.isArray(customMarkers) ? customMarkers[idx] : customMarkers + } isStrokeColor={isStrokeColor} /> )); @@ -42,6 +45,10 @@ LegendCategories.propTypes = { legend: PropTypes.shape({ labels: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])), colors: PropTypes.oneOfType([PropTypes.arrayOf(ColorType), PropTypes.string]), + customMarkers: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.string), + PropTypes.string + ]), isStrokeColor: PropTypes.bool }).isRequired }; @@ -56,14 +63,16 @@ const useStyles = makeStyles((theme) => ({ '& $circle': {} } }, - circle: { + marker: { whiteSpace: 'nowrap', display: 'block', width: '12px', height: '12px', borderRadius: '50%', position: 'relative', - border: '2px solid transparent', + border: '2px solid transparent' + }, + circle: { '&::after': { position: 'absolute', display: ({ isMax }) => (isMax ? 'block' : 'none'), @@ -76,6 +85,10 @@ const useStyles = makeStyles((theme) => ({ boxSizing: 'content-box' } }, + icon: { + maskRepeat: 'no-repeat', + maskSize: 'cover' + }, flexParent: { display: 'flex', alignItems: 'center' @@ -94,7 +107,7 @@ const useStyles = makeStyles((theme) => ({ } })); -function Row({ label, isMax, isStrokeColor, color = '#000' }) { +function Row({ label, isMax, isStrokeColor, color = '#000', icon }) { const classes = useStyles({ isMax }); const [showTooltip, setShowTooltip] = useState(false); @@ -121,8 +134,18 @@ function Row({ label, isMax, isStrokeColor, color = '#000' }) {