-
Notifications
You must be signed in to change notification settings - Fork 46
Open
Description
better editor feedback without being aidsy than pretty much every other style library (at least imo)
import React from 'react'
import { HTMLProps, CSSProperties } from 'react'
const h = React.createElement
//new CSSRuleList() //items, length
//let r = new CSSStyleRule
//was using this like this, jus took context out though idk, deal later
//{theme: defined(context.theme, props.theme, pallete: 'none')}
const defined = (...args) => {
for (var i = 0; i < args.length; i++) {
if (args[i] !== undefined) return args[i]
}
}
let cache = {}
let prefix = 'x'
const rules: CSSStyleRule[] = [] //[]
let insert = (rule: CSSStyleRule) => void rules.push(rule as CSSStyleRule)
const hyph = s => s.replace(/[A-Z]|^ms/g, '-$&').toLowerCase()
const mx = (rule, media) => (media ? `${media}{${rule}}` : rule)
const rx = (cn, prop, val) => `.${cn}{${hyph(prop)}:${val}}`
const noAnd = s => s.replace(/&/g, '')
const parse = (obj, child = '', media?) =>
Object.keys(obj)
.map(key => {
const val = obj[key]
if (val === null) return ''
if (typeof val === 'object') {
const m2 = /^@/.test(key) ? key : null
const c2 = m2 ? child : child + key
return parse(val, c2, m2 || media)
}
const _key = key + val + child + media
if (cache[_key]) return cache[_key]
const className = prefix + rules.length.toString(36)
insert(mx(rx(className + noAnd(child), key, val), media))
cache[_key] = className
return className
})
.join(' ')
function cxs(...styles) {
return styles
.map(style => parse(style))
.join(' ')
.trim()
}
cxs.css = () => rules.sort().join('')
cxs.reset = () => {
cache = {}
while (rules.length) rules.pop()
}
cxs.prefix = val => (prefix = val)
if (typeof document !== 'undefined') {
const sheet = document.head.appendChild(document.createElement('style')).sheet as CSSStyleSheet
insert = (rule: CSSStyleRule & string) => {
rules.push(rule as CSSStyleRule)
sheet.insertRule(rule, sheet.cssRules.length)
}
}
type DomProps = Partial<HTMLProps<any>>
type CSX = { css?: CSSProperties }
type StyledCSX = DomProps & CSX
type Proptional<P> = CSSProperties | ((...args: P[]) => CSSProperties)
function styled<P>(C) {
return (...args: Proptional<P>[]) => {
const Comp = (props: P & StyledCSX) => {
const stylePropKeys = [...Object.keys({}), 'css']
//const styleProps = Object.assign({ theme: defined(context.theme, props.theme, {}) }, props)
const next: any = {}
for (let key in props) {
if (stylePropKeys.includes(key)) continue
next[key] = props[key]
}
next.className = [
next.className,
...args
.map(proptional => (typeof proptional === 'function' ? proptional(props) : proptional))
.filter(s => !!s)
.map(s => cxs(s)),
cxs(props.css || {}),
]
.join(' ')
.trim()
return h(C, next)
}
return Comp
}
}
styled.css = cxs.css
styled.reset = cxs.reset
export { cxs }
export { styled }
export default styled
// export function styledComponentWithProps<T, U extends HTMLElement = HTMLElement>(styledFunction: StyledFunction<React.HTMLProps<U>>): StyledFunction<T & React.HTMLProps<U>> {
// return styledFunction as any;
// }
// thanks microsoft, please teach our youth how to read, i think you've got it figured out
// type Unpacked<T> = T extends (infer U)[]
// ? U
// : T extends (...args: any[]) => infer U
// ? U
// : T extends Promise<infer U>
// ? U
// : T
// type T0 = Unpacked<string> // string
// type T1 = Unpacked<string[]> // string
// type T2 = Unpacked<() => string> // string
// type Foo<T> = T extends { a: infer U; b: infer U } ? U : never
// type T10 = Foo<{ a: string; b: string }> // string
// type T11 = Foo<{ a: string; b: number }> // string | number
//type CC = (...args: CSSProperties[]) => infer R ? R : CSSProperties
//type ReturnType<T> = (...args) => T ? T : CSSProperties
// im going to space mountain charley fml
// function styled1(C) {
// return (...args) => {
// const Comp = (props, context: any = {}) => {
// const stylePropKeys = [...Object.keys({}), 'css']
// const styleProps = Object.assign({ theme: defined(context.theme, props.theme, {}) }, props)
// const next: any = {}
// for (let key in props) {
// if (stylePropKeys.includes(key)) continue
// next[key] = props[key]
// }
// next.className = [
// next.className,
// ...args
// .map(a => (typeof a === 'function' ? a(styleProps) : a))
// .filter(s => !!s)
// .map(s => cxs(s)),
// cxs(props.css || {}),
// ]
// .join(' ')
// .trim()
// return h(C, next)
// }
// return Comp
// }
// }usage
import React from 'react'
import { styled } from './styled'
type Props = {
color: 'green' | 'black'
}
let MyButton = styled<Props>('button')(props => ({
backgroundColor: (props.color && props.color) || 'green',
}))
let NoPropsButton = styled('button')({
backgroundColor: 'green',
})
export { MyButton, NoPropsButton }
let Demo = props => <MyButton onClick={e => console.log('hi')} color={'black'}/>Metadata
Metadata
Assignees
Labels
No labels