![require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages](https://cdn.sanity.io/images/cgdhsj6q/production/be8ab80c8efa5907bc341c6fefe9aa20d239d890-1600x1097.png?w=400&fit=max&auto=format)
Security News
require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
@instructure/ui-themeable
Advanced tools
The ui-themeable library is meant to be used along with a babel plugin to import CSS styles and generate theme variables. With this framework, each UI component can be used in isolation and support multiple themes, including dynamic themes provided at runtime, while still working within a system of components that use a shared global theme.
Two-tiered theme variable system: system-wide variables + component level variables. With this variable system, components can be themed, tested, and rendered in isolation from the rest of the system, and we can mitigate issues that may arise with system-wide theme updates.
Runtime theme application and definition: to apply user/account level themes without using the CSS cascade.
Prevent CSS Cascade bugs: All components should specify variants via props or component level theme variables only (no className or style overrides) with a clear API and should not rely on any external styles.
Theme variables should be accessible in both JS and CSS.
All component styles and variables should scoped to the component.
Pre-render/server-side render support (inline critical CSS).
yarn add @instructure/ui-themeable
Make a UI component themeable:
// Button/index.js
import themeable from '@instructure/ui-themeable'
import styles from 'styles.css'
import theme from 'theme.js'
class Button extends React.Component {
render () {
return <button className={styles.root}>{this.props.children}</button>
}
}
export default themeable(theme, styles)(Example)
Themeable components inject their themed styles into the document when they are mounted.
After the initial mount, a themeable component's theme can be configured explicitly
via its theme
prop or passed via React context using the ApplyTheme component.
Themeable components register themselves with the global theme registry when they are imported into the application, so you will need to be sure to import them before you mount your application so that the default themed styles can be generated and injected.
The themeable component transforms the JS variables defined in the theme.js
file into CSS custom properties
that are automatically scoped and applied to the component.
For example, to add a variable for the hover
state of a Button
component,
the theme.js
file might contain the following:
// Button/theme.js
export default function generator ({ colors }) {
return (
background: colors.backgroundMedium,
color: colors.textDarkest,
hoverColor: colors.textLightest,
hoverBackground: colors.backgroundDarkest
)
}
The arguments to the generator function are the global theme variables. In the above example, we've defined the default theme for the Button component.
The purpose of the generator function is to take the global variables and apply them as values to the functional component level variables. When coming up with names for the component level variables, try to make them describe how they are used in the component (vs describing the variable value).
If we want to make the Button transform the global theme variables differently with a another theme, (e.g. canvas-high-contrast) we can make a generator for that theme:
// Button/theme.js
...
generator['canvas-high-contrast'] = function ({ colors }) {
return {
background: colors.backgroundLightest
}
}
This will override the default Button theme and use the global theme variable colors.textLightest
for the
value of its background
theme variable instead of colors.tiara
.
The rest of the variables will pick up from the default Button theme generator (applying the global theme variables
from the canvas-high-contrast
theme).
Note: Don't worry about scoping your CSS variables (the ui-themeable library will take care of that for you):
.root {
background: var(--background);
color: var(--color);
&:hover {
background: var(--hoverBackground);
color: var(--hoverColor);
}
}
Since the variables are defined in JS you can also access them in your component JS (e.g. this.theme.hoverColor
) which will give
you the theme values applied via React context with ApplyTheme
or the theme
prop (falling back to the defaults provided in the theme.js
file).
The babel plugin does a few things:
theme.css
file using plugins defined in postcss.config.js, plus postcss-themeable-styles.theme.js
can be injected into the CSS
for browsers that don't support CSS variables.The ui-themeable library will call the theme function and inject the resulting CSS string into the document when the component mounts. If the browser supports CSS variables, it will inject namespaced CSS variables into the CSS before adding it to the document.
e.g. The following is injected into the document for browsers with CSS var support:
.list__root {
color: var(--list__color);
background: var(--list__background);
}
:root {
--list__color: #8893A2;
--list__background: #FFFFFF;
}
Whereas if the browser does not support CSS variables:
.list__root {
color: #8893A2;
background: #FFFFFF;
}
The ui-themeable library also supports runtime themes as follows:
For browsers that support CSS variables, it will add variables via the style attribute on the component root (when the theme is changed, either via the theme property or via React context using the ApplyTheme component).
<div style="--list-background: red">
For browsers that don't support CSS variables it will update the DOM like:
<div data-theme="XYZ">
<style type="text/css">
[data-theme="XYZ"].list__root {
background: red;
}
</style>
</div>
7.0.0 (2020-05-27)
Note: For instructions on upgrading to version 7.0.0 and more information about breaking changes, see the upgrade guide.
canvas-ams-theme
package. Use canvas-theme
instead.Change-Id: I077f6b8cbbef9ee12e5904fb4c9dc4b48409acbb Reviewed-on: https://gerrit.instructure.com/c/instructure-ui/+/237960 Tested-by: Service Cloud Jenkins svc.cloudjenkins@instructure.com Reviewed-by: Steve Jensen sejensen@instructure.com QA-Review: Daniel Sasaki dsasaki@instructure.com Product-Review: Steve Jensen sejensen@instructure.com Visual-Regression-Test: Steve Jensen sejensen@instructure.com
TEST PLAN:
Change-Id: Ib714de4dc2a4ef048af2f43f272bcb8a2e545a5c Reviewed-on: https://gerrit.instructure.com/c/instructure-ui/+/237790 Tested-by: Service Cloud Jenkins svc.cloudjenkins@instructure.com Reviewed-by: Chris Guerrero cguerrero@instructure.com Product-Review: Ken Meleta kmeleta@instructure.com QA-Review: Daniel Sasaki dsasaki@instructure.com Visual-Regression-Test: Ken Meleta kmeleta@instructure.com
TEST PLAN:
Change-Id: I7cd9dd6423fb9524e0a1a0dd490caeee3a2c2c17 Reviewed-on: https://gerrit.instructure.com/c/instructure-ui/+/237727 Tested-by: Service Cloud Jenkins svc.cloudjenkins@instructure.com Reviewed-by: Chris Guerrero cguerrero@instructure.com Product-Review: Steve Jensen sejensen@instructure.com QA-Review: Daniel Sasaki dsasaki@instructure.com Visual-Regression-Test: Ken Meleta kmeleta@instructure.com
Change-Id: I5c632274264d7c934abc86f41399b8a7cda23e26 Reviewed-on: https://gerrit.instructure.com/c/instructure-ui/+/236873 Tested-by: Service Cloud Jenkins svc.cloudjenkins@instructure.com Reviewed-by: Ken Meleta kmeleta@instructure.com Product-Review: Ken Meleta kmeleta@instructure.com QA-Review: Daniel Sasaki dsasaki@instructure.com Visual-Regression-Test: Steve Jensen sejensen@instructure.com
TEST PLAN:
Change-Id: I2c054c986421014ffe15f0402e14bd2725cbc267 Reviewed-on: https://gerrit.instructure.com/c/instructure-ui/+/229009 Tested-by: Service Cloud Jenkins svc.cloudjenkins@instructure.com QA-Review: Daniel Sasaki dsasaki@instructure.com Visual-Regression-Test: Ken Meleta kmeleta@instructure.com Reviewed-by: Steve Jensen sejensen@instructure.com Product-Review: Steve Jensen sejensen@instructure.com
ui-token-scripts
commandsui-token-scripts
configuration fileChange-Id: I33213d2350f9ce07c157a6ad3f8cd2e6bccb14e9 Reviewed-on: https://gerrit.instructure.com/c/instructure-ui/+/236552 Reviewed-by: Steve Jensen sejensen@instructure.com Product-Review: Steve Jensen sejensen@instructure.com Tested-by: Service Cloud Jenkins svc.cloudjenkins@instructure.com QA-Review: Daniel Sasaki dsasaki@instructure.com Visual-Regression-Test: Steve Jensen sejensen@instructure.com
TEST PLAN:
Change-Id: I68398d56447af2a03c9db51bee5cce96f1fe5bd2 Reviewed-on: https://gerrit.instructure.com/c/instructure-ui/+/224132 Tested-by: Service Cloud Jenkins svc.cloudjenkins@instructure.com Reviewed-by: Chris Hart chart@instructure.com Visual-Regression-Test: Ken Meleta kmeleta@instructure.com Product-Review: Chris Hart chart@instructure.com QA-Review: Daniel Sasaki dsasaki@instructure.com
scopeStylesToNode
, scopeCssText
, and customPropertiesSupported
utility helpers.Change-Id: I41de82b6167f1aa9f25d87ddc279e5d3c5f0b413 Reviewed-on: https://gerrit.instructure.com/c/instructure-ui/+/235818 Tested-by: Service Cloud Jenkins svc.cloudjenkins@instructure.com Reviewed-by: Steve Jensen sejensen@instructure.com Product-Review: Steve Jensen sejensen@instructure.com QA-Review: Daniel Sasaki dsasaki@instructure.com Visual-Regression-Test: Chris Guerrero cguerrero@instructure.com
FAQs
A UI component library made by Instructure Inc.
The npm package @instructure/ui-themeable receives a total of 1,311 weekly downloads. As such, @instructure/ui-themeable popularity was classified as popular.
We found that @instructure/ui-themeable demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 28 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.