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

feat: support theming and styling #16

Merged
merged 25 commits into from
Aug 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
06ae6d9
move rules and vars to themes, add typings
levithomason Aug 3, 2018
a9bbbac
wip
levithomason Aug 3, 2018
9328b1b
test: add mergeTheme tests
levithomason Aug 4, 2018
af4ed15
merge master, resolve conflicts, fix tests
levithomason Aug 6, 2018
28a0270
fix: mv listVariables to listItemVariables
levithomason Aug 6, 2018
4b299a2
fix lint error, add changelog entry
levithomason Aug 6, 2018
e136132
docs: restore default imports in doc examples
levithomason Aug 6, 2018
37d1d5a
docs: cleanup cruft component-anatomy page
levithomason Aug 6, 2018
e837319
fix: Provier theme propTypes
levithomason Aug 6, 2018
bd201af
refactor: use toCompactArray where possible
levithomason Aug 6, 2018
6b788f0
refactor: renderComponentStyles to getClasses
levithomason Aug 6, 2018
b408da7
add todo for avatar icon work
levithomason Aug 7, 2018
5bd4b47
merge master, fix conflicts
levithomason Aug 9, 2018
49f2bf6
merge master
levithomason Aug 9, 2018
9c008a0
merge master
levithomason Aug 9, 2018
2820a5f
revert minor changes
levithomason Aug 9, 2018
d3bfe32
rename getClasses
levithomason Aug 9, 2018
d24d07d
rename getClasses with git mv
levithomason Aug 9, 2018
0fdb27e
merge master
levithomason Aug 9, 2018
6143126
uncomment icon styles
levithomason Aug 9, 2018
812392f
refactor: avatar styles, fix export name
levithomason Aug 9, 2018
48c5b96
refactor: add perf link to callable
levithomason Aug 9, 2018
c325f95
feat: expose resolved variables/styles in renderComponent
levithomason Aug 9, 2018
7218855
merge master
levithomason Aug 9, 2018
f12091f
feat: pass resolved variables and styles to components
levithomason Aug 9, 2018
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add `fluid` variant and size variables to Image @kuzhelov ([#54](https://github.com/stardust-ui/react/pull/54))
- Add SVG icons support @kuzhelov ([#50](https://github.com/stardust-ui/react/pull/50))
- Add `fluid` prop and variation and width variables to Input @alinais ([#59](https://github.com/stardust-ui/react/pull/59))

- Support `styles` prop and nested theme Providers @levithomason ([#16](https://github.com/stardust-ui/react/pull/16))

<!--------------------------------[ v0.2.5 ]------------------------------- -->
## [v0.2.5](https://github.com/stardust-ui/react/tree/v0.2.5) (2018-08-03)
[Compare changes](https://github.com/stardust-ui/react/compare/v0.2.4...v0.2.5)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ import {
knobsContext,
repoURL,
scrollToAnchor,
variablesContext,
} from 'docs/src/utils'
import evalTypeScript from 'docs/src/utils/evalTypeScript'
import { pxToRem, doesNodeContainClick } from 'src/lib'
import { callable, doesNodeContainClick, mergeThemes, pxToRem } from 'src/lib'
import Editor from 'docs/src/components/Editor'
import ComponentControls from '../ComponentControls'
import ComponentExampleTitle from './ComponentExampleTitle'
import ContributionPrompt from '../ContributionPrompt'
import getSourceCodeManager, { ISourceCodeManager, SourceCodeType } from './SourceCodeManager'
import { IThemeInput, IThemePrepared } from 'types/theme'
import { theme as teamsTheme } from '../../../../../src/themes/teams'

export interface IComponentExampleProps extends RouteComponentProps<any, any> {
title: string
Expand All @@ -33,19 +34,19 @@ export interface IComponentExampleProps extends RouteComponentProps<any, any> {

interface IComponentExampleState {
knobs: Object
componentVariables: { [key: string]: Object }
exampleElement: JSX.Element
handleMouseLeave: () => void
handleMouseMove: () => void
sourceCode: string
markup: string
error: string
showCode: boolean
showHTML: boolean
showRtl: boolean
showVariables: boolean
isHovering: boolean
copiedCode: boolean
theme: IThemeInput
exampleElement?: JSX.Element
handleMouseLeave?: () => void
handleMouseMove?: () => void
sourceCode?: string
markup?: string
error?: string
showCode?: boolean
showHTML?: boolean
showRtl?: boolean
showVariables?: boolean
isHovering?: boolean
copiedCode?: boolean
}

const EDITOR_BACKGROUND_COLOR = '#1D1F21'
Expand All @@ -61,17 +62,6 @@ const codeTypeApiButtonLabels: { [key in SourceCodeType]: string } = {
shorthand: 'Shorthand API',
}

const variablesPanelStyle = {
display: 'flex',
flexWrap: 'wrap',
maxHeight: pxToRem(250),
overflowY: 'auto',
}

const variableInputStyle = {
paddingBottom: pxToRem(10),
}

/**
* Renders a `component` and the raw `code` that produced it.
* Allows toggling the the raw `code` code block.
Expand All @@ -83,7 +73,10 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp
private kebabExamplePath: string
private KnobsComponent: any

public state = { knobs: {} } as IComponentExampleState
public state: IComponentExampleState = {
knobs: {},
theme: teamsTheme,
}

public static contextTypes = {
onPassed: PropTypes.func,
Expand Down Expand Up @@ -349,8 +342,15 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp
private getDisplayName = () => this.props.examplePath.split('/')[1]

private renderWithProvider(ExampleComponent) {
const { showRtl, theme } = this.state

const newTheme: IThemeInput = {
componentVariables: theme.componentVariables,
rtl: showRtl,
}

return (
<Provider componentVariables={this.state.componentVariables} rtl={this.state.showRtl}>
<Provider theme={mergeThemes(teamsTheme, newTheme)}>
<ExampleComponent knobs={this.getKnobsValue()} />
</Provider>
)
Expand Down Expand Up @@ -534,34 +534,36 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp
<span style={{ opacity: 0.5 }}>Theme</span>
</Divider>
<Provider.Consumer
render={({ siteVariables }) => {
const variablesFilename = `./${displayName}/${_.camelCase(displayName)}Variables.ts`
const hasVariablesFile = _.includes(variablesContext.keys(), variablesFilename)
render={({ siteVariables, componentVariables }: IThemePrepared) => {
const variables = componentVariables[displayName]

if (!hasVariablesFile) {
if (!variables) {
return (
<Segment size="small" inverted padded basic>
This component has no variables to edit.
{displayName} has no variables to edit.
</Segment>
)
}

const variables = variablesContext(variablesFilename).default
const defaultVariables = variables(siteVariables)
const variablesObject = callable(variables)(siteVariables)

return (
<Form inverted style={{ padding: '1rem' }}>
<Form.Group inline style={variablesPanelStyle}>
{_.map(defaultVariables, (val, key) => (
<Form.Input
style={variableInputStyle}
key={key}
label={key}
defaultValue={val}
onChange={this.handleVariableChange(displayName, key)}
/>
))}
</Form.Group>
<Form inverted widths="equal" style={{ padding: '1rem' }}>
{_.chunk(_.toPairs(variablesObject), 2).map(fields => {
return (
<Form.Group widths="equal" key={fields.map(([key]) => key).join('-')}>
{fields.map(([key, val]) => (
<Form.Input
fluid
key={key}
label={key}
defaultValue={val}
onChange={this.handleVariableChange(displayName, key)}
/>
))}
</Form.Group>
)
})}
</Form>
)
}}
Expand All @@ -573,11 +575,14 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp
private handleVariableChange = (component, variable) => (e, { value }) => {
this.setState(
state => ({
componentVariables: {
...state.componentVariables,
[component]: {
...(state.componentVariables && state.componentVariables[component]),
[variable]: value,
theme: {
...state.theme,
componentVariables: {
...state.theme.componentVariables,
[component]: {
...(state.theme.componentVariables && state.theme.componentVariables[component]),
[variable]: value,
},
},
},
}),
Expand Down
4 changes: 2 additions & 2 deletions docs/src/components/IconSearch/IconSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as _ from 'lodash/fp'
import leven from 'leven'
import * as React from 'react'

import { SUI } from 'src/lib'
import { SUI, toCompactArray } from 'src/lib'
import { Form, Grid, Header, Icon, Message, Popup } from 'semantic-ui-react'

const gridStyle = {
Expand Down Expand Up @@ -107,7 +107,7 @@ export default class IconSearch extends React.Component<any, any> {

renderIconColumn = (name, section?: string) => (
<Popup
key={[name, section].filter(Boolean).join('_')}
key={toCompactArray(name, section).join('_')}
mouseEnterDelay={1000}
inverted
closeOnTriggerClick={false}
Expand Down
40 changes: 2 additions & 38 deletions docs/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'

// TODO make themes a monorepo of packages
import { siteVariables, normalizeCSS } from 'src/themes/teams'
import { fontFaces, staticStyles, theme } from 'src/themes/teams'
import { Provider } from '@stardust-ui/react'

import Router from './routes'
Expand All @@ -15,46 +15,10 @@ import Router from './routes'
const mountNode = document.createElement('div')
document.body.appendChild(mountNode)

const globalRules = siteVars => ({
html: {
fontSize: siteVars.htmlFontSize,
},
body: {
padding: siteVars.bodyPadding,
margin: siteVars.bodyMargin,
fontFamily: siteVars.bodyFontFamily,
fontSize: siteVars.bodyFontSize,
lineHeight: siteVars.lineHeightBase,
},
})

// TODO: formalize fonts into siteVariables/theme contract. Leaving hard coded for now.
const fontFaces = [
{
name: 'Segoe UI',
paths: ['public/fonts/segoe-ui-regular.woff2'],
style: { fontWeight: 400 },
},
{
name: 'Segoe UI',
paths: ['public/fonts/segoe-ui-semibold.woff2'],
style: { fontWeight: 600 },
},
{
name: 'Segoe UI',
paths: ['public/fonts/segoe-ui-bold.woff2'],
style: { fontWeight: 700 },
},
]

const render = NewApp =>
ReactDOM.render(
<AppContainer>
<Provider
siteVariables={siteVariables}
staticStyles={[normalizeCSS, globalRules]}
fontFaces={fontFaces}
>
<Provider theme={theme} staticStyles={staticStyles} fontFaces={fontFaces}>
<NewApp />
</Provider>
</AppContainer>,
Expand Down
1 change: 0 additions & 1 deletion docs/src/utils/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ export { default as getFormattedHash } from './getFormattedHash'
export { default as getInfoForSeeTags } from './getInfoForSeeTags'
export { default as knobsContext } from './knobsContext'
export { default as parseExamplePath } from './parseExamplePath'
export { default as variablesContext } from './variablesContext'
export { default as scrollToAnchor } from './scrollToAnchor'
6 changes: 0 additions & 6 deletions docs/src/utils/variablesContext.ts

This file was deleted.

4 changes: 2 additions & 2 deletions specifications/creating-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const Image = (props) => {
}

export default createComponent(Image, {
rules: imageStyles,
styles: imageStyles,
variables: imageVariables,
})
```
Expand All @@ -73,7 +73,7 @@ class Image extends React.Component {
handledProps={[ ... ]}
state={StateMachine}
props={this.props}
rules={...}
styles={...}
variables={...}
render={({ ElementType, rest, classes }) => (
<ElementType {...rest} className={classes.root} />
Expand Down
3 changes: 0 additions & 3 deletions src/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as PropTypes from 'prop-types'
import * as React from 'react'

import { AutoControlledComponent, customPropTypes, childrenExist } from '../../lib'
import accordionStyles from '../../themes/teams/components/Accordion/accordionStyles'
import AccordionTitle from './AccordionTitle'
import AccordionContent from './AccordionContent'
import { DefaultBehavior } from '../../lib/accessibility'
Expand Down Expand Up @@ -66,8 +65,6 @@ class Accordion extends AutoControlledComponent<any, any> {
accessibility: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
}

static styles = accordionStyles

static handledProps = [
'accessibility',
'activeIndex',
Expand Down
6 changes: 0 additions & 6 deletions src/components/Accordion/AccordionContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import * as PropTypes from 'prop-types'
import * as React from 'react'

import { childrenExist, createShorthandFactory, customPropTypes, UIComponent } from '../../lib'
import accordionContentStyles from '../../themes/teams/components/Accordion/accordionContentStyles'
import accordionContentVariables from '../../themes/teams/components/Accordion/accordionContentVariables'

/**
* A standard AccordionContent.
Expand Down Expand Up @@ -42,10 +40,6 @@ class AccordionContent extends UIComponent<any, any> {

static handledProps = ['as', 'active', 'children', 'className', 'content', 'onClick']

static styles = accordionContentStyles

static variables = accordionContentVariables

renderComponent({ ElementType, classes, rest }) {
const { children, content } = this.props

Expand Down
3 changes: 0 additions & 3 deletions src/components/Accordion/AccordionTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as PropTypes from 'prop-types'
import * as React from 'react'

import { childrenExist, createShorthandFactory, customPropTypes, UIComponent } from '../../lib'
import accordionTitleStyles from '../../themes/teams/components/Accordion/accordionTitleStyles'

/**
* A standard AccordionTitle.
Expand Down Expand Up @@ -45,8 +44,6 @@ class AccordionTitle extends UIComponent<any, any> {

static handledProps = ['as', 'active', 'children', 'className', 'content', 'index', 'onClick']

static styles = accordionTitleStyles

handleClick = e => {
_.invoke(this.props, 'onClick', e, this.props)
}
Expand Down
6 changes: 0 additions & 6 deletions src/components/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import * as React from 'react'
import { Image, Label, Icon } from '../../'

import { customPropTypes, UIComponent } from '../../lib'
import avatarStyles from '../../themes/teams/components/Avatar/avatarStyles'
import avatarVariables from '../../themes/teams/components/Avatar/avatarVariables'

/**
* An avatar is a graphic representation of user alongside with a presence icon.
Expand All @@ -18,10 +16,6 @@ class Avatar extends UIComponent<any, any> {

static handledProps = ['alt', 'as', 'className', 'getInitials', 'name', 'size', 'src', 'status']

static styles = avatarStyles

static variables = avatarVariables

static propTypes = {
/** The alternative text for the image used in the Avatar. */
alt: PropTypes.string,
Expand Down
6 changes: 0 additions & 6 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import * as PropTypes from 'prop-types'
import * as React from 'react'

import { UIComponent, childrenExist, customPropTypes } from '../../lib'
import buttonStyles from '../../themes/teams/components/Button/buttonStyles'
import buttonVariables from '../../themes/teams/components/Button/buttonVariables'
import Icon from '../Icon'
import Text from '../Text'
import { ButtonBehavior } from '../../lib/accessibility'
Expand All @@ -18,10 +16,6 @@ class Button extends UIComponent<any, any> {

public static className = 'ui-button'

public static styles = buttonStyles

public static variables = buttonVariables

public static propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,
Expand Down
Loading