@aozi6666/bee-design 0.1.2 → 0.2.3

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.
Files changed (107) hide show
  1. package/dist/components/src/App.d.ts +4 -0
  2. package/{build → dist/components/src}/components/AutoComplete/autoCompleteDropdown.d.ts +2 -2
  3. package/dist/components/src/components/AutoComplete/index.d.ts +4 -0
  4. package/{build → dist/components/src}/components/Button/button.d.ts +2 -2
  5. package/{build → dist/components/src}/components/Button/button.types.d.ts +1 -1
  6. package/dist/components/src/components/Button/index.d.ts +2 -0
  7. package/{build → dist/components/src}/components/Icon/icon.d.ts +2 -2
  8. package/dist/components/src/components/Icon/icon.types.d.ts +6 -0
  9. package/dist/components/src/components/Icon/index.d.ts +2 -0
  10. package/dist/components/src/components/Input/index.d.ts +4 -0
  11. package/dist/components/src/components/Input/input.d.ts +5 -0
  12. package/{build → dist/components/src}/components/Input/input.types.d.ts +4 -4
  13. package/{build → dist/components/src}/components/Menu/index.d.ts +4 -4
  14. package/{build → dist/components/src}/components/Menu/menu.d.ts +2 -2
  15. package/{build → dist/components/src}/components/Menu/menuContext.d.ts +1 -1
  16. package/{build → dist/components/src}/components/Menu/menuItem.d.ts +2 -2
  17. package/{build → dist/components/src}/components/Menu/subMenu.d.ts +1 -1
  18. package/dist/components/src/components/Progress/index.d.ts +2 -0
  19. package/dist/components/src/components/Progress/progress.d.ts +4 -0
  20. package/{build → dist/components/src}/components/Progress/progress.types.d.ts +2 -2
  21. package/dist/components/src/components/Transition/index.d.ts +3 -0
  22. package/dist/components/src/components/Transition/transition.d.ts +4 -0
  23. package/dist/components/src/components/Transition/transition.types.d.ts +9 -0
  24. package/{build → dist/components/src}/components/Upload/dragger.d.ts +1 -1
  25. package/dist/components/src/components/Upload/index.d.ts +2 -0
  26. package/{build → dist/components/src}/components/Upload/upload.d.ts +2 -2
  27. package/{build → dist/components/src}/components/Upload/upload.types.d.ts +1 -1
  28. package/{build → dist/components/src}/components/Upload/uploadList.d.ts +2 -2
  29. package/dist/components/src/index.d.ts +9 -0
  30. package/dist/components/src/main.d.ts +1 -0
  31. package/dist/components/src/setupIcons.d.ts +1 -0
  32. package/dist/components/src/setupTests.d.ts +1 -0
  33. package/dist/index.cjs +16272 -0
  34. package/dist/index.cjs.map +1 -0
  35. package/{build → dist}/index.css +24 -24
  36. package/dist/index.esm.js +709 -0
  37. package/dist/index.esm.js.map +1 -0
  38. package/dist/index.umd.js +14381 -0
  39. package/dist/index.umd.js.map +1 -0
  40. package/dist/utils/src/dom/getScrollParent.d.ts +1 -0
  41. package/dist/utils/src/index.d.ts +5 -0
  42. package/dist/utils/src/number/clamp.d.ts +9 -0
  43. package/dist/utils/src/object/pickOmit.d.ts +2 -0
  44. package/dist/utils/src/react/composeEventHandlers.d.ts +7 -0
  45. package/dist/utils/src/react/mergeRefs.d.ts +2 -0
  46. package/package.json +52 -82
  47. package/README.md +0 -182
  48. package/build/App.d.ts +0 -4
  49. package/build/App.js +0 -137
  50. package/build/components/AutoComplete/autoComplete.js +0 -150
  51. package/build/components/AutoComplete/autoComplete.types.js +0 -1
  52. package/build/components/AutoComplete/autoCompleteDropdown.js +0 -17
  53. package/build/components/AutoComplete/index.d.ts +0 -4
  54. package/build/components/AutoComplete/index.js +0 -3
  55. package/build/components/Button/button.js +0 -43
  56. package/build/components/Button/button.types.js +0 -19
  57. package/build/components/Button/index.d.ts +0 -2
  58. package/build/components/Button/index.js +0 -2
  59. package/build/components/Icon/icon.js +0 -24
  60. package/build/components/Icon/icon.types.d.ts +0 -6
  61. package/build/components/Icon/icon.types.js +0 -2
  62. package/build/components/Icon/index.d.ts +0 -2
  63. package/build/components/Icon/index.js +0 -2
  64. package/build/components/Input/index.d.ts +0 -4
  65. package/build/components/Input/index.js +0 -3
  66. package/build/components/Input/input.d.ts +0 -5
  67. package/build/components/Input/input.js +0 -32
  68. package/build/components/Input/input.types.js +0 -1
  69. package/build/components/Menu/index.js +0 -9
  70. package/build/components/Menu/menu.js +0 -48
  71. package/build/components/Menu/menuContext.js +0 -2
  72. package/build/components/Menu/menuItem.js +0 -20
  73. package/build/components/Menu/subMenu.js +0 -57
  74. package/build/components/Progress/index.d.ts +0 -2
  75. package/build/components/Progress/index.js +0 -2
  76. package/build/components/Progress/progress.d.ts +0 -4
  77. package/build/components/Progress/progress.js +0 -6
  78. package/build/components/Progress/progress.types.js +0 -2
  79. package/build/components/Transition/index.d.ts +0 -3
  80. package/build/components/Transition/index.js +0 -2
  81. package/build/components/Transition/transition.d.ts +0 -4
  82. package/build/components/Transition/transition.js +0 -10
  83. package/build/components/Transition/transition.types.d.ts +0 -9
  84. package/build/components/Transition/transition.types.js +0 -1
  85. package/build/components/Upload/dragger.js +0 -42
  86. package/build/components/Upload/index.d.ts +0 -2
  87. package/build/components/Upload/index.js +0 -2
  88. package/build/components/Upload/native/axios-react.js +0 -99
  89. package/build/components/Upload/native/from-html.js +0 -5
  90. package/build/components/Upload/upload.js +0 -192
  91. package/build/components/Upload/upload.types.js +0 -3
  92. package/build/components/Upload/uploadList.js +0 -13
  93. package/build/hooks/useClickOutside.js +0 -38
  94. package/build/hooks/useDebounce.js +0 -28
  95. package/build/index.css.map +0 -1
  96. package/build/index.d.ts +0 -9
  97. package/build/index.js +0 -12
  98. package/build/main.d.ts +0 -1
  99. package/build/main.js +0 -7
  100. package/build/setupTests.d.ts +0 -1
  101. package/build/setupTests.js +0 -1
  102. /package/{build → dist/components/src}/components/AutoComplete/autoComplete.d.ts +0 -0
  103. /package/{build → dist/components/src}/components/AutoComplete/autoComplete.types.d.ts +0 -0
  104. /package/{build → dist/components/src}/components/Upload/native/axios-react.d.ts +0 -0
  105. /package/{build → dist/components/src}/components/Upload/native/from-html.d.ts +0 -0
  106. /package/{build → dist/components/src}/hooks/useClickOutside.d.ts +0 -0
  107. /package/{build → dist/components/src}/hooks/useDebounce.d.ts +0 -0
@@ -1,150 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // AutoComplete 组件: 带搜索建议的 Input
3
- import { useState, useEffect, useRef } from "react";
4
- import Input from "../Input/input";
5
- import useDebounce from "../../hooks/useDebounce";
6
- import useClickOutside from "../../hooks/useClickOutside";
7
- import AutoCompleteDropdown from "./autoCompleteDropdown";
8
- /**
9
- * 输入框自动完成功能。当输入值需要自动完成时使用,支持同步和异步两种方式
10
- * 支持 Input 组件的所有属性 支持键盘事件选择
11
- * ### 引用方法
12
- *
13
- * ~~~js
14
- * import { AutoComplete } from 'vikingship'
15
- * ~~~
16
- */
17
- export const AutoComplete = (props) => {
18
- const { fetchSuggestions, onSelect, onChange, value, renderOption, ...restProps } = props;
19
- // 输入框当前显示的文本
20
- const [inputValue, setInputValue] = useState(value || "");
21
- // 候选项列表:下拉建议列表的数据源(渲染 `<li>` 就靠它)
22
- const [suggestions, setSugestions] = useState([]);
23
- // 加载状态:异步请求进行中就显示 loading
24
- const [loading, setLoading] = useState(false);
25
- // 是否展示下拉(配合 `Transition` 动画)
26
- const [showDropdown, setShowDropdown] = useState(false);
27
- // 高亮索引:键盘上下选择时,哪一项高亮(对应 class `is-active`)
28
- const [highlightIndex, setHighlightIndex] = useState(-1);
29
- // 两个关键 ref:
30
- // 用来区分“用户打字触发搜索” vs “用户选中后把值塞回去(不应该再搜一次)”
31
- // 用户打字时:true,用户选中:false
32
- const triggerSearch = useRef(false);
33
- // 挂到最外层 div 上,给 `useClickOutside` 判断“点击是否发生在组件外”
34
- const componentRef = useRef(null);
35
- // 防抖Hook:把“频繁输入”变成“停顿后再触发一次”
36
- const debouncedValue = useDebounce(inputValue, 300);
37
- // 自定义Hook:点击组件外部时,触发自定义的回调
38
- /* 在 `document` 上挂一个 `click` 监听
39
- * @param componentRef 组件的 ref
40
- * @param callback 点击外部时执行的回调
41
- */
42
- // componentRef: 指向 AutoComplete 最外层 DOM
43
- useClickOutside(componentRef, () => {
44
- setSugestions([]);
45
- setShowDropdown(false);
46
- });
47
- // 监听 `debouncedValue防抖后的值` 变化
48
- // fetchSuggestions这个函数本身的引用地址变没变,改变时,监听变化
49
- // 因为:React在 effect 里用到了这个函数,避免:闭包拿到旧函数
50
- useEffect(() => {
51
- // 调度函数: 把 函数 放入微任务队列(执行)
52
- // 页面更新等逻辑处理完再更新 UI,减少闪烁、时序混乱的问题
53
- const schedule = (fn) => {
54
- queueMicrotask(fn);
55
- };
56
- /* 停止搜索,关闭下拉框
57
- * 两种情况:
58
- * 1. 输入框为空(防抖后的值为空)
59
- * 2. 用户选中下拉建议某一项后,输入框值会变为选中项的值(不应该再搜一次)
60
- */
61
- if (!debouncedValue || !triggerSearch.current) {
62
- // 调用 调度函数: 把函数放入微任务队列(执行)
63
- schedule(() => {
64
- setShowDropdown(false); // 关闭下拉框 展示
65
- setHighlightIndex(-1); // 重置高亮索引
66
- });
67
- return;
68
- }
69
- // 搜索执行
70
- // 1. 拿当前输入内容,获取 建议项
71
- const results = fetchSuggestions(debouncedValue);
72
- // 异步返回:
73
- if (results instanceof Promise) {
74
- schedule(() => {
75
- setLoading(true); // 显示“加载中”
76
- setHighlightIndex(-1); // 不高亮任何项
77
- });
78
- // 异步返回: 拿到数据后,更新状态
79
- results.then((data) => {
80
- setLoading(false); // 关闭 “加载中”
81
- setSugestions(data); // 更新建议项列表
82
- setShowDropdown(data.length > 0); // 有数据,就显示下拉框
83
- });
84
- }
85
- else {
86
- // 同步返回: 本地有个数组,直接筛选
87
- schedule(() => {
88
- setLoading(false); // 关闭 “加载中”
89
- setSugestions(results);
90
- setShowDropdown(results.length > 0);
91
- setHighlightIndex(-1);
92
- });
93
- }
94
- }, [debouncedValue, fetchSuggestions]);
95
- const highlight = (index) => {
96
- if (index < 0)
97
- index = 0;
98
- if (index >= suggestions.length) {
99
- index = suggestions.length - 1;
100
- }
101
- setHighlightIndex(index);
102
- };
103
- const handleKeyDown = (e) => {
104
- switch (e.keyCode) {
105
- case 13:
106
- if (suggestions[highlightIndex]) {
107
- handleSelect(suggestions[highlightIndex]);
108
- }
109
- break;
110
- case 38:
111
- highlight(highlightIndex - 1);
112
- break;
113
- case 40:
114
- highlight(highlightIndex + 1);
115
- break;
116
- case 27:
117
- setShowDropdown(false);
118
- break;
119
- default:
120
- break;
121
- }
122
- };
123
- // 回调:消息框内容发生变化
124
- const handleChange = (e) => {
125
- // 获取 输入框内容 (去掉首尾空格)
126
- const value = e.target.value.trim();
127
- // 更新 输入框内容
128
- // `inputValue` 变化 → 经过 `useDebounce` 得到 `debouncedValue`
129
- setInputValue(value);
130
- // 组件使用者传来的回调:消息框内容发生变化
131
- if (onChange) {
132
- onChange(value);
133
- }
134
- // 告诉后面“这次是用户输入,应当触发搜索”
135
- triggerSearch.current = true;
136
- };
137
- // 回调:用户选中某一项
138
- const handleSelect = (item) => {
139
- setInputValue(item.value);
140
- setShowDropdown(false);
141
- if (onSelect) {
142
- onSelect(item);
143
- }
144
- triggerSearch.current = false;
145
- };
146
- return (_jsxs("div", { className: "viking-auto-complete", ref: componentRef, children: [_jsx(Input, { ...restProps, value: inputValue, onChange: handleChange, onKeyDown: handleKeyDown }), _jsx(AutoCompleteDropdown, { loading: loading, showDropdown: showDropdown, suggestions: suggestions, highlightIndex: highlightIndex, onSelect: handleSelect, renderOption: renderOption, onExited: () => {
147
- setSugestions([]);
148
- } })] }));
149
- };
150
- export default AutoComplete;
@@ -1 +0,0 @@
1
- export {};
@@ -1,17 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import classNames from 'classnames';
3
- import Icon from '../Icon/icon';
4
- import Transition from '../Transition/transition';
5
- export const AutoCompleteDropdown = (props) => {
6
- const { loading, showDropdown, suggestions, highlightIndex, onSelect, renderOption, onExited, } = props;
7
- const renderTemplate = (item) => {
8
- return renderOption ? renderOption(item) : item.value;
9
- };
10
- return (_jsx(Transition, { in: showDropdown || loading, animation: "zoom-in-top", timeout: 300, onExited: onExited, children: _jsxs("ul", { className: "viking-suggestion-list", children: [loading && (_jsx("div", { className: "suggestions-loading-icon", children: _jsx(Icon, { icon: "spinner", spin: true }) })), suggestions.map((item, index) => {
11
- const cnames = classNames('suggestion-item', {
12
- 'is-active': index === highlightIndex,
13
- });
14
- return (_jsx("li", { className: cnames, onClick: () => onSelect(item), children: renderTemplate(item) }, index));
15
- })] }) }));
16
- };
17
- export default AutoCompleteDropdown;
@@ -1,4 +0,0 @@
1
- import AutoComplete from './autoComplete';
2
- export default AutoComplete;
3
- export { AutoComplete } from './autoComplete';
4
- export type { AutoCompleteProps, DataSourceType } from './autoComplete.types';
@@ -1,3 +0,0 @@
1
- import AutoComplete from './autoComplete';
2
- export default AutoComplete;
3
- export { AutoComplete } from './autoComplete';
@@ -1,43 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- // 第三方工具库: 自动智能拼接 class 字符串
3
- import classNames from 'classnames';
4
- import { ButtonSize, ButtonType, } from './button.types';
5
- const Button = ({ className, disabled = false, size, btnType = ButtonType.Default, children, href, ...restProps }) => {
6
- // btn, btn-lg, btn-primary
7
- // ① classNames 生成 class
8
- /*
9
- 用户写:<Button btnType="primary" size="lg">
10
- 组件算出 class:btn btn-primary btn-lg
11
- */
12
- // 返回 字符串
13
- const classes = classNames('btn', className, {
14
- /*
15
- 外部传来 <Button btnType={ButtonType.Primary}>
16
- -> 变成 { "btn-primary": true }
17
- -> classNames 会加上: btn-primary
18
- -> 最终变为 : btn btn-primary
19
- */
20
- [`btn-${btnType}`]: btnType,
21
- [`btn-${size}`]: size,
22
- // 是 link 按钮 && disabled === true
23
- // classNames 会加上: disabled
24
- disabled: btnType === ButtonType.Link && disabled,
25
- });
26
- // ② 根据类型决定渲染:
27
- /*
28
- 用户写:<Button btnType="link" href="https://xxx">
29
- 组件算出: <a class="btn btn-link">...</a>
30
- */
31
- if (btnType === ButtonType.Link && href) {
32
- return (_jsx("a", { className: classes, href: href, ...restProps, children: children }));
33
- }
34
- /*
35
- 用户写:<Button btnType="primary">
36
- 组件算出: <button class="btn btn-primary">
37
- */
38
- return (_jsx("button", { className: classes, disabled: disabled, ...restProps, children: children }));
39
- };
40
- // 导出一个 React 组件函数
41
- export default Button;
42
- // 重新导出类型和枚举,方便测试等地方从 `./button` 统一导入
43
- export { ButtonSize, ButtonType };
@@ -1,19 +0,0 @@
1
- /* 定义 Button 组件可以接收哪些 props(组件 API) */
2
- // TS 导出 两个固定值 'lg' / 'sm'
3
- /*
4
- as const: 把 ButtonSize对象的值 变成不可修改的 字面量类型
5
- - 如果没有 as const: Large: string
6
- - 如果有 as const: Large: "lg"
7
-
8
- 不写 as const: Large: 'lg' 会被 TS 自动推导为 string 类型
9
- */
10
- export const ButtonSize = {
11
- Large: 'lg',
12
- Small: 'sm',
13
- };
14
- export const ButtonType = {
15
- Primary: 'primary',
16
- Default: 'default',
17
- Danger: 'danger',
18
- Link: 'link',
19
- };
@@ -1,2 +0,0 @@
1
- import Button from './button';
2
- export default Button;
@@ -1,2 +0,0 @@
1
- import Button from './button';
2
- export default Button;
@@ -1,24 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import classNames from 'classnames';
3
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
4
- /**
5
- * 提供了一套常用的图标集合 基于 react-fontawesome。
6
- *
7
- * 支持 react-fontawesome的所有属性 可以在这里查询 https://github.com/FortAwesome/react-fontawesome#basic
8
- *
9
- * 支持 fontawesome 所有 free-solid-icons,可以在这里查看所有图标 https://fontawesome.com/icons?d=gallery&s=solid&m=free
10
- * ### 引用方法
11
- *
12
- * ~~~js
13
- * import { Icon } from 'vikingship'
14
- * ~~~
15
- */
16
- export const Icon = (props) => {
17
- // icon-primary
18
- const { className, theme, ...restProps } = props;
19
- const classes = classNames('viking-icon', className, {
20
- [`icon-${theme}`]: theme
21
- });
22
- return (_jsx(FontAwesomeIcon, { className: classes, ...restProps }));
23
- };
24
- export default Icon;
@@ -1,6 +0,0 @@
1
- import type { FontAwesomeIconProps } from '@fortawesome/react-fontawesome';
2
- export type ThemeProps = 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'danger' | 'light' | 'dark';
3
- export interface IconProps extends FontAwesomeIconProps {
4
- /** 支持框架主题,根据主题显示不同的颜色 */
5
- theme?: ThemeProps;
6
- }
@@ -1,2 +0,0 @@
1
- // Icon 组件的类型定义拆分到单独文件
2
- export {};
@@ -1,2 +0,0 @@
1
- import Icon from './icon';
2
- export default Icon;
@@ -1,2 +0,0 @@
1
- import Icon from './icon';
2
- export default Icon;
@@ -1,4 +0,0 @@
1
- import Input from './input';
2
- export default Input;
3
- export { Input } from './input';
4
- export type * from './input.types';
@@ -1,3 +0,0 @@
1
- import Input from './input';
2
- export default Input;
3
- export { Input } from './input';
@@ -1,5 +0,0 @@
1
- import type { FC } from 'react';
2
- import type { InputProps } from './input.types';
3
- export type { InputProps, InputSize } from './input.types';
4
- export declare const Input: FC<InputProps>;
5
- export default Input;
@@ -1,32 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo } from 'react';
3
- import classNames from 'classnames';
4
- import Icon from '../Icon/icon';
5
- export const Input = (props) => {
6
- const { disabled, size, icon, prepend, append, style, onChange, ...restProps } = props;
7
- const classes = useMemo(() => classNames('viking-input-wrapper', {
8
- [`input-size-${size}`]: size,
9
- 'input-group': prepend || append,
10
- 'input-group-prepend': !!prepend,
11
- 'input-group-append': !!append,
12
- }), [append, prepend, size]);
13
- const inputClasses = classNames('viking-input-inner', {
14
- 'is-disabled': disabled,
15
- });
16
- const handleChange = (e) => {
17
- if (onChange)
18
- onChange(e);
19
- };
20
- const renderPrepend = () => {
21
- if (!prepend)
22
- return null;
23
- return _jsx("div", { className: "viking-input-group-prepend", children: prepend });
24
- };
25
- const renderAppend = () => {
26
- if (!append && !icon)
27
- return null;
28
- return (_jsxs("div", { className: "viking-input-group-append", children: [append, icon ? (_jsx("div", { className: "icon-wrapper", children: _jsx(Icon, { icon: icon }) })) : null] }));
29
- };
30
- return (_jsxs("div", { className: classes, style: style, children: [renderPrepend(), _jsx("input", { className: inputClasses, disabled: disabled, onChange: handleChange, ...restProps }), renderAppend()] }));
31
- };
32
- export default Input;
@@ -1 +0,0 @@
1
- export {};
@@ -1,9 +0,0 @@
1
- import Menu, {} from './menu';
2
- import SubMenu, {} from './subMenu';
3
- import MenuItem, {} from './menuItem';
4
- // Menu 做类型转换
5
- const TransMenu = Menu;
6
- // 把子组件挂到 Menu 上
7
- TransMenu.Item = MenuItem;
8
- TransMenu.SubMenu = SubMenu;
9
- export default TransMenu;
@@ -1,48 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import React, { useState } from 'react';
3
- import classNames from 'classnames';
4
- import { MenuContext } from './menuContext';
5
- /**
6
- * 为网站提供导航功能的菜单。支持横向纵向两种模式,支持下拉菜单。
7
- *
8
- * ```javascript
9
- * import { Menu } from 'vikingship'
10
- *
11
- * //然后可以使用 Menu.Item 和 Menu.Submenu 访问选项和子下拉菜单组件
12
- * ```
13
- */
14
- export const Menu = ({ className, mode = 'horizontal', style, children, defaultIndex = '0', onSelect, defaultOpenSubMenus = [], }) => {
15
- const [currentActive, setActive] = useState(defaultIndex);
16
- const classes = classNames('viking-menu', className, {
17
- 'menu-vertical': mode === 'vertical',
18
- 'menu-horizontal': mode !== 'vertical',
19
- });
20
- const handleClick = (index) => {
21
- setActive(index);
22
- if (onSelect) {
23
- onSelect(index);
24
- }
25
- };
26
- const passedContext = {
27
- index: currentActive ? currentActive : '0',
28
- onSelect: handleClick,
29
- mode,
30
- defaultOpenSubMenus,
31
- };
32
- const renderChildren = () => {
33
- return React.Children.map(children, (child, index) => {
34
- const childElement = child;
35
- const { displayName } = childElement.type;
36
- if (displayName === 'MenuItem' || displayName === 'SubMenu') {
37
- return React.cloneElement(childElement, {
38
- index: index.toString()
39
- });
40
- }
41
- else {
42
- console.error("Warning: Menu has a child which is not a MenuItem component");
43
- }
44
- });
45
- };
46
- return (_jsx("ul", { className: classes, style: style, "data-testid": "test-menu", children: _jsx(MenuContext.Provider, { value: passedContext, children: renderChildren() }) }));
47
- };
48
- export default Menu;
@@ -1,2 +0,0 @@
1
- import { createContext } from 'react';
2
- export const MenuContext = createContext({ index: '0' });
@@ -1,20 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import React, { useContext } from 'react';
3
- import classNames from 'classnames';
4
- import { MenuContext } from './menuContext';
5
- export const MenuItem = (props) => {
6
- const { index, disabled, className, style, children } = props;
7
- const context = useContext(MenuContext);
8
- const classes = classNames('menu-item', className, {
9
- 'is-disabled': disabled,
10
- 'is-active': context.index === index
11
- });
12
- const handleClick = () => {
13
- if (context.onSelect && !disabled && (typeof index === 'string')) {
14
- context.onSelect(index);
15
- }
16
- };
17
- return (_jsx("li", { className: classes, style: style, onClick: handleClick, children: children }));
18
- };
19
- MenuItem.displayName = 'MenuItem';
20
- export default MenuItem;
@@ -1,57 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { useContext, useState } from 'react';
3
- import classNames from 'classnames';
4
- import { MenuContext } from './menuContext';
5
- import Icon from '../Icon/icon';
6
- import Transition from '../Transition/transition';
7
- export const SubMenu = ({ index, title, children, className }) => {
8
- const context = useContext(MenuContext);
9
- const openedSubMenus = (context.defaultOpenSubMenus ?? []);
10
- const isOpend = (index && context.mode === 'vertical') ? openedSubMenus.includes(index) : false;
11
- const [menuOpen, setOpen] = useState(isOpend);
12
- const classes = classNames('menu-item submenu-item', className, {
13
- 'is-active': context.index === index,
14
- 'is-opened': menuOpen,
15
- 'is-vertical': context.mode === 'vertical'
16
- });
17
- const handleClick = (e) => {
18
- e.preventDefault();
19
- setOpen(!menuOpen);
20
- };
21
- let timer;
22
- const handleMouse = (e, toggle) => {
23
- if (timer)
24
- clearTimeout(timer);
25
- e.preventDefault();
26
- timer = setTimeout(() => {
27
- setOpen(toggle);
28
- }, 300);
29
- };
30
- const clickEvents = context.mode === 'vertical' ? {
31
- onClick: handleClick
32
- } : {};
33
- const hoverEvents = context.mode !== 'vertical' ? {
34
- onMouseEnter: (e) => { handleMouse(e, true); },
35
- onMouseLeave: (e) => { handleMouse(e, false); }
36
- } : {};
37
- const renderChildren = () => {
38
- const subMenuClasses = classNames('viking-submenu', {
39
- 'menu-opened': menuOpen
40
- });
41
- const childrenComponent = React.Children.map(children, (child, i) => {
42
- const childElement = child;
43
- if (childElement.type.displayName === 'MenuItem') {
44
- return React.cloneElement(childElement, {
45
- index: `${index}-${i}`
46
- });
47
- }
48
- else {
49
- console.error("Warning: SubMenu has a child which is not a MenuItem component");
50
- }
51
- });
52
- return (_jsx(Transition, { in: menuOpen, timeout: 300, animation: "zoom-in-top", children: _jsx("ul", { className: subMenuClasses, children: childrenComponent }) }));
53
- };
54
- return (_jsxs("li", { className: classes, ...hoverEvents, children: [_jsxs("div", { className: "submenu-title", ...clickEvents, children: [title, _jsx(Icon, { icon: "angle-down", className: "arrow-icon" })] }), renderChildren()] }, index));
55
- };
56
- SubMenu.displayName = 'SubMenu';
57
- export default SubMenu;
@@ -1,2 +0,0 @@
1
- import Progress from './progress';
2
- export default Progress;
@@ -1,2 +0,0 @@
1
- import Progress from './progress';
2
- export default Progress;
@@ -1,4 +0,0 @@
1
- import type { FC } from 'react';
2
- import type { ProgressProps } from './progress.types';
3
- declare const Progress: FC<ProgressProps>;
4
- export default Progress;
@@ -1,6 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- const Progress = (props) => {
3
- const { percent, strokeHeight = 15, showText = true, styles, theme = 'primary', } = props;
4
- return (_jsx("div", { className: "viking-progress-bar", style: styles, children: _jsx("div", { className: "viking-progress-bar-outer", style: { height: `${strokeHeight}px` }, children: _jsx("div", { className: `viking-progress-bar-inner color-${theme}`, style: { width: `${percent}%` }, children: showText && _jsx("span", { className: "inner-text", children: `${percent}%` }) }) }) }));
5
- };
6
- export default Progress;
@@ -1,2 +0,0 @@
1
- // Progress 组件的类型定义,单独拆分成文件,便于复用
2
- export {};
@@ -1,3 +0,0 @@
1
- import Transition from './transition';
2
- export default Transition;
3
- export type { AnimationName, TransitionProps } from './transition';
@@ -1,2 +0,0 @@
1
- import Transition from './transition';
2
- export default Transition;
@@ -1,4 +0,0 @@
1
- import type { TransitionProps } from './transition.types';
2
- export type { AnimationName, TransitionProps } from './transition.types';
3
- declare const Transition: (props: TransitionProps) => import("react/jsx-runtime").JSX.Element;
4
- export default Transition;
@@ -1,10 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useRef } from 'react';
3
- import { CSSTransition } from 'react-transition-group';
4
- const Transition = (props) => {
5
- const { children, classNames: classNamesProp, animation, wrapper = false, unmountOnExit = true, appear = true, timeout, ...restProps } = props;
6
- const cls = animation ? animation : classNamesProp;
7
- const nodeRef = useRef(null);
8
- return (_jsx(CSSTransition, { nodeRef: nodeRef, classNames: cls, unmountOnExit: unmountOnExit, appear: appear, timeout: timeout, ...restProps, children: _jsx("div", { ref: nodeRef, "data-transition-wrapper": wrapper ? 'true' : 'false', children: children }) }));
9
- };
10
- export default Transition;
@@ -1,9 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import type { CSSTransitionProps } from 'react-transition-group/CSSTransition';
3
- export type AnimationName = 'zoom-in-top' | 'zoom-in-left' | 'zoom-in-bottom' | 'zoom-in-right';
4
- export type TransitionProps = Omit<CSSTransitionProps<HTMLElement>, 'timeout'> & {
5
- animation?: AnimationName;
6
- wrapper?: boolean;
7
- children?: ReactNode;
8
- timeout: NonNullable<CSSTransitionProps<HTMLElement>['timeout']>;
9
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,42 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- /* Dragger 是专门处理拖拽上传逻辑的子组件:
3
- - 只负责获取拖拽的文件
4
- - 上传文件还是靠 Upload
5
- 监听浏览器拖拽事件 → 拿到拖进来的文件 → 传回 Upload 组件
6
-
7
- 浏览器 Drag & Drop API 事件:
8
- dragenter → 进入区域
9
- dragover → 在区域上方拖动
10
- dragleave → 离开区域
11
- drop → 松手放下文件(包含拖进来的文件)
12
- */
13
- import { useState } from 'react';
14
- import classNames from 'classnames';
15
- export const Dragger = (props) => {
16
- const { onFile, children } = props;
17
- // 负责拖拽样式
18
- const [dragOver, setDragOver] = useState(false);
19
- // 使用 `classNames` 拼 `className`:
20
- const klass = classNames('viking-uploader-dragger', {
21
- // 如果 `dragOver === true` 时,再加一个:`is-dragover`
22
- 'is-dragover': dragOver
23
- });
24
- // 上传流程
25
- const handleDrop = (e) => {
26
- e.preventDefault(); // 阻止默认行为
27
- setDragOver(false); // 拖拽结束:改变拖拽样式
28
- // dataTransfer: 浏览器 drop-API 的对象
29
- // 包含: files(文件列表FileList)、items、types
30
- // 通过 onFile回调 传回 Upload 处理
31
- onFile(e.dataTransfer.files);
32
- };
33
- // 回调: 控制拖拽状态(改变样式)
34
- const handleDrag = (e, over) => {
35
- e.preventDefault();
36
- setDragOver(over);
37
- };
38
- return (_jsx("div", { className: klass,
39
- // e: 监听DragEvent拖拽事件对象
40
- onDragOver: e => { handleDrag(e, true); }, onDragLeave: e => { handleDrag(e, false); }, onDrop: handleDrop, children: children }));
41
- };
42
- export default Dragger;
@@ -1,2 +0,0 @@
1
- import Upload from './upload';
2
- export default Upload;
@@ -1,2 +0,0 @@
1
- import Upload from './upload';
2
- export default Upload;