react-headings 4.0.0 → 4.0.2
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 +24 -16
- package/dist/index.d.ts +18 -18
- package/dist/index.development.js +118 -86
- package/dist/index.js +44 -32
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
</a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
|
-
> Never write
|
|
14
|
+
> Never write `<h1>`–`<h6>` again.
|
|
15
15
|
|
|
16
16
|
Hardcoded heading levels break accessibility and SEO when components are reused. React Headings fixes this by computing each level from your component tree.
|
|
17
17
|
|
|
18
18
|
## Features
|
|
19
19
|
|
|
20
20
|
- Supports server-side rendering
|
|
21
|
-
- Only
|
|
21
|
+
- Only 373 bytes minified & brotlied
|
|
22
22
|
- Typed with TypeScript
|
|
23
23
|
- Works with any CSS solution (Tailwind, CSS-in-JS, etc.)
|
|
24
24
|
- Plays nicely with component libraries
|
|
@@ -39,13 +39,13 @@ import { Heading, HeadingLevel } from "react-headings";
|
|
|
39
39
|
function Page() {
|
|
40
40
|
return (
|
|
41
41
|
<>
|
|
42
|
-
<Heading>Star Wars</Heading> {/* h1 */}
|
|
42
|
+
<Heading>Star Wars</Heading> {/* <h1> */}
|
|
43
43
|
<HeadingLevel>
|
|
44
|
-
<Heading>Characters</Heading> {/* h2 */}
|
|
44
|
+
<Heading>Characters</Heading> {/* <h2> */}
|
|
45
45
|
<HeadingLevel>
|
|
46
|
-
<Section title="Luke" /> {/* h3 */}
|
|
47
|
-
<Section title="Leia" /> {/* h3 */}
|
|
48
|
-
<Section title="Han Solo" /> {/* h3 */}
|
|
46
|
+
<Section title="Luke" /> {/* <h3> */}
|
|
47
|
+
<Section title="Leia" /> {/* <h3> */}
|
|
48
|
+
<Section title="Han Solo" /> {/* <h3> */}
|
|
49
49
|
</HeadingLevel>
|
|
50
50
|
</HeadingLevel>
|
|
51
51
|
</>
|
|
@@ -62,23 +62,29 @@ function Section({ title, children }) {
|
|
|
62
62
|
}
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
`Section` doesn't know its level: it renders
|
|
65
|
+
`Section` doesn't know its level: it renders `<h3>` here.
|
|
66
66
|
|
|
67
67
|
### Dialogs
|
|
68
68
|
|
|
69
|
-
Portaled elements, like dialogs, aren't part of the page outline. Use `level` to start their headings at
|
|
69
|
+
Portaled elements, like dialogs, aren't part of the page outline. Use `level` to start their headings at `<h1>`:
|
|
70
70
|
|
|
71
71
|
```tsx
|
|
72
72
|
<Dialog>
|
|
73
73
|
<HeadingLevel level={1}>
|
|
74
|
-
<Heading>Delete file?</Heading> {/* h1 */}
|
|
74
|
+
<Heading>Delete file?</Heading> {/* <h1> */}
|
|
75
75
|
</HeadingLevel>
|
|
76
76
|
</Dialog>
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
### Styling
|
|
80
80
|
|
|
81
|
-
React Headings only picks the tag. Style headings however you like
|
|
81
|
+
React Headings only picks the tag. Style headings however you like:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
<Heading className="text-lg">Title</Heading>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Or use `render` for component libraries:
|
|
82
88
|
|
|
83
89
|
```tsx
|
|
84
90
|
<Heading render={(props, { tag }) => <Text as={tag} size="lg" {...props} />}>
|
|
@@ -88,21 +94,23 @@ React Headings only picks the tag. Style headings however you like, or use `rend
|
|
|
88
94
|
|
|
89
95
|
## API
|
|
90
96
|
|
|
91
|
-
###
|
|
97
|
+
### `<Heading>`
|
|
92
98
|
|
|
93
|
-
Renders
|
|
99
|
+
Renders `<h1>`, `<h2>`, `<h3>`, `<h4>`, `<h5>`, or `<h6>` based on the current level. `<h1>` by default.
|
|
94
100
|
|
|
95
|
-
Accepts every
|
|
101
|
+
Accepts every `<h1>` prop and a `ref`, plus:
|
|
96
102
|
|
|
97
103
|
| Prop | Type | Description |
|
|
98
104
|
| -------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
99
105
|
| `render` | `(props, { level, tag }) => ReactElement` | Renders your own element. Spread `props` on it (includes `children` and `ref`). |
|
|
100
106
|
|
|
101
|
-
###
|
|
107
|
+
### `<HeadingLevel>`
|
|
108
|
+
|
|
109
|
+
Moves the headings inside one level deeper.
|
|
102
110
|
|
|
103
111
|
| Prop | Type | Default | Description |
|
|
104
112
|
| -------- | -------- | ------- | ------------------------------------------------ |
|
|
105
|
-
| `offset` | `number` | `1` | Levels added to headings inside.
|
|
113
|
+
| `offset` | `number` | `1` | Levels added to headings inside. Rarely used. |
|
|
106
114
|
| `level` | `number` | | Level of headings inside, ignoring parents. |
|
|
107
115
|
|
|
108
116
|
Pass `offset` or `level`, not both. Nested offsets add up. `offset={0}` adds nothing, which is useful for conditional nesting.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ComponentPropsWithRef, ComponentPropsWithoutRef, ReactElement, ReactNode } from "react";
|
|
2
2
|
type Level = 1 | 2 | 3 | 4 | 5 | 6;
|
|
3
3
|
type Tag = `h${Level}`;
|
|
4
4
|
export type HeadingProps = ComponentPropsWithoutRef<"h1"> & {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
render?: (props: ComponentPropsWithRef<"h1">, heading: {
|
|
6
|
+
level: Level;
|
|
7
|
+
tag: Tag;
|
|
8
|
+
}) => ReactElement;
|
|
9
9
|
};
|
|
10
10
|
export type HeadingLevelProps = {
|
|
11
|
-
|
|
11
|
+
children?: ReactNode;
|
|
12
12
|
} & ({
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
offset?: number;
|
|
14
|
+
level?: never;
|
|
15
15
|
} | {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
level: number;
|
|
17
|
+
offset?: never;
|
|
18
18
|
});
|
|
19
19
|
/**
|
|
20
20
|
* Renders an `h1`–`h6` according to the current level.
|
|
21
21
|
*/
|
|
22
22
|
export declare const Heading: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, "ref"> & {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
render?: (props: ComponentPropsWithRef<"h1">, heading: {
|
|
24
|
+
level: Level;
|
|
25
|
+
tag: Tag;
|
|
26
|
+
}) => ReactElement;
|
|
27
27
|
} & import("react").RefAttributes<HTMLHeadingElement>>;
|
|
28
28
|
/**
|
|
29
29
|
* Renders headings inside `offset` levels deeper (default 1), or at `level`
|
|
30
30
|
* regardless of ancestors.
|
|
31
31
|
*/
|
|
32
|
-
export declare function HeadingLevel({ offset, level, children
|
|
32
|
+
export declare function HeadingLevel({ offset, level, children }: HeadingLevelProps): import("react").JSX.Element;
|
|
33
33
|
/**
|
|
34
34
|
* Returns the level and tag a `Heading` would render at this position.
|
|
35
35
|
*/
|
|
36
36
|
export declare function useHeadingLevel(): {
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
level: Level;
|
|
38
|
+
tag: Tag;
|
|
39
39
|
};
|
|
40
|
-
export {};
|
|
40
|
+
export {};
|
|
@@ -1,103 +1,135 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
// src/index.tsx
|
|
4
|
-
import {
|
|
5
|
-
createContext,
|
|
6
|
-
forwardRef,
|
|
7
|
-
useContext,
|
|
8
|
-
useEffect,
|
|
9
|
-
useMemo
|
|
10
|
-
} from "react";
|
|
2
|
+
import { createContext, forwardRef, useContext, useEffect, useMemo } from "react";
|
|
11
3
|
import { jsx } from "react/jsx-runtime";
|
|
12
|
-
|
|
4
|
+
// src/index.tsx
|
|
5
|
+
const LevelContext = createContext(1);
|
|
13
6
|
function isValidOffset(offset) {
|
|
14
|
-
|
|
7
|
+
return Number.isInteger(offset) && offset >= 0;
|
|
15
8
|
}
|
|
16
9
|
function isValidLevel(level) {
|
|
17
|
-
|
|
10
|
+
return Number.isInteger(level) && level >= 1;
|
|
18
11
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
);
|
|
12
|
+
/**
|
|
13
|
+
* Renders an `h1`–`h6` according to the current level.
|
|
14
|
+
*/
|
|
15
|
+
const Heading = forwardRef(function Heading({ render, ...props }, ref) {
|
|
16
|
+
const { level, tag } = useHeadingLevel();
|
|
17
|
+
useHeadingChecks();
|
|
18
|
+
if (render) return render({
|
|
19
|
+
...props,
|
|
20
|
+
ref
|
|
21
|
+
}, {
|
|
22
|
+
level,
|
|
23
|
+
tag
|
|
24
|
+
});
|
|
25
|
+
return /* @__PURE__ */ jsx(tag, {
|
|
26
|
+
ref,
|
|
27
|
+
...props
|
|
28
|
+
});
|
|
29
|
+
});
|
|
25
30
|
Heading.displayName = "Heading";
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Renders headings inside `offset` levels deeper (default 1), or at `level`
|
|
33
|
+
* regardless of ancestors.
|
|
34
|
+
*/
|
|
35
|
+
function HeadingLevel({ offset = 1, level, children }) {
|
|
36
|
+
const parentLevel = useContext(LevelContext);
|
|
37
|
+
const isReset = isValidLevel(level);
|
|
38
|
+
const isOffsetValid = isValidOffset(offset);
|
|
39
|
+
const innerLevel = isReset ? level : parentLevel + (isOffsetValid ? offset : 1);
|
|
40
|
+
useInvalidPropWarning("offset", offset, isOffsetValid);
|
|
41
|
+
useInvalidPropWarning("level", level, isReset);
|
|
42
|
+
children = /* @__PURE__ */ jsx(SkippedLevelScope, {
|
|
43
|
+
firstLevel: isReset ? innerLevel : parentLevel + 1,
|
|
44
|
+
isIsolated: isReset,
|
|
45
|
+
isPassthrough: !isReset && offset === 0,
|
|
46
|
+
children
|
|
47
|
+
});
|
|
48
|
+
return /* @__PURE__ */ jsx(LevelContext.Provider, {
|
|
49
|
+
value: innerLevel,
|
|
50
|
+
children
|
|
51
|
+
});
|
|
41
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Returns the level and tag a `Heading` would render at this position.
|
|
55
|
+
*/
|
|
42
56
|
function useHeadingLevel() {
|
|
43
|
-
|
|
44
|
-
|
|
57
|
+
const level = Math.min(useContext(LevelContext), 6);
|
|
58
|
+
return {
|
|
59
|
+
level,
|
|
60
|
+
tag: `h${level}`
|
|
61
|
+
};
|
|
45
62
|
}
|
|
46
|
-
|
|
63
|
+
const ScopeContext = /* @__PURE__ */ createContext(null);
|
|
64
|
+
/**
|
|
65
|
+
* Collects the heading levels rendered inside a HeadingLevel and warns if one between `firstLevel` and the deepest is missing. A
|
|
66
|
+
* non-empty nested scope counts as a heading at its own `firstLevel` in its
|
|
67
|
+
* parent, so each gap is reported by exactly one scope.
|
|
68
|
+
*/
|
|
47
69
|
function createScopeRegistry(firstLevel, parentRegistry) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
const headingLevels = /* @__PURE__ */ new Map();
|
|
71
|
+
let unregisterFromParent;
|
|
72
|
+
let isCheckScheduled = false;
|
|
73
|
+
let hasWarned = false;
|
|
74
|
+
function warnIfLevelSkipped() {
|
|
75
|
+
isCheckScheduled = false;
|
|
76
|
+
if (hasWarned || headingLevels.size === 0) return;
|
|
77
|
+
const presentLevels = new Set(headingLevels.values());
|
|
78
|
+
const deepestLevel = Math.max(...presentLevels);
|
|
79
|
+
for (let level = firstLevel; level < deepestLevel; level++) if (!presentLevels.has(level)) {
|
|
80
|
+
hasWarned = true;
|
|
81
|
+
console.warn(`react-headings: Skipped heading level ${level}: found a level ${deepestLevel} heading but no level ${level} heading.`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function scheduleCheck() {
|
|
86
|
+
if (isCheckScheduled) return;
|
|
87
|
+
isCheckScheduled = true;
|
|
88
|
+
queueMicrotask(warnIfLevelSkipped);
|
|
89
|
+
}
|
|
90
|
+
return { register(level) {
|
|
91
|
+
const token = {};
|
|
92
|
+
headingLevels.set(token, level);
|
|
93
|
+
if (headingLevels.size === 1) unregisterFromParent = parentRegistry?.register(firstLevel);
|
|
94
|
+
scheduleCheck();
|
|
95
|
+
return () => {
|
|
96
|
+
headingLevels.delete(token);
|
|
97
|
+
if (headingLevels.size === 0) {
|
|
98
|
+
unregisterFromParent?.();
|
|
99
|
+
unregisterFromParent = void 0;
|
|
100
|
+
}
|
|
101
|
+
scheduleCheck();
|
|
102
|
+
};
|
|
103
|
+
} };
|
|
71
104
|
}
|
|
72
|
-
function SkippedLevelScope({
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
105
|
+
function SkippedLevelScope({ firstLevel, isIsolated, isPassthrough, children }) {
|
|
106
|
+
const parentRegistry = useContext(ScopeContext);
|
|
107
|
+
const registry = useMemo(() => isPassthrough ? parentRegistry : createScopeRegistry(firstLevel, isIsolated ? null : parentRegistry), [
|
|
108
|
+
firstLevel,
|
|
109
|
+
isIsolated,
|
|
110
|
+
isPassthrough,
|
|
111
|
+
parentRegistry
|
|
112
|
+
]);
|
|
113
|
+
return /* @__PURE__ */ jsx(ScopeContext.Provider, {
|
|
114
|
+
value: registry,
|
|
115
|
+
children
|
|
116
|
+
});
|
|
83
117
|
}
|
|
84
118
|
function useHeadingChecks() {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
119
|
+
const level = useContext(LevelContext);
|
|
120
|
+
const scopeRegistry = useContext(ScopeContext);
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (level > 6) console.warn(`react-headings: Heading level ${level} exceeds 6 and was clamped to h6.`);
|
|
123
|
+
}, [level]);
|
|
124
|
+
useEffect(() => scopeRegistry?.register(level), [scopeRegistry, level]);
|
|
91
125
|
}
|
|
92
126
|
function useInvalidPropWarning(prop, value, isValid) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
if (value != null && !isValid) console.warn(`react-headings: HeadingLevel received invalid ${prop} ${value}, ignored.`);
|
|
129
|
+
}, [
|
|
130
|
+
prop,
|
|
131
|
+
value,
|
|
132
|
+
isValid
|
|
133
|
+
]);
|
|
98
134
|
}
|
|
99
|
-
export {
|
|
100
|
-
Heading,
|
|
101
|
-
HeadingLevel,
|
|
102
|
-
useHeadingLevel
|
|
103
|
-
};
|
|
135
|
+
export { Heading, HeadingLevel, useHeadingLevel };
|
package/dist/index.js
CHANGED
|
@@ -1,42 +1,54 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
// src/index.tsx
|
|
4
|
-
import {
|
|
5
|
-
createContext,
|
|
6
|
-
forwardRef,
|
|
7
|
-
useContext,
|
|
8
|
-
useEffect,
|
|
9
|
-
useMemo
|
|
10
|
-
} from "react";
|
|
2
|
+
import { createContext, forwardRef, useContext } from "react";
|
|
11
3
|
import { jsx } from "react/jsx-runtime";
|
|
12
|
-
|
|
4
|
+
// src/index.tsx
|
|
5
|
+
const LevelContext = createContext(1);
|
|
13
6
|
function isValidOffset(offset) {
|
|
14
|
-
|
|
7
|
+
return Number.isInteger(offset) && offset >= 0;
|
|
15
8
|
}
|
|
16
9
|
function isValidLevel(level) {
|
|
17
|
-
|
|
10
|
+
return Number.isInteger(level) && level >= 1;
|
|
18
11
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
)
|
|
12
|
+
/**
|
|
13
|
+
* Renders an `h1`–`h6` according to the current level.
|
|
14
|
+
*/
|
|
15
|
+
const Heading = forwardRef(function Heading({ render, ...props }, ref) {
|
|
16
|
+
const { level, tag } = useHeadingLevel();
|
|
17
|
+
if (render) return render({
|
|
18
|
+
...props,
|
|
19
|
+
ref
|
|
20
|
+
}, {
|
|
21
|
+
level,
|
|
22
|
+
tag
|
|
23
|
+
});
|
|
24
|
+
return /* @__PURE__ */ jsx(tag, {
|
|
25
|
+
ref,
|
|
26
|
+
...props
|
|
27
|
+
});
|
|
28
|
+
});
|
|
25
29
|
Heading.displayName = "Heading";
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}) {
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Renders headings inside `offset` levels deeper (default 1), or at `level`
|
|
32
|
+
* regardless of ancestors.
|
|
33
|
+
*/
|
|
34
|
+
function HeadingLevel({ offset = 1, level, children }) {
|
|
35
|
+
const parentLevel = useContext(LevelContext);
|
|
36
|
+
const isReset = isValidLevel(level);
|
|
37
|
+
const isOffsetValid = isValidOffset(offset);
|
|
38
|
+
const innerLevel = isReset ? level : parentLevel + (isOffsetValid ? offset : 1);
|
|
39
|
+
return /* @__PURE__ */ jsx(LevelContext.Provider, {
|
|
40
|
+
value: innerLevel,
|
|
41
|
+
children
|
|
42
|
+
});
|
|
33
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Returns the level and tag a `Heading` would render at this position.
|
|
46
|
+
*/
|
|
34
47
|
function useHeadingLevel() {
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
const level = Math.min(useContext(LevelContext), 6);
|
|
49
|
+
return {
|
|
50
|
+
level,
|
|
51
|
+
tag: `h${level}`
|
|
52
|
+
};
|
|
37
53
|
}
|
|
38
|
-
export {
|
|
39
|
-
Heading,
|
|
40
|
-
HeadingLevel,
|
|
41
|
-
useHeadingLevel
|
|
42
|
-
};
|
|
54
|
+
export { Heading, HeadingLevel, useHeadingLevel };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-headings",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Dynamic heading levels for React.",
|
|
6
6
|
"author": "Alex Nault",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"./package.json": "./package.json"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
|
-
"build": "
|
|
32
|
+
"build": "tsdown",
|
|
33
33
|
"typecheck": "tsc",
|
|
34
34
|
"format": "prettier ./ --write",
|
|
35
35
|
"lint": "eslint ./ --max-warnings=0",
|
|
@@ -48,21 +48,22 @@
|
|
|
48
48
|
"@size-limit/preset-small-lib": "^14.3.0",
|
|
49
49
|
"@testing-library/dom": "^10.4.2",
|
|
50
50
|
"@testing-library/react": "^16.3.3",
|
|
51
|
+
"@types/node": "^24.19.2",
|
|
51
52
|
"@types/react": "^19.3.0",
|
|
52
53
|
"@types/react-dom": "^19.3.0",
|
|
53
|
-
"@vitest/coverage-v8": "^5.0
|
|
54
|
+
"@vitest/coverage-v8": "^5.1.0",
|
|
54
55
|
"conventional-changelog-conventionalcommits": "^9.3.1",
|
|
55
|
-
"esbuild": "^0.28.2",
|
|
56
56
|
"eslint": "^10.14.0",
|
|
57
57
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
58
58
|
"jsdom": "^30.1.3",
|
|
59
59
|
"prettier": "^3.9.10",
|
|
60
60
|
"react": "^19.3.1",
|
|
61
61
|
"react-dom": "^19.3.1",
|
|
62
|
-
"semantic-release": "^25.0.
|
|
62
|
+
"semantic-release": "^25.0.9",
|
|
63
63
|
"size-limit": "^14.3.0",
|
|
64
|
-
"
|
|
64
|
+
"tsdown": "^0.23.5",
|
|
65
|
+
"typescript": "^6.0.3",
|
|
65
66
|
"typescript-eslint": "^8.72.1",
|
|
66
|
-
"vitest": "^5.0
|
|
67
|
+
"vitest": "^5.1.0"
|
|
67
68
|
}
|
|
68
69
|
}
|