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

docs(custom-components): adding initial guide for creating custom components#517

Merged
mnajdova merged 12 commits intomasterfrom
docs/custom-components
Nov 26, 2018
Merged

docs(custom-components): adding initial guide for creating custom components#517
mnajdova merged 12 commits intomasterfrom
docs/custom-components

Conversation

@mnajdova
Copy link
Contributor

@mnajdova mnajdova commented Nov 22, 2018

This PR adds guide for how the custom components can be created using the renderComponent functionality in Stardust.
To do

  • update the changelog

@codecov
Copy link

codecov bot commented Nov 22, 2018

Codecov Report

Merging #517 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #517   +/-   ##
=======================================
  Coverage   88.17%   88.17%           
=======================================
  Files          42       42           
  Lines        1455     1455           
  Branches      212      187   -25     
=======================================
  Hits         1283     1283           
  Misses        167      167           
  Partials        5        5

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 53da689...688a80d. Read the comment docs.

].join('\n')}
/>

<p>Let's go step by step throughout all bits from the renderComponent method.</p>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renderComponent -> createComponent
I also changed this in the CHANGELOG.md file that seems to mention renderComponent as well
https://github.com/stardust-ui/react/pull/518/files#r235773446

const componentProps = _.pick(props, 'children')
return <button className={cx(props.className, classes.root)} {...componentProps} />
},
})
Copy link
Member

@layershifter layershifter Nov 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we should omit the usage of lodash in such basic examples:

const StyledButton: React.SFC<StyledButtonProps> = createComponent<StyledButtonProps, {}>({
  displayName: 'StyledButton',
  render({ className, stardust, ...props }) {
    const { classes } = stardust

    return <button {...rest} className={cx(className, classes.root)} />
  },
})

As I see, my code does the same thing or no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are applying in this case the styles and variables to the button, but I get your point, will change it not to use lodash.

Copy link
Contributor Author

@mnajdova mnajdova Nov 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this?

const StyledButton: React.SFC<StyledButtonProps> = createComponent<StyledButtonProps, {}>({
  displayName: 'StyledButton',
  render({ stardust, className, children }) {
    const { classes } = stardust
    const componentProps = { children }

    return <button className={cx(className, classes.root)} {...componentProps} />
  },
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-return <button className={cx(className, classes.root)} {...componentProps} />
+return <button className={cx(className, classes.root)}>{children}</button>

👍

})

export default () => (
<DocPage title="Custom Components">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe something like "Integrate Custom Components" - because currently this is not absolutely clear from header whether we are suggesting to develop custom components or integrate existing ones

<DocPage title="Custom Components">
<Header as="h2" content="Overview" />
<p>
You can use your own components as part of the Stardust's theming mechanism. In order for all
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'styling and theming'

value={[
`import { createComponent } from '@stardust-ui/react'`,
``,
`export interface StyledButtonProps {`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to remove TS from this example - main reason is that it introduces quite a lot of 'noise', and additional one (and the one that applies to broader community) is that our docs should be readable for folks that have no prior knowledge of TS

</p>

<p>
The first argument to the <code>createComponent</code> config's param is the displayName. This
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would suggest to also wrap displayName and Provider in <code/>


<p>
The first argument to the <code>createComponent</code> config's param is the displayName. This
name is very important, because that's the key that will be used in the Provider's theme if
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could simplify this sentence a bit:

is the displayName, 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.

I think that this will provide enough thrill to the reader, so one will fully understand the importance of this prop ;)

`<Provider`,
` theme={{`,
` componentStyles: {`,
` StyledButton: {`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would suggest to swap variables and styles sections, as the later one uses data defined in former.

/>

<p>
The second argument of the <code>createComponent</code> config param is the render method.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets wrap render in <code> as well


<p>
The second argument of the <code>createComponent</code> config param is the render method.
This is the place where you link the Stardust bits with your custom component. This method is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit-nit:

... where you might link Stardust bits with your custom component - e.g. by simply passing them as props. This render method will be invoked with the following parameters:

</p>
<ul>
<li>
<code>stardust</code> - this is the object containing the evaluated theming props (classes
Copy link
Contributor

@kuzhelov kuzhelov Nov 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: 'this is' is not necessary, can be safely omitted.

classes and rtl should be wrapped in <code />

</p>
<ul>
<li>
<code>stardust</code> - this is the object containing the evaluated theming props (classes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets end each item's text with dot

</li>
</ul>
<p>
The previous implementation of the render method inside the <code>createComponent</code>{' '}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, not sure that can completely understand what this paragraph is about - why previous and, also, it seems that there are too many commas there

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph is not really necessary as we already covered all important bits in the paragraph before the list items :)


<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 few examples of how the user can further
Copy link
Contributor

@kuzhelov kuzhelov Nov 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'few' -> 'several/couple' (as 'few' has rather 'not enough' semantics :)

<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 few examples of how the user can further
customize the styling and variables of the custom components, the same way they would do with
Copy link
Contributor

@kuzhelov kuzhelov Nov 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe simplified:
customize the styling and variables -> customize styles and variables of these components

the Stardust components.
</p>

<Header as="h3" content="Example 1. Using the variables property" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would omit the and use <code>:

<Header as="h3" content={<>Example 1. Using <code>variables</code> property</>} />

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, would rather expect to see section devoted to styles prop first, as this is a first thing customer would learn about Stardust - with variables being rather more advanced concept

render={() => (
<Provider
theme={{
componentStyles: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here - would suggest to swap places of componentVariables and componentStyles sections

)}
/>

<Header as="h3" content="Example 2. Using the styles property" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just 'using styles property' should be enough


<ExampleSnippet
value={[
`<StyledButton styles={({theme: {siteVariables}}) => ({backgroundColor: siteVariables.black})}>`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather strive for simplifying examples as much as possible. We should just show that it is possible to use styles prop, as well as suggest the fact that it could be used the same way as for Stardust components. Then I see us providing simple example that might prove that, and after this example make a sentence that all other advanced scenarios are supported as well, please, take a look on the corresponding docs.

This will allow us

  • to simplify example's code (crucially important thing)
  • not introduce additional maintainability burden to us - say, in case if implementation of styles prop change, we won't need to fix this example's code


<ExampleSnippet
value={[
`<StyledButton variables={(siteVars) => ({color: siteVars.black})}>`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets try to simplify it a bit - while I do understand that this example is aimed to cover all things that are possible to do with this prop being introduced, at the same time, while being in the client's shoes, I would rather expect something pretty simple that would just deliver necessary idea to me. Otherwise, just imagine that I am not yet familiar with siteVariables and what the beast it is - should I learn that or, maybe, it is fine for me to use variables without this knowledge? I would say that the later is just fine

@mnajdova
Copy link
Contributor Author

@kuzhelov thanks much for the review! All comments resolved :)

import * as React from 'react'
import * as cx from 'classnames'
import { NavLink } from 'react-router-dom'
import { Header } from 'semantic-ui-react'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we can use own Header component there 😃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching the theme to dark will make the Header component white, and we don't have the other themes implemented for all page (like making the background dark in dark-mode). I would not like to introduce unnecessary providers just for handling things like that. In all docs pages, the Headers are from semantic-ui, so when the dark mode will be implemented for all page, we can safely replace them all in one iteration.

className?: string
styles?: ComponentSlotStyle
variables?: ComponentVariablesInput
children?: React.ReactNodeArray | React.ReactNode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have own type for this, ReactChildren

children?: React.ReactNodeArray | React.ReactNode
}

const StyledButton: React.SFC<StyledButtonProps> = createComponent<StyledButtonProps, {}>({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The state is optional.

Suggested change
const StyledButton: React.SFC<StyledButtonProps> = createComponent<StyledButtonProps, {}>({
const StyledButton: React.SFC<StyledButtonProps> = createComponent<StyledButtonProps>({

` StyledButton: {`,
` root: ({ props, variables, theme: {siteVariables} }) => ({`,
` backgroundColor: siteVariables.brand,`,
` color: (variables as any).color,`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
` color: (variables as any).color,`,
` color: variables.color,`,

Can we omit any this in example's code?

StyledButton: {
root: ({ props, variables, theme: { siteVariables } }) => ({
backgroundColor: siteVariables.brand,
color: (variables as any).color,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same thing, ^

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot omit it here, but it is removed from the string displayed as a code in the docs page.

/>

<p>
Let's go step by step throughout all bits from the <code>createComponent</code> method.
Copy link
Contributor

@kuzhelov kuzhelov Nov 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: '.. from the createComponent ..' => '... of the createComponent ...'

and <code>rtl</code>).
</li>
<li>
<code>...props</code> - all other props provided by the user.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe user props would be enough


<ExampleSnippet
value={[
`<StyledButton variables={{color: "black" }}>`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to be sure - could you, please, suggest where is the code that suggests to the user where this variable is used (i.e. styles code)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added paragraph with Provider and example componentStyles that would be applied.

/>

<p>
All other advanced scenarios for applying styles and variables are supported as well. For more
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would suggest to write it this way:

  • for each example (Styles and Variables) introduce the concluding paragraph that would tell the following (essentially, the though expressed in this paragraph: 'Note that all other scenarios for applying styles/variables are supported as well - please, take a look on the corresponding ... section for more details.')

  • introduce additional example where theming support will be mentioned (primitive example is necessary):

const customTheme = {
  // component's displayName arg is used as a selector
  StyledButton: {
   ...
  }
}

<Provider theme={customTheme}>
  <StyledButton>
</Provider>
  • and, the same way, conclude with a similar paragraph saying 'for more advanced theming scenarios, please, take a look on the corresponding Theming section'

@mnajdova mnajdova merged commit d33711e into master Nov 26, 2018
@layershifter layershifter deleted the docs/custom-components branch January 10, 2019 11:26
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants