wssf-kage-ui 0.1.2 → 0.1.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 (83) hide show
  1. package/dist/cjs/Alert/index.d.ts +37 -0
  2. package/dist/cjs/Alert/index.js +124 -0
  3. package/dist/cjs/Alert/style.less +248 -0
  4. package/dist/cjs/Drawer/index.d.ts +57 -0
  5. package/dist/cjs/Drawer/index.js +203 -0
  6. package/dist/cjs/Drawer/style.less +215 -0
  7. package/dist/cjs/FloatButton/index.d.ts +54 -0
  8. package/dist/cjs/FloatButton/index.js +119 -0
  9. package/dist/cjs/FloatButton/style.less +266 -0
  10. package/dist/cjs/Message/index.d.ts +38 -0
  11. package/dist/cjs/Message/index.js +292 -0
  12. package/dist/cjs/Message/style.less +183 -0
  13. package/dist/cjs/Modal/index.d.ts +63 -0
  14. package/dist/cjs/Modal/index.js +254 -0
  15. package/dist/cjs/Modal/style.less +298 -0
  16. package/dist/cjs/Notification/index.d.ts +48 -0
  17. package/dist/cjs/Notification/index.js +340 -0
  18. package/dist/cjs/Notification/style.less +260 -0
  19. package/dist/cjs/Popconfirm/index.d.ts +58 -0
  20. package/dist/cjs/Popconfirm/index.js +393 -0
  21. package/dist/cjs/Popconfirm/style.less +417 -0
  22. package/dist/cjs/Progress/index.d.ts +43 -0
  23. package/dist/cjs/Progress/index.js +213 -0
  24. package/dist/cjs/Progress/style.less +206 -0
  25. package/dist/cjs/Result/index.d.ts +25 -0
  26. package/dist/cjs/Result/index.js +63 -0
  27. package/dist/cjs/Result/style.less +111 -0
  28. package/dist/cjs/Skeleton/index.d.ts +88 -0
  29. package/dist/cjs/Skeleton/index.js +207 -0
  30. package/dist/cjs/Skeleton/style.less +487 -0
  31. package/dist/cjs/Spin/index.d.ts +25 -0
  32. package/dist/cjs/Spin/index.js +98 -0
  33. package/dist/cjs/Spin/style.less +169 -0
  34. package/dist/cjs/Tree/index.d.ts +82 -0
  35. package/dist/cjs/Tree/index.js +226 -0
  36. package/dist/cjs/Tree/style.less +313 -0
  37. package/dist/cjs/Watermark/index.d.ts +41 -0
  38. package/dist/cjs/Watermark/index.js +353 -0
  39. package/dist/cjs/Watermark/style.less +31 -0
  40. package/dist/cjs/index.d.ts +27 -1
  41. package/dist/cjs/index.js +91 -0
  42. package/dist/esm/Alert/index.d.ts +37 -0
  43. package/dist/esm/Alert/index.js +121 -0
  44. package/dist/esm/Alert/style.less +248 -0
  45. package/dist/esm/Drawer/index.d.ts +57 -0
  46. package/dist/esm/Drawer/index.js +202 -0
  47. package/dist/esm/Drawer/style.less +215 -0
  48. package/dist/esm/FloatButton/index.d.ts +54 -0
  49. package/dist/esm/FloatButton/index.js +123 -0
  50. package/dist/esm/FloatButton/style.less +266 -0
  51. package/dist/esm/Message/index.d.ts +38 -0
  52. package/dist/esm/Message/index.js +294 -0
  53. package/dist/esm/Message/style.less +183 -0
  54. package/dist/esm/Modal/index.d.ts +63 -0
  55. package/dist/esm/Modal/index.js +251 -0
  56. package/dist/esm/Modal/style.less +298 -0
  57. package/dist/esm/Notification/index.d.ts +48 -0
  58. package/dist/esm/Notification/index.js +345 -0
  59. package/dist/esm/Notification/style.less +260 -0
  60. package/dist/esm/Popconfirm/index.d.ts +58 -0
  61. package/dist/esm/Popconfirm/index.js +389 -0
  62. package/dist/esm/Popconfirm/style.less +417 -0
  63. package/dist/esm/Progress/index.d.ts +43 -0
  64. package/dist/esm/Progress/index.js +208 -0
  65. package/dist/esm/Progress/style.less +206 -0
  66. package/dist/esm/Result/index.d.ts +25 -0
  67. package/dist/esm/Result/index.js +57 -0
  68. package/dist/esm/Result/style.less +111 -0
  69. package/dist/esm/Skeleton/index.d.ts +88 -0
  70. package/dist/esm/Skeleton/index.js +213 -0
  71. package/dist/esm/Skeleton/style.less +487 -0
  72. package/dist/esm/Spin/index.d.ts +25 -0
  73. package/dist/esm/Spin/index.js +95 -0
  74. package/dist/esm/Spin/style.less +169 -0
  75. package/dist/esm/Tree/index.d.ts +82 -0
  76. package/dist/esm/Tree/index.js +225 -0
  77. package/dist/esm/Tree/style.less +313 -0
  78. package/dist/esm/Watermark/index.d.ts +41 -0
  79. package/dist/esm/Watermark/index.js +349 -0
  80. package/dist/esm/Watermark/style.less +31 -0
  81. package/dist/esm/index.d.ts +27 -1
  82. package/dist/esm/index.js +14 -1
  83. package/package.json +1 -1
@@ -0,0 +1,215 @@
1
+ // Drawer 抽屉组件样式
2
+
3
+ @prefix: kage-drawer;
4
+
5
+ // 颜色变量
6
+ @drawer-bg: #fff;
7
+ @drawer-mask-bg: rgba(0, 0, 0, 0.45);
8
+ @drawer-border-color: rgba(0, 0, 0, 0.06);
9
+ @drawer-title-color: rgba(0, 0, 0, 0.85);
10
+ @drawer-text-color: rgba(0, 0, 0, 0.65);
11
+
12
+ // ============ 遮罩层 ============
13
+ .@{prefix}-mask {
14
+ position: fixed;
15
+ top: 0;
16
+ left: 0;
17
+ right: 0;
18
+ bottom: 0;
19
+ background-color: @drawer-mask-bg;
20
+ opacity: 0;
21
+ visibility: hidden;
22
+ transition: opacity 0.3s, visibility 0.3s;
23
+
24
+ &-open {
25
+ opacity: 1;
26
+ visibility: visible;
27
+ }
28
+ }
29
+
30
+ // ============ 抽屉主体 ============
31
+ .@{prefix} {
32
+ position: fixed;
33
+ z-index: 1000;
34
+ display: flex;
35
+ flex-direction: column;
36
+ background-color: @drawer-bg;
37
+ box-shadow: -6px 0 16px 0 rgba(0, 0, 0, 0.08), -3px 0 6px -4px rgba(0, 0, 0, 0.12),
38
+ -9px 0 28px 8px rgba(0, 0, 0, 0.05);
39
+ transition: transform 0.3s cubic-bezier(0.7, 0.3, 0.1, 1), box-shadow 0.3s;
40
+
41
+ * {
42
+ box-sizing: border-box;
43
+ }
44
+ }
45
+
46
+ // ============ 位置 - 右侧 ============
47
+ .@{prefix}-right {
48
+ top: 0;
49
+ right: 0;
50
+ bottom: 0;
51
+ width: 378px;
52
+ transform: translateX(100%);
53
+
54
+ &.@{prefix}-open {
55
+ transform: translateX(0);
56
+ }
57
+ }
58
+
59
+ // ============ 位置 - 左侧 ============
60
+ .@{prefix}-left {
61
+ top: 0;
62
+ left: 0;
63
+ bottom: 0;
64
+ width: 378px;
65
+ transform: translateX(-100%);
66
+
67
+ &.@{prefix}-open {
68
+ transform: translateX(0);
69
+ }
70
+ }
71
+
72
+ // ============ 位置 - 顶部 ============
73
+ .@{prefix}-top {
74
+ top: 0;
75
+ left: 0;
76
+ right: 0;
77
+ height: 378px;
78
+ transform: translateY(-100%);
79
+
80
+ &.@{prefix}-open {
81
+ transform: translateY(0);
82
+ }
83
+ }
84
+
85
+ // ============ 位置 - 底部 ============
86
+ .@{prefix}-bottom {
87
+ bottom: 0;
88
+ left: 0;
89
+ right: 0;
90
+ height: 378px;
91
+ transform: translateY(100%);
92
+
93
+ &.@{prefix}-open {
94
+ transform: translateY(0);
95
+ }
96
+ }
97
+
98
+ // ============ 头部 ============
99
+ .@{prefix}-header {
100
+ position: relative;
101
+ display: flex;
102
+ align-items: center;
103
+ padding: 16px 24px;
104
+ border-bottom: 1px solid @drawer-border-color;
105
+ flex-shrink: 0;
106
+ }
107
+
108
+ .@{prefix}-title {
109
+ flex: 1;
110
+ margin: 0;
111
+ color: @drawer-title-color;
112
+ font-size: 16px;
113
+ font-weight: 500;
114
+ line-height: 1.5;
115
+ overflow: hidden;
116
+ text-overflow: ellipsis;
117
+ white-space: nowrap;
118
+ }
119
+
120
+ // ============ 关闭按钮 ============
121
+ .@{prefix}-close {
122
+ position: absolute;
123
+ top: 0;
124
+ right: 0;
125
+ display: flex;
126
+ align-items: center;
127
+ justify-content: center;
128
+ width: 56px;
129
+ height: 56px;
130
+ padding: 0;
131
+ margin: 0;
132
+ color: rgba(0, 0, 0, 0.45);
133
+ font-size: 16px;
134
+ line-height: 1;
135
+ text-align: center;
136
+ background: transparent;
137
+ border: none;
138
+ border-radius: 0;
139
+ cursor: pointer;
140
+ transition: all 0.2s;
141
+
142
+ &:hover {
143
+ color: rgba(0, 0, 0, 0.85);
144
+ background-color: rgba(0, 0, 0, 0.06);
145
+ }
146
+
147
+ &:active {
148
+ background-color: rgba(0, 0, 0, 0.1);
149
+ }
150
+ }
151
+
152
+ // ============ 内容区域 ============
153
+ .@{prefix}-body {
154
+ flex: 1;
155
+ padding: 24px;
156
+ overflow: auto;
157
+ color: @drawer-text-color;
158
+ font-size: 14px;
159
+ line-height: 1.5715;
160
+ }
161
+
162
+ // ============ 底部 ============
163
+ .@{prefix}-footer {
164
+ padding: 10px 16px;
165
+ border-top: 1px solid @drawer-border-color;
166
+ flex-shrink: 0;
167
+ }
168
+
169
+ // ============ 暗色模式适配 ============
170
+ [data-theme='dark'],
171
+ [data-prefers-color-scheme='dark'],
172
+ [data-prefers-color='dark'],
173
+ html.dark,
174
+ body.dark,
175
+ .dark {
176
+ .@{prefix} {
177
+ background-color: #1f1f1f;
178
+ box-shadow: -6px 0 16px 0 rgba(0, 0, 0, 0.48), -3px 0 6px -4px rgba(0, 0, 0, 0.32),
179
+ -9px 0 28px 8px rgba(0, 0, 0, 0.2);
180
+ }
181
+
182
+ .@{prefix}-mask {
183
+ background-color: rgba(0, 0, 0, 0.65);
184
+ }
185
+
186
+ .@{prefix}-header {
187
+ border-bottom-color: rgba(255, 255, 255, 0.1);
188
+ }
189
+
190
+ .@{prefix}-title {
191
+ color: rgba(255, 255, 255, 0.85);
192
+ }
193
+
194
+ .@{prefix}-close {
195
+ color: rgba(255, 255, 255, 0.45);
196
+
197
+ &:hover {
198
+ color: rgba(255, 255, 255, 0.85);
199
+ background-color: rgba(255, 255, 255, 0.08);
200
+ }
201
+
202
+ &:active {
203
+ background-color: rgba(255, 255, 255, 0.12);
204
+ }
205
+ }
206
+
207
+ .@{prefix}-body {
208
+ color: rgba(255, 255, 255, 0.65);
209
+ }
210
+
211
+ .@{prefix}-footer {
212
+ border-top-color: rgba(255, 255, 255, 0.1);
213
+ }
214
+ }
215
+
@@ -0,0 +1,54 @@
1
+ import React, { ReactNode, CSSProperties } from 'react';
2
+ import './style.less';
3
+ /** FloatButton 类型 */
4
+ export type FloatButtonType = 'default' | 'primary';
5
+ /** FloatButton 形状 */
6
+ export type FloatButtonShape = 'circle' | 'square';
7
+ /** FloatButton 触发方式 */
8
+ export type FloatButtonTrigger = 'click' | 'hover';
9
+ /** FloatButton 属性 */
10
+ export interface FloatButtonProps {
11
+ /** 图标 */
12
+ icon?: ReactNode;
13
+ /** 描述文字 */
14
+ description?: ReactNode;
15
+ /** 按钮类型 */
16
+ type?: FloatButtonType;
17
+ /** 按钮形状 */
18
+ shape?: FloatButtonShape;
19
+ /** 自定义类名 */
20
+ className?: string;
21
+ /** 自定义样式 */
22
+ style?: CSSProperties;
23
+ /** 点击回调 */
24
+ onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
25
+ /** 工具提示 */
26
+ tooltip?: ReactNode;
27
+ /** 是否禁用 */
28
+ disabled?: boolean;
29
+ /** 是否危险按钮 */
30
+ danger?: boolean;
31
+ /** 子元素 */
32
+ children?: ReactNode;
33
+ }
34
+ /** FloatButtonGroup 属性 */
35
+ export interface FloatButtonGroupProps {
36
+ /** 触发方式 */
37
+ trigger?: FloatButtonTrigger;
38
+ /** 是否打开 */
39
+ open?: boolean;
40
+ /** 默认是否打开 */
41
+ defaultOpen?: boolean;
42
+ /** 打开状态改变回调 */
43
+ onOpenChange?: (open: boolean) => void;
44
+ /** 自定义类名 */
45
+ className?: string;
46
+ /** 自定义样式 */
47
+ style?: CSSProperties;
48
+ /** 子元素 */
49
+ children?: ReactNode;
50
+ }
51
+ export declare const FloatButton: React.FC<FloatButtonProps> & {
52
+ Group: React.FC<FloatButtonGroupProps>;
53
+ };
54
+ export default FloatButton;
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = exports.FloatButton = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ require("./style.less");
10
+ var _jsxRuntime = require("react/jsx-runtime");
11
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
12
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
16
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
17
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
18
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
19
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
20
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
21
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
22
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
23
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } // ============ 类型定义 ============
24
+ /** FloatButton 类型 */ /** FloatButton 形状 */ /** FloatButton 触发方式 */ /** FloatButton 属性 */ /** FloatButtonGroup 属性 */
25
+ // ============ FloatButton 组件 ============
26
+ var FloatButton = exports.FloatButton = function FloatButton(_ref) {
27
+ var icon = _ref.icon,
28
+ description = _ref.description,
29
+ _ref$type = _ref.type,
30
+ type = _ref$type === void 0 ? 'default' : _ref$type,
31
+ _ref$shape = _ref.shape,
32
+ shape = _ref$shape === void 0 ? 'circle' : _ref$shape,
33
+ _ref$className = _ref.className,
34
+ className = _ref$className === void 0 ? '' : _ref$className,
35
+ style = _ref.style,
36
+ onClick = _ref.onClick,
37
+ tooltip = _ref.tooltip,
38
+ _ref$disabled = _ref.disabled,
39
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
40
+ _ref$danger = _ref.danger,
41
+ danger = _ref$danger === void 0 ? false : _ref$danger,
42
+ children = _ref.children;
43
+ var classNames = ['kage-float-btn', "kage-float-btn-".concat(type), "kage-float-btn-".concat(shape), danger && 'kage-float-btn-danger', disabled && 'kage-float-btn-disabled', className].filter(Boolean).join(' ');
44
+ var content = children || icon;
45
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
46
+ className: "kage-float-btn-wrapper",
47
+ children: [tooltip && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
48
+ className: "kage-float-btn-tooltip",
49
+ children: tooltip
50
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
51
+ type: "button",
52
+ className: classNames,
53
+ style: style,
54
+ onClick: onClick,
55
+ disabled: disabled,
56
+ "aria-label": typeof (description || tooltip) === 'string' ? description || tooltip : undefined,
57
+ children: content
58
+ }), description && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
59
+ className: "kage-float-btn-description",
60
+ children: description
61
+ })]
62
+ });
63
+ };
64
+
65
+ // ============ FloatButtonGroup 组件 ============
66
+ var FloatButtonGroup = function FloatButtonGroup(_ref2) {
67
+ var _ref2$trigger = _ref2.trigger,
68
+ trigger = _ref2$trigger === void 0 ? 'click' : _ref2$trigger,
69
+ controlledOpen = _ref2.open,
70
+ _ref2$defaultOpen = _ref2.defaultOpen,
71
+ defaultOpen = _ref2$defaultOpen === void 0 ? false : _ref2$defaultOpen,
72
+ onOpenChange = _ref2.onOpenChange,
73
+ _ref2$className = _ref2.className,
74
+ className = _ref2$className === void 0 ? '' : _ref2$className,
75
+ style = _ref2.style,
76
+ children = _ref2.children;
77
+ var _useState = (0, _react.useState)(defaultOpen),
78
+ _useState2 = _slicedToArray(_useState, 2),
79
+ internalOpen = _useState2[0],
80
+ setInternalOpen = _useState2[1];
81
+ var isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;
82
+ var updateOpen = function updateOpen(newOpen) {
83
+ if (controlledOpen === undefined) {
84
+ setInternalOpen(newOpen);
85
+ }
86
+ onOpenChange === null || onOpenChange === void 0 || onOpenChange(newOpen);
87
+ };
88
+ var handleClick = function handleClick() {
89
+ if (trigger === 'click') {
90
+ updateOpen(!isOpen);
91
+ }
92
+ };
93
+ var handleMouseEnter = function handleMouseEnter() {
94
+ if (trigger === 'hover') {
95
+ updateOpen(true);
96
+ }
97
+ };
98
+ var handleMouseLeave = function handleMouseLeave() {
99
+ if (trigger === 'hover') {
100
+ updateOpen(false);
101
+ }
102
+ };
103
+ var classNames = ['kage-float-btn-group', isOpen && 'kage-float-btn-group-open', className].filter(Boolean).join(' ');
104
+ var groupProps = {};
105
+ if (trigger === 'click') {
106
+ groupProps.onClick = handleClick;
107
+ } else if (trigger === 'hover') {
108
+ groupProps.onMouseEnter = handleMouseEnter;
109
+ groupProps.onMouseLeave = handleMouseLeave;
110
+ }
111
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", _objectSpread(_objectSpread({
112
+ className: classNames,
113
+ style: style
114
+ }, groupProps), {}, {
115
+ children: children
116
+ }));
117
+ };
118
+ FloatButton.Group = FloatButtonGroup;
119
+ var _default = exports.default = FloatButton;
@@ -0,0 +1,266 @@
1
+ // FloatButton 悬浮按钮组件样式
2
+
3
+ @prefix: kage-float-btn;
4
+
5
+ // 颜色变量
6
+ @float-btn-default-bg: #fff;
7
+ @float-btn-default-color: rgba(0, 0, 0, 0.85);
8
+ @float-btn-primary-bg: #1890ff;
9
+ @float-btn-primary-color: #fff;
10
+ @float-btn-danger-bg: #ff4d4f;
11
+ @float-btn-danger-color: #fff;
12
+ @float-btn-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
13
+
14
+ // ============ 主容器 ============
15
+ .@{prefix}-wrapper {
16
+ position: relative;
17
+ display: inline-block;
18
+ }
19
+
20
+ // ============ 悬浮按钮 ============
21
+ .@{prefix} {
22
+ position: relative;
23
+ z-index: 10;
24
+ display: flex;
25
+ align-items: center;
26
+ justify-content: center;
27
+ width: 56px;
28
+ height: 56px;
29
+ padding: 0;
30
+ color: @float-btn-default-color;
31
+ font-size: 20px;
32
+ line-height: 1;
33
+ text-align: center;
34
+ background-color: @float-btn-default-bg;
35
+ border: none;
36
+ border-radius: 50%;
37
+ box-shadow: @float-btn-shadow;
38
+ cursor: pointer;
39
+ transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
40
+ user-select: none;
41
+
42
+ &:hover {
43
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
44
+ }
45
+
46
+ &:active {
47
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12);
48
+ }
49
+
50
+ &:disabled {
51
+ color: rgba(0, 0, 0, 0.25);
52
+ background-color: #f5f5f5;
53
+ cursor: not-allowed;
54
+ box-shadow: none;
55
+
56
+ &:hover {
57
+ box-shadow: none;
58
+ }
59
+ }
60
+
61
+ * {
62
+ box-sizing: border-box;
63
+ }
64
+ }
65
+
66
+ // ============ 类型 ============
67
+ .@{prefix}-primary {
68
+ color: @float-btn-primary-color;
69
+ background-color: @float-btn-primary-bg;
70
+
71
+ &:hover {
72
+ background-color: #40a9ff;
73
+ }
74
+
75
+ &:active {
76
+ background-color: #0958d9;
77
+ }
78
+
79
+ &:disabled {
80
+ color: rgba(0, 0, 0, 0.25);
81
+ background-color: #f5f5f5;
82
+ }
83
+ }
84
+
85
+ .@{prefix}-danger {
86
+ color: @float-btn-danger-color;
87
+ background-color: @float-btn-danger-bg;
88
+
89
+ &:hover {
90
+ background-color: #ff7875;
91
+ }
92
+
93
+ &:active {
94
+ background-color: #cf1322;
95
+ }
96
+
97
+ &:disabled {
98
+ color: rgba(0, 0, 0, 0.25);
99
+ background-color: #f5f5f5;
100
+ }
101
+ }
102
+
103
+ // ============ 形状 ============
104
+ .@{prefix}-square {
105
+ border-radius: 8px;
106
+ }
107
+
108
+ // ============ 描述 ============
109
+ .@{prefix}-description {
110
+ position: absolute;
111
+ right: 100%;
112
+ display: flex;
113
+ align-items: center;
114
+ height: 22px;
115
+ margin-right: 12px;
116
+ padding: 0 8px;
117
+ color: rgba(0, 0, 0, 0.85);
118
+ font-size: 14px;
119
+ line-height: 22px;
120
+ white-space: nowrap;
121
+ background-color: rgba(0, 0, 0, 0.75);
122
+ border-radius: 4px;
123
+ opacity: 0;
124
+ transform: scale(0.8);
125
+ transform-origin: right center;
126
+ transition: all 0.2s;
127
+ pointer-events: none;
128
+
129
+ &::after {
130
+ position: absolute;
131
+ top: 50%;
132
+ right: -4px;
133
+ width: 0;
134
+ height: 0;
135
+ border: 4px solid transparent;
136
+ border-left-color: rgba(0, 0, 0, 0.75);
137
+ transform: translateY(-50%);
138
+ content: '';
139
+ }
140
+ }
141
+
142
+ .@{prefix}-wrapper:hover .@{prefix}-description {
143
+ opacity: 1;
144
+ transform: scale(1);
145
+ }
146
+
147
+ // ============ 工具提示 ============
148
+ .@{prefix}-tooltip {
149
+ position: absolute;
150
+ right: 100%;
151
+ display: flex;
152
+ align-items: center;
153
+ height: 22px;
154
+ margin-right: 12px;
155
+ padding: 0 8px;
156
+ color: #fff;
157
+ font-size: 14px;
158
+ line-height: 22px;
159
+ white-space: nowrap;
160
+ background-color: rgba(0, 0, 0, 0.75);
161
+ border-radius: 4px;
162
+ opacity: 0;
163
+ transform: scale(0.8);
164
+ transform-origin: right center;
165
+ transition: all 0.2s;
166
+ pointer-events: none;
167
+
168
+ &::after {
169
+ position: absolute;
170
+ top: 50%;
171
+ right: -4px;
172
+ width: 0;
173
+ height: 0;
174
+ border: 4px solid transparent;
175
+ border-left-color: rgba(0, 0, 0, 0.75);
176
+ transform: translateY(-50%);
177
+ content: '';
178
+ }
179
+ }
180
+
181
+ .@{prefix}-wrapper:hover .@{prefix}-tooltip {
182
+ opacity: 1;
183
+ transform: scale(1);
184
+ }
185
+
186
+ // ============ 按钮组 ============
187
+ .@{prefix}-group {
188
+ position: relative;
189
+ display: flex;
190
+ flex-direction: column;
191
+ gap: 16px;
192
+ align-items: center;
193
+ }
194
+
195
+ .@{prefix}-group-open {
196
+ .@{prefix} {
197
+ opacity: 1;
198
+ transform: scale(1);
199
+ }
200
+ }
201
+
202
+ .@{prefix}-group:not(.@{prefix}-group-open) {
203
+ > .@{prefix}:not(:first-child) {
204
+ opacity: 0;
205
+ transform: scale(0);
206
+ pointer-events: none;
207
+ }
208
+ }
209
+
210
+ // ============ 暗色模式适配 ============
211
+ [data-theme='dark'],
212
+ [data-prefers-color-scheme='dark'],
213
+ [data-prefers-color='dark'],
214
+ html.dark,
215
+ body.dark,
216
+ .dark {
217
+ .@{prefix} {
218
+ background-color: #1f1f1f;
219
+ color: rgba(255, 255, 255, 0.85);
220
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
221
+
222
+ &:hover {
223
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
224
+ }
225
+
226
+ &:disabled {
227
+ color: rgba(255, 255, 255, 0.25);
228
+ background-color: rgba(255, 255, 255, 0.08);
229
+ }
230
+ }
231
+
232
+ .@{prefix}-primary {
233
+ background-color: #1890ff;
234
+
235
+ &:hover {
236
+ background-color: #40a9ff;
237
+ }
238
+
239
+ &:disabled {
240
+ background-color: rgba(255, 255, 255, 0.08);
241
+ }
242
+ }
243
+
244
+ .@{prefix}-danger {
245
+ background-color: #ff4d4f;
246
+
247
+ &:hover {
248
+ background-color: #ff7875;
249
+ }
250
+
251
+ &:disabled {
252
+ background-color: rgba(255, 255, 255, 0.08);
253
+ }
254
+ }
255
+
256
+ .@{prefix}-description,
257
+ .@{prefix}-tooltip {
258
+ background-color: rgba(255, 255, 255, 0.85);
259
+ color: rgba(0, 0, 0, 0.85);
260
+
261
+ &::after {
262
+ border-left-color: rgba(255, 255, 255, 0.85);
263
+ }
264
+ }
265
+ }
266
+
@@ -0,0 +1,38 @@
1
+ import React, { ReactNode, CSSProperties } from 'react';
2
+ import './style.less';
3
+ /** Message 类型 */
4
+ export type MessageType = 'success' | 'info' | 'warning' | 'error' | 'loading';
5
+ /** Message 配置 */
6
+ export interface MessageConfig {
7
+ /** 提示内容 */
8
+ content: ReactNode;
9
+ /** 提示类型 */
10
+ type?: MessageType;
11
+ /** 自动关闭的延时,单位秒。设为 0 时不自动关闭 */
12
+ duration?: number;
13
+ /** 自定义图标 */
14
+ icon?: ReactNode;
15
+ /** 自定义类名 */
16
+ className?: string;
17
+ /** 自定义样式 */
18
+ style?: CSSProperties;
19
+ /** 关闭时的回调 */
20
+ onClose?: () => void;
21
+ /** 消息唯一标识 */
22
+ key?: string | number;
23
+ }
24
+ /** Message API */
25
+ export interface MessageApi {
26
+ success: (content: ReactNode, duration?: number, onClose?: () => void) => void;
27
+ error: (content: ReactNode, duration?: number, onClose?: () => void) => void;
28
+ info: (content: ReactNode, duration?: number, onClose?: () => void) => void;
29
+ warning: (content: ReactNode, duration?: number, onClose?: () => void) => void;
30
+ loading: (content: ReactNode, duration?: number, onClose?: () => void) => void;
31
+ open: (config: MessageConfig) => void;
32
+ destroy: (key?: string | number) => void;
33
+ }
34
+ declare const MessageContainer: React.FC;
35
+ export declare const Message: MessageApi & {
36
+ Container: typeof MessageContainer;
37
+ };
38
+ export default Message;