system-ui / theme-ui Goto Github PK
View Code? Open in Web Editor NEWBuild consistent, themeable React apps based on constraint-based design principles
Home Page: https://theme-ui.com
License: MIT License
Build consistent, themeable React apps based on constraint-based design principles
Home Page: https://theme-ui.com
License: MIT License
This should include at least:
npm ls
yarn list
)any thoughts on doing something like this?
…
colors: {
grays: ['#424445', '#666666', '#999999', '#CCCCCC', '#e0e3e6', '#e6e6e6'],
reds: [
'#a00',
'#e62b1e',
'#fF5041',
],
};
…
<h1 color="grays[1]">fairly dark</h1>
i know passing something like that as a string sucks and is not the best option, but do you have any ideas around this in general?
A schema validation for Theme UI objects could help with other packages and libraries built on top of the core. Leveraging a library like yup
or joi
, this validator should be able to detect whether a theme object is valid and detect typos among other things
Select any theme other than light which is default on Theme UI
Then try refreshing the page. It will flash the light theme which is the default for a second & then quickly changes to the theme selected.
I think it's a bug. Wait until local storage (which is async I think) returns value.
The implementation from gatsby-plugin-theme-ui
should also be used in gatsby-theme-ui
is it possible to use Styled like this:
const Section = styled.span`
background: #333;
`
is there a short syntax for this in your lib?
Right now, there's no support for shorthand properties. This means that I can't set something like this:
{
Container: {
border: '1px solid primary'
}
}
One idea for allowing this could be to split the shorthand into string tokens using .split
, then look for tokens and replace.
// assumes the value is border shorthand: '1px solid primary'
border.split(' ').map(replaceThemeUITokensWithValues).join(' ')
The edge case here would be comma-separated values (e.g. multiple backgrounds):
{
Container: {
background: 'primary, rgba(0, 0, 0, 0.75)'
}
}
This could be worked around with regex 😱 (e.g. /([,\s]*)(\w+)([,\s]*)/
) to capture non-word characters and drop them back in:
const handleNonWordCharacters = str => {
const [_, pre, maybeToken, post] = str.match(/([,\s]*)(\w+)([,\s]*)/);
return pre + replaceThemeUITokensWithValues(maybeToken) + post;
}
There are probably a large number of dragons to consider with this approach, but if it's limited to only a few shorthand properties (e.g. border
, background
) maybe it's manageable?
Hi!
I spun up a codesandbox starter for Theme UI
features:
base
themeStyled
@emotion/babel-plugin-jsx-pragmatic
to insert the jsx pragma and point it at theme-uibabel-plugin-emotion
for smartnessI mirrored the prettier settings from this project and tried to keep the sandbox free of my own opinions, but feel free to offer feedback, and if you like it, fork it and add it to the docs or readme - letting people get up and running quickly.
Hi!
Maybe the top
, bottom
, left
, and right
properties should follow the same negative value rules as margins?
Personally, I find myself often doing something like this:
<Card>
<Box
css={{
position: 'relative',
top: `-${theme.sizes[1]}`,
}}
>
<Avatar size="2" />
</Box>
<Content />
</Card>
Is this a common enough occurrence to warrant an API breaking change?
In simple terms, I'm just wondering why you'd choose this over styled system? My understanding so far is its a layer on top of style system to help streamline a few things such as general layout creation, as well as offering the ability to style certain components from the context of a theme file?
Cheers!
my theme.js
file:
export default {
space: {
'1': '0.25rem',
'2': '0.5rem',
}
}
my Header.js
file:
<div
css={{
display: 'grid',
gridGap: 2, // returns 2px, instead of 0.5rem
p: 2, // works as intended, return 0.5rem
}}
></div>
As you can see none of the grid gap properties pick up the correct value.
Is this a bug, or is my configuration wrong? Thanks!
When loading a page that uses color modes, any page that uses a non-white background color will show a flash of the default color mode styles before picking up a stored color mode value from localStorage
. The useDarkMode
library uses an inline script to set classnames on the <body>
element before rendering the page. If we do something similar for Theme UI, this should be based on values from the theme
context and not be added as global CSS
It's used in digital-garden though, so makes it a bit harder to debug
Since Bulma has modifiers we can build a transformer to generate static CSS and Sass variables from a Theme UI config.
Add a Gatsby plugin to control how theme and component context is handled when using multiple Gatsby themes in a site.
This plugin should:
src/theme
module to the theme contextDoes theme-ui support responsive styles using objects, as in styled-system? Or are you moving away from this approach?
<div
css={css({
width: [ '100%', '50%', '25%' ],
})}
/>
<div
width={{ _: '100%', sm: '100%', md: '50%', lg: '25%' }}
/>
When defining a custom pragma with theme-ui and using the Emotion preset, the preset still applies transforms from babel-plugin-emotion
, meaning that theme-ui's pragma no longer works.
Similar to the idea of a Chrome extension (#86), it would be nice to have a plugin for VS Code and/or other IDEs with graphical interfaces for editing things like colors and typography
The problem, in brief: If you are using src
as a relative module lookup directory, the location of the theme file shadows the actual gatsby-theme-ui module because they have the same name. Could we set the path to the theme file in the plugin options?
// gatsby-node.js
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
resolve: {
modules: [path.resolve(__dirname, "src"), "node_modules"],
},
})
}
// src/gatsby-theme-ui/index.js
import baseTheme from 'gatsby-theme-ui' /* Uh oh */
export default {
... baseTheme.
colors: { ...
}
When the developer sets the value only for the first viewport, The CSS props function is unable to override all viewport values of the theme config .
//theme.js
const breakpoints = ["52em"];
const styles = {
h1: {
color: ["red", "blue"]
}
};
<Styled.h1 css={css({ color: ["rebeccapurple" ]})}>
{props.children}
</Styled.h1>
I expected this to override the the larger viewports as well. But i had to explicitly set the value for all viewports.
<Styled.h1 css={css({ color: ["rebeccapurple", 'rebeccapurple'] })}>
{props.children}
</Styled.h1>
I have reproduced the issue in this codesanbox. you can reproduce the issue by resizing
Is this the intended behaviour? If not, can we filter the props and merge in jsx function/pragma?
Similar to https://github.com/styled-system/styled-system/tree/master/packages/edit, these components should allow for live updating the theme object
Related to #59
Most of my existing styles are written using emotion, however they're written using interpolated strings, as in:
<h1 css={css`color: red`}>Hi</h1>
I was unable to find a way to make this work using theme-ui. Is there existing / planned support for this method of writing styles?
Thanks for your help!
Hi Jackson! Awesome stuff as usual.
Just gave this a test run while making a gatsby theme.
I was following one of the examples on how to use it with gatsby. (not as a plugin)
And I got stuck with a dom attribute error saying css
shouldn't be there. Turns out
you need to have gatsby-plugin-emotion installed as well
I guess just a heads up to anyone who might encounter the same issue.
Mind asking what made you choose emotion for this project? You seemed to use styled-components in the past (e.g. rebass) since this is a relatively new project and now that you've worked on a bunch of css-in-js libraries, do you personally prefer emotion at this point?
I expected I could use theme colors like this, but primary
is not replaced with the theme color:
import styled from '@emotion/styled';
import { Box, css } from 'theme-ui';
const Box1 = styled(Box)(css({
borderBottom: '4px solid primary', // results in '4px solid primary'
}));
const Box2 = styled(Box)(css({
boxShadow: '0 0 0 4px primary',
}));
Border bottom color can be achieved like this (but it took a while to realize that borderColor
must be defined after borderBottom
in order it to work):
const Box3 = styled(Box)(css({
borderBottom: '4px solid', // results in 'border-bottom-color: initial';
borderColor: 'primary', // overrides border colors with theme color
}));
For boxShadow, on the other hand, there isn't a separate property to define the color in.
It would be really handy being able to use theme colors inside border and boxShadow definitions.
Since Bootstrap uses utility classes we can build a transformer to generate static CSS from a Theme UI config.
I used rebass before and really like this new idea, especially since it allows even more flexibility.
Not sure if you prefer adding definition files only or refactoring into typescript? I can make pr for either approach 🤔
Hey @johno, theme-ui
is looking awesome!
I'm getting a following error after importing MDXRenderer
:
Failed to compile
./node_modules/gatsby-mdx/context.js 11:2
Module parse failed: Unexpected token (11:2)
You may need an appropriate loader to handle this file type.
|
| export const MDXScopeProvider = ({ __mdxScope, children }) => (
> <GatsbyMDXScopeContext.Provider value={__mdxScope}>
| {children}
| </GatsbyMDXScopeContext.Provider>
Do you think it could be because of ThemeProvider
? It works fine for mdx in /pages
, but I'd like to render eg. articles which is when MDXRenderer
would come handy.
🙏
Based on a few issues and discussion, it might be worth bumping to v0.2 with some small breaking changes. Currently, I'm thinking the following:
css
prop in the JSX pragma to not collide with Emotion (#69)css
prop (#65)ThemeProvider
into two separate components (#89)@emotion/styled
as a dependency and creating all built-in components with the css
prop, which would help reduce the core bundle size (This could cause issues when certain props get accidentally passed through to MDX elements, but docs could be added to show some common pitfalls)toStyle
API from theme-ui-typography
in favor of using toTheme
– this should reduce the overall bundle size@theme-ui
scopeCurrently the ThemeProvider component can be nested to create theming contexts inside of a parent theme. This allows components like the experimental MDX Blocks to work and is a powerful feature that probably isn't leveraged much yet.
That said, there are a few issues with this in its current implementation:
pre
tagsgatsby-theme-ui
package is geared towards having one, single root themeThis is a proposal to split the functionality of the ThemeProvider into two separate components.
theme
object (ignoring theme.styles
)theme.styles
With the two separate components, an application tree could look something like the following:
<ThemeProvider theme={theme}>
<div>root-level context available</div>
<NestedTheme theme={subTheme}>
<div>nested context available</div>
</NestedTheme>
</ThemeProvider>
Theme UI includes a @theme-ui/presets
package, which is intended to serve as a base for creating custom themes on top of. It'd be great to have more presets added to the package. Presets can be as minimal as a basic color palette and typographic styles, or include MDX element styles, syntax highlighting, or any other useful design tokens.
If you'd like to contribute a new preset, but aren't sure how to get started, feel free to leave a comment here, and we'll try to help you out
Having a few built in style guide components to show demonstrate parts of the theme would be a great addition. For example:
The docs site currently includes a skip nav link and some handling of the focus state for the sidebar menu. Layout components could be added to the core library to make building accessible page layouts easier
Currently the color mode flash prevention only handles foreground and background colors for the <body>
element, which means that colors used in other elements will still flash on page load. The styles generated by the ColorMode
component could optionally include all values as CSS custom properties, and the ThemeProvider
component could map the values used in context to their relevant custom properties instead of raw color values.
This should be an opt-in feature since custom properties are not supported in IE 11.
Common gotchas:
content: '""'
for peudo-elementsHi! This is looking great.
I ran into an issue while setting up theme-ui
in a Next.js project which is rendered on the server.
error:
Warning:
useLayoutEffect
does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this,useLayoutEffect
should only be used in components that render exclusively on the client. See https://fb.me/react-uselayouteffect-ssr for common fixes.
theme-ui/packages/theme-ui/src/color-modes.js
Lines 28 to 39 in b782a1d
According to the link referenced in the error, we'd either need to push this to useEffect
(sounds undesirable), or, similar to what redux does, create a useIsomorphicLayoutEffect
like this:
const useIsomorphicLayoutEffect =
typeof window !== 'undefined' ? useLayoutEffect : useEffect
thoughts?
Currently the theme.styles
object is used as a shortcut to style components that are used in MDX. Each key in this object maps to a component that is passed to the MDXProvider's context. This allows the styles used in MDX to be generated and/or defined in multiple ways, including using Typography.js as an input. There might be alternative, more component-based approaches to handling this.
Currently, Theme UI passes components like the following to MDX context:
// mdx components
{
h1: styled('h1')(props => props.theme.styles.h1)
}
And the styles for this component can be defined in the theme.styles
object like this:
theme: {
styles: {
h1: {
color: 'tomato',
}
}
}
Given a theme-ui object, create usable css variables for ingestion in a front end framework.
The docs site's sidebar navigation is a styled MDX document, with a list of links. The pagination component uses the same MDX to render previous and next links. A similar approach is used in the official MDX docs and the Styled System docs. It'd be great to abstract these navigation components out into a new package in the monorepo for reuse.
ThemeProvider
can be used to provide a custom wrapper
component through MDX context and include theme.styles
pathname
prop, but not be coupled to Reach RouterThemeProvider
, so currently the MDXProvider
is used. This was something related to focus management IIRCAn optional Chrome devtools extension could allow someone to inspect and live edit a site built with Theme UI could make adjusting the style of a site easier by providing a GUI for editing things like color values, which can be difficult to assess when editing raw values in code.
Ideas/questions
Rough proof of concept: #79
Similar concepts & prior art:
Currently theme-ui has a default wrapper
component that's used to add base styles (typography, color, etc) to an MDX doc. It's also used in the typography.js transform in place of setting styled on the body and html elements. This wrapper
component can easily be overridden/removed when using the export default
syntax in an MDX file, but it also might be the kind of thing that is a little too magical in how it works – i.e. it seems like an easy thing for someone to get tripped up with
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.