@setsunajs/css
v0.2.3
Published
Provide a joint solution of "atom css" and "css in js"
Downloads
3
Readme
@setsunajs/css
中文文档
a css in js that can apply to multiple frameworks -- atom css runtime
atom css
is atomic CSS. You can associate it withtailwindcss
@setsunajs/css
no configuration is required, just import the relevant API to use it. The internally created atom will generate a permanent cache to avoid the performance loss caused by the constant destruction and creation of `css in js'It's a balance between good performance and ease of use
a 'css in js' runtime that can apply to multiple frameworks
Considering that if it is purely atomic CSS, it may encounter the problem of insufficient flexibility due to the use of different developers, their usage habits, and improper disassembly, so it provides a similar 'css in js' function as' @ emotion/react'
Of course, its volume will be much smaller, which is an optional feature. You can also choose other forms to make up for the lack of flexibility of atomic CSS
Currently, the supported frameworks are (rect ',
vue'), and the related TS types are complete
If you want the size advantage of 'tailwindcss' and a more flexible atomic css scheme, you also like the flexibility of' css in js'
Maybe you can try it
install
npm i @setsunajs/css
Table of Contents
-
setsuna
-
vue
-
react
- core,Customized encapsulation can be applied to any frame
setsuna
The style container component is required to be used as the pocket bottom. It is used as follows
import { Styled, C } from "@setsunajs/css/lib/setsunajs"
// using Style Components
const App = () => {
//Is indicates which node should be rendered. The default is div
//Atom is used to set the atomic css. It is written in the same style as the inline style and has only one level
//Css is used to set the cssInJs style, which is the same as the inline style, but can have nesting and multi-level
return () => (
<Styled is="h1" atom={{ color: "red" }} css={{ color: "orange" }}>
text...
</Styled>
)
}
// Using the short 01, C is the alias of the Styled component
const App1 = () => {
return () => (
<C is="h1" atom={{ color: "red" }} css={{ color: "orange" }}>
这是一段文字...
</C>
)
}
// Using the short 02, Different tag names are mounted on the style container, which is another way to use the is attribute
const App1 = () => {
return () => (
<div>
<Styled.h1> text... </Styled.h1>
<C.h2> text... </C.h2>
</div>
)
}
use atom css
The use of atomic css depends on the 'atom' attribute of the style container, which can receive a style object (objects can only have one level and cannot be nested), or a style array
Once used, the atomic CSS will be cached to the global for a long time, and the actual style will not be destroyed, which means better performance. This is intentional
Seecore acss for complete acceptable parameters
const App1 = () => {
return () => (
<C.div
atom={{
color: "red",
//The use of pseudo classes is to use the pseudo class symbol as the key, and then write the nested object style
//This is the only condition that allows nesting. Special processing will be done internally
":hover": {
color: "slateblue"
}
}}
>
text
</C.div>
)
}
use cssInJs
The positioning of css in js is a supplement to atomic css and an alternative. It is recommended not to rely too much on it
It relies on the css
attribute of the style container. It can receive a style object (objects can have multiple levels and can be nested) or a style array
const App1 = () => {
return () => (
<C.div
atom={{
color: "red",
"&hover": {
color: "slateblue"
},
".title": {
color: "orange"
}
}}
>
text
</C.div>
)
}
External Styles
import { scss } from "@setsunajs/css/lib/setsunajs"
const atomStyle1 = { color: "red" }
const atomStyle2 = { fontSize: "12px" }
const cssStyle1 = { color: "red" }
const cssStyle2 = scss({ "&:hover": { color: "orange" } })
const App1 = () => {
return () => (
<C.div atom={[atomStyle1, atomStyle2]} css={[cssStyle1, cssStyle2]}>
text
</C.div>
)
}
Create a responsive style&develop recommended writing
- Create a style hook to extract the style to the outside (only required if there are many styles), or directly write the atomic css in the line (when there are few styles)
- Dynamically adjust parameters internally according to external parameter changes
import { FC, S, useEffect, useState } from "setsunajs"
import { C } from "@setsunajs/css/lib/setsunajs"
const useHomeStyle = (num: S<number>) => {
const [style, setStyle] = useState({
textAlign: "center",
color: "orange"
})
useEffect([num], n => {
console.log(n)
setStyle({ ...style(), color: n % 2 === 0 ? "red" : "orange" })
})
return style
}
export const Home: FC = () => {
const [num, setNum] = useState(0)
const add = () => setNum(num() + 1)
return () => (
<C.h1 atom={useHomeStyle(num)}>
<p>{num()}</p>
<button onClick={add}>++</button>
</C.h1>
)
}
vue
use atom css
Used by the directive (` v-atom ')
This instruction will generate a global, persistent style (that is, it still exists in the global after unloading, which is intentional)
Repeated creation will automatically remove duplicates to ensure global uniqueness
<script setup lang="ts">
import { vAtom } from "@setsunajs/css/lib/vue"
</script>
<template>
<div v-atom="{ color: 'red', ':hover': { color: 'orange' } }">hello</div>
</template>
use css in js
by directive (v-css
<script setup lang="ts">
import { vCss } from "@setsunajs/css/lib/vue"
</script>
<template>
<div v-css="{ color: 'red' }">hello</div>
</template>
Create responsive style change effects
<script setup lang="ts">
import { vAtom, vCss } from "@setsunajs/css/lib/vue"
import { reactive } from "vue"
const atomStyle = reactive({ color: "red" })
const cssStyle = reactive({ color: "red" })
setTimeout(() => {
atomStyle.color = "blue"
cssStyle.fontSize = "12px"
}, 2000)
</script>
<template>
<div v-css="atomStyle">hello</div>
<div v-css="cssStyle">hello</div>
</template>
style component
is
attribute is used to specify what will be displayed finally. The default is div
css
attribute is consistent with the v-css
directive
atom
attribute has the same effect as the v-atom
directive
<script setup lang="ts">
import { vCss } from '@setsunajs/css/lib/vue'
const atomStyle = reactive({ color: "red" })
const cssStyle = reactive({ color: "red" })
</script>
<template>
<Styled is="h1" :atom="atomStyle" :css="cssStyle">hello</div>
</template>
use external styles
scss
is an auxiliary function, but you may not use it core-scss
<script setup lang="ts">
import { vCss, scss } from '@setsunajs/css/lib/vue'
const atomStyle = reactive({ color: "red" })
const cssStyle = reactive({ color: "red" })
const s1 = scss({ fontSize: "30px" })
</script>
<template>
<div v-css="[cssStyle, s1]">hello</div>
<Styled :css="[cssStyle, s1]">hello</Styled>
<div v-atom="[atomStyle, { fontSize: "40px" }]">aaa</div>
<Styled :atom="atomStyle, { fontSize: "40px" }]">hello</Styled>
</template>
Development recommendation
We certainly don't want all our styles written in the line or in a file
So here are two recommended practices
use
v-atom
to write in the line, just liketailwindcss
use
reactive
to extract it for external use, and introduce it when usingfunction useAppStyle() { const style = reactive({ color: "red" }) return style }
react
Use with style components
The following three writing methods have the same effect
import { FC } from "react"
import { Styled, C } from "@setsunajs/css/lib/react"
const Home: FC = () => {
return (
<>
//01 display elements can be changed through is. default is div
<Styled is="h1">aaa</Styled>
//02 the short
<Styled.h1>aaa</Styled.h1>
//03 the short
<C.h1>aaa</C.h1>
</>
)
}
export default Home
use atom css
A global and persistent style will be generated (that is, it still exists in the global after uninstallation, which is intentional)
Repeated creation will automatically remove duplicates to ensure global uniqueness
import { FC } from "react"
import { Styled } from "@setsunajs/css/lib/react"
const Home: FC = () => {
return (
<>
<Styled.h1 atom={{ color: "red" }}>aaa</Styled.h1>
<Styled is="h1" atom={{ color: "red", ":hover": { color: "orange" } }}>
aaa
</Styled>
</>
)
}
//batchs
const Home: FC = () => {
return (
<>
<Styled.h1 atom={[{ color: "red" }]}>aaa</Styled.h1>
<Styled is="h1" atom={[{ color: "red" }]}>
aaa
</Styled>
</>
)
}
export default Home
use css in js
import { FC } from "react"
import { Styled } from "@setsunajs/css/lib/react"
const Home: FC = () => {
return (
<>
<Styled.h1 css={{ color: "red" }}>aaa</Styled.h1>
<Styled is="h1" css={{ color: "red" }}>
aaa
</Styled>
</>
)
}
//batchs
const Home1: FC = () => {
return (
<>
<Styled.h1 css={[{ color: "red" }]}>aaa</Styled.h1>
<Styled is="h1" css={[{ color: "red" }]}>
aaa
</Styled>
</>
)
}
export default Home
use external styles
scss
is an auxiliary function, but you may not use it core-scss
import { FC, useState } from "react"
import { scss, Styled } from "@setsunajs/css/lib/react"
const css1 = scss({ color: "red" })
const Home: FC = () => {
const [style, setStyle] = useState({ color: "red" })
const toggleStyle = () => {
setStyle({ color: style.color === "red" ? "orange" : "red" })
}
return (
<Styled.h1
css={[
style,
scss({ fontSize: "14px", [css1.className]: { color: "red" } })
]}
>
home page
<hr />
<button onClick={toggleStyle}>{JSON.stringify(style)}</button>
</Styled.h1>
)
}
export default Home
Q & A
Why not use it in a way similar to '@ emotion/react'?
Because in essence, style components need to generate a layer on the outside. Although '@ emotion/react' can be written directly in the line, it needs to be configured, and there is not much code to write style components
Are there external style components like '@ emotion/styled'?
No, there are 2 reasons
It is more recommended to use the form of 'atom' to write the style. Even if it is written in the line, there will be no problem. Or, if it is extracted to the outside through js, the container component will automatically update the style according to the external incoming
For style separation and dynamics under 'css in js', it is recommended to combine' scss() '. You can create multiple' scss() 'instances, then conditionally update and combine them, and finally throw them to container components
Comparison with 'emotion'
Smaller volume
You can use atomic css in js
Easier to use
core
four core APIs, all of which can be imported from '@ setsunajs/css'. All the following demos can be imported in<a href=“ https://github.com/setsunajs/css/blob/main/src/test/browser.test.ts ">Herefind the actual demonstration
createCache
create a cache, need call it first
acss
Create an atomic css object (it has not been inserted at this time)
The style generation rule is {color: "red"}==>color red
, that is, flat key values. All illegal references, such as nested styles, will be ignored
Once the style is inserted, it will remain in the dom and cannot be deleted through removeCss
This is intentional
The underlying API of all atomic CSS in setsunajs, react, and vue
import { acss } from "@setsunajs/css"
//once
const css1 = acss({ color: "red" })
//multiple
const css2 = acss({ color: "red" }, { fontSize: "14px" })
After getting the atomic object, you can proceed to the next step as required
const css = acss({
color: "red",
fontSize: "12px"
})
//get the generated class names
css.classNames
//insert to dom
css.insert()
acss
Create a css in js
object (it has not been inserted at this time)
This API is an alternative solution to make up for the lack of flexibility of atomic CSS. Random class names will be generated internally to ensure the uniqueness of the style
Styles can be nested, reused, combined and deleted
Styles depend on compilation at run time
The underlying API of all css in js
in setsunajs, react, vue
import { acss } from "@setsunajs/css"
//basic
const css1 = acss({ color: "red" })
//combination
const css2 = acss(
{ color: "red" },
{ fontSize: "14px" },
acss({ color: "blue" })
)
//nested
const css3 = acss({
color: "red",
".title": { color: "orange" }
})
//deep style
const css4 = acss({
color: "red",
[css1.className]: {
color: "orange"
}
})
//Pseudo element
const css5: acss({
color: "red",
":hover": {
color: "orange"
}
})
After you get the created object, you can proceed to the next step as required
const css = acss({ color: "red" })
//get the generated class name
css.className
//Get multiple generated class names (when style nesting occurs, multiple names will be generated when compiled into css)
css.classNames
//insert to dom
css.insert()
removeCss
The style used to delete scss
inserted into dom
import { removeCss } from "@emotion/css"
removeCss(2, scssClassName)