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: {