simplestyle-js 3.4.2-alpha.3 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +184 -229
- package/dist/cjs/createStyles.cjs +27 -5
- package/dist/cjs/createStyles.d.ts +6 -4
- package/dist/cjs/index.cjs +8 -2
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/simpleStyleRegistry.cjs +12 -0
- package/dist/cjs/simpleStyleRegistry.d.ts +9 -0
- package/dist/esm/createStyles.d.ts +6 -4
- package/dist/esm/createStyles.mjs +19 -4
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/simpleStyleRegistry.d.ts +9 -0
- package/dist/esm/simpleStyleRegistry.mjs +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,278 +1,233 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
# Simplestyle-js Reference
|
|
2
|
+
|
|
3
|
+
A concise guide to the core `simplestyle-js` APIs, how they fit together, and how to use them in browser and server-rendered apps (including Next.js).
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
- [Install](#install)
|
|
7
|
+
- [Quick Start](#quick-start)
|
|
8
|
+
- [API Reference (from `src/index.ts`)](#api-reference-from-srcindexts)
|
|
9
|
+
- [Patterns and Tips](#patterns-and-tips)
|
|
10
|
+
- [SSR](#ssr)
|
|
11
|
+
- [SSR steps for most SSR / SSG frameworks (including Next.js)](#ssr-steps-for-most-ssr--ssg-frameworks)
|
|
12
|
+
- [1. Set your seed, create a SimpleStyleRegistry and your style functions](#1-set-your-seed-create-a-simplestyleregistry-and-your-style-functions)
|
|
13
|
+
- [2. Render the generated styles in your HTML](#2-render-the-generated-styles-in-your-html)
|
|
14
|
+
- [3. Create your styles and have fun!](#3-create-your-styles-and-have-fun)
|
|
15
|
+
- [Creating a simplestyle-js plugin](#creating-a-simplestyle-js-plugin)
|
|
16
|
+
- [Plugin Example (Autoprefixer)](#plugin-example-autoprefixer)
|
|
17
|
+
- [License](#license)
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
**bun**
|
|
22
|
+
```
|
|
23
|
+
bun add simplestyle-js
|
|
24
|
+
```
|
|
11
25
|
|
|
12
|
-
|
|
13
|
-
|
|
26
|
+
**npm**
|
|
27
|
+
```
|
|
28
|
+
npm install simplestyle-js --save
|
|
29
|
+
```
|
|
14
30
|
|
|
15
|
-
|
|
16
|
-
[Codesandbox React Hooks Demo](https://codesandbox.io/s/nice-franklin-485wi?file=/src/App.tsx)
|
|
31
|
+
**pnpm**
|
|
17
32
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const { classes } = createStyles({
|
|
22
|
-
myButton: {
|
|
23
|
-
'&:hover': {
|
|
24
|
-
backgroundColor: 'red',
|
|
25
|
-
},
|
|
26
|
-
'&:active, &:focus': {
|
|
27
|
-
borderColor: 'blue',
|
|
28
|
-
},
|
|
29
|
-
backgroundColor: 'black',
|
|
30
|
-
border: '1px solid',
|
|
31
|
-
boxSizing: 'border-box',
|
|
32
|
-
color: 'white',
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
const btn = document.createElement('button');
|
|
36
|
-
btn.classList.add(classes.myButton);
|
|
37
|
-
document.body.appendChild(btn);
|
|
33
|
+
```
|
|
34
|
+
pnpm add simplestyle-js
|
|
35
|
+
```
|
|
38
36
|
|
|
39
|
-
|
|
37
|
+
**yarn**
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
```
|
|
40
|
+
yarn add simplestyle-js
|
|
42
41
|
```
|
|
43
42
|
|
|
44
|
-
##
|
|
43
|
+
## Quick Start
|
|
45
44
|
|
|
46
|
-
|
|
45
|
+
```tsx
|
|
46
|
+
import createStyles from 'simplestyle-js';
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
fontSize: '16px',
|
|
57
|
-
},
|
|
58
|
-
'body *': {
|
|
59
|
-
boxSizing: 'border-box',
|
|
60
|
-
},
|
|
61
|
-
a: {
|
|
62
|
-
'&:hover': {
|
|
63
|
-
color: 'red',
|
|
64
|
-
textDecoration: 'none',
|
|
65
|
-
},
|
|
48
|
+
const { classes } = createStyles('Button', {
|
|
49
|
+
root: {
|
|
50
|
+
'&:hover': { backgroundColor: '#2d6cdf' },
|
|
51
|
+
'@media (max-width: 768px)': { padding: '10px 12px' },
|
|
52
|
+
backgroundColor: '#1f4aa8',
|
|
53
|
+
borderRadius: 6,
|
|
54
|
+
color: '#fff',
|
|
55
|
+
padding: '12px 16px',
|
|
66
56
|
},
|
|
67
57
|
});
|
|
68
58
|
|
|
69
|
-
|
|
70
|
-
// You can then use this animation name in your CSS-in-JS styles
|
|
71
|
-
// in place of where you'd normally place an animation name
|
|
72
|
-
const [animationName] = keyframes({
|
|
73
|
-
'0%': {
|
|
74
|
-
borderColor: 'red',
|
|
75
|
-
},
|
|
76
|
-
'50%': {
|
|
77
|
-
borderColor: 'blue',
|
|
78
|
-
},
|
|
79
|
-
'100%': {
|
|
80
|
-
borderColor: 'red',
|
|
81
|
-
},
|
|
82
|
-
});
|
|
59
|
+
document.querySelector('button')?.classList.add(classes.root);
|
|
83
60
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
61
|
+
// or, in a React / JSX-like component
|
|
62
|
+
const Button = (props) => <button {...props} className={classes.root}>Awesome button</button>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Rules support nested selectors via `&`, media queries, and `$className` back-references to other generated classes.
|
|
66
|
+
|
|
67
|
+
## API Reference (from `src/index.ts`)
|
|
68
|
+
|
|
69
|
+
- `createStyles(ruleId, rules, options?)`
|
|
70
|
+
- Builds a set of class names and CSS from a rules object. Returns `{ classes, stylesheet, updateSheet }`.
|
|
71
|
+
- `options.flush` (default `true`): injects a `<style>` tag into `document.head`.
|
|
72
|
+
- `options.insertBefore` / `insertAfter`: choose where the `<style>` tag is placed when flushing.
|
|
73
|
+
- `options.registry`: provide a `SimpleStyleRegistry` instance to **collect** CSS instead of touching the DOM (ideal for SSR).
|
|
74
|
+
- `updateSheet(updatedRules)` merges rules and updates the existing sheet (works when `flush` is `true` or a `registry` is provided). Returns `{ classes, stylesheet } | null`.
|
|
75
|
+
- Example:
|
|
76
|
+
```ts
|
|
77
|
+
const { classes, stylesheet } = createStyles('Nav', {
|
|
78
|
+
wrapper: { display: 'flex', gap: 12 },
|
|
79
|
+
link: {
|
|
80
|
+
'&:hover': { textDecoration: 'underline' },
|
|
103
81
|
},
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
height: '100px',
|
|
110
|
-
left: 0,
|
|
111
|
-
position: 'fixed',
|
|
112
|
-
right: 0,
|
|
113
|
-
top: 0,
|
|
114
|
-
},
|
|
115
|
-
}); // A new <style /> tag will appear in the header immediately after calling this function
|
|
82
|
+
'@media (max-width: 600px)': {
|
|
83
|
+
wrapper: { flexDirection: 'column' },
|
|
84
|
+
},
|
|
85
|
+
}, { flush: false }); // do not write to the DOM automatically
|
|
86
|
+
```
|
|
116
87
|
|
|
117
|
-
|
|
118
|
-
|
|
88
|
+
- `keyframes(ruleId, frames, options?)`
|
|
89
|
+
- Generates a unique animation name and accompanying `@keyframes` CSS.
|
|
90
|
+
- Returns `[animationName, stylesheet]`. Respects `flush` and `insertBefore/After` options.
|
|
119
91
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
// the same classNames across successive calls.
|
|
124
|
-
// This is useful if you're going to be generating your stylesheets on the server
|
|
125
|
-
// and then rehydrating
|
|
92
|
+
- `rawStyles(ruleId, rules, options?)`
|
|
93
|
+
- Writes rules without generating new class names. Keys must already be selectors (e.g., `html`, `body *`, `.app`).
|
|
94
|
+
- Good for global resets or theme primitives. Respects `flush` and `registry`.
|
|
126
95
|
|
|
127
|
-
|
|
96
|
+
- `makeCreateStyles(registry)`
|
|
97
|
+
- Convenience wrapper that returns a `createStyles` instance pre-bound to a `SimpleStyleRegistry`. Use this when you want every call to accumulate in a registry (especially useful for SSR / Server-side rendering).
|
|
128
98
|
|
|
129
|
-
|
|
99
|
+
- `makeRawStyles(registry)` *(from `simplestyle-js/createStyles`)*
|
|
100
|
+
- Returns a `rawStyles` helper preconfigured with the provided registry; calls will auto-add to that registry instead of touching the DOM (same motivation as `makeCreateStyles` for SSR motivations).
|
|
130
101
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
backgroundColor: 'red,
|
|
134
|
-
},
|
|
135
|
-
});
|
|
102
|
+
- `makeKeyframes(registry)` *(from `simplestyle-js/createStyles`)*
|
|
103
|
+
- Returns a `keyframes` helper preconfigured with the provided registry; calls will auto-add to that registry instead of touching the DOM (same motivation as `makeCreateStyles` for SSR motivations).
|
|
136
104
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
myRule: {
|
|
140
|
-
height: '400px,
|
|
141
|
-
},
|
|
142
|
-
});
|
|
143
|
-
const { classes: updatedClasses } = updateSheet({
|
|
144
|
-
anotherRule: {
|
|
145
|
-
textTransform: 'uppercase',
|
|
146
|
-
},
|
|
147
|
-
myRule: {
|
|
148
|
-
height: '200px',
|
|
149
|
-
},
|
|
150
|
-
}); // will update replace the existing sheet's contents and you can use the updatedClassnames here
|
|
105
|
+
- `setSeed(seed: number | null)`
|
|
106
|
+
- Controls the deterministic suffix used for generated class names. Setting the same seed in server and client renders keeps class names stable for hydration. Pass `null` to reset to `Date.now()`.
|
|
151
107
|
|
|
152
|
-
|
|
108
|
+
- `registerPosthook(fn: (sheet: string) => string)`
|
|
109
|
+
- Adds a transform that runs after CSS strings are generated but before they are flushed or stored. Use for autoprefixing, minification, or custom transforms. Hooks run in registration order.
|
|
153
110
|
|
|
154
|
-
|
|
155
|
-
|
|
111
|
+
- Types
|
|
112
|
+
- `SimpleStyleRules`: `{ [selectorOrKey: string]: Properties | SimpleStyleRules }` (recursive rule tree).
|
|
113
|
+
- `CreateStylesOptions`: shape of the options described above.
|
|
114
|
+
- `PosthookPlugin`: signature for `registerPosthook`.
|
|
156
115
|
|
|
157
|
-
|
|
158
|
-
nav: {
|
|
159
|
-
backgroundColor: '#ccaa00',
|
|
160
|
-
width: '24em',
|
|
161
|
-
},
|
|
162
|
-
}, { flush: false }); // prevents immediate flushing of the <style /> tag to the DOM
|
|
163
|
-
const { classes: moreClasses, stylesheet: moreSheetContents } = createStyles({
|
|
164
|
-
navButtons: {
|
|
165
|
-
padding: '.5em',
|
|
166
|
-
},
|
|
167
|
-
}, { flush: false }); // prevents immediate flushing of the <style /> tag to the DOM
|
|
116
|
+
## Patterns and Tips
|
|
168
117
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
118
|
+
- **Nested selectors**: `&` is replaced with the parent selector. Comma-separated selectors are supported (e.g., `'&:hover, &:focus'`).
|
|
119
|
+
- **Back-references**: Use `$otherRule` to reference another generated class in the same `createStyles` call.
|
|
120
|
+
- **NOTE:** The `$otherRule` needs to have been declared above where you're trying to use it in a descendant selector.
|
|
121
|
+
- **Media queries**: Top-level `@media` keys contain further rule objects.
|
|
122
|
+
- **DOM placement**: `insertBefore` and `insertAfter` let you control the exact placement for where `<style />` tags will be rendered (does not apply to SSR / Server-side rendering).br
|
|
123
|
+
- **Updating styles**: `updateSheet` merges the new rules and updates the existing `<style>` tag (or registry entry, if you're not letting `simplestyle-js` flush to the DOM automatically for you). It also returns `{ classes, stylesheet }` so you can re-use class names if needed.
|
|
172
124
|
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* By default, simple style will insert the <style /> tags
|
|
176
|
-
* it creates in the document <head />. You can change this
|
|
177
|
-
* by providing either an "insertBefore" or "insertAfter"
|
|
178
|
-
* DOM node.
|
|
179
|
-
*/
|
|
180
|
-
|
|
181
|
-
const someElement = document.getElementById('some-element');
|
|
182
|
-
|
|
183
|
-
const { classes, stylesheet } = createStyles({
|
|
184
|
-
nav: {
|
|
185
|
-
backgroundColor: '#ccaa00',
|
|
186
|
-
width: '24em',
|
|
187
|
-
},
|
|
188
|
-
}, { insertBefore: someElement }); // <style /> will be inserted into the DOM *before* someElement
|
|
125
|
+
## SSR
|
|
189
126
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
navButtons: {
|
|
193
|
-
padding: '.5em',
|
|
194
|
-
},
|
|
195
|
-
}, { insertAfter: anotherElement }); // <style /> will be insert into the DOM *after* anotherElement
|
|
127
|
+
`simplestyle-js` is intentionally unopinionated, especially when it comes to deep integrations with various frameworks. This also applies to SSR / Server-side rendering.
|
|
128
|
+
The core APIs needed to make this work are:
|
|
196
129
|
|
|
197
|
-
|
|
198
|
-
|
|
130
|
+
- `new SimpleStyleRegistry()` - creates a new StyleSheet registry where all of your styles will be accumulated
|
|
131
|
+
- `setSeed(number)` - ensures that classNames are deterministically computed and will be the same on the server and when they're rehydrated on the client
|
|
132
|
+
- `makeCreateStyle(registry)` - returns a `createStyles()` function that is locked to your StyleSheet registry
|
|
133
|
+
- `makeKeyframes(registry)` - returns a `keyframes()` function that is locaked to your StyleSheet registry
|
|
199
134
|
|
|
200
|
-
|
|
135
|
+
### SSR steps for most SSR / SSG frameworks (including Next.js)
|
|
136
|
+
|
|
137
|
+
#### 1. Set your seed, create a SimpleStyleRegistry and your style functions
|
|
201
138
|
|
|
202
|
-
|
|
203
|
-
|
|
139
|
+
**Note**: This file can be located anywhere in your repository.
|
|
140
|
+
For demonstration purposes, we'll locate this at our `src/` root, and name it `styleLib.js`
|
|
204
141
|
|
|
205
142
|
```javascript
|
|
206
|
-
import
|
|
207
|
-
import {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
143
|
+
import { makeCreateStyles, makeKeyframes, makeRawStyles, setSeed } from "simplestyle-js";
|
|
144
|
+
import { SimpleStyleRegistry } from "simplestyle-js/simpleStyleRegistry";
|
|
145
|
+
|
|
146
|
+
// set the className generation seed to ensure classNames are computed consistently
|
|
147
|
+
// between the client and the server.
|
|
148
|
+
// the number you use is arbitrary.
|
|
149
|
+
// set it higher to have most characters injected in your generated class names
|
|
150
|
+
setSeed(1);
|
|
151
|
+
|
|
152
|
+
// create the registry to hold all of the styles on the server
|
|
153
|
+
export const StyleRegistry = new SimpleStyleRegistry();
|
|
154
|
+
|
|
155
|
+
// export the style functions that will be locked to your registry
|
|
156
|
+
export const createStyles = makeCreateStyles(StyleRegistry);
|
|
157
|
+
export const keyframes = makeKeyframes(StyleRegistry);
|
|
158
|
+
export const rawStyles = makeRawStyles(StyleRegistry);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### 2. Render the generated styles in your HTML
|
|
223
162
|
|
|
163
|
+
**Note**: If you use Next.js, you would do this in your `layout.jsx` or `layout.tsx` file.
|
|
164
|
+
Additionally, if you're not using React or any other JSX-inspired framework, you can use
|
|
165
|
+
`StyleRegistry.getHTML()` to return an HTML string with all of the `<style />` tags you need,
|
|
166
|
+
or `StyleRegistry.getCSS()` to just return a single, concatenated CSS string.
|
|
167
|
+
|
|
168
|
+
```jsx
|
|
169
|
+
import { StyleRegistry } from '../styleLib.js';
|
|
170
|
+
|
|
171
|
+
export default function Layout({ children }) {
|
|
224
172
|
return (
|
|
225
|
-
<
|
|
226
|
-
<
|
|
227
|
-
|
|
173
|
+
<body lang="en">
|
|
174
|
+
{/* render your <style /> tags and set the IDs on them */}
|
|
175
|
+
{StyleRegistry.getRulesById().map(([id, css]) => (
|
|
176
|
+
<style id={id} key={id}>
|
|
177
|
+
{css}
|
|
178
|
+
</style>
|
|
179
|
+
))}
|
|
180
|
+
{children}
|
|
181
|
+
</body>
|
|
228
182
|
);
|
|
229
|
-
}
|
|
183
|
+
}
|
|
230
184
|
```
|
|
231
185
|
|
|
232
|
-
|
|
233
|
-
A recent update has removed the need for a "prehook" plugin (see previous [documentation](https://github.com/benduran/simplestyle/blob/276aac7fd8b64c6cbfced152249aac7024351092/README.md#prehook-plugin-example-poor-mans-autoprefixer) for historical purposes).
|
|
234
|
-
There is a single type of plugin:
|
|
235
|
-
- `posthook`
|
|
236
|
-
- Called on all style rule objects *after* the CSS string has been generated, but before it has been written to the DOM in a `<style />` tag
|
|
237
|
-
- When creating a plugin, for improved SEO, it is **highly recommended** that you prefix the plugin package name with `simplestyle-js-plugin-*`.
|
|
238
|
-
- See the official `postcss` Simplestyle plugin as an example: [simplestyle-js-plugin-postcss](https://www.npmjs.com/package/simplestyle-js-plugin-postcss)
|
|
186
|
+
#### 3. Create your styles and have fun!
|
|
239
187
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
import autoprefixer from 'autoprefixer';
|
|
243
|
-
import postcss from 'postcss';
|
|
244
|
-
import { createStyles, registerPostHook } from 'simplestyle-js';
|
|
188
|
+
```jsx
|
|
189
|
+
import { createStyles } from '../styleLib.js';
|
|
245
190
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
191
|
+
// create your styles
|
|
192
|
+
const { classes } = createStyles({
|
|
193
|
+
awesome: {
|
|
194
|
+
backgroundColor: 'purple',
|
|
195
|
+
fontSize: '2rem',
|
|
196
|
+
padding: '2rem',
|
|
197
|
+
|
|
198
|
+
'& > span': {
|
|
199
|
+
fontStyle: 'italic',
|
|
200
|
+
fontWeight: 'bold',
|
|
201
|
+
textDecoration: 'underline',
|
|
202
|
+
},
|
|
251
203
|
},
|
|
252
204
|
});
|
|
253
|
-
const div = document.createElement('div');
|
|
254
|
-
div.classList.add(styles.posthookRoot); // This div will have all vendor prefixed CSS properties based on how PostCSS and Autoprefixer transform the CSS
|
|
255
|
-
document.body.appendChild(div);
|
|
256
|
-
|
|
257
|
-
// Or in a React / JSX-style component
|
|
258
205
|
|
|
259
|
-
|
|
206
|
+
export function MyCoolComponent() {
|
|
207
|
+
// use your styles here!
|
|
208
|
+
return (
|
|
209
|
+
<div className={classes.awesome}>
|
|
210
|
+
This is super <span>cool.</span>
|
|
211
|
+
</div>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
260
214
|
```
|
|
261
|
-
### Plugin API
|
|
262
|
-
SimpleStyle does one thing out of the box well, and that's providing an intuitive way for you to write your CSS-in-JS in ways that are very similar to popular CSS Preprocessors like LESS, SASS, Stylus, among others. If you need to provide additional functionality that's not offered in the core library, `simplestyle-js` provides easy ways to tie into lifecycle hooks in the style rendering process if you need to stub out additional behavior. This allows you to create and chain an infinite number of plugins, based on your needs.
|
|
263
215
|
|
|
264
|
-
|
|
216
|
+
## Creating a simplestyle-js plugin
|
|
217
|
+
|
|
218
|
+
Do this if you want to integrate with `postcss`, `autoprefixer`, or any other CSS transformation utility you desire.
|
|
265
219
|
|
|
266
|
-
|
|
267
|
-
- `postHookFnc` is a function that accepts one parameter, which is the string contents of the sheet that should eventually be written to the DOM. This function should return a string, after you've done any desired transformations to the sheetContents.
|
|
220
|
+
### Plugin Example (Autoprefixer)
|
|
268
221
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
222
|
+
```ts
|
|
223
|
+
import autoprefixer from 'autoprefixer';
|
|
224
|
+
import postcss from 'postcss';
|
|
225
|
+
import { registerPosthook } from 'simplestyle-js';
|
|
226
|
+
|
|
227
|
+
registerPosthook(css => postcss([autoprefixer]).process(css, { from: undefined }).css);
|
|
228
|
+
```
|
|
273
229
|
|
|
274
|
-
|
|
275
|
-
If you need SSR rendering in a CSS-in-JS engine, consider using [Emotion](https://emotion.sh/docs/introduction), instead.
|
|
230
|
+
Any future `createStyles`, `rawStyles`, or `keyframes` calls will run through the posthook chain.
|
|
276
231
|
|
|
277
232
|
## License
|
|
278
233
|
[MIT](https://en.wikipedia.org/wiki/MIT_License)
|
|
@@ -15,8 +15,14 @@ _export(exports, {
|
|
|
15
15
|
get keyframes () {
|
|
16
16
|
return keyframes;
|
|
17
17
|
},
|
|
18
|
-
get
|
|
19
|
-
return
|
|
18
|
+
get makeCreateStyles () {
|
|
19
|
+
return makeCreateStyles;
|
|
20
|
+
},
|
|
21
|
+
get makeKeyframes () {
|
|
22
|
+
return makeKeyframes;
|
|
23
|
+
},
|
|
24
|
+
get makeRawStyles () {
|
|
25
|
+
return makeRawStyles;
|
|
20
26
|
},
|
|
21
27
|
get rawStyles () {
|
|
22
28
|
return rawStyles;
|
|
@@ -151,6 +157,13 @@ function rawStyles(ruleId, rules, options) {
|
|
|
151
157
|
if (coerced.flush) flushSheetContents(ruleId, mergedContents, options);
|
|
152
158
|
return mergedContents;
|
|
153
159
|
}
|
|
160
|
+
function makeRawStyles(registry) {
|
|
161
|
+
return function wrappedRawStyles(ruleId, rules) {
|
|
162
|
+
return rawStyles(ruleId, rules, {
|
|
163
|
+
registry
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
}
|
|
154
167
|
function keyframes(ruleId, frames, options) {
|
|
155
168
|
const coerced = coerceCreateStylesOptions(options);
|
|
156
169
|
const keyframeName = (0, _generateClassName.generateClassName)(`${ruleId}_keyframes_`);
|
|
@@ -162,7 +175,14 @@ function keyframes(ruleId, frames, options) {
|
|
|
162
175
|
sheetContents
|
|
163
176
|
];
|
|
164
177
|
}
|
|
165
|
-
function
|
|
178
|
+
function makeKeyframes(registry) {
|
|
179
|
+
return function wrappedCreateKeyframes(ruleId, rules) {
|
|
180
|
+
return keyframes(ruleId, rules, {
|
|
181
|
+
registry
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function makeCreateStyles(registry) {
|
|
166
186
|
return function wrappedCreateStyles(ruleId, rules) {
|
|
167
187
|
return createStyles(ruleId, rules, {
|
|
168
188
|
registry
|
|
@@ -175,9 +195,8 @@ function createStyles(ruleId, rules, options) {
|
|
|
175
195
|
const mergedContents = `${sheetContents}${mediaQueriesContents}`;
|
|
176
196
|
const replacedSheetContents = replaceBackReferences(out, mergedContents);
|
|
177
197
|
let sheet = null;
|
|
178
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
179
198
|
const updateSheet = (updatedRules)=>{
|
|
180
|
-
if (
|
|
199
|
+
if (options?.flush || options?.registry || !options?.flush) {
|
|
181
200
|
// We prefer the first set, and then we shallow merge
|
|
182
201
|
const { classes: updatedOut, sheetBuffer: updatedSheetContents, mediaQueriesBuffer: updatedMediaQueriesContents } = execCreateStyles(ruleId, (0, _deepmerge.default)(rules, updatedRules), {
|
|
183
202
|
flush: false
|
|
@@ -185,6 +204,9 @@ function createStyles(ruleId, rules, options) {
|
|
|
185
204
|
const updatedMergedContents = `${updatedSheetContents}${updatedMediaQueriesContents}`;
|
|
186
205
|
const updatedReplacedSheetContents = replaceBackReferences(out, updatedMergedContents);
|
|
187
206
|
if (sheet) sheet.innerHTML = updatedReplacedSheetContents;
|
|
207
|
+
else if (options?.registry) {
|
|
208
|
+
options.registry.add(ruleId, updatedReplacedSheetContents);
|
|
209
|
+
}
|
|
188
210
|
return {
|
|
189
211
|
classes: updatedOut,
|
|
190
212
|
stylesheet: updatedSheetContents
|
|
@@ -26,12 +26,14 @@ export type CreateStylesOptions = Partial<{
|
|
|
26
26
|
*/
|
|
27
27
|
registry?: SimpleStyleRegistry;
|
|
28
28
|
}>;
|
|
29
|
-
export declare function rawStyles<T extends SimpleStyleRules
|
|
29
|
+
export declare function rawStyles<T extends SimpleStyleRules>(ruleId: string, rules: T, options?: Partial<CreateStylesOptions>): string;
|
|
30
|
+
export declare function makeRawStyles(registry: SimpleStyleRegistry): <T extends SimpleStyleRules>(ruleId: string, rules: T) => string;
|
|
30
31
|
export declare function keyframes<T extends Record<string, Properties>>(ruleId: string, frames: T, options?: CreateStylesOptions): [string, string];
|
|
31
|
-
export declare function
|
|
32
|
+
export declare function makeKeyframes(registry: SimpleStyleRegistry): <T extends Record<string, Properties>>(ruleId: string, rules: T) => [string, string];
|
|
33
|
+
export declare function makeCreateStyles(registry: SimpleStyleRegistry): <T extends SimpleStyleRules, K extends keyof T, O extends Record<K, string>>(ruleId: string, rules: T) => {
|
|
32
34
|
classes: O;
|
|
33
35
|
stylesheet: string;
|
|
34
|
-
updateSheet: <T2 extends SimpleStyleRules
|
|
36
|
+
updateSheet: <T2 extends SimpleStyleRules>(updatedRules: Partial<T2>) => {
|
|
35
37
|
classes: Record<string | number | keyof T2, string>;
|
|
36
38
|
stylesheet: string;
|
|
37
39
|
} | null;
|
|
@@ -39,7 +41,7 @@ export declare function makeCreateStyle(registry: SimpleStyleRegistry): <T exten
|
|
|
39
41
|
export default function createStyles<T extends SimpleStyleRules, K extends keyof T, O extends Record<K, string>>(ruleId: string, rules: T, options?: Partial<CreateStylesOptions>): {
|
|
40
42
|
classes: O;
|
|
41
43
|
stylesheet: string;
|
|
42
|
-
updateSheet: <T2 extends SimpleStyleRules
|
|
44
|
+
updateSheet: <T2 extends SimpleStyleRules>(updatedRules: Partial<T2>) => {
|
|
43
45
|
classes: Record<string | number | keyof T2, string>;
|
|
44
46
|
stylesheet: string;
|
|
45
47
|
} | null;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -15,8 +15,14 @@ _export(exports, {
|
|
|
15
15
|
get keyframes () {
|
|
16
16
|
return _createStyles.keyframes;
|
|
17
17
|
},
|
|
18
|
-
get
|
|
19
|
-
return _createStyles.
|
|
18
|
+
get makeCreateStyles () {
|
|
19
|
+
return _createStyles.makeCreateStyles;
|
|
20
|
+
},
|
|
21
|
+
get makeKeyframes () {
|
|
22
|
+
return _createStyles.makeKeyframes;
|
|
23
|
+
},
|
|
24
|
+
get makeRawStyles () {
|
|
25
|
+
return _createStyles.makeRawStyles;
|
|
20
26
|
},
|
|
21
27
|
get rawStyles () {
|
|
22
28
|
return _createStyles.rawStyles;
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { CreateStylesArgs, CreateStylesOptions } from './createStyles.js';
|
|
2
|
-
export { default as createStyles, keyframes,
|
|
2
|
+
export { default as createStyles, keyframes, makeCreateStyles, makeKeyframes, makeRawStyles, rawStyles, } from './createStyles.js';
|
|
3
3
|
export { setSeed } from './generateClassName.js';
|
|
4
4
|
export type { PosthookPlugin } from './plugins.js';
|
|
5
5
|
export { registerPosthook } from './plugins.js';
|
|
@@ -33,4 +33,16 @@ ${contents}`, '');
|
|
|
33
33
|
return this.sheets.entries().reduce((prev, [ruleId, contents])=>`${prev}
|
|
34
34
|
<style id="${ruleId}">${contents}</style>`, '');
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* returns an array of tuples, [string, string][]
|
|
38
|
+
* where the first item in the tuple is the ID for the style rule
|
|
39
|
+
* and the second item is the actual CSS.
|
|
40
|
+
* Use this if you need to fully-control how you're rendering
|
|
41
|
+
* style tags BUT BE SURE TO USE THE ID or else HMR
|
|
42
|
+
* won't work during local development
|
|
43
|
+
*/ getRulesById() {
|
|
44
|
+
return [
|
|
45
|
+
...this.sheets.entries()
|
|
46
|
+
];
|
|
47
|
+
}
|
|
36
48
|
}
|
|
@@ -16,4 +16,13 @@ export declare class SimpleStyleRegistry {
|
|
|
16
16
|
* mapped to their internal ruleset IDs
|
|
17
17
|
*/
|
|
18
18
|
getHTML(): string;
|
|
19
|
+
/**
|
|
20
|
+
* returns an array of tuples, [string, string][]
|
|
21
|
+
* where the first item in the tuple is the ID for the style rule
|
|
22
|
+
* and the second item is the actual CSS.
|
|
23
|
+
* Use this if you need to fully-control how you're rendering
|
|
24
|
+
* style tags BUT BE SURE TO USE THE ID or else HMR
|
|
25
|
+
* won't work during local development
|
|
26
|
+
*/
|
|
27
|
+
getRulesById(): [string, string][];
|
|
19
28
|
}
|
|
@@ -26,12 +26,14 @@ export type CreateStylesOptions = Partial<{
|
|
|
26
26
|
*/
|
|
27
27
|
registry?: SimpleStyleRegistry;
|
|
28
28
|
}>;
|
|
29
|
-
export declare function rawStyles<T extends SimpleStyleRules
|
|
29
|
+
export declare function rawStyles<T extends SimpleStyleRules>(ruleId: string, rules: T, options?: Partial<CreateStylesOptions>): string;
|
|
30
|
+
export declare function makeRawStyles(registry: SimpleStyleRegistry): <T extends SimpleStyleRules>(ruleId: string, rules: T) => string;
|
|
30
31
|
export declare function keyframes<T extends Record<string, Properties>>(ruleId: string, frames: T, options?: CreateStylesOptions): [string, string];
|
|
31
|
-
export declare function
|
|
32
|
+
export declare function makeKeyframes(registry: SimpleStyleRegistry): <T extends Record<string, Properties>>(ruleId: string, rules: T) => [string, string];
|
|
33
|
+
export declare function makeCreateStyles(registry: SimpleStyleRegistry): <T extends SimpleStyleRules, K extends keyof T, O extends Record<K, string>>(ruleId: string, rules: T) => {
|
|
32
34
|
classes: O;
|
|
33
35
|
stylesheet: string;
|
|
34
|
-
updateSheet: <T2 extends SimpleStyleRules
|
|
36
|
+
updateSheet: <T2 extends SimpleStyleRules>(updatedRules: Partial<T2>) => {
|
|
35
37
|
classes: Record<string | number | keyof T2, string>;
|
|
36
38
|
stylesheet: string;
|
|
37
39
|
} | null;
|
|
@@ -39,7 +41,7 @@ export declare function makeCreateStyle(registry: SimpleStyleRegistry): <T exten
|
|
|
39
41
|
export default function createStyles<T extends SimpleStyleRules, K extends keyof T, O extends Record<K, string>>(ruleId: string, rules: T, options?: Partial<CreateStylesOptions>): {
|
|
40
42
|
classes: O;
|
|
41
43
|
stylesheet: string;
|
|
42
|
-
updateSheet: <T2 extends SimpleStyleRules
|
|
44
|
+
updateSheet: <T2 extends SimpleStyleRules>(updatedRules: Partial<T2>) => {
|
|
43
45
|
classes: Record<string | number | keyof T2, string>;
|
|
44
46
|
stylesheet: string;
|
|
45
47
|
} | null;
|
|
@@ -115,7 +115,6 @@ function coerceCreateStylesOptions(options) {
|
|
|
115
115
|
flush: options && typeof options.flush === 'boolean' ? options.flush : true
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
119
118
|
export function rawStyles(ruleId, rules, options) {
|
|
120
119
|
const coerced = coerceCreateStylesOptions(options);
|
|
121
120
|
const { sheetBuffer: sheetContents, mediaQueriesBuffer: mediaQueriesContents } = execCreateStyles(ruleId, rules, coerced, null, true);
|
|
@@ -123,6 +122,13 @@ export function rawStyles(ruleId, rules, options) {
|
|
|
123
122
|
if (coerced.flush) flushSheetContents(ruleId, mergedContents, options);
|
|
124
123
|
return mergedContents;
|
|
125
124
|
}
|
|
125
|
+
export function makeRawStyles(registry) {
|
|
126
|
+
return function wrappedRawStyles(ruleId, rules) {
|
|
127
|
+
return rawStyles(ruleId, rules, {
|
|
128
|
+
registry
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
}
|
|
126
132
|
export function keyframes(ruleId, frames, options) {
|
|
127
133
|
const coerced = coerceCreateStylesOptions(options);
|
|
128
134
|
const keyframeName = generateClassName(`${ruleId}_keyframes_`);
|
|
@@ -134,7 +140,14 @@ export function keyframes(ruleId, frames, options) {
|
|
|
134
140
|
sheetContents
|
|
135
141
|
];
|
|
136
142
|
}
|
|
137
|
-
export function
|
|
143
|
+
export function makeKeyframes(registry) {
|
|
144
|
+
return function wrappedCreateKeyframes(ruleId, rules) {
|
|
145
|
+
return keyframes(ruleId, rules, {
|
|
146
|
+
registry
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
export function makeCreateStyles(registry) {
|
|
138
151
|
return function wrappedCreateStyles(ruleId, rules) {
|
|
139
152
|
return createStyles(ruleId, rules, {
|
|
140
153
|
registry
|
|
@@ -147,9 +160,8 @@ export default function createStyles(ruleId, rules, options) {
|
|
|
147
160
|
const mergedContents = `${sheetContents}${mediaQueriesContents}`;
|
|
148
161
|
const replacedSheetContents = replaceBackReferences(out, mergedContents);
|
|
149
162
|
let sheet = null;
|
|
150
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
151
163
|
const updateSheet = (updatedRules)=>{
|
|
152
|
-
if (
|
|
164
|
+
if (options?.flush || options?.registry || !options?.flush) {
|
|
153
165
|
// We prefer the first set, and then we shallow merge
|
|
154
166
|
const { classes: updatedOut, sheetBuffer: updatedSheetContents, mediaQueriesBuffer: updatedMediaQueriesContents } = execCreateStyles(ruleId, merge(rules, updatedRules), {
|
|
155
167
|
flush: false
|
|
@@ -157,6 +169,9 @@ export default function createStyles(ruleId, rules, options) {
|
|
|
157
169
|
const updatedMergedContents = `${updatedSheetContents}${updatedMediaQueriesContents}`;
|
|
158
170
|
const updatedReplacedSheetContents = replaceBackReferences(out, updatedMergedContents);
|
|
159
171
|
if (sheet) sheet.innerHTML = updatedReplacedSheetContents;
|
|
172
|
+
else if (options?.registry) {
|
|
173
|
+
options.registry.add(ruleId, updatedReplacedSheetContents);
|
|
174
|
+
}
|
|
160
175
|
return {
|
|
161
176
|
classes: updatedOut,
|
|
162
177
|
stylesheet: updatedSheetContents
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { CreateStylesArgs, CreateStylesOptions } from './createStyles.js';
|
|
2
|
-
export { default as createStyles, keyframes,
|
|
2
|
+
export { default as createStyles, keyframes, makeCreateStyles, makeKeyframes, makeRawStyles, rawStyles, } from './createStyles.js';
|
|
3
3
|
export { setSeed } from './generateClassName.js';
|
|
4
4
|
export type { PosthookPlugin } from './plugins.js';
|
|
5
5
|
export { registerPosthook } from './plugins.js';
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { default as createStyles, keyframes,
|
|
1
|
+
export { default as createStyles, keyframes, makeCreateStyles, makeKeyframes, makeRawStyles, rawStyles } from './createStyles.mjs';
|
|
2
2
|
export { setSeed } from './generateClassName.mjs';
|
|
3
3
|
export { registerPosthook } from './plugins.mjs';
|
|
@@ -16,4 +16,13 @@ export declare class SimpleStyleRegistry {
|
|
|
16
16
|
* mapped to their internal ruleset IDs
|
|
17
17
|
*/
|
|
18
18
|
getHTML(): string;
|
|
19
|
+
/**
|
|
20
|
+
* returns an array of tuples, [string, string][]
|
|
21
|
+
* where the first item in the tuple is the ID for the style rule
|
|
22
|
+
* and the second item is the actual CSS.
|
|
23
|
+
* Use this if you need to fully-control how you're rendering
|
|
24
|
+
* style tags BUT BE SURE TO USE THE ID or else HMR
|
|
25
|
+
* won't work during local development
|
|
26
|
+
*/
|
|
27
|
+
getRulesById(): [string, string][];
|
|
19
28
|
}
|
|
@@ -28,4 +28,16 @@ ${contents}`, '');
|
|
|
28
28
|
return this.sheets.entries().reduce((prev, [ruleId, contents])=>`${prev}
|
|
29
29
|
<style id="${ruleId}">${contents}</style>`, '');
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* returns an array of tuples, [string, string][]
|
|
33
|
+
* where the first item in the tuple is the ID for the style rule
|
|
34
|
+
* and the second item is the actual CSS.
|
|
35
|
+
* Use this if you need to fully-control how you're rendering
|
|
36
|
+
* style tags BUT BE SURE TO USE THE ID or else HMR
|
|
37
|
+
* won't work during local development
|
|
38
|
+
*/ getRulesById() {
|
|
39
|
+
return [
|
|
40
|
+
...this.sheets.entries()
|
|
41
|
+
];
|
|
42
|
+
}
|
|
31
43
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simplestyle-js",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "An incredibly straightforward and simple CSS-in-JS solution with zero runtime dependencies, and out-of-the-box TypeScript support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|