Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental WIP: strict-ui #719

Closed
wants to merge 50 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
64eab4e
Experimental WIP: strict-ui
mxstbr Feb 24, 2020
ece7a33
Add support for camelCase props
mxstbr Mar 2, 2020
004fba1
v0.0.2
mxstbr Mar 2, 2020
ff34efd
Disallow non theme-based values for properties that are in the theme
mxstbr Mar 2, 2020
d18cb23
Slight test suite cleanup
mxstbr Mar 2, 2020
3af8f7f
Publish 0.0.3 to npm
mxstbr Mar 2, 2020
734ed42
Fix publish usage for now
mxstbr Mar 2, 2020
1083fb3
Copy all the unexported stuff from @theme-ui/css
mxstbr Mar 3, 2020
3157517
0.0.5
mxstbr Mar 3, 2020
cea48bb
Add some more missing exports
mxstbr Mar 3, 2020
e55f067
useStrictUI
mxstbr Mar 3, 2020
54c253b
0.0.6
mxstbr Mar 3, 2020
eac4d76
Some more custom reset stuff
mxstbr Mar 3, 2020
80bc32f
0.0.7
mxstbr Mar 3, 2020
0762127
Also export <Flex />
mxstbr Mar 3, 2020
4649a67
Force CSS reset usage
mxstbr Mar 3, 2020
8857816
0.0.9
mxstbr Mar 3, 2020
ae18312
Add support for responsive arrays
mxstbr Mar 3, 2020
1b9b3a1
Add support for blocking marginX and mx shorthands
mxstbr Mar 3, 2020
1980454
0.0.10
mxstbr Mar 3, 2020
eaedc88
Add test verifying that red: "red" in theme works
mxstbr Mar 3, 2020
2bbcf21
Simplify "is theme value" check, add support for missing scales
mxstbr Mar 4, 2020
ca6980c
Throw error on unspecified scale
mxstbr Mar 4, 2020
de7df5f
0.0.11
mxstbr Mar 4, 2020
8dd3ea7
Add test that verifies correct CSS transformation occurring
mxstbr Mar 4, 2020
64892ad
Remove <Flex /> again, doesnt work as-is
mxstbr Mar 4, 2020
d7cdf29
0.0.12
mxstbr Mar 4, 2020
99575e1
No margin on anything
mxstbr Mar 5, 2020
bc398c6
0.0.13
mxstbr Mar 5, 2020
85d3858
!important
mxstbr Mar 5, 2020
0ee6921
0.0.14
mxstbr Mar 9, 2020
90fde43
Re-export <Flex /> for now
mxstbr Mar 9, 2020
92225a0
0.0.15
mxstbr Mar 9, 2020
9d7beb5
I forgot why this is a bad idea, nvm
mxstbr Mar 9, 2020
0dfae83
No more !important
mxstbr Mar 17, 2020
3bbf426
Add <Flex gap={2} justifyContent="space-between" />
mxstbr Mar 17, 2020
ad98fad
0.0.17
mxstbr Mar 17, 2020
e92508e
Add support for <Flex gap={3} flexDirection="column" />
mxstbr Mar 17, 2020
849a3fa
0.0.18
mxstbr Mar 17, 2020
7ee7447
Fix types for <Flex />
mxstbr Mar 19, 2020
28f4b89
Protect against null props
mxstbr May 25, 2020
459f935
Merge branch 'master' into strict-ui
mxstbr May 25, 2020
fe6f80a
strict-ui@0.1.0
mxstbr May 25, 2020
db420dc
Use theme-ui 0.4
mxstbr May 25, 2020
7b50c96
strict-ui@0.1.1
mxstbr May 25, 2020
66b488d
Potentially fix "Grid not exported from theme" typescript error
mxstbr May 25, 2020
75b6933
Deps...
mxstbr May 26, 2020
f3c3ea5
Handle falsy childs in <Flex>
mxstbr May 26, 2020
4d74ade
v0.1.3
mxstbr May 26, 2020
f8a2c37
Merge branch 'master' into strict-ui
mxstbr Jul 30, 2020
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
2 changes: 1 addition & 1 deletion packages/css/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
"access": "public"
},
"dependencies": {
"csstype": "^2.5.7"
"csstype": "^2.6.10"
}
}
4 changes: 2 additions & 2 deletions packages/css/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const defaultTheme = {
fontSizes: [12, 14, 16, 20, 24, 32, 48, 64, 72],
}

const aliases = {
export const aliases = {
bg: 'backgroundColor',
m: 'margin',
mt: 'marginTop',
Expand Down Expand Up @@ -195,7 +195,7 @@ const positiveOrNegative = (scale: object, value: string | number) => {
return Number(n) * -1
}

const transforms = [
export const transforms = [
'margin',
'marginTop',
'marginRight',
Expand Down
2 changes: 2 additions & 0 deletions packages/strict-ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

# `strict-ui`
26 changes: 26 additions & 0 deletions packages/strict-ui/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "strict-ui",
"version": "0.1.3",
"source": "src/index.ts",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"sideEffects": false,
"scripts": {
"prepare": "microbundle --no-compress",
"watch": "microbundle watch --no-compress"
},
"author": "Max Stoiber",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@theme-ui/components": ">= 0.4.0-alpha.0",
"@theme-ui/css": ">= 0.4.0-alpha.0",
"@types/reflexbox": "^4.0.0",
"emotion": "^10.0.27",
"reflexbox": "^4.0.6",
"theme-ui": ">= 0.4.0-alpha.0"
}
}
36 changes: 36 additions & 0 deletions packages/strict-ui/src/Flex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* @jsx jsx */
import React from 'react'
import { jsx } from 'theme-ui'
import { Flex as Reflex, BoxProps } from 'reflexbox'

export const Flex = (
props: BoxProps & {
gap?: number
children: React.ReactNode
}
) => {
let { children, ...rest } = props

if (typeof props.gap === 'number' && props.gap !== 0) {
children = React.Children.map(children, (child, index) => {
if (!child) return child

return jsx(
'div',
{
sx:
index !== 0
? {
[props.flexDirection === 'column'
? 'marginTop'
: 'marginLeft']: props.gap,
}
: {},
},
child
)
})
}

return jsx(Reflex, rest, children)
}
107 changes: 107 additions & 0 deletions packages/strict-ui/src/css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { get } from '@theme-ui/css'

/**
*
* COPIED FROM @theme-ui/css UNTIL EXPORTS ARE MERGED + PUBLISHED
*/
export const aliases = {
bg: 'backgroundColor',
m: 'margin',
mt: 'marginTop',
mr: 'marginRight',
mb: 'marginBottom',
ml: 'marginLeft',
mx: 'marginX',
my: 'marginY',
p: 'padding',
pt: 'paddingTop',
pr: 'paddingRight',
pb: 'paddingBottom',
pl: 'paddingLeft',
px: 'paddingX',
py: 'paddingY',
}

export const positiveOrNegative = (scale: object, value: string | number) => {
if (typeof value !== 'number' || value >= 0) {
return get(scale, value, value)
}
const absolute = Math.abs(value)
const n = get(scale, absolute, absolute)
if (typeof n === 'string') return '-' + n
return Number(n) * -1
}

export const scales = {
color: 'colors',
backgroundColor: 'colors',
borderColor: 'colors',
margin: 'space',
marginTop: 'space',
marginRight: 'space',
marginBottom: 'space',
marginLeft: 'space',
marginX: 'space',
marginY: 'space',
padding: 'space',
paddingTop: 'space',
paddingRight: 'space',
paddingBottom: 'space',
paddingLeft: 'space',
paddingX: 'space',
paddingY: 'space',
top: 'space',
right: 'space',
bottom: 'space',
left: 'space',
gridGap: 'space',
gridColumnGap: 'space',
gridRowGap: 'space',
gap: 'space',
columnGap: 'space',
rowGap: 'space',
fontFamily: 'fonts',
fontSize: 'fontSizes',
fontWeight: 'fontWeights',
lineHeight: 'lineHeights',
letterSpacing: 'letterSpacings',
border: 'borders',
borderTop: 'borders',
borderRight: 'borders',
borderBottom: 'borders',
borderLeft: 'borders',
borderWidth: 'borderWidths',
borderStyle: 'borderStyles',
borderRadius: 'radii',
borderTopRightRadius: 'radii',
borderTopLeftRadius: 'radii',
borderBottomRightRadius: 'radii',
borderBottomLeftRadius: 'radii',
borderTopWidth: 'borderWidths',
borderTopColor: 'colors',
borderTopStyle: 'borderStyles',
borderBottomWidth: 'borderWidths',
borderBottomColor: 'colors',
borderBottomStyle: 'borderStyles',
borderLeftWidth: 'borderWidths',
borderLeftColor: 'colors',
borderLeftStyle: 'borderStyles',
borderRightWidth: 'borderWidths',
borderRightColor: 'colors',
borderRightStyle: 'borderStyles',
outlineColor: 'colors',
boxShadow: 'shadows',
textShadow: 'shadows',
zIndex: 'zIndices',
width: 'sizes',
minWidth: 'sizes',
maxWidth: 'sizes',
height: 'sizes',
minHeight: 'sizes',
maxHeight: 'sizes',
flexBasis: 'sizes',
size: 'sizes',
// svg
fill: 'colors',
stroke: 'colors',
}
112 changes: 112 additions & 0 deletions packages/strict-ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { jsx as themeuijsx } from 'theme-ui'
import { get } from '@theme-ui/css'
import { scales, aliases } from './css'
// Always inject the CSS reset. You should not be able to use strict-ui without it.
import './sanitize.css'

export { ThemeProvider, useThemeUI as useStrictUI } from 'theme-ui'
export { Grid } from '@theme-ui/components'
export * from './Flex'

export const jsx = (type, props, ...children) => {
if (props && props.css) throw new Error('Using the `css` prop is disallowed.')

if (process.env.NODE_ENV !== 'production' && props && props.sx) {
const filteredCSSProps = [
// General
'box-sizing',
'float',
'margin',
'margin-top',
'margin-left',
'margin-right',
'margin-bottom',
'margin-x',
'margin-y',
'display', // TBD!
// Flexbox
'justify-content',
'align-items',
'order',
'flex-direction',
'flex-grow',
'flex-wrap',
'flex-shrink',
'flex-basis',
'flex-flow',
'flex',
'align-self',
'align-content',
// Grid
'grid-column-start',
'grid-column-end',
'grid-row-start',
'grid-row-end',
'grid-template-columns',
'grid-template-rows',
'grid-column',
'grid-row',
'grid-area',
'grid-template-areas',
'justify-self',
'grid-template',
'grid-column-gap',
'grid-row-gap',
'grid-gap',
'place-self',
'place-items',
'place-content',
'grid-auto-columns',
'grid-auto-rows',
'grid-auto-flow',
'grid',
]

const dashize = (str: string) => {
return str.replace(/(\w)([A-Z])/g, (word, first, second) => {
return `${first}-${second.toLowerCase()}`
})
}

for (const prop of Object.keys(props.sx)) {
const alias = prop in aliases ? aliases[prop] : prop

// Filter certain CSS properties like e.g. margin
if (
filteredCSSProps.indexOf(dashize(prop)) > -1 ||
(aliases[prop] &&
(filteredCSSProps.indexOf(aliases[prop]) > -1 ||
filteredCSSProps.indexOf(dashize(aliases[prop])) > -1))
)
throw new Error(`Cannot specify disallowed CSS property "${prop}".`)

// Disallow non theme-based values for properties that are in the theme
if (scales[alias]) {
const value = props.sx[prop]
props.sx[prop] = (theme) => {
const scale = get(theme, scales[alias])
if (!scale)
throw new Error(
`Cannot specify "${prop}" because no "${scales[alias]}" scale is defined in the theme.`
)

const valuesToCheck = Array.isArray(value) ? value : [value]

valuesToCheck.forEach((toCheck) => {
const scaleValue = get(scale, toCheck)

if (!scaleValue) {
throw new Error(
`Cannot use a non-theme value "${toCheck}" for "${prop}". Please either use a theme value or add a new value to the theme.`
)
}
})

return value
}
}
}
}

return themeuijsx(type, props, ...children)
}
Loading