Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

Commit

Permalink
docs(custom-components): adding initial guide for creating custom com…
Browse files Browse the repository at this point in the history
…ponents (#517)

* -added custom components guide in the docs

* -updated changelog

* -replaced renderComponent with createComponent

* -replaced renderComponent with createComponent

* -simplified StyledButton example code

* -addressed comments from PR

* -addressed PR comments

* -addressed final PR comments

* -updated changelog

* -adding descriptive comments for the displayName in the Provider's examples

* -small lexical change
  • Loading branch information
mnajdova authored Nov 26, 2018
1 parent 53da689 commit d33711e
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Fix the behaviour of `AutoControlledComponent` when `undefined` is passed as a prop value @layershifter ([#499](https://github.com/stardust-ui/react/pull/499))
- Stop event propagation when press Escape on the popup @sophieH29 ([#515](https://github.com/stardust-ui/react/pull/515))

### Documentation
- Add `Integrate Custom Components` guide page in the docs @mnajdova ([#517](https://github.com/stardust-ui/react/pull/517))

<!--------------------------------[ v0.12.0 ]------------------------------- -->
## [v0.12.0](https://github.com/stardust-ui/react/tree/v0.12.0) (2018-11-19)
[Compare changes](https://github.com/stardust-ui/react/compare/v0.11.0...v0.12.0)
Expand Down
8 changes: 8 additions & 0 deletions docs/src/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,14 @@ class Sidebar extends React.Component<any, any> {
<Menu.Item as={NavLink} exact to="/theming-examples" activeClassName="active">
Theming Examples
</Menu.Item>
<Menu.Item
as={NavLink}
exact
to="/integrate-custom-components"
activeClassName="active"
>
Integrate Custom Components
</Menu.Item>
</Menu.Menu>
</Menu.Item>
{process.env.NODE_ENV !== 'production' && (
Expand Down
6 changes: 6 additions & 0 deletions docs/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import PageNotFound from './views/PageNotFound'
import QuickStart from './views/QuickStart'
import Theming from './views/Theming'
import ThemingExamples from './views/ThemingExamples'
import IntegrateCustomComponents from './views/IntegrateCustomComponents'

const Router = () => (
<BrowserRouter basename={__BASENAME__}>
Expand Down Expand Up @@ -62,6 +63,11 @@ const Router = () => (
<DocsLayout exact path="/theming" component={Theming} />
<DocsLayout exact path="/theming-examples" component={ThemingExamples} />
<DocsLayout exact path="/shorthand-props" component={ShorthandProps} />
<DocsLayout
exact
path="/integrate-custom-components"
component={IntegrateCustomComponents}
/>
<DocsLayout exact path="/*" component={PageNotFound} />
</Switch>
</Switch>
Expand Down
274 changes: 274 additions & 0 deletions docs/src/views/IntegrateCustomComponents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
import * as React from 'react'
import * as cx from 'classnames'
import { NavLink } from 'react-router-dom'
import { Header } from 'semantic-ui-react'
import {
Button,
Divider,
Provider,
createComponent,
ComponentSlotStyle,
ComponentVariablesInput,
} from '@stardust-ui/react'

import DocPage from '../components/DocPage/DocPage'
import ExampleSnippet from '../components/ExampleSnippet/ExampleSnippet'
import { ReactChildren } from '../../../types/utils'

interface StyledButtonProps {
className?: string
styles?: ComponentSlotStyle
variables?: ComponentVariablesInput
children?: ReactChildren
}

const StyledButton: React.SFC<StyledButtonProps> = createComponent<StyledButtonProps>({
displayName: 'StyledButton',
render({ stardust, className, children }) {
const { classes } = stardust
return <button className={cx(className, classes.root)}>{children}</button>
},
})

export default () => (
<DocPage title="Integrate Custom Components">
<Header as="h2" content="Overview" />
<p>
You can use your own components as part of the Stardust's styling and theming mechanisms. In
order for all theming aspects to be available to your custom components, you should use the{' '}
<code>createComponent</code> function, provided by the Stardust library.
</p>
<Header as="h2" content="Create custom component" />
<p>
Let's take a look into one simple example of using the <code>createComponent</code> function
for adapting your custom component to the Stardust's styling and theming mechanisms.
</p>
<ExampleSnippet
value={[
`import { createComponent } from '@stardust-ui/react'`,
``,
`const StyledButton = createComponent({`,
` displayName: 'StyledButton',`,
` render: ({stardust, className, children}) => {`,
` const { classes } = stardust`,
` return <button className={cx(className, classes.root)}>{children}</button>`,
` }`,
`})`,
].join('\n')}
/>
<p>
Let's go step by step throughout all bits of the <code>createComponent</code> method.
</p>
<p>
The first argument to the <code>createComponent</code> config's param is the is the{' '}
<code>displayName</code>, which value might be used as key to define component's styles and
variables in theme, exactly the same way how it might be done for any first-class Stardust
component.
</p>
<ExampleSnippet
value={[
`<Provider`,
` theme={{`,
` componentVariables: {`,
` StyledButton: {`,
` color: '#F2F2F2',`,
` },`,
` },`,
` componentStyles: {`,
` StyledButton: {`,
` root: ({ props, variables, theme: {siteVariables} }) => ({`,
` backgroundColor: siteVariables.brand,`,
` color: variables.color,`,
` }),`,
` },`,
` },`,
` }}`,
`>`,
` <StyledButton> Provider styled button </StyledButton>`,
'</Provider>',
].join('\n')}
render={() => (
<Provider
theme={{
componentVariables: {
StyledButton: {
color: '#F2F2F2',
},
},
componentStyles: {
StyledButton: {
root: ({ props, variables, theme: { siteVariables } }) => ({
backgroundColor: siteVariables.brand,
color: (variables as any).color,
}),
},
},
}}
>
<StyledButton>Provider styled button</StyledButton>
</Provider>
)}
/>
<p>
The second argument of the <code>createComponent</code> config param is the{' '}
<code>render</code> method. This is the place where where you might link Stardust bits with
your custom component - e.g. by simply passing them as props. This <code>render</code> method
will be invoked with the following parameters:
</p>
<ul>
<li>
<code>stardust</code> - the object containing the evaluated theming props (<code>
classes
</code>
and <code>rtl</code>).
</li>
<li>
<code>...props</code> - all <code>user props</code>.
</li>
</ul>
<Header as="h2" content="Using the custom components" />
<p>
We already saw how the <code>Provider</code> can define some stylings and variables for the
custom components. Next, we will take a look into several examples of how the user can further
customize styles and variables of these components, the same way they would do with the
Stardust components.
</p>
<Header
as="h3"
content={
<>
Example 1. Using <code>styles</code> property
</>
}
/>
<ExampleSnippet
value={[
`<StyledButton styles={{':hover': {backgroundColor: "yellow"}}>`,
` Inline styled button`,
`</StyledButton>`,
].join('\n')}
render={() => (
<StyledButton styles={{ ':hover': { backgroundColor: 'yellow' } }}>
Inline styled button
</StyledButton>
)}
/>
The same can be achieved with adding styles in the <code>componentStyles</code> part of the{' '}
<code>theme</code> in the <code>Provider</code>.
<ExampleSnippet
value={[
`<Provider`,
` theme={{`,
` // component's displayName arg is used as a selector`,
` componentStyles: {`,
` StyledButton: {`,
` root: () => ({`,
` ':hover': {`,
` backgroundColor: "yellow"`,
` }`,
` }),`,
` },`,
` },`,
` }}`,
`>`,
` <StyledButton>Inline styled button</StyledButton>`,
'</Provider>',
].join('\n')}
/>
<p>
For more advanced theming scenarios, please take a look in the <b>Styles</b> section on the{' '}
<NavLink to="theming">Theming guide</NavLink>.
</p>
<Header
as="h3"
content={
<>
Example 2. Using <code>variables</code> property
</>
}
/>
Let's consider that the following <code>theme</code> was passed to the <code>Provider</code>.
<ExampleSnippet
value={[
`<Provider`,
` theme={{`,
` // other theme parts`,
` componentStyles: {`,
` StyledButton: {`,
` root: ({ variables }) => ({`,
` color: variables.color,`,
` }),`,
` },`,
` },`,
` }}`,
`>`,
` ...`,
'</Provider>',
].join('\n')}
/>
Then we can use the <code>variables</code> prop for changing the color inside the{' '}
<code>StyledButton</code>.
<ExampleSnippet
value={[
`<StyledButton variables={{color: "red" }}>`,
` Inline styled button`,
`</StyledButton>`,
].join('\n')}
render={() => (
<Provider
theme={{
componentStyles: {
StyledButton: {
root: ({ variables }) => ({
color: (variables as any).color,
}),
},
},
}}
>
<StyledButton variables={{ color: 'red' }}>Inline styled button</StyledButton>
</Provider>
)}
/>
The alternative approach with defining <code>componentVariables</code> inside the{' '}
<code>theme</code> would like like this:
<ExampleSnippet
value={[
`<Provider`,
` theme={{`,
` // component's displayName arg is used as a selector`,
` componentVariables: {`,
` StyledButton: {`,
` color: "red"`,
` },`,
` }`,
` componentStyles: {`,
` StyledButton: {`,
` root: ({ variables }) => ({`,
` color: variables.color,`,
` }),`,
` },`,
` },`,
` }}`,
`>`,
` ...`,
'</Provider>',
].join('\n')}
/>
<p>
For more advanced theming scenarios, please take a look in the <b>Variables</b> section on the{' '}
<NavLink to="theming">Theming guide</NavLink>.
</p>
<br />
<Divider size={1} />
<br />
<Button
as={NavLink}
content="Theming Examples"
icon="arrow left"
iconPosition="before"
primary
to="/theming-examples"
/>
</DocPage>
)
10 changes: 10 additions & 0 deletions docs/src/views/ThemingExamples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Button, Divider, Icon, Label, Provider } from '@stardust-ui/react'

import DocPage from '../components/DocPage/DocPage'
import ExampleSnippet from '../components/ExampleSnippet/ExampleSnippet'
import { pxToRem } from '../../../src/lib'

export default () => (
<DocPage title="Theming Examples">
Expand Down Expand Up @@ -409,5 +410,14 @@ export default () => (
primary
to="theming"
/>
<Button
as={NavLink}
content="Integrate Custom Components"
icon="arrow right"
iconPosition="after"
primary
to="integrate-custom-components"
variables={{ maxWidth: pxToRem(300) }}
/>
</DocPage>
)

0 comments on commit d33711e

Please sign in to comment.