|
| 1 | +--- |
| 2 | +title: Themed components |
| 3 | +category: Contributor Guides |
| 4 | +order: 10 |
| 5 | +--- |
| 6 | + |
| 7 | +## Making InstUI-like components with theming |
| 8 | + |
| 9 | +InstUI uses [Emotion](https://emotion.sh/docs/introduction) under the hood to theme and style its components. |
| 10 | +If you want to read about the design behind the system and how to build `class-based` components with InstUI, please read [this](https://instructure.design/#emotion) |
| 11 | + |
| 12 | +This page will show you how to build `functional` react components with InstUI |
| 13 | + |
| 14 | +### Anatomy of a functional InstUI component |
| 15 | + |
| 16 | +To make similar and similarly maintainable components to InstUI, you should to follow a basic structure. This is not strictly necessary but recommended and this guide will assume you do use it. |
| 17 | + |
| 18 | +A fully equipped InstUI component has three files: `index.tsx`, `style.ts`, `theme.ts` and uses the `useStyles` hook. |
| 19 | + |
| 20 | +Let's take a look at the simplest example possible: |
| 21 | + |
| 22 | +```html |
| 23 | +--- |
| 24 | +type: code |
| 25 | +--- |
| 26 | + |
| 27 | +// index.tsx /** @jsx jsx */ import { jsx, useStyle } from |
| 28 | +'@instructure/emotion' import generateStyle from './styles' import |
| 29 | +generateComponentTheme from './theme' const InstUIComponent = (props:PropsType) |
| 30 | +=> { const styles = useStyle({ generateStyle, generateComponentTheme, params: |
| 31 | +{color:props.color, variant:props.variant}, componentId: "InstUIComponent_id" // |
| 32 | +any unique id }) return ( |
| 33 | +<div css="{styles?.root}">content</div> |
| 34 | +) } export default InstUIComponent |
| 35 | +``` |
| 36 | + |
| 37 | +```html |
| 38 | +--- |
| 39 | +type: code |
| 40 | +--- |
| 41 | + |
| 42 | +// style.ts const generateStyle = ( componentTheme: componentThemeType, params: |
| 43 | +ParamType ): AvatarStyle => { const { color, variant } = params // assuming you |
| 44 | +passed the `color` and `variant` to the useStyle hook const variantStyles = { |
| 45 | +circle: { width: '2.5em', position: 'relative', borderRadius: '100%', overflow: |
| 46 | +'hidden' }, rectangle: { width: '3em' } } const colorVariants = { default: |
| 47 | +componentTheme.defaultColor, green: componentTheme.niceGreenColor, |
| 48 | +nonThemedColor: "pink" } return { instUIComponent: { //for the root element's |
| 49 | +style label: 'instUIComponent', color: colorVariants[color], backgroundColor: |
| 50 | +componentTheme.bgColor, ...variantStyles[variant], } aChildElement: { label: |
| 51 | +'instUIComponent_aChildElement', // this label is needed. Please prefix it with |
| 52 | +the root label fontWeight: "400" //you can hardcode values. Don't need to get |
| 53 | +them from the team necessarily . } } export default generateStyle |
| 54 | +``` |
| 55 | + |
| 56 | +```html |
| 57 | +--- |
| 58 | +type: code |
| 59 | +--- |
| 60 | + |
| 61 | +// theme.ts import type { Theme } from '@instructure/ui-themes' const |
| 62 | +generateComponentTheme = (theme: Theme) => { const { colors } = theme // the |
| 63 | +theme you are using. See instUI's theme docs as well const componentVariables = |
| 64 | +{ defaultColor: colors?.contrasts?.white1010, niceGreenColor: |
| 65 | +colors.contrasts.green4570, bgColor:"purple" //this is hardcoded, but added to |
| 66 | +the theme, so it can be overridden } return { ...componentVariables } } export |
| 67 | +default generateComponentTheme |
| 68 | +``` |
| 69 | + |
| 70 | +Let's take a look at the key parts of the above example: |
| 71 | + |
| 72 | +The `useStyle` hook calculates the styles for the component. It needs an object with: |
| 73 | + |
| 74 | +- `generateStyle` function, this function contains all the `css` information (`style.ts` file in the example). |
| 75 | +- `componentId`. This must be a unique string to identify the component by. It is used for [component level overrides](https://instructure.design/#using-theme-overrides/#Overriding%20theme%20for%20a%20specific%20component%20in%20a%20subtree) |
| 76 | +- `generateComponentTheme` is an optional param. This provides themed |
0 commit comments