diff --git a/.eslintrc.json b/.eslintrc.json index 07ca3b9503b..04d26133ed7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,7 +15,8 @@ "globals": { "jest": true, "BASE_PATH_NAME": true, - "PACKAGE_VERSION": true + "PACKAGE_VERSION": true, + "COMPONENT_IDS": true }, "plugins": ["prettier", "react", "jest", "jsx-a11y"], "env": { diff --git a/packages/theming/README.md b/packages/theming/README.md index 4aaab5bd7bd..e0e77e36cca 100644 --- a/packages/theming/README.md +++ b/packages/theming/README.md @@ -80,6 +80,57 @@ const LocalizedComponent = withTheme(StyledDiv); ; ``` +### Advanced usage + +If you need to compose from other theme overrides e.g. you find yourself overriding +the same properties in several components or you're using props to alter your +overrides then please see the following code example. + +```jsx static +import { ThemeProvider } from '@zendeskgarden/react-theming'; +import { Notification, Title, Paragraph } from '@zendeskgarden/react-notifications'; +import { css } from 'styled-components'; + +const commonOverrides = ` + &&:hover { + color: blue; + } +`; +const theme = { + 'notifications.title': css` + ${commonOverrides} + && { + color: red; + } + `, + 'notifications.paragraph': css` + ${commonOverrides} + ${props => (props.purple ? 'color: purple' : '')} + ` +}; + + + + Themed Title (hover as well) + Custom theme triggered by prop + +; +``` + +The main difference here is the usage of the [`css` helper](https://www.styled-components.com/docs/api#css) +from styled-components. This will correctly pass down the props from the component so you can conditionally +apply styles based on props or compose from other template literals. + +### Theme ids + +Each component has a `COMPONENT_ID` applied so you can target it in your own theme +file to override the default look and feel. This table contains all the ids and which +package they apply to. + +```jsx noeditor + +``` + ### WARNING Theming is meant to be used for small, global changes to a component diff --git a/utils/scripts/get-cids.sh b/utils/scripts/get-cids.sh new file mode 100755 index 00000000000..bb797c42e40 --- /dev/null +++ b/utils/scripts/get-cids.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +AWKCMD=' + # Split record by (=) + BEGIN { FS = "="; } + # Remove all semicolons + { gsub(/;/, "") } + { + # On first record + if ( NR == 1) { + # Remove single quotes + gsub(/\047/, ""); + } else { + # Replace first single quote with (,) + sub(/\047/, ","); + # Remove single quotes + gsub(/\047/, ""); + } + } + # Print second column only which contains component_id + { print $2 } +' + +grep \ + --exclude-dir=.template \ + --exclude-dir=node_modules \ + --include=\*.js \ + --exclude=\*.spec.js \ + -rnw '../../packages' \ + -e 'const COMPONENT_ID = ' | # Find all COMPONENT_IDs + sort | # Sort alphabetically + awk "$AWKCMD" | # Run the above awk program + tr '\n' ' ' # Collapse result to single line diff --git a/utils/styleguide/CIDTable/index.js b/utils/styleguide/CIDTable/index.js new file mode 100644 index 00000000000..dfc31c93552 --- /dev/null +++ b/utils/styleguide/CIDTable/index.js @@ -0,0 +1,50 @@ +/** + * Copyright Zendesk, Inc. + * + * Use of this source code is governed under the Apache License, Version 2.0 + * found at http://www.apache.org/licenses/LICENSE-2.0. + */ + +import React, { Component } from 'react'; +import { Table, Head, Row, HeaderRow, HeaderCell, Body, Cell } from '../../../packages/tables/src'; + +export default class CIDTable extends Component { + groupIds = data => { + const cids = data.split(','); + + return cids.reduce((acc, item) => { + const [group] = item.split('.'); + + if (acc[group]) { + acc[group].push(item); + } else { + acc[group] = [item]; + } + + return acc; + }, {}); + }; + + render() { + const groups = this.groupIds(COMPONENT_IDS); + + return ( + + + + Component + COMPONENT_IDs + + + + {Object.entries(groups).map(([componentName, ids]) => ( + + {componentName.trim()} + {ids.map(s => s.trim()).join(', ')} + + ))} + +
+ ); + } +} diff --git a/utils/styleguide/setup.js b/utils/styleguide/setup.js index eb5e40dc69f..eeb872830dc 100644 --- a/utils/styleguide/setup.js +++ b/utils/styleguide/setup.js @@ -16,9 +16,11 @@ global.styled = styled; // Styleguide components import State from './State'; +import CIDTable from './CIDTable'; import { Grid, Row, Col } from '../../packages/grid/src'; global.State = State; +global.CIDTable = CIDTable; global.Grid = Grid; global.Row = styled(Row).attrs({ alignItems: 'center' diff --git a/utils/styleguide/styleguide.base.config.js b/utils/styleguide/styleguide.base.config.js index 19bdc656c24..30846ef96df 100644 --- a/utils/styleguide/styleguide.base.config.js +++ b/utils/styleguide/styleguide.base.config.js @@ -15,6 +15,15 @@ const { } = require('@zendeskgarden/css-variables'); const packageManifest = require(path.resolve('package.json')); const customStyleguideConfig = require(path.resolve('styleguide.config.js')); +const exec = require('child_process').execSync; + +const COMPONENT_IDS = exec('"../../utils/scripts/get-cids.sh"', (error, stdout) => { + if (error !== null) { + throw new Error(`exec error: ${error}`); + } + + return stdout; +}); const basePathName = path.basename(path.resolve('./')); const googleTrackingId = 'UA-970836-25'; const capitalizePackageName = basePathName.charAt(0).toUpperCase() + basePathName.slice(1); @@ -169,7 +178,8 @@ const defaultStyleguideConfig = { plugins: [ new webpack.DefinePlugin({ BASE_PATH_NAME: JSON.stringify(basePathName), - PACKAGE_VERSION: JSON.stringify(packageManifest.version) + PACKAGE_VERSION: JSON.stringify(packageManifest.version), + COMPONENT_IDS: JSON.stringify(COMPONENT_IDS.toString('utf8')) }) ], resolve: {