@fe-free/core 2.7.1 → 2.8.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @fe-free/core
2
2
 
3
+ ## 2.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - fix: tree
8
+ - @fe-free/tool@2.8.1
9
+
10
+ ## 2.8.0
11
+
12
+ ### Minor Changes
13
+
14
+ - feat: className
15
+
16
+ ### Patch Changes
17
+
18
+ - @fe-free/tool@2.8.0
19
+
3
20
  ## 2.7.1
4
21
 
5
22
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fe-free/core",
3
- "version": "2.7.1",
3
+ "version": "2.8.1",
4
4
  "description": "",
5
5
  "main": "./src/index.ts",
6
6
  "author": "",
@@ -41,7 +41,7 @@
41
41
  "remark-gfm": "^4.0.1",
42
42
  "vanilla-jsoneditor": "^0.23.1",
43
43
  "zustand": "^4.5.4",
44
- "@fe-free/tool": "2.7.1"
44
+ "@fe-free/tool": "2.8.1"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@ant-design/pro-components": "2.8.9",
@@ -22,7 +22,7 @@ CRUDOfList 组件。(简洁的列表形态的 CRUD 组件)
22
22
  decorators: [
23
23
  (Story) => {
24
24
  return (
25
- <div className="c-border h-[500px] w-[300px] overflow-y-auto">
25
+ <div className="fec-border h-[500px] w-[300px] overflow-y-auto">
26
26
  <Story />
27
27
  </div>
28
28
  );
@@ -27,11 +27,11 @@ interface EditorMentionProps {
27
27
  }
28
28
 
29
29
  const emptyArr = [];
30
- const tagClassName = 'cl-editor-mention-tag';
30
+ const tagClassName = 'fec-editor-mention-tag';
31
31
  const defaultPrefix = ['/'];
32
32
 
33
33
  function defaultRenderItem({ item }) {
34
- return <div className="py-1 text-sm pl-4 pr-2">{item.label}</div>;
34
+ return <div className="py-1 pl-4 pr-2 text-sm">{item.label}</div>;
35
35
  }
36
36
 
37
37
  function defaultRenderTagHTML({ item }) {
@@ -104,16 +104,16 @@ function useDropdown({ items, renderItem, onSelect, editorRef }) {
104
104
  <div
105
105
  // 阻止下拉菜单点击事件冒泡
106
106
  onClick={(e) => e.stopPropagation()}
107
- className="shadow-md rounded p-1 z-10 max-h-[250px] overflow-y-auto bg-white absolute max-w-[250px]"
107
+ className="absolute z-10 max-h-[250px] max-w-[250px] overflow-y-auto rounded bg-white p-1 shadow-md"
108
108
  style={{
109
109
  top: `${position.top}px`,
110
110
  left: `${position.left}px`,
111
111
  }}
112
112
  >
113
- {items.length === 0 && <div className="text-desc text-sm p-2">暂无数据</div>}
113
+ {items.length === 0 && <div className="p-2 text-sm text-desc">暂无数据</div>}
114
114
  {items.map((group, i) => (
115
115
  <div key={group.label}>
116
- <div className="text-desc text-sm p-2">{group.label}</div>
116
+ <div className="p-2 text-sm text-desc">{group.label}</div>
117
117
  <div>
118
118
  {group.options.map((item) => (
119
119
  <div
@@ -122,7 +122,7 @@ function useDropdown({ items, renderItem, onSelect, editorRef }) {
122
122
  e.preventDefault(); // 防止失去焦点
123
123
  handleSelect(item);
124
124
  }}
125
- className="cursor-pointer hover:bg-gray-100 rounded"
125
+ className="cursor-pointer rounded hover:bg-gray-100"
126
126
  >
127
127
  {renderItem({ item, index: i })}
128
128
  </div>
@@ -200,7 +200,7 @@ function useChange({ content, editorRef, onChange }) {
200
200
  const node = (
201
201
  <div
202
202
  ref={ref}
203
- className="absolute top-[-10px] left-[-10px] w-[1px] h-[1px] overflow-auto"
203
+ className="absolute left-[-10px] top-[-10px] h-[1px] w-[1px] overflow-auto"
204
204
  contentEditable="true"
205
205
  />
206
206
  );
@@ -324,7 +324,7 @@ const EditorMention = ({
324
324
  const isEmpty = !content || content === '<br>';
325
325
 
326
326
  return (
327
- <div className="c-editor-mention relative h-full flex">
327
+ <div className="c-editor-mention relative flex h-full">
328
328
  <div
329
329
  ref={editorRef}
330
330
  contentEditable="true"
@@ -332,7 +332,7 @@ const EditorMention = ({
332
332
  onInput={handleInput}
333
333
  onKeyDown={handleKeyDown}
334
334
  className={classNames(
335
- 'flex-1 w-full p-2 c-border rounded outline-none overflow-y-auto focus:border-primary',
335
+ 'fec-border w-full flex-1 overflow-y-auto rounded p-2 outline-none focus:border-primary',
336
336
  resizeHeight && 'resize-y',
337
337
  )}
338
338
  style={{
@@ -341,7 +341,7 @@ const EditorMention = ({
341
341
  />
342
342
  {placeholder && isEmpty && (
343
343
  <div
344
- className="absolute top-0 left-0 text-gray-500 p-2 cursor-text"
344
+ className="absolute left-0 top-0 cursor-text p-2 text-gray-500"
345
345
  onClick={() => {
346
346
  editorRef.current?.focus();
347
347
  }}
@@ -85,7 +85,7 @@ function RecordArray(props: RecordArrayProps) {
85
85
 
86
86
  return (
87
87
  <ProFormListHelper
88
- className={classNames('c-bg rounded p-2', className)}
88
+ className={classNames('fec-bg rounded p-2', className)}
89
89
  value={value}
90
90
  onChange={onChange}
91
91
  getAdd={() => ({
package/src/style.scss CHANGED
@@ -8,31 +8,31 @@
8
8
  /* stylelint-disable-next-line at-rule-no-unknown */
9
9
  @tailwind utilities;
10
10
 
11
- .c-border {
11
+ .fec-border {
12
12
  border: 1px solid #f0f0f0;
13
13
  }
14
14
 
15
- .c-border-bottom {
15
+ .fec-border-bottom {
16
16
  border-bottom: 1px solid #f0f0f0;
17
17
  }
18
18
 
19
- .c-border-top {
19
+ .fec-border-top {
20
20
  border-top: 1px solid #f0f0f0;
21
21
  }
22
22
 
23
- .c-border-left {
23
+ .fec-border-left {
24
24
  border-left: 1px solid #f0f0f0;
25
25
  }
26
26
 
27
- .c-border-right {
27
+ .fec-border-right {
28
28
  border-right: 1px solid #f0f0f0;
29
29
  }
30
30
 
31
- .c-bg {
31
+ .fec-bg {
32
32
  background-color: #f3f5f6;
33
33
  }
34
34
 
35
- .c-bg-hover {
35
+ .fec-bg-hover {
36
36
  background-color: #f3f5f6;
37
37
 
38
38
  &:hover {
@@ -13,12 +13,12 @@ export const Default = () => {
13
13
  <div className="text-desc">text-desc</div>
14
14
  </div>
15
15
  <div>
16
- <div className="c-border-bottom">c-border-bottom</div>
17
- <div className="c-border-top">c-border-top</div>
18
- <div className="c-border-left">c-border-left</div>
19
- <div className="c-border-right">c-border-right</div>
20
- <div className="c-bg">c-bg</div>
21
- <div className="c-bg-hover">c-bg-hover</div>
16
+ <div className="fec-border-bottom">fec-border-bottom</div>
17
+ <div className="fec-border-top">fec-border-top</div>
18
+ <div className="fec-border-left">fec-border-left</div>
19
+ <div className="fec-border-right">fec-border-right</div>
20
+ <div className="fec-bg">fec-bg</div>
21
+ <div className="fec-bg-hover">fec-bg-hover</div>
22
22
  </div>
23
23
  </div>
24
24
  );
@@ -8,7 +8,7 @@ const meta: Meta<typeof FileTree> = {
8
8
  decorators: [
9
9
  (Story) => {
10
10
  return (
11
- <div className="c-border w-[200px] overflow-y-auto">
11
+ <div className="fec-border w-[200px] overflow-y-auto">
12
12
  <Story />
13
13
  </div>
14
14
  );
@@ -141,14 +141,16 @@ function FileTree<D extends DataNode>(props: FileTreeProps<D>) {
141
141
 
142
142
  const titleRender = useCallback(
143
143
  (nodeData) => {
144
- console.log(nodeData);
145
144
  const hasMore = props.actions?.includes('update') || props.actions?.includes('delete');
146
145
  return (
147
146
  <div className="group flex gap-1">
148
147
  {nodeData.children ? (
149
148
  <FileCard.FileIcon isDirectory className="text-base" />
150
149
  ) : (
151
- <FileCard.FileIcon name={nodeData.title} className="text-base" />
150
+ <FileCard.FileIcon
151
+ name={nodeData.originData?.title || nodeData.title}
152
+ className="text-base"
153
+ />
152
154
  )}
153
155
  <div className="flex-1 truncate">{nodeData.title}</div>
154
156
  <div className={classNames('text-desc', { 'group-hover:hidden': hasMore })}>
@@ -183,7 +185,7 @@ function FileTree<D extends DataNode>(props: FileTreeProps<D>) {
183
185
  treeProps={{
184
186
  titleRender,
185
187
  ...props.treeProps,
186
- className: classNames('cl-file-tree', props.treeProps?.className),
188
+ className: classNames('fec-file-tree', props.treeProps?.className),
187
189
  }}
188
190
  />
189
191
  );
@@ -1,5 +1,5 @@
1
- .cl-tree {
2
- &.cl-tree-no-wrap {
1
+ .fec-tree {
2
+ &.fec-tree-no-wrap {
3
3
  .ant-tree-title {
4
4
  white-space: nowrap;
5
5
  }
@@ -10,13 +10,13 @@
10
10
  }
11
11
  }
12
12
 
13
- .cl-file-tree {
13
+ .fec-file-tree {
14
14
  .ant-tree-node-content-wrapper {
15
15
  overflow: hidden;
16
16
  padding-inline-start: 0 !important;
17
17
  }
18
18
 
19
- &.cl-tree-all-leaf {
19
+ &.fec-tree-all-leaf {
20
20
  .ant-tree-switcher {
21
21
  display: none;
22
22
  }
@@ -7,7 +7,7 @@ const meta: Meta<typeof Tree> = {
7
7
  tags: ['autodocs'],
8
8
  decorators: [
9
9
  (Story) => (
10
- <div className="c-border w-[300px]">
10
+ <div className="fec-border w-[300px]">
11
11
  <Story />
12
12
  </div>
13
13
  ),
package/src/tree/tree.tsx CHANGED
@@ -30,10 +30,10 @@ function useHighLightTreeData({ treeData, search }) {
30
30
 
31
31
  const loop = (data) => {
32
32
  return data.map((item) => {
33
- const strTitle = item.title as string;
34
- const index = strTitle.indexOf(search);
35
- const beforeStr = strTitle.substring(0, index);
36
- const afterStr = strTitle.slice(index + search.length);
33
+ const originStrTitle = item.title as string;
34
+ const index = originStrTitle.indexOf(search);
35
+ const beforeStr = originStrTitle.substring(0, index);
36
+ const afterStr = originStrTitle.slice(index + search.length);
37
37
  const title =
38
38
  index > -1 ? (
39
39
  <span key={item.key}>
@@ -42,7 +42,7 @@ function useHighLightTreeData({ treeData, search }) {
42
42
  {afterStr}
43
43
  </span>
44
44
  ) : (
45
- <span key={item.key}>{strTitle}</span>
45
+ <span key={item.key}>{originStrTitle}</span>
46
46
  );
47
47
 
48
48
  if (item.children) {
@@ -52,6 +52,7 @@ function useHighLightTreeData({ treeData, search }) {
52
52
  return {
53
53
  ...item,
54
54
  title,
55
+ originData: item,
55
56
  };
56
57
  });
57
58
  };
@@ -76,21 +77,23 @@ function useFilterTreeData({ treeData, search }) {
76
77
 
77
78
  // 递归过滤树形数据
78
79
  const filterTree = (nodes) => {
80
+ // 返回自己。 而非 [] undefined,因为要保留原数据格式。
79
81
  if (!nodes || nodes.length === 0) {
80
- return [];
82
+ return nodes;
81
83
  }
82
84
 
83
85
  return nodes
84
86
  .map((node) => {
85
- const children = node.children ? filterTree(node.children) : [];
86
87
  const isMatch = isNodeMatch(node);
87
- const hasMatchingChildren = children.length > 0;
88
+
89
+ const children = filterTree(node.children);
90
+ const hasMatchingChildren = children?.length > 0;
88
91
 
89
92
  // 如果当前节点匹配或者有匹配的子节点,则保留该节点
90
93
  if (isMatch || hasMatchingChildren) {
91
94
  return {
92
95
  ...node,
93
- children: hasMatchingChildren ? children : undefined,
96
+ children,
94
97
  };
95
98
  }
96
99
 
@@ -105,7 +108,11 @@ function useFilterTreeData({ treeData, search }) {
105
108
 
106
109
  function useIsAllLeaf(treeData?: DataNode[]) {
107
110
  return useMemo(() => {
108
- return treeData?.every((item) => item.children === undefined) || true;
111
+ if (treeData) {
112
+ return !treeData.find((item) => item.children);
113
+ }
114
+
115
+ return true;
109
116
  }, [treeData]);
110
117
  }
111
118
 
@@ -157,9 +164,9 @@ function Tree<T extends DataNode>(props: TreeProps<T>) {
157
164
  {...treeProps}
158
165
  treeData={newTreeData}
159
166
  className={classNames(
160
- 'cl-tree cl-tree-no-wrap',
167
+ 'fec-tree fec-tree-no-wrap',
161
168
  {
162
- 'cl-tree-all-leaf': isAllLeaf,
169
+ 'fec-tree-all-leaf': isAllLeaf,
163
170
  },
164
171
  treeProps?.className,
165
172
  )}