Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
51 changes: 51 additions & 0 deletions packages/theming/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,57 @@ const LocalizedComponent = withTheme(StyledDiv);
</ThemeProvider>;
```

### 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' : '')}
`
};

<ThemeProvider theme={theme}>
<Notification>
<Title>Themed Title (hover as well)</Title>
<Paragraph purple>Custom theme triggered by prop</Paragraph>
</Notification>
</ThemeProvider>;
```

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
<CIDTable />
```

### WARNING

Theming is meant to be used for small, global changes to a component
Expand Down
33 changes: 33 additions & 0 deletions utils/scripts/get-cids.sh
Original file line number Diff line number Diff line change
@@ -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
50 changes: 50 additions & 0 deletions utils/styleguide/CIDTable/index.js
Original file line number Diff line number Diff line change
@@ -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 (
<Table>
<Head>
<HeaderRow>
<HeaderCell width="20%">Component</HeaderCell>
<HeaderCell width="80%">COMPONENT_IDs</HeaderCell>
</HeaderRow>
</Head>
<Body>
{Object.entries(groups).map(([componentName, ids]) => (
<Row key={componentName}>
<Cell width="20%">{componentName.trim()}</Cell>
<Cell width="80%">{ids.map(s => s.trim()).join(', ')}</Cell>
</Row>
))}
</Body>
</Table>
);
}
}
2 changes: 2 additions & 0 deletions utils/styleguide/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
12 changes: 11 additions & 1 deletion utils/styleguide/styleguide.base.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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: {
Expand Down