@negative-space/file-tree 1.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/LICENSE +21 -0
- package/README.md +15 -0
- package/dist/index.d.mts +77 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.js +213 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +207 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Matheus Bastani
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @negative-space/file-tree
|
|
2
|
+
|
|
3
|
+
A lightweight and flexible file tree component for React.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
# Using Yarn
|
|
8
|
+
yarn add @negative-space/file-tree
|
|
9
|
+
|
|
10
|
+
# Using npm
|
|
11
|
+
npm install @negative-space/file-tree
|
|
12
|
+
|
|
13
|
+
## Contributing
|
|
14
|
+
|
|
15
|
+
Feel free to fork, tweak, and send a pull request!
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { FlexProps } from '@negative-space/flex';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { IconButtonProps } from '@negative-space/button';
|
|
4
|
+
|
|
5
|
+
interface FileTreeFolderProps extends Omit<FlexProps, 'children' | 'className' | 'style' | 'prefix'> {
|
|
6
|
+
classNames?: {
|
|
7
|
+
root?: string;
|
|
8
|
+
header?: string;
|
|
9
|
+
collapseButton?: IconButtonProps['classNames'];
|
|
10
|
+
prefix?: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
suffix?: string;
|
|
13
|
+
children?: string;
|
|
14
|
+
};
|
|
15
|
+
styles?: {
|
|
16
|
+
root?: React.CSSProperties;
|
|
17
|
+
header?: React.CSSProperties;
|
|
18
|
+
collapseButton?: IconButtonProps['styles'];
|
|
19
|
+
prefix?: React.CSSProperties;
|
|
20
|
+
label?: React.CSSProperties;
|
|
21
|
+
suffix?: React.CSSProperties;
|
|
22
|
+
children?: React.CSSProperties;
|
|
23
|
+
};
|
|
24
|
+
prefix?: React.ReactNode;
|
|
25
|
+
label?: React.ReactNode;
|
|
26
|
+
suffix?: React.ReactNode;
|
|
27
|
+
children?: React.ReactNode;
|
|
28
|
+
collapsable?: boolean;
|
|
29
|
+
collapsed?: boolean;
|
|
30
|
+
setCollapsed?: (collapsed: boolean) => void;
|
|
31
|
+
active?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface FileTreeItemProps extends Omit<FlexProps, 'children' | 'className' | 'style' | 'prefix'> {
|
|
35
|
+
classNames?: {
|
|
36
|
+
root?: string;
|
|
37
|
+
prefix?: string;
|
|
38
|
+
label?: string;
|
|
39
|
+
suffix?: string;
|
|
40
|
+
};
|
|
41
|
+
styles?: {
|
|
42
|
+
root?: React.CSSProperties;
|
|
43
|
+
prefix?: React.CSSProperties;
|
|
44
|
+
label?: React.CSSProperties;
|
|
45
|
+
suffix?: React.CSSProperties;
|
|
46
|
+
};
|
|
47
|
+
prefix?: React.ReactNode;
|
|
48
|
+
label?: React.ReactNode;
|
|
49
|
+
suffix?: React.ReactNode;
|
|
50
|
+
active?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type FileTreeEntry = {
|
|
54
|
+
folder: Omit<FileTreeFolderProps, 'children'>;
|
|
55
|
+
items?: FileTreeEntry[];
|
|
56
|
+
item?: never;
|
|
57
|
+
} | {
|
|
58
|
+
item: FileTreeItemProps;
|
|
59
|
+
folder?: never;
|
|
60
|
+
items?: never;
|
|
61
|
+
};
|
|
62
|
+
interface FileTreeProps extends Omit<FlexProps, 'children'> {
|
|
63
|
+
classNames?: {
|
|
64
|
+
root?: string;
|
|
65
|
+
folders?: FileTreeFolderProps['classNames'];
|
|
66
|
+
items?: FileTreeItemProps['classNames'];
|
|
67
|
+
};
|
|
68
|
+
styles?: {
|
|
69
|
+
root?: React.CSSProperties;
|
|
70
|
+
folders?: FileTreeFolderProps['styles'];
|
|
71
|
+
items?: FileTreeItemProps['styles'];
|
|
72
|
+
};
|
|
73
|
+
items?: FileTreeEntry[];
|
|
74
|
+
}
|
|
75
|
+
declare const FileTree: React.ForwardRefExoticComponent<FileTreeProps & React.RefAttributes<HTMLDivElement>>;
|
|
76
|
+
|
|
77
|
+
export { FileTree, type FileTreeProps };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { FlexProps } from '@negative-space/flex';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { IconButtonProps } from '@negative-space/button';
|
|
4
|
+
|
|
5
|
+
interface FileTreeFolderProps extends Omit<FlexProps, 'children' | 'className' | 'style' | 'prefix'> {
|
|
6
|
+
classNames?: {
|
|
7
|
+
root?: string;
|
|
8
|
+
header?: string;
|
|
9
|
+
collapseButton?: IconButtonProps['classNames'];
|
|
10
|
+
prefix?: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
suffix?: string;
|
|
13
|
+
children?: string;
|
|
14
|
+
};
|
|
15
|
+
styles?: {
|
|
16
|
+
root?: React.CSSProperties;
|
|
17
|
+
header?: React.CSSProperties;
|
|
18
|
+
collapseButton?: IconButtonProps['styles'];
|
|
19
|
+
prefix?: React.CSSProperties;
|
|
20
|
+
label?: React.CSSProperties;
|
|
21
|
+
suffix?: React.CSSProperties;
|
|
22
|
+
children?: React.CSSProperties;
|
|
23
|
+
};
|
|
24
|
+
prefix?: React.ReactNode;
|
|
25
|
+
label?: React.ReactNode;
|
|
26
|
+
suffix?: React.ReactNode;
|
|
27
|
+
children?: React.ReactNode;
|
|
28
|
+
collapsable?: boolean;
|
|
29
|
+
collapsed?: boolean;
|
|
30
|
+
setCollapsed?: (collapsed: boolean) => void;
|
|
31
|
+
active?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface FileTreeItemProps extends Omit<FlexProps, 'children' | 'className' | 'style' | 'prefix'> {
|
|
35
|
+
classNames?: {
|
|
36
|
+
root?: string;
|
|
37
|
+
prefix?: string;
|
|
38
|
+
label?: string;
|
|
39
|
+
suffix?: string;
|
|
40
|
+
};
|
|
41
|
+
styles?: {
|
|
42
|
+
root?: React.CSSProperties;
|
|
43
|
+
prefix?: React.CSSProperties;
|
|
44
|
+
label?: React.CSSProperties;
|
|
45
|
+
suffix?: React.CSSProperties;
|
|
46
|
+
};
|
|
47
|
+
prefix?: React.ReactNode;
|
|
48
|
+
label?: React.ReactNode;
|
|
49
|
+
suffix?: React.ReactNode;
|
|
50
|
+
active?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type FileTreeEntry = {
|
|
54
|
+
folder: Omit<FileTreeFolderProps, 'children'>;
|
|
55
|
+
items?: FileTreeEntry[];
|
|
56
|
+
item?: never;
|
|
57
|
+
} | {
|
|
58
|
+
item: FileTreeItemProps;
|
|
59
|
+
folder?: never;
|
|
60
|
+
items?: never;
|
|
61
|
+
};
|
|
62
|
+
interface FileTreeProps extends Omit<FlexProps, 'children'> {
|
|
63
|
+
classNames?: {
|
|
64
|
+
root?: string;
|
|
65
|
+
folders?: FileTreeFolderProps['classNames'];
|
|
66
|
+
items?: FileTreeItemProps['classNames'];
|
|
67
|
+
};
|
|
68
|
+
styles?: {
|
|
69
|
+
root?: React.CSSProperties;
|
|
70
|
+
folders?: FileTreeFolderProps['styles'];
|
|
71
|
+
items?: FileTreeItemProps['styles'];
|
|
72
|
+
};
|
|
73
|
+
items?: FileTreeEntry[];
|
|
74
|
+
}
|
|
75
|
+
declare const FileTree: React.ForwardRefExoticComponent<FileTreeProps & React.RefAttributes<HTMLDivElement>>;
|
|
76
|
+
|
|
77
|
+
export { FileTree, type FileTreeProps };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var flex = require('@negative-space/flex');
|
|
4
|
+
var system = require('@negative-space/system');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var button = require('@negative-space/button');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
|
|
9
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
|
|
11
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
12
|
+
|
|
13
|
+
// src/FileTree.tsx
|
|
14
|
+
var FileTreeFolder = React__default.default.forwardRef(
|
|
15
|
+
({
|
|
16
|
+
classNames,
|
|
17
|
+
styles,
|
|
18
|
+
collapsable = true,
|
|
19
|
+
collapsed = true,
|
|
20
|
+
setCollapsed: setCollapsedProp,
|
|
21
|
+
prefix,
|
|
22
|
+
label,
|
|
23
|
+
suffix,
|
|
24
|
+
active,
|
|
25
|
+
children,
|
|
26
|
+
...props
|
|
27
|
+
}, ref) => {
|
|
28
|
+
const { global } = system.useNSUI();
|
|
29
|
+
const [collapsedState, setCollapsedState] = React.useState(collapsed);
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
setCollapsedState(collapsed);
|
|
32
|
+
}, [collapsed]);
|
|
33
|
+
const isCollapsed = setCollapsedProp ? collapsed : collapsedState;
|
|
34
|
+
const handleCollapse = () => {
|
|
35
|
+
const nextCollapsed = !isCollapsed;
|
|
36
|
+
setCollapsedState(nextCollapsed);
|
|
37
|
+
setCollapsedProp?.(nextCollapsed);
|
|
38
|
+
};
|
|
39
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
40
|
+
flex.Flex,
|
|
41
|
+
{
|
|
42
|
+
ref,
|
|
43
|
+
direction: "column",
|
|
44
|
+
className: system.cn(`${global?.prefixCls}-file-tree-folder`, classNames?.root),
|
|
45
|
+
"data-active": active,
|
|
46
|
+
style: styles?.root,
|
|
47
|
+
...props,
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
50
|
+
flex.Flex,
|
|
51
|
+
{
|
|
52
|
+
className: system.cn(`${global?.prefixCls}-file-tree-folder-header`, classNames?.header),
|
|
53
|
+
"data-active": active,
|
|
54
|
+
"data-collapsed": isCollapsed,
|
|
55
|
+
style: styles?.header,
|
|
56
|
+
children: [
|
|
57
|
+
collapsable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
58
|
+
button.IconButton,
|
|
59
|
+
{
|
|
60
|
+
classNames: classNames?.collapseButton,
|
|
61
|
+
"data-collapsed": isCollapsed,
|
|
62
|
+
styles: styles?.collapseButton,
|
|
63
|
+
onClick: handleCollapse,
|
|
64
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
65
|
+
system.ChevronDown,
|
|
66
|
+
{
|
|
67
|
+
style: {
|
|
68
|
+
transform: isCollapsed ? "rotate(-90deg)" : "",
|
|
69
|
+
...styles?.collapseButton?.icon
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
prefix && /* @__PURE__ */ jsxRuntime.jsx(
|
|
76
|
+
"div",
|
|
77
|
+
{
|
|
78
|
+
className: system.cn(`${global?.prefixCls}-file-tree-folder-prefix`, classNames?.prefix),
|
|
79
|
+
style: styles?.prefix,
|
|
80
|
+
children: prefix
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
84
|
+
"div",
|
|
85
|
+
{
|
|
86
|
+
className: system.cn(`${global?.prefixCls}-file-tree-folder-label`, classNames?.label),
|
|
87
|
+
style: styles?.label,
|
|
88
|
+
children: label
|
|
89
|
+
}
|
|
90
|
+
),
|
|
91
|
+
suffix && /* @__PURE__ */ jsxRuntime.jsx(
|
|
92
|
+
"div",
|
|
93
|
+
{
|
|
94
|
+
className: system.cn(`${global?.prefixCls}-file-tree-folder-suffix`, classNames?.suffix),
|
|
95
|
+
style: styles?.suffix,
|
|
96
|
+
children: suffix
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
),
|
|
102
|
+
!isCollapsed && /* @__PURE__ */ jsxRuntime.jsx(
|
|
103
|
+
"div",
|
|
104
|
+
{
|
|
105
|
+
className: system.cn(`${global?.prefixCls}-file-tree-folder-children`, classNames?.children),
|
|
106
|
+
style: styles?.children,
|
|
107
|
+
children
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
FileTreeFolder.displayName = "FileTreeFolder";
|
|
116
|
+
var FileTreeItem = React__default.default.forwardRef(
|
|
117
|
+
({ classNames, styles, prefix, label, suffix, active, ...props }, ref) => {
|
|
118
|
+
const { global } = system.useNSUI();
|
|
119
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
120
|
+
flex.Flex,
|
|
121
|
+
{
|
|
122
|
+
ref,
|
|
123
|
+
className: system.cn(`${global?.prefixCls}-file-tree-item`, classNames?.root),
|
|
124
|
+
"data-active": active,
|
|
125
|
+
style: styles?.root,
|
|
126
|
+
...props,
|
|
127
|
+
children: [
|
|
128
|
+
prefix && /* @__PURE__ */ jsxRuntime.jsx(
|
|
129
|
+
"div",
|
|
130
|
+
{
|
|
131
|
+
className: system.cn(`${global?.prefixCls}-file-tree-item-prefix`, classNames?.prefix),
|
|
132
|
+
style: styles?.prefix,
|
|
133
|
+
children: prefix
|
|
134
|
+
}
|
|
135
|
+
),
|
|
136
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
137
|
+
"div",
|
|
138
|
+
{
|
|
139
|
+
className: system.cn(`${global?.prefixCls}-file-tree-item-label`, classNames?.label),
|
|
140
|
+
style: styles?.label,
|
|
141
|
+
children: label
|
|
142
|
+
}
|
|
143
|
+
),
|
|
144
|
+
suffix && /* @__PURE__ */ jsxRuntime.jsx(
|
|
145
|
+
"div",
|
|
146
|
+
{
|
|
147
|
+
className: system.cn(`${global?.prefixCls}-file-tree-item-suffix`, classNames?.suffix),
|
|
148
|
+
style: styles?.suffix,
|
|
149
|
+
children: suffix
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
FileTreeItem.displayName = "FileTreeItem";
|
|
158
|
+
var FileTree = React__default.default.forwardRef(
|
|
159
|
+
({ className, classNames, styles, items = [], ...props }, ref) => {
|
|
160
|
+
const { global } = system.useNSUI();
|
|
161
|
+
const renderEntries = (entries) => entries.map((entry, index) => {
|
|
162
|
+
if (entry.folder) {
|
|
163
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
164
|
+
FileTreeFolder,
|
|
165
|
+
{
|
|
166
|
+
...entry.folder,
|
|
167
|
+
classNames: {
|
|
168
|
+
...classNames?.folders,
|
|
169
|
+
...entry.folder.classNames
|
|
170
|
+
},
|
|
171
|
+
styles: {
|
|
172
|
+
...styles?.folders,
|
|
173
|
+
...entry.folder.styles
|
|
174
|
+
},
|
|
175
|
+
children: entry.items && renderEntries(entry.items)
|
|
176
|
+
},
|
|
177
|
+
index
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
181
|
+
FileTreeItem,
|
|
182
|
+
{
|
|
183
|
+
...entry.item,
|
|
184
|
+
classNames: {
|
|
185
|
+
...classNames?.items,
|
|
186
|
+
...entry.item.classNames
|
|
187
|
+
},
|
|
188
|
+
styles: {
|
|
189
|
+
...styles?.items,
|
|
190
|
+
...entry.item.styles
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
index
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
197
|
+
flex.Flex,
|
|
198
|
+
{
|
|
199
|
+
ref,
|
|
200
|
+
direction: "column",
|
|
201
|
+
className: system.cn(`${global?.prefixCls}-file-tree`, className, classNames?.root),
|
|
202
|
+
style: styles?.root,
|
|
203
|
+
...props,
|
|
204
|
+
children: renderEntries(items)
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
FileTree.displayName = "FileTree";
|
|
210
|
+
|
|
211
|
+
exports.FileTree = FileTree;
|
|
212
|
+
//# sourceMappingURL=index.js.map
|
|
213
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/FileTreeFolder.tsx","../src/FileTreeItem.tsx","../src/FileTree.tsx"],"names":["React","useNSUI","useState","useEffect","jsxs","Flex","cn","jsx","IconButton","ChevronDown"],"mappings":"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","file":"index.js","sourcesContent":["import { IconButton, type IconButtonProps } from '@negative-space/button'\nimport { Flex, type FlexProps } from '@negative-space/flex'\nimport { ChevronDown, cn, useNSUI } from '@negative-space/system'\nimport React, { useEffect, useState } from 'react'\n\nexport interface FileTreeFolderProps extends Omit<\n FlexProps,\n 'children' | 'className' | 'style' | 'prefix'\n> {\n classNames?: {\n root?: string\n header?: string\n collapseButton?: IconButtonProps['classNames']\n prefix?: string\n label?: string\n suffix?: string\n children?: string\n }\n styles?: {\n root?: React.CSSProperties\n header?: React.CSSProperties\n collapseButton?: IconButtonProps['styles']\n prefix?: React.CSSProperties\n label?: React.CSSProperties\n suffix?: React.CSSProperties\n children?: React.CSSProperties\n }\n prefix?: React.ReactNode\n label?: React.ReactNode\n suffix?: React.ReactNode\n children?: React.ReactNode\n collapsable?: boolean\n collapsed?: boolean\n setCollapsed?: (collapsed: boolean) => void\n active?: boolean\n}\n\nexport const FileTreeFolder = React.forwardRef<HTMLDivElement, FileTreeFolderProps>(\n (\n {\n classNames,\n styles,\n collapsable = true,\n collapsed = true,\n setCollapsed: setCollapsedProp,\n prefix,\n label,\n suffix,\n active,\n children,\n ...props\n },\n ref\n ) => {\n const { global } = useNSUI()\n const [collapsedState, setCollapsedState] = useState(collapsed)\n\n useEffect(() => {\n setCollapsedState(collapsed)\n }, [collapsed])\n\n const isCollapsed = setCollapsedProp ? collapsed : collapsedState\n\n const handleCollapse = () => {\n const nextCollapsed = !isCollapsed\n\n setCollapsedState(nextCollapsed)\n setCollapsedProp?.(nextCollapsed)\n }\n\n return (\n <Flex\n ref={ref}\n direction=\"column\"\n className={cn(`${global?.prefixCls}-file-tree-folder`, classNames?.root)}\n data-active={active}\n style={styles?.root}\n {...props}\n >\n <Flex\n className={cn(`${global?.prefixCls}-file-tree-folder-header`, classNames?.header)}\n data-active={active}\n data-collapsed={isCollapsed}\n style={styles?.header}\n >\n {collapsable && (\n <IconButton\n classNames={classNames?.collapseButton}\n data-collapsed={isCollapsed}\n styles={styles?.collapseButton}\n onClick={handleCollapse}\n >\n <ChevronDown\n style={{\n transform: isCollapsed ? 'rotate(-90deg)' : '',\n ...styles?.collapseButton?.icon\n }}\n />\n </IconButton>\n )}\n\n {prefix && (\n <div\n className={cn(`${global?.prefixCls}-file-tree-folder-prefix`, classNames?.prefix)}\n style={styles?.prefix}\n >\n {prefix}\n </div>\n )}\n\n <div\n className={cn(`${global?.prefixCls}-file-tree-folder-label`, classNames?.label)}\n style={styles?.label}\n >\n {label}\n </div>\n\n {suffix && (\n <div\n className={cn(`${global?.prefixCls}-file-tree-folder-suffix`, classNames?.suffix)}\n style={styles?.suffix}\n >\n {suffix}\n </div>\n )}\n </Flex>\n\n {!isCollapsed && (\n <div\n className={cn(`${global?.prefixCls}-file-tree-folder-children`, classNames?.children)}\n style={styles?.children}\n >\n {children}\n </div>\n )}\n </Flex>\n )\n }\n)\n\nFileTreeFolder.displayName = 'FileTreeFolder'\n","import { Flex, type FlexProps } from '@negative-space/flex'\nimport { cn, useNSUI } from '@negative-space/system'\nimport React from 'react'\n\nexport interface FileTreeItemProps extends Omit<\n FlexProps,\n 'children' | 'className' | 'style' | 'prefix'\n> {\n classNames?: {\n root?: string\n prefix?: string\n label?: string\n suffix?: string\n }\n styles?: {\n root?: React.CSSProperties\n prefix?: React.CSSProperties\n label?: React.CSSProperties\n suffix?: React.CSSProperties\n }\n prefix?: React.ReactNode\n label?: React.ReactNode\n suffix?: React.ReactNode\n active?: boolean\n}\n\nexport const FileTreeItem = React.forwardRef<HTMLDivElement, FileTreeItemProps>(\n ({ classNames, styles, prefix, label, suffix, active, ...props }, ref) => {\n const { global } = useNSUI()\n\n return (\n <Flex\n ref={ref}\n className={cn(`${global?.prefixCls}-file-tree-item`, classNames?.root)}\n data-active={active}\n style={styles?.root}\n {...props}\n >\n {prefix && (\n <div\n className={cn(`${global?.prefixCls}-file-tree-item-prefix`, classNames?.prefix)}\n style={styles?.prefix}\n >\n {prefix}\n </div>\n )}\n\n <div\n className={cn(`${global?.prefixCls}-file-tree-item-label`, classNames?.label)}\n style={styles?.label}\n >\n {label}\n </div>\n\n {suffix && (\n <div\n className={cn(`${global?.prefixCls}-file-tree-item-suffix`, classNames?.suffix)}\n style={styles?.suffix}\n >\n {suffix}\n </div>\n )}\n </Flex>\n )\n }\n)\n\nFileTreeItem.displayName = 'FileTreeItem'\n","import { Flex, type FlexProps } from '@negative-space/flex'\nimport { cn, useNSUI } from '@negative-space/system'\nimport React from 'react'\n\nimport { FileTreeFolder, type FileTreeFolderProps } from './FileTreeFolder'\nimport { FileTreeItem, type FileTreeItemProps } from './FileTreeItem'\n\nexport type FileTreeEntry =\n | {\n folder: Omit<FileTreeFolderProps, 'children'>\n items?: FileTreeEntry[]\n item?: never\n }\n | {\n item: FileTreeItemProps\n folder?: never\n items?: never\n }\n\nexport interface FileTreeProps extends Omit<FlexProps, 'children'> {\n classNames?: {\n root?: string\n folders?: FileTreeFolderProps['classNames']\n items?: FileTreeItemProps['classNames']\n }\n styles?: {\n root?: React.CSSProperties\n folders?: FileTreeFolderProps['styles']\n items?: FileTreeItemProps['styles']\n }\n items?: FileTreeEntry[]\n}\n\nexport const FileTree = React.forwardRef<HTMLDivElement, FileTreeProps>(\n ({ className, classNames, styles, items = [], ...props }, ref) => {\n const { global } = useNSUI()\n\n const renderEntries = (entries: FileTreeEntry[]) =>\n entries.map((entry, index) => {\n if (entry.folder) {\n return (\n <FileTreeFolder\n key={index}\n {...entry.folder}\n classNames={{\n ...classNames?.folders,\n ...entry.folder.classNames\n }}\n styles={{\n ...styles?.folders,\n ...entry.folder.styles\n }}\n >\n {entry.items && renderEntries(entry.items)}\n </FileTreeFolder>\n )\n }\n\n return (\n <FileTreeItem\n key={index}\n {...entry.item}\n classNames={{\n ...classNames?.items,\n ...entry.item.classNames\n }}\n styles={{\n ...styles?.items,\n ...entry.item.styles\n }}\n />\n )\n })\n\n return (\n <Flex\n ref={ref}\n direction=\"column\"\n className={cn(`${global?.prefixCls}-file-tree`, className, classNames?.root)}\n style={styles?.root}\n {...props}\n >\n {renderEntries(items)}\n </Flex>\n )\n }\n)\n\nFileTree.displayName = 'FileTree'\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { Flex } from '@negative-space/flex';
|
|
2
|
+
import { useNSUI, cn, ChevronDown } from '@negative-space/system';
|
|
3
|
+
import React, { useState, useEffect } from 'react';
|
|
4
|
+
import { IconButton } from '@negative-space/button';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
// src/FileTree.tsx
|
|
8
|
+
var FileTreeFolder = React.forwardRef(
|
|
9
|
+
({
|
|
10
|
+
classNames,
|
|
11
|
+
styles,
|
|
12
|
+
collapsable = true,
|
|
13
|
+
collapsed = true,
|
|
14
|
+
setCollapsed: setCollapsedProp,
|
|
15
|
+
prefix,
|
|
16
|
+
label,
|
|
17
|
+
suffix,
|
|
18
|
+
active,
|
|
19
|
+
children,
|
|
20
|
+
...props
|
|
21
|
+
}, ref) => {
|
|
22
|
+
const { global } = useNSUI();
|
|
23
|
+
const [collapsedState, setCollapsedState] = useState(collapsed);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
setCollapsedState(collapsed);
|
|
26
|
+
}, [collapsed]);
|
|
27
|
+
const isCollapsed = setCollapsedProp ? collapsed : collapsedState;
|
|
28
|
+
const handleCollapse = () => {
|
|
29
|
+
const nextCollapsed = !isCollapsed;
|
|
30
|
+
setCollapsedState(nextCollapsed);
|
|
31
|
+
setCollapsedProp?.(nextCollapsed);
|
|
32
|
+
};
|
|
33
|
+
return /* @__PURE__ */ jsxs(
|
|
34
|
+
Flex,
|
|
35
|
+
{
|
|
36
|
+
ref,
|
|
37
|
+
direction: "column",
|
|
38
|
+
className: cn(`${global?.prefixCls}-file-tree-folder`, classNames?.root),
|
|
39
|
+
"data-active": active,
|
|
40
|
+
style: styles?.root,
|
|
41
|
+
...props,
|
|
42
|
+
children: [
|
|
43
|
+
/* @__PURE__ */ jsxs(
|
|
44
|
+
Flex,
|
|
45
|
+
{
|
|
46
|
+
className: cn(`${global?.prefixCls}-file-tree-folder-header`, classNames?.header),
|
|
47
|
+
"data-active": active,
|
|
48
|
+
"data-collapsed": isCollapsed,
|
|
49
|
+
style: styles?.header,
|
|
50
|
+
children: [
|
|
51
|
+
collapsable && /* @__PURE__ */ jsx(
|
|
52
|
+
IconButton,
|
|
53
|
+
{
|
|
54
|
+
classNames: classNames?.collapseButton,
|
|
55
|
+
"data-collapsed": isCollapsed,
|
|
56
|
+
styles: styles?.collapseButton,
|
|
57
|
+
onClick: handleCollapse,
|
|
58
|
+
children: /* @__PURE__ */ jsx(
|
|
59
|
+
ChevronDown,
|
|
60
|
+
{
|
|
61
|
+
style: {
|
|
62
|
+
transform: isCollapsed ? "rotate(-90deg)" : "",
|
|
63
|
+
...styles?.collapseButton?.icon
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
prefix && /* @__PURE__ */ jsx(
|
|
70
|
+
"div",
|
|
71
|
+
{
|
|
72
|
+
className: cn(`${global?.prefixCls}-file-tree-folder-prefix`, classNames?.prefix),
|
|
73
|
+
style: styles?.prefix,
|
|
74
|
+
children: prefix
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
/* @__PURE__ */ jsx(
|
|
78
|
+
"div",
|
|
79
|
+
{
|
|
80
|
+
className: cn(`${global?.prefixCls}-file-tree-folder-label`, classNames?.label),
|
|
81
|
+
style: styles?.label,
|
|
82
|
+
children: label
|
|
83
|
+
}
|
|
84
|
+
),
|
|
85
|
+
suffix && /* @__PURE__ */ jsx(
|
|
86
|
+
"div",
|
|
87
|
+
{
|
|
88
|
+
className: cn(`${global?.prefixCls}-file-tree-folder-suffix`, classNames?.suffix),
|
|
89
|
+
style: styles?.suffix,
|
|
90
|
+
children: suffix
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
),
|
|
96
|
+
!isCollapsed && /* @__PURE__ */ jsx(
|
|
97
|
+
"div",
|
|
98
|
+
{
|
|
99
|
+
className: cn(`${global?.prefixCls}-file-tree-folder-children`, classNames?.children),
|
|
100
|
+
style: styles?.children,
|
|
101
|
+
children
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
FileTreeFolder.displayName = "FileTreeFolder";
|
|
110
|
+
var FileTreeItem = React.forwardRef(
|
|
111
|
+
({ classNames, styles, prefix, label, suffix, active, ...props }, ref) => {
|
|
112
|
+
const { global } = useNSUI();
|
|
113
|
+
return /* @__PURE__ */ jsxs(
|
|
114
|
+
Flex,
|
|
115
|
+
{
|
|
116
|
+
ref,
|
|
117
|
+
className: cn(`${global?.prefixCls}-file-tree-item`, classNames?.root),
|
|
118
|
+
"data-active": active,
|
|
119
|
+
style: styles?.root,
|
|
120
|
+
...props,
|
|
121
|
+
children: [
|
|
122
|
+
prefix && /* @__PURE__ */ jsx(
|
|
123
|
+
"div",
|
|
124
|
+
{
|
|
125
|
+
className: cn(`${global?.prefixCls}-file-tree-item-prefix`, classNames?.prefix),
|
|
126
|
+
style: styles?.prefix,
|
|
127
|
+
children: prefix
|
|
128
|
+
}
|
|
129
|
+
),
|
|
130
|
+
/* @__PURE__ */ jsx(
|
|
131
|
+
"div",
|
|
132
|
+
{
|
|
133
|
+
className: cn(`${global?.prefixCls}-file-tree-item-label`, classNames?.label),
|
|
134
|
+
style: styles?.label,
|
|
135
|
+
children: label
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
suffix && /* @__PURE__ */ jsx(
|
|
139
|
+
"div",
|
|
140
|
+
{
|
|
141
|
+
className: cn(`${global?.prefixCls}-file-tree-item-suffix`, classNames?.suffix),
|
|
142
|
+
style: styles?.suffix,
|
|
143
|
+
children: suffix
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
FileTreeItem.displayName = "FileTreeItem";
|
|
152
|
+
var FileTree = React.forwardRef(
|
|
153
|
+
({ className, classNames, styles, items = [], ...props }, ref) => {
|
|
154
|
+
const { global } = useNSUI();
|
|
155
|
+
const renderEntries = (entries) => entries.map((entry, index) => {
|
|
156
|
+
if (entry.folder) {
|
|
157
|
+
return /* @__PURE__ */ jsx(
|
|
158
|
+
FileTreeFolder,
|
|
159
|
+
{
|
|
160
|
+
...entry.folder,
|
|
161
|
+
classNames: {
|
|
162
|
+
...classNames?.folders,
|
|
163
|
+
...entry.folder.classNames
|
|
164
|
+
},
|
|
165
|
+
styles: {
|
|
166
|
+
...styles?.folders,
|
|
167
|
+
...entry.folder.styles
|
|
168
|
+
},
|
|
169
|
+
children: entry.items && renderEntries(entry.items)
|
|
170
|
+
},
|
|
171
|
+
index
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
return /* @__PURE__ */ jsx(
|
|
175
|
+
FileTreeItem,
|
|
176
|
+
{
|
|
177
|
+
...entry.item,
|
|
178
|
+
classNames: {
|
|
179
|
+
...classNames?.items,
|
|
180
|
+
...entry.item.classNames
|
|
181
|
+
},
|
|
182
|
+
styles: {
|
|
183
|
+
...styles?.items,
|
|
184
|
+
...entry.item.styles
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
index
|
|
188
|
+
);
|
|
189
|
+
});
|
|
190
|
+
return /* @__PURE__ */ jsx(
|
|
191
|
+
Flex,
|
|
192
|
+
{
|
|
193
|
+
ref,
|
|
194
|
+
direction: "column",
|
|
195
|
+
className: cn(`${global?.prefixCls}-file-tree`, className, classNames?.root),
|
|
196
|
+
style: styles?.root,
|
|
197
|
+
...props,
|
|
198
|
+
children: renderEntries(items)
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
);
|
|
203
|
+
FileTree.displayName = "FileTree";
|
|
204
|
+
|
|
205
|
+
export { FileTree };
|
|
206
|
+
//# sourceMappingURL=index.mjs.map
|
|
207
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/FileTreeFolder.tsx","../src/FileTreeItem.tsx","../src/FileTree.tsx"],"names":["React","useNSUI","jsxs","Flex","cn","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["import { IconButton, type IconButtonProps } from '@negative-space/button'\nimport { Flex, type FlexProps } from '@negative-space/flex'\nimport { ChevronDown, cn, useNSUI } from '@negative-space/system'\nimport React, { useEffect, useState } from 'react'\n\nexport interface FileTreeFolderProps extends Omit<\n FlexProps,\n 'children' | 'className' | 'style' | 'prefix'\n> {\n classNames?: {\n root?: string\n header?: string\n collapseButton?: IconButtonProps['classNames']\n prefix?: string\n label?: string\n suffix?: string\n children?: string\n }\n styles?: {\n root?: React.CSSProperties\n header?: React.CSSProperties\n collapseButton?: IconButtonProps['styles']\n prefix?: React.CSSProperties\n label?: React.CSSProperties\n suffix?: React.CSSProperties\n children?: React.CSSProperties\n }\n prefix?: React.ReactNode\n label?: React.ReactNode\n suffix?: React.ReactNode\n children?: React.ReactNode\n collapsable?: boolean\n collapsed?: boolean\n setCollapsed?: (collapsed: boolean) => void\n active?: boolean\n}\n\nexport const FileTreeFolder = React.forwardRef<HTMLDivElement, FileTreeFolderProps>(\n (\n {\n classNames,\n styles,\n collapsable = true,\n collapsed = true,\n setCollapsed: setCollapsedProp,\n prefix,\n label,\n suffix,\n active,\n children,\n ...props\n },\n ref\n ) => {\n const { global } = useNSUI()\n const [collapsedState, setCollapsedState] = useState(collapsed)\n\n useEffect(() => {\n setCollapsedState(collapsed)\n }, [collapsed])\n\n const isCollapsed = setCollapsedProp ? collapsed : collapsedState\n\n const handleCollapse = () => {\n const nextCollapsed = !isCollapsed\n\n setCollapsedState(nextCollapsed)\n setCollapsedProp?.(nextCollapsed)\n }\n\n return (\n <Flex\n ref={ref}\n direction=\"column\"\n className={cn(`${global?.prefixCls}-file-tree-folder`, classNames?.root)}\n data-active={active}\n style={styles?.root}\n {...props}\n >\n <Flex\n className={cn(`${global?.prefixCls}-file-tree-folder-header`, classNames?.header)}\n data-active={active}\n data-collapsed={isCollapsed}\n style={styles?.header}\n >\n {collapsable && (\n <IconButton\n classNames={classNames?.collapseButton}\n data-collapsed={isCollapsed}\n styles={styles?.collapseButton}\n onClick={handleCollapse}\n >\n <ChevronDown\n style={{\n transform: isCollapsed ? 'rotate(-90deg)' : '',\n ...styles?.collapseButton?.icon\n }}\n />\n </IconButton>\n )}\n\n {prefix && (\n <div\n className={cn(`${global?.prefixCls}-file-tree-folder-prefix`, classNames?.prefix)}\n style={styles?.prefix}\n >\n {prefix}\n </div>\n )}\n\n <div\n className={cn(`${global?.prefixCls}-file-tree-folder-label`, classNames?.label)}\n style={styles?.label}\n >\n {label}\n </div>\n\n {suffix && (\n <div\n className={cn(`${global?.prefixCls}-file-tree-folder-suffix`, classNames?.suffix)}\n style={styles?.suffix}\n >\n {suffix}\n </div>\n )}\n </Flex>\n\n {!isCollapsed && (\n <div\n className={cn(`${global?.prefixCls}-file-tree-folder-children`, classNames?.children)}\n style={styles?.children}\n >\n {children}\n </div>\n )}\n </Flex>\n )\n }\n)\n\nFileTreeFolder.displayName = 'FileTreeFolder'\n","import { Flex, type FlexProps } from '@negative-space/flex'\nimport { cn, useNSUI } from '@negative-space/system'\nimport React from 'react'\n\nexport interface FileTreeItemProps extends Omit<\n FlexProps,\n 'children' | 'className' | 'style' | 'prefix'\n> {\n classNames?: {\n root?: string\n prefix?: string\n label?: string\n suffix?: string\n }\n styles?: {\n root?: React.CSSProperties\n prefix?: React.CSSProperties\n label?: React.CSSProperties\n suffix?: React.CSSProperties\n }\n prefix?: React.ReactNode\n label?: React.ReactNode\n suffix?: React.ReactNode\n active?: boolean\n}\n\nexport const FileTreeItem = React.forwardRef<HTMLDivElement, FileTreeItemProps>(\n ({ classNames, styles, prefix, label, suffix, active, ...props }, ref) => {\n const { global } = useNSUI()\n\n return (\n <Flex\n ref={ref}\n className={cn(`${global?.prefixCls}-file-tree-item`, classNames?.root)}\n data-active={active}\n style={styles?.root}\n {...props}\n >\n {prefix && (\n <div\n className={cn(`${global?.prefixCls}-file-tree-item-prefix`, classNames?.prefix)}\n style={styles?.prefix}\n >\n {prefix}\n </div>\n )}\n\n <div\n className={cn(`${global?.prefixCls}-file-tree-item-label`, classNames?.label)}\n style={styles?.label}\n >\n {label}\n </div>\n\n {suffix && (\n <div\n className={cn(`${global?.prefixCls}-file-tree-item-suffix`, classNames?.suffix)}\n style={styles?.suffix}\n >\n {suffix}\n </div>\n )}\n </Flex>\n )\n }\n)\n\nFileTreeItem.displayName = 'FileTreeItem'\n","import { Flex, type FlexProps } from '@negative-space/flex'\nimport { cn, useNSUI } from '@negative-space/system'\nimport React from 'react'\n\nimport { FileTreeFolder, type FileTreeFolderProps } from './FileTreeFolder'\nimport { FileTreeItem, type FileTreeItemProps } from './FileTreeItem'\n\nexport type FileTreeEntry =\n | {\n folder: Omit<FileTreeFolderProps, 'children'>\n items?: FileTreeEntry[]\n item?: never\n }\n | {\n item: FileTreeItemProps\n folder?: never\n items?: never\n }\n\nexport interface FileTreeProps extends Omit<FlexProps, 'children'> {\n classNames?: {\n root?: string\n folders?: FileTreeFolderProps['classNames']\n items?: FileTreeItemProps['classNames']\n }\n styles?: {\n root?: React.CSSProperties\n folders?: FileTreeFolderProps['styles']\n items?: FileTreeItemProps['styles']\n }\n items?: FileTreeEntry[]\n}\n\nexport const FileTree = React.forwardRef<HTMLDivElement, FileTreeProps>(\n ({ className, classNames, styles, items = [], ...props }, ref) => {\n const { global } = useNSUI()\n\n const renderEntries = (entries: FileTreeEntry[]) =>\n entries.map((entry, index) => {\n if (entry.folder) {\n return (\n <FileTreeFolder\n key={index}\n {...entry.folder}\n classNames={{\n ...classNames?.folders,\n ...entry.folder.classNames\n }}\n styles={{\n ...styles?.folders,\n ...entry.folder.styles\n }}\n >\n {entry.items && renderEntries(entry.items)}\n </FileTreeFolder>\n )\n }\n\n return (\n <FileTreeItem\n key={index}\n {...entry.item}\n classNames={{\n ...classNames?.items,\n ...entry.item.classNames\n }}\n styles={{\n ...styles?.items,\n ...entry.item.styles\n }}\n />\n )\n })\n\n return (\n <Flex\n ref={ref}\n direction=\"column\"\n className={cn(`${global?.prefixCls}-file-tree`, className, classNames?.root)}\n style={styles?.root}\n {...props}\n >\n {renderEntries(items)}\n </Flex>\n )\n }\n)\n\nFileTree.displayName = 'FileTree'\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@negative-space/file-tree",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "A lightweight and flexible file tree component for React",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"components",
|
|
10
|
+
"file-tree",
|
|
11
|
+
"navigation",
|
|
12
|
+
"negative-space",
|
|
13
|
+
"nsui",
|
|
14
|
+
"react",
|
|
15
|
+
"ui"
|
|
16
|
+
],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"main": "dist/index.js",
|
|
19
|
+
"module": "dist/index.mjs",
|
|
20
|
+
"types": "dist/index.d.ts",
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/negative-space-ui/nsui",
|
|
27
|
+
"directory": "packages/ui/file-tree"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/negative-space-ui/nsui/issues"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@negative-space/button": "2.9.3",
|
|
34
|
+
"@negative-space/flex": "1.3.2",
|
|
35
|
+
"@negative-space/system": "1.5.2"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"react": "^19.2.3"
|
|
39
|
+
},
|
|
40
|
+
"clean-package": "../../../../clean-package.config.json",
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup",
|
|
43
|
+
"clean": "rimraf dist .turbo dist"
|
|
44
|
+
}
|
|
45
|
+
}
|