mintcss 0.1.0 → 0.2.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 +97 -56
- package/dist/core.d.ts +20 -3
- package/dist/core.js +82 -43
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/next.d.ts +10 -0
- package/dist/next.js +27 -0
- package/package.json +28 -5
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# mintcss
|
|
2
2
|
|
|
3
|
-
Small, dependency-free CSS-in-JS
|
|
4
|
-
[Salvia](https://github.com/nexryai/rosmarinus/tree/main/salvia), with no React
|
|
5
|
-
runtime or type dependency. MIT licensed.
|
|
3
|
+
Small, dependency-free CSS-in-JS with optional Next.js App Router integration.
|
|
6
4
|
|
|
7
5
|
## Install
|
|
8
6
|
|
|
@@ -12,7 +10,8 @@ npm install mintcss
|
|
|
12
10
|
|
|
13
11
|
mintcss is an ESM package with bundled TypeScript declarations. It targets modern
|
|
14
12
|
browsers with `String.replaceAll` support. Importing it does not touch the DOM;
|
|
15
|
-
|
|
13
|
+
the top-level styling functions require a browser `document` with a `head`.
|
|
14
|
+
For server rendering, use `createStyleRegistry` or the Next.js integration below.
|
|
16
15
|
|
|
17
16
|
## Usage
|
|
18
17
|
|
|
@@ -55,6 +54,96 @@ export function Button() {
|
|
|
55
54
|
}
|
|
56
55
|
```
|
|
57
56
|
|
|
57
|
+
## Next.js App Router
|
|
58
|
+
|
|
59
|
+
The optional `mintcss/next` entry point supports Next.js 14–16 with React 18.2 or
|
|
60
|
+
19. React and Next.js are optional peer dependencies; the core entry point does
|
|
61
|
+
not import either framework.
|
|
62
|
+
|
|
63
|
+
Wrap the app in `MintStyleRegistry` in your root layout. The layout can remain a
|
|
64
|
+
Server Component:
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
// app/layout.tsx
|
|
68
|
+
import type { ReactNode } from "react";
|
|
69
|
+
import { MintStyleRegistry } from "mintcss/next";
|
|
70
|
+
|
|
71
|
+
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
72
|
+
return (
|
|
73
|
+
<html lang="en">
|
|
74
|
+
<body>
|
|
75
|
+
<MintStyleRegistry>{children}</MintStyleRegistry>
|
|
76
|
+
</body>
|
|
77
|
+
</html>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
In Client Components, obtain the styling functions from `useMintcss` and call
|
|
83
|
+
them during rendering:
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
// app/button.tsx
|
|
87
|
+
"use client";
|
|
88
|
+
|
|
89
|
+
import { useMintcss } from "mintcss/next";
|
|
90
|
+
|
|
91
|
+
export function Button() {
|
|
92
|
+
const { css, globalCss, keyframes } = useMintcss();
|
|
93
|
+
globalCss({ body: { margin: 0 } });
|
|
94
|
+
const fade = keyframes({ from: { opacity: 0 }, to: { opacity: 1 } });
|
|
95
|
+
const button = css({
|
|
96
|
+
backgroundColor: "#f4bd36",
|
|
97
|
+
borderRadius: 8,
|
|
98
|
+
animation: `${fade} 150ms ease-out`,
|
|
99
|
+
"&:hover": { opacity: 0.8 },
|
|
100
|
+
});
|
|
101
|
+
return <button type="button" className={button}>Hello</button>;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The registry collects CSS separately for each server render and uses Next.js's
|
|
106
|
+
[`useServerInsertedHTML`](https://nextjs.org/docs/app/guides/css-in-js) integration
|
|
107
|
+
to emit new rules as content streams. The browser reuses those rules during
|
|
108
|
+
hydration and inserts new rules for subsequent renders and navigation. The same
|
|
109
|
+
styles produce the same identifiers on the server and client.
|
|
110
|
+
|
|
111
|
+
Use the hook inside Client Components under the registry. Module-level calls to
|
|
112
|
+
the browser-only `css`, `globalCss`, or `keyframes` exports still require a DOM,
|
|
113
|
+
even in files with `"use client"`, because Next.js also renders Client Components
|
|
114
|
+
on the server. Style objects can be declared at module scope, then passed to the
|
|
115
|
+
hook's functions during rendering. Server Components cannot use `useMintcss`.
|
|
116
|
+
The automatic integration targets the App Router; Pages Router applications
|
|
117
|
+
need their own SSR collection using the API below.
|
|
118
|
+
|
|
119
|
+
For a nonce-based CSP, pass the request's nonce as
|
|
120
|
+
`<MintStyleRegistry nonce={nonce}>`. It is applied to server-generated style tags
|
|
121
|
+
and new browser style tags. Configure the corresponding CSP in your app.
|
|
122
|
+
|
|
123
|
+
## Server rendering
|
|
124
|
+
|
|
125
|
+
`createStyleRegistry({ nonce? })` provides `css`, `globalCss`, and `keyframes`
|
|
126
|
+
without requiring a DOM. Create a separate registry for every server render and
|
|
127
|
+
use its functions throughout that render; do not share a mutable registry
|
|
128
|
+
between requests.
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import { createStyleRegistry } from "mintcss";
|
|
132
|
+
|
|
133
|
+
const registry = createStyleRegistry();
|
|
134
|
+
const button = registry.css({ color: "red" });
|
|
135
|
+
const styles = registry.getStyles();
|
|
136
|
+
// styles: { ids: string[], css: string }
|
|
137
|
+
// Render a <style data-mintcss={styles.ids.join(" ")}> containing styles.css
|
|
138
|
+
// in the document head alongside the HTML using button as its class name.
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`getStyles()` returns all collected rules in insertion order. `flush()` returns
|
|
142
|
+
only the rules collected since the previous flush, retaining deduplication for
|
|
143
|
+
later streaming chunks. Include `data-mintcss` with the emitted identifiers so
|
|
144
|
+
browser calls can reuse the SSR styles. In the browser, registry styling calls
|
|
145
|
+
also insert rules into the document head.
|
|
146
|
+
|
|
58
147
|
## API
|
|
59
148
|
|
|
60
149
|
- `css(styles: CSSObject): string` inserts rules and returns a deterministic
|
|
@@ -88,60 +177,12 @@ are implementation details and should not be persisted or hard-coded.
|
|
|
88
177
|
|
|
89
178
|
## Limits
|
|
90
179
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
Strict CSP deployments must permit the generated inline stylesheet.
|
|
180
|
+
There is no build-time extraction or automatic vendor prefixing. Styles accumulate
|
|
181
|
+
for the lifetime of the document; prefer reusing stable style objects and CSS
|
|
182
|
+
variables for continuously changing values. Strict CSP deployments must permit
|
|
183
|
+
the generated inline stylesheet, for example with the registry nonce option.
|
|
96
184
|
|
|
97
185
|
The serializer rejects malformed properties and rules, non-finite numeric
|
|
98
186
|
values, and certain injection-like strings. It is **not an untrusted-input
|
|
99
187
|
sanitizer**: pass application-authored styles and validate external data before
|
|
100
188
|
using it, particularly URLs. It does not enforce an external URL policy.
|
|
101
|
-
|
|
102
|
-
## Tests
|
|
103
|
-
|
|
104
|
-
Tests with a DOM environment can reset the shared stylesheet between cases:
|
|
105
|
-
|
|
106
|
-
```ts
|
|
107
|
-
import { afterEach } from "vitest";
|
|
108
|
-
import { __resetCssForTests } from "mintcss/testing";
|
|
109
|
-
|
|
110
|
-
afterEach(__resetCssForTests);
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
This helper removes all mintcss rules in the current document. Use it only in tests.
|
|
114
|
-
|
|
115
|
-
## Development and publishing
|
|
116
|
-
|
|
117
|
-
Use Node.js 22.12 or later:
|
|
118
|
-
|
|
119
|
-
```sh
|
|
120
|
-
npm ci
|
|
121
|
-
npm run lint
|
|
122
|
-
npm run check
|
|
123
|
-
npm test
|
|
124
|
-
npm run test:package
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
`test:package` builds a real npm tarball, installs it into a temporary consumer,
|
|
128
|
-
and checks its ESM exports, TypeScript declarations, and shipped files without
|
|
129
|
-
React. CI runs these checks on Node.js 22 and 24. The Biome configuration and
|
|
130
|
-
version are copied from Salvia; package-internal `#` imports keep the same rule
|
|
131
|
-
against relative imports.
|
|
132
|
-
|
|
133
|
-
For the first release, verify the package name is still available and sign in
|
|
134
|
-
to an npm account authorized to publish it:
|
|
135
|
-
|
|
136
|
-
```sh
|
|
137
|
-
npm view mintcss
|
|
138
|
-
npm login
|
|
139
|
-
npm publish --dry-run
|
|
140
|
-
npm publish
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
The initial version is `0.1.0`. `prepack` builds `dist`; `prepublishOnly` runs the
|
|
144
|
-
checks before publishing. Only compiled JavaScript, declarations, README,
|
|
145
|
-
LICENSE, and package metadata are shipped. Later releases must increment the
|
|
146
|
-
version before publishing. Publishing is manual; a successful CI run does not
|
|
147
|
-
publish a release.
|
package/dist/core.d.ts
CHANGED
|
@@ -3,7 +3,24 @@ export type CSSObject = {
|
|
|
3
3
|
[key: string]: CSSValue | CSSObject | undefined;
|
|
4
4
|
};
|
|
5
5
|
export type CSSDeclarations = Record<string, CSSValue | undefined>;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
declare const createStyleApi: (insert: (id: string, rule: string) => void) => {
|
|
7
|
+
css: (object: CSSObject) => string;
|
|
8
|
+
keyframes: (frames: Record<string, CSSDeclarations>) => string;
|
|
9
|
+
globalCss: (rules: Record<string, CSSObject>) => void;
|
|
10
|
+
};
|
|
11
|
+
export declare const css: (object: CSSObject) => string, keyframes: (frames: Record<string, CSSDeclarations>) => string, globalCss: (rules: Record<string, CSSObject>) => void;
|
|
12
|
+
export type StyleSnapshot = {
|
|
13
|
+
ids: string[];
|
|
14
|
+
css: string;
|
|
15
|
+
};
|
|
16
|
+
export type StyleApi = ReturnType<typeof createStyleApi>;
|
|
17
|
+
export type StyleRegistry = StyleApi & {
|
|
18
|
+
getStyles: () => StyleSnapshot;
|
|
19
|
+
flush: () => StyleSnapshot;
|
|
20
|
+
};
|
|
21
|
+
/** Create a registry per server render. Browser calls also insert into the DOM. */
|
|
22
|
+
export declare const createStyleRegistry: (options?: {
|
|
23
|
+
nonce?: string;
|
|
24
|
+
}) => StyleRegistry;
|
|
9
25
|
export declare const __resetCssForTests: () => void;
|
|
26
|
+
export {};
|
package/dist/core.js
CHANGED
|
@@ -49,6 +49,7 @@ const declaration = (property, value) => {
|
|
|
49
49
|
return `${hyphenate(property)}:${serialized};`;
|
|
50
50
|
};
|
|
51
51
|
const serializeRule = (selector, object) => {
|
|
52
|
+
assertSafe(selector, "selector");
|
|
52
53
|
let declarations = "";
|
|
53
54
|
let nested = "";
|
|
54
55
|
for (const key of Object.keys(object).sort()) {
|
|
@@ -88,7 +89,7 @@ const hash = (value) => {
|
|
|
88
89
|
}
|
|
89
90
|
return (result >>> 0).toString(36);
|
|
90
91
|
};
|
|
91
|
-
const registry = () => {
|
|
92
|
+
const registry = (nonce) => {
|
|
92
93
|
if (typeof document === "undefined")
|
|
93
94
|
throw new Error("mintcss requires a browser document");
|
|
94
95
|
if (styleElement?.isConnected && styleElement.ownerDocument === document)
|
|
@@ -97,12 +98,21 @@ const registry = () => {
|
|
|
97
98
|
styleElement = existing ?? document.createElement("style");
|
|
98
99
|
if (!existing) {
|
|
99
100
|
styleElement.setAttribute(STYLE_ATTRIBUTE, "");
|
|
101
|
+
if (nonce !== undefined)
|
|
102
|
+
styleElement.nonce = nonce;
|
|
100
103
|
document.head.append(styleElement);
|
|
101
104
|
}
|
|
102
105
|
return styleElement;
|
|
103
106
|
};
|
|
104
|
-
const insert = (id, rule) => {
|
|
105
|
-
|
|
107
|
+
const insert = (id, rule, nonce) => {
|
|
108
|
+
if (typeof document === "undefined")
|
|
109
|
+
throw new Error("mintcss requires a browser document; use createStyleRegistry for SSR or useMintcss in Next.js");
|
|
110
|
+
// Streaming SSR can emit several style elements. Consult all of them.
|
|
111
|
+
for (const element of document.head.querySelectorAll(`style[${STYLE_ATTRIBUTE}]`)) {
|
|
112
|
+
if ((element.dataset.mintcss ?? "").split(" ").includes(id))
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const target = registry(nonce);
|
|
106
116
|
// The DOM is authoritative across module reloads and stylesheet replacement.
|
|
107
117
|
const registeredInDOM = new Set((target.dataset.mintcss ?? "").split(" ").filter(Boolean));
|
|
108
118
|
if (registeredInDOM.has(id))
|
|
@@ -111,46 +121,75 @@ const insert = (id, rule) => {
|
|
|
111
121
|
target.dataset.mintcss = [...registeredInDOM].join(" ");
|
|
112
122
|
target.append(document.createTextNode(rule));
|
|
113
123
|
};
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
124
|
+
const createStyleApi = (insert) => ({
|
|
125
|
+
css: (object) => {
|
|
126
|
+
const id = `mint-${hash(canonicalize(object))}`;
|
|
127
|
+
insert(id, serializeRule(`.${id}`, object));
|
|
128
|
+
return id;
|
|
129
|
+
},
|
|
130
|
+
keyframes: (frames) => {
|
|
131
|
+
const object = frames;
|
|
132
|
+
const name = `mint-kf-${hash(canonicalize(object))}`;
|
|
133
|
+
const body = Object.entries(object)
|
|
134
|
+
.sort(([left], [right]) => {
|
|
135
|
+
const position = (step) => (step === "from" ? 0 : step === "to" ? 100 : Number.parseInt(step, 10));
|
|
136
|
+
return position(left) - position(right);
|
|
137
|
+
})
|
|
138
|
+
.map(([step, properties]) => {
|
|
139
|
+
if (!/^(from|to|(?:\d|[1-9]\d|100)%)$/.test(step))
|
|
140
|
+
throw new Error(`Invalid keyframe step: ${step}`);
|
|
141
|
+
return serializeRule(step, properties);
|
|
142
|
+
})
|
|
143
|
+
.join("");
|
|
144
|
+
insert(name, `@keyframes ${name}{${body}}`);
|
|
145
|
+
return name;
|
|
146
|
+
},
|
|
147
|
+
globalCss: (rules) => {
|
|
148
|
+
const output = Object.entries(rules)
|
|
149
|
+
.map(([selector, object]) => {
|
|
150
|
+
if (selector.startsWith("@media") || selector.startsWith("@supports")) {
|
|
151
|
+
assertConditionalRule(selector);
|
|
152
|
+
return `${selector}{${Object.entries(object)
|
|
153
|
+
.map(([nestedSelector, nestedObject]) => {
|
|
154
|
+
assertSafe(nestedSelector, "selector");
|
|
155
|
+
return serializeRule(nestedSelector, nestedObject);
|
|
156
|
+
})
|
|
157
|
+
.join("")}}`;
|
|
158
|
+
}
|
|
159
|
+
assertSafe(selector, "selector");
|
|
160
|
+
return serializeRule(selector, object);
|
|
161
|
+
})
|
|
162
|
+
.join("");
|
|
163
|
+
const id = `mint-global-${hash(output)}`;
|
|
164
|
+
insert(id, output);
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
export const { css, keyframes, globalCss } = createStyleApi(insert);
|
|
168
|
+
/** Create a registry per server render. Browser calls also insert into the DOM. */
|
|
169
|
+
export const createStyleRegistry = (options = {}) => {
|
|
170
|
+
const rules = new Map();
|
|
171
|
+
const pending = new Map();
|
|
172
|
+
const snapshot = (entries) => ({
|
|
173
|
+
ids: [...entries.keys()],
|
|
174
|
+
// Rules are validated by the serializer, including closing style tags.
|
|
175
|
+
css: [...entries.values()].join(""),
|
|
176
|
+
});
|
|
177
|
+
return {
|
|
178
|
+
...createStyleApi((id, rule) => {
|
|
179
|
+
if (typeof document !== "undefined")
|
|
180
|
+
insert(id, rule, options.nonce);
|
|
181
|
+
if (rules.has(id))
|
|
182
|
+
return;
|
|
183
|
+
rules.set(id, rule);
|
|
184
|
+
pending.set(id, rule);
|
|
185
|
+
}),
|
|
186
|
+
getStyles: () => snapshot(rules),
|
|
187
|
+
flush: () => {
|
|
188
|
+
const styles = snapshot(pending);
|
|
189
|
+
pending.clear();
|
|
190
|
+
return styles;
|
|
191
|
+
},
|
|
192
|
+
};
|
|
154
193
|
};
|
|
155
194
|
export const __resetCssForTests = () => {
|
|
156
195
|
document.head.querySelector(`style[${STYLE_ATTRIBUTE}]`)?.remove();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { CSSDeclarations, CSSObject, CSSValue } from "#core";
|
|
2
|
-
export { css, globalCss, keyframes } from "#core";
|
|
1
|
+
export type { CSSDeclarations, CSSObject, CSSValue, StyleApi, StyleRegistry, StyleSnapshot } from "#core";
|
|
2
|
+
export { createStyleRegistry, css, globalCss, keyframes } from "#core";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { css, globalCss, keyframes } from "#core";
|
|
1
|
+
export { createStyleRegistry, css, globalCss, keyframes } from "#core";
|
package/dist/next.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type StyleApi, type StyleRegistry } from "#core";
|
|
3
|
+
export type MintStyleRegistryProps = {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
nonce?: string;
|
|
6
|
+
};
|
|
7
|
+
/** Collect styles for each server render and flush them before streamed content. */
|
|
8
|
+
export declare function MintStyleRegistry({ children, nonce }: MintStyleRegistryProps): import("react").FunctionComponentElement<import("react").ProviderProps<StyleRegistry | null>>;
|
|
9
|
+
/** Use inside a Client Component wrapped in MintStyleRegistry. */
|
|
10
|
+
export declare function useMintcss(): StyleApi;
|
package/dist/next.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useServerInsertedHTML } from "next/navigation.js";
|
|
3
|
+
import { createContext, createElement, useContext, useState } from "react";
|
|
4
|
+
import { createStyleRegistry } from "#core";
|
|
5
|
+
const MintContext = createContext(null);
|
|
6
|
+
/** Collect styles for each server render and flush them before streamed content. */
|
|
7
|
+
export function MintStyleRegistry({ children, nonce }) {
|
|
8
|
+
const [registry] = useState(() => createStyleRegistry({ nonce }));
|
|
9
|
+
useServerInsertedHTML(() => {
|
|
10
|
+
const styles = registry.flush();
|
|
11
|
+
if (!styles.ids.length)
|
|
12
|
+
return null;
|
|
13
|
+
return createElement("style", {
|
|
14
|
+
"data-mintcss": styles.ids.join(" "),
|
|
15
|
+
nonce,
|
|
16
|
+
dangerouslySetInnerHTML: { __html: styles.css },
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
return createElement(MintContext.Provider, { value: registry }, children);
|
|
20
|
+
}
|
|
21
|
+
/** Use inside a Client Component wrapped in MintStyleRegistry. */
|
|
22
|
+
export function useMintcss() {
|
|
23
|
+
const registry = useContext(MintContext);
|
|
24
|
+
if (!registry)
|
|
25
|
+
throw new Error("useMintcss must be used inside MintStyleRegistry");
|
|
26
|
+
return registry;
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mintcss",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Small, dependency-free CSS-in-JS
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Small, dependency-free CSS-in-JS styling library for React.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "nexryai",
|
|
@@ -25,7 +25,11 @@
|
|
|
25
25
|
"types": "./dist/testing.d.ts",
|
|
26
26
|
"import": "./dist/testing.js"
|
|
27
27
|
},
|
|
28
|
-
"./package.json": "./package.json"
|
|
28
|
+
"./package.json": "./package.json",
|
|
29
|
+
"./next": {
|
|
30
|
+
"types": "./dist/next.d.ts",
|
|
31
|
+
"import": "./dist/next.js"
|
|
32
|
+
}
|
|
29
33
|
},
|
|
30
34
|
"files": ["dist", "README.md", "LICENSE"],
|
|
31
35
|
"sideEffects": false,
|
|
@@ -41,18 +45,37 @@
|
|
|
41
45
|
"test": "vitest run",
|
|
42
46
|
"test:package": "node scripts/test-package.mjs",
|
|
43
47
|
"prepack": "npm run build",
|
|
44
|
-
"prepublishOnly": "npm run lint && npm run check && npm test && npm run test:package"
|
|
48
|
+
"prepublishOnly": "npm run lint && npm run check && npm test && npm run test:package && npm run test:next",
|
|
49
|
+
"test:next": "node scripts/test-next.mjs"
|
|
45
50
|
},
|
|
46
51
|
"devDependencies": {
|
|
47
52
|
"@biomejs/biome": "2.5.11",
|
|
48
53
|
"@types/node": "^24.13.3",
|
|
54
|
+
"@types/react": "^19.3.0",
|
|
55
|
+
"@types/react-dom": "^19.3.0",
|
|
49
56
|
"jsdom": "30.1.2",
|
|
57
|
+
"next": "^16.4.0",
|
|
58
|
+
"react": "^19.3.0",
|
|
59
|
+
"react-dom": "^19.3.0",
|
|
50
60
|
"typescript": "~6.0.2",
|
|
51
61
|
"vitest": "^4.1.11"
|
|
52
62
|
},
|
|
53
63
|
"imports": {
|
|
54
64
|
"#core": "./dist/core.js",
|
|
55
65
|
"#mintcss": "./dist/index.js",
|
|
56
|
-
"#testing": "./dist/testing.js"
|
|
66
|
+
"#testing": "./dist/testing.js",
|
|
67
|
+
"#next": "./dist/next.js"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"next": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
71
|
+
"react": "^18.2.0 || ^19.0.0"
|
|
72
|
+
},
|
|
73
|
+
"peerDependenciesMeta": {
|
|
74
|
+
"next": {
|
|
75
|
+
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"react": {
|
|
78
|
+
"optional": true
|
|
79
|
+
}
|
|
57
80
|
}
|
|
58
81
|
}
|