@996-design/996-happy-work-theme 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 ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+ Copyright (c) 2015-present Alipay.com, https://www.alipay.com/
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/NOTICE.md ADDED
@@ -0,0 +1,23 @@
1
+ # Upstream attribution
2
+
3
+ The runtime and declaration artifacts in `es/` and `lib/` are derived from
4
+ `@ant-design/happy-work-theme` 2.0.0.
5
+
6
+ - Upstream: https://github.com/ant-design/happy-work-theme/tree/2.0.0
7
+ - License: MIT. See `LICENSE`.
8
+
9
+ Local changes are limited to the package identity, workspace scripts and
10
+ metadata, and rewriting Ant Design, CSS-in-JS, and FastColor imports to the
11
+ corresponding `@996-design/*` packages. The theme behavior is otherwise kept
12
+ aligned with the published 2.0.0 package.
13
+
14
+ ## Mechanical parity source
15
+
16
+ - npm tarball: https://registry.npmjs.org/@ant-design/happy-work-theme/-/happy-work-theme-2.0.0.tgz
17
+ - Integrity: `sha512-3pvwSOGl9YKkhusTFVsSAouoQPJNsf95I2ooIiUmG/tOkayFUbFqPqMHkMc5Q0XdpfKW+sCr6bCtLdsDnWxaaA==`
18
+ - Guard inventory: 16 runtime files; sorted-path SHA-256
19
+ `15a1411dd3d7ade353f1c9ae1f33006a71b078f3a845b2c71c90e333f3d049a1`.
20
+
21
+ The parity inventory excludes package metadata, local build products,
22
+ `node_modules`, and caches. Every inventoried file is compared after only the
23
+ declared package-namespace rewrite.
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # 996 Design Happy Work Theme
2
+
3
+ Expressive interaction theme for focused, energetic product experiences.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ pnpm add @996-design/996-happy-work-theme
9
+ ```
10
+
11
+ The package supplies theme runtime files and accompanying style assets. It is designed to be applied through the 996 Design configuration provider.
12
+
13
+ ## License
14
+
15
+ MIT. See `LICENSE` and `NOTICE.md` for license and source attribution.
@@ -0,0 +1,10 @@
1
+ import type { GlobalToken } from '@996-design/996-components';
2
+ import * as React from 'react';
3
+ interface DotEffectProps {
4
+ target: HTMLElement;
5
+ token: GlobalToken;
6
+ hashId: string;
7
+ onFinish: VoidFunction;
8
+ }
9
+ export default function DotEffect({ hashId, target, token, onFinish, }: DotEffectProps): React.JSX.Element;
10
+ export {};
@@ -0,0 +1,184 @@
1
+ import { FastColor } from '@996-design/996-fast-color';
2
+ import { clsx } from 'clsx';
3
+ import { CSSMotionList } from '@rc-component/motion';
4
+ import raf from "@rc-component/util/es/raf";
5
+ import * as React from 'react';
6
+ import useStyle, { TARGET_ATTR } from "./style";
7
+ const DOT_COUNT = 7;
8
+ const DOT_COUNT_LG = 10;
9
+ function inRange(x, y, left, top, right, bottom) {
10
+ return x >= left && x <= right && y >= top && y <= bottom;
11
+ }
12
+ export default function DotEffect({
13
+ hashId,
14
+ target,
15
+ token,
16
+ onFinish
17
+ }) {
18
+ const prefixCls = 'happy-wave';
19
+ const dotPrefixCls = `${prefixCls}-dot`;
20
+ const [dots, setDots] = React.useState(null);
21
+ const [left, setLeft] = React.useState(0);
22
+ const [top, setTop] = React.useState(0);
23
+ useStyle(prefixCls, hashId, token);
24
+ const targetAttrName = `${TARGET_ATTR}-${hashId}`;
25
+
26
+ // ========================= Dots =========================
27
+ React.useEffect(() => {
28
+ const id = raf(() => {
29
+ if (['-dangerous', '-error'].some(skipCls => target.className.includes(skipCls))) {
30
+ return;
31
+ }
32
+ const rect = target.getBoundingClientRect();
33
+ const {
34
+ width,
35
+ height
36
+ } = rect;
37
+ setLeft(rect.left + width / 2);
38
+ setTop(rect.top + height / 2);
39
+ setDots([]);
40
+ const minSize = Math.min(width, height);
41
+ const maxSize = Math.max(width, height);
42
+ const halfMinSize = minSize / 2;
43
+ const halfMaxSize = maxSize / 2;
44
+ const halfWidth = width / 2;
45
+ const halfHeight = height / 2;
46
+ const OFFSET_MIN = 15;
47
+ const OFFSET_MAX = 30;
48
+ const halfOffsetMinWidth = halfWidth + OFFSET_MIN;
49
+ const halfOffsetMinHeight = halfHeight + OFFSET_MIN;
50
+ const halfOffsetMaxWidth = halfWidth + OFFSET_MAX;
51
+ const halfOffsetMaxHeight = halfHeight + OFFSET_MAX;
52
+ const dotCount = minSize >= 20 ? DOT_COUNT_LG : DOT_COUNT;
53
+
54
+ // Delay to start dot motion
55
+ setTimeout(() => {
56
+ const offsetAngle = Math.random() * 360;
57
+
58
+ // Color
59
+ const {
60
+ colorPrimary
61
+ } = token;
62
+ const colorHsv = new FastColor(colorPrimary).toHsv();
63
+ colorHsv.h -= 30;
64
+ const colorPrimaryWeak = new FastColor(colorHsv).toHexString();
65
+ setDots(new Array(dotCount).fill(null).map((_, index) => {
66
+ const rotate = 360 / dotCount;
67
+ const randomAngle = offsetAngle + rotate * index;
68
+
69
+ // Get start XY (Which should align the rect edge)
70
+ let startX = 0;
71
+ let startY = 0;
72
+ for (let startDist = halfMinSize - 1; startDist <= halfMaxSize; startDist += 1) {
73
+ const x = Math.cos(randomAngle * Math.PI / 180) * startDist;
74
+ const y = Math.sin(randomAngle * Math.PI / 180) * startDist;
75
+ if (!inRange(x, y, -halfWidth, -halfHeight, halfWidth, halfHeight)) {
76
+ break;
77
+ }
78
+ startX = x;
79
+ startY = y;
80
+ }
81
+
82
+ // Get end XY
83
+ let endX = startX;
84
+ let endY = startY;
85
+ let endDist = halfMinSize;
86
+ const endHalfWidth = Math.random() * (halfOffsetMaxWidth - halfOffsetMinWidth) + halfOffsetMinWidth;
87
+ const endHalfHeight = Math.random() * (halfOffsetMaxHeight - halfOffsetMinHeight) + halfOffsetMinHeight;
88
+ do {
89
+ endX = Math.cos(randomAngle * Math.PI / 180) * endDist;
90
+ endY = Math.sin(randomAngle * Math.PI / 180) * endDist;
91
+ endDist += 1;
92
+ } while (inRange(endX, endY, -endHalfWidth, -endHalfHeight, endHalfWidth, endHalfHeight));
93
+ let size = Math.random() * 3 + 3;
94
+ if (height >= 20) {
95
+ size = Math.random() * 4 + 6;
96
+ }
97
+ return {
98
+ key: index + 1,
99
+ startX: `${startX}px`,
100
+ startY: `${startY}px`,
101
+ endX: `${endX}px`,
102
+ endY: `${endY}px`,
103
+ startSize: `${size}px`,
104
+ endSize: `${Math.random() > 0.75 ? size : 0}px`,
105
+ type: Math.random() > 0.6 ? 'outlined' : 'fill',
106
+ color: Math.random() > 0.5 ? colorPrimary : colorPrimaryWeak
107
+ };
108
+ }));
109
+ }, 50);
110
+ target.setAttribute(targetAttrName, 'true');
111
+ });
112
+ return () => {
113
+ raf.cancel(id);
114
+ };
115
+ }, []);
116
+
117
+ // ======================== Clean =========================
118
+ React.useEffect(() => {
119
+ const id = setTimeout(() => {
120
+ target.removeAttribute(targetAttrName);
121
+ onFinish();
122
+ }, 600);
123
+ return () => {
124
+ clearTimeout(id);
125
+ };
126
+ }, []);
127
+
128
+ // ======================== Render ========================
129
+ if (!dots) {
130
+ return null;
131
+ }
132
+ return /*#__PURE__*/React.createElement("div", {
133
+ className: clsx(prefixCls, hashId),
134
+ style: {
135
+ left,
136
+ top
137
+ }
138
+ }, /*#__PURE__*/React.createElement(CSSMotionList, {
139
+ component: false,
140
+ keys: dots,
141
+ motionAppear: true,
142
+ motionName: "happy-in-out"
143
+ }, ({
144
+ className: motionCls,
145
+ style: motionStyle,
146
+ key,
147
+ startX,
148
+ startY,
149
+ endX,
150
+ endY,
151
+ startSize,
152
+ endSize,
153
+ type,
154
+ color
155
+ }) => {
156
+ const name = `${dotPrefixCls}-${key}`;
157
+ const dotCls = clsx(dotPrefixCls, motionCls, name);
158
+
159
+ // if (dotCls.includes('active')) {
160
+ // debugger;
161
+ // }
162
+
163
+ const dotStyle = {
164
+ [`--start-x`]: startX,
165
+ [`--start-y`]: startY,
166
+ [`--end-x`]: endX,
167
+ [`--end-y`]: endY,
168
+ [`--start-size`]: startSize,
169
+ [`--end-size`]: endSize
170
+ };
171
+ if (type === 'fill') {
172
+ dotStyle['--background'] = color;
173
+ } else {
174
+ dotStyle['--border'] = `1px solid ${color}`;
175
+ }
176
+ return /*#__PURE__*/React.createElement("div", {
177
+ className: dotCls,
178
+ style: {
179
+ ...motionStyle,
180
+ ...dotStyle
181
+ }
182
+ });
183
+ }));
184
+ }
@@ -0,0 +1,4 @@
1
+ import type { GlobalToken } from '@996-design/996-components';
2
+ export declare const TARGET_ATTR = "data-happy-wave-target";
3
+ declare const useStyle: (prefixCls: string, hashId: string, token: GlobalToken) => void;
4
+ export default useStyle;
@@ -0,0 +1,100 @@
1
+ import { createTheme, Keyframes, useStyleRegister } from '@996-design/996-cssinjs';
2
+ const DEFAULT_THEME = createTheme(token => token);
3
+ export const TARGET_ATTR = 'data-happy-wave-target';
4
+ const antWaveTargetEffect = new Keyframes('antWaveTargetEffect', {
5
+ '0%': {
6
+ transform: 'scale(1)'
7
+ },
8
+ '10%': {
9
+ transform: 'scale(1.1)'
10
+ },
11
+ '35%': {
12
+ transform: 'scale(0.94)'
13
+ },
14
+ '60%': {
15
+ transform: 'scale(1.05)'
16
+ },
17
+ '85%': {
18
+ transform: 'scale(0.97)'
19
+ },
20
+ '100%': {
21
+ transform: 'scale(1)'
22
+ }
23
+ });
24
+ const antWaveDotEffect = new Keyframes('antWaveDotEffect', {
25
+ '0%': {
26
+ opacity: 0,
27
+ left: `var(--start-x)`,
28
+ top: `var(--start-y)`,
29
+ width: `var(--start-size)`,
30
+ height: `var(--start-size)`,
31
+ background: `var(--background)`,
32
+ border: `var(--border)`
33
+ },
34
+ '25%': {
35
+ opacity: 1
36
+ },
37
+ '50%': {
38
+ opacity: 0.8
39
+ },
40
+ '100%': {
41
+ opacity: 0,
42
+ left: `var(--end-x)`,
43
+ top: `var(--end-y)`,
44
+ width: `var(--end-size)`,
45
+ height: `var(--end-size)`,
46
+ background: `var(--background)`,
47
+ border: `var(--border)`
48
+ }
49
+ });
50
+ const useStyle = (prefixCls, hashId, token) => {
51
+ const sharedConfig = {
52
+ theme: DEFAULT_THEME,
53
+ token
54
+ };
55
+ useStyleRegister({
56
+ ...sharedConfig,
57
+ path: ['HappyWorkTheme', 'target']
58
+ }, () => ({
59
+ // ======================== Target ========================
60
+ [`[${TARGET_ATTR}-${hashId}], & [${TARGET_ATTR}-${hashId}]`]: {
61
+ animationName: antWaveTargetEffect,
62
+ animationDuration: `0.45s`,
63
+ animationTimingFunction: 'ease-in-out',
64
+ animationFillMode: 'backwards'
65
+ }
66
+ }));
67
+ useStyleRegister({
68
+ ...sharedConfig,
69
+ hashId,
70
+ path: ['HappyWorkTheme', 'effect']
71
+ }, () => {
72
+ const dotPrefixCls = `.${prefixCls}`;
73
+ return [{
74
+ // ========================= Dots =========================
75
+ [dotPrefixCls]: {
76
+ position: 'fixed',
77
+ pointerEvents: 'none',
78
+ zIndex: 999999,
79
+ [`${dotPrefixCls}-dot`]: {
80
+ boxSizing: 'border-box',
81
+ position: 'absolute',
82
+ borderRadius: '100%',
83
+ opacity: 0,
84
+ transform: 'translate3d(-50%, -50%, 0)',
85
+ // Start Position
86
+ zIndex: 999999,
87
+ // =================== Basic Motion ===================
88
+ '&.happy-in-out': {
89
+ animationName: antWaveDotEffect,
90
+ animationDuration: token.motionDurationSlow,
91
+ // animationDuration: '10s',
92
+ animationTimingFunction: 'linear',
93
+ animationFillMode: 'backwards'
94
+ }
95
+ }
96
+ }
97
+ }];
98
+ });
99
+ };
100
+ export default useStyle;
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ export interface HappyProviderProps {
3
+ disabled?: boolean;
4
+ }
5
+ declare const HappyProvider: React.FC<React.PropsWithChildren<HappyProviderProps>>;
6
+ export default HappyProvider;
@@ -0,0 +1,46 @@
1
+ import { ConfigProvider } from '@996-design/996-components';
2
+ import useEvent from "@rc-component/util/es/hooks/useEvent";
3
+ import * as React from 'react';
4
+ import DotEffect from "./DotEffect";
5
+ import { render, unmount } from "@rc-component/util/es/React/render";
6
+ const HappyProvider = props => {
7
+ const {
8
+ children,
9
+ disabled
10
+ } = props;
11
+ const showEffect = useEvent((target, info) => {
12
+ const {
13
+ token,
14
+ hashId
15
+ } = info;
16
+
17
+ // Create holder
18
+ const holder = document.createElement('div');
19
+ holder.style.position = 'absolute';
20
+ holder.style.left = `0px`;
21
+ holder.style.top = `0px`;
22
+ document.body.appendChild(holder);
23
+ render( /*#__PURE__*/React.createElement(DotEffect, {
24
+ target: target,
25
+ token: token,
26
+ hashId: hashId,
27
+ onFinish: () => {
28
+ unmount(holder).then(() => {
29
+ holder.remove();
30
+ });
31
+ }
32
+ }), holder);
33
+ });
34
+ const memoizedWaveConfig = React.useMemo(() => {
35
+ if (disabled) {
36
+ return {};
37
+ }
38
+ return {
39
+ showEffect
40
+ };
41
+ }, [disabled]);
42
+ return /*#__PURE__*/React.createElement(ConfigProvider, {
43
+ wave: memoizedWaveConfig
44
+ }, children);
45
+ };
46
+ export default HappyProvider;
package/es/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import HappyProvider from './HappyProvider';
2
+ export { HappyProvider };
package/es/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import HappyProvider from "./HappyProvider";
2
+ export { HappyProvider };
@@ -0,0 +1,10 @@
1
+ import type { GlobalToken } from '@996-design/996-components';
2
+ import * as React from 'react';
3
+ interface DotEffectProps {
4
+ target: HTMLElement;
5
+ token: GlobalToken;
6
+ hashId: string;
7
+ onFinish: VoidFunction;
8
+ }
9
+ export default function DotEffect({ hashId, target, token, onFinish, }: DotEffectProps): React.JSX.Element;
10
+ export {};
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = DotEffect;
9
+ var _fastColor = require("@996-design/996-fast-color");
10
+ var _clsx = require("clsx");
11
+ var _motion = require("@rc-component/motion");
12
+ var _raf = _interopRequireDefault(require("@rc-component/util/lib/raf"));
13
+ var React = _interopRequireWildcard(require("react"));
14
+ var _style = _interopRequireWildcard(require("./style"));
15
+ const DOT_COUNT = 7;
16
+ const DOT_COUNT_LG = 10;
17
+ function inRange(x, y, left, top, right, bottom) {
18
+ return x >= left && x <= right && y >= top && y <= bottom;
19
+ }
20
+ function DotEffect({
21
+ hashId,
22
+ target,
23
+ token,
24
+ onFinish
25
+ }) {
26
+ const prefixCls = 'happy-wave';
27
+ const dotPrefixCls = `${prefixCls}-dot`;
28
+ const [dots, setDots] = React.useState(null);
29
+ const [left, setLeft] = React.useState(0);
30
+ const [top, setTop] = React.useState(0);
31
+ (0, _style.default)(prefixCls, hashId, token);
32
+ const targetAttrName = `${_style.TARGET_ATTR}-${hashId}`;
33
+
34
+ // ========================= Dots =========================
35
+ React.useEffect(() => {
36
+ const id = (0, _raf.default)(() => {
37
+ if (['-dangerous', '-error'].some(skipCls => target.className.includes(skipCls))) {
38
+ return;
39
+ }
40
+ const rect = target.getBoundingClientRect();
41
+ const {
42
+ width,
43
+ height
44
+ } = rect;
45
+ setLeft(rect.left + width / 2);
46
+ setTop(rect.top + height / 2);
47
+ setDots([]);
48
+ const minSize = Math.min(width, height);
49
+ const maxSize = Math.max(width, height);
50
+ const halfMinSize = minSize / 2;
51
+ const halfMaxSize = maxSize / 2;
52
+ const halfWidth = width / 2;
53
+ const halfHeight = height / 2;
54
+ const OFFSET_MIN = 15;
55
+ const OFFSET_MAX = 30;
56
+ const halfOffsetMinWidth = halfWidth + OFFSET_MIN;
57
+ const halfOffsetMinHeight = halfHeight + OFFSET_MIN;
58
+ const halfOffsetMaxWidth = halfWidth + OFFSET_MAX;
59
+ const halfOffsetMaxHeight = halfHeight + OFFSET_MAX;
60
+ const dotCount = minSize >= 20 ? DOT_COUNT_LG : DOT_COUNT;
61
+
62
+ // Delay to start dot motion
63
+ setTimeout(() => {
64
+ const offsetAngle = Math.random() * 360;
65
+
66
+ // Color
67
+ const {
68
+ colorPrimary
69
+ } = token;
70
+ const colorHsv = new _fastColor.FastColor(colorPrimary).toHsv();
71
+ colorHsv.h -= 30;
72
+ const colorPrimaryWeak = new _fastColor.FastColor(colorHsv).toHexString();
73
+ setDots(new Array(dotCount).fill(null).map((_, index) => {
74
+ const rotate = 360 / dotCount;
75
+ const randomAngle = offsetAngle + rotate * index;
76
+
77
+ // Get start XY (Which should align the rect edge)
78
+ let startX = 0;
79
+ let startY = 0;
80
+ for (let startDist = halfMinSize - 1; startDist <= halfMaxSize; startDist += 1) {
81
+ const x = Math.cos(randomAngle * Math.PI / 180) * startDist;
82
+ const y = Math.sin(randomAngle * Math.PI / 180) * startDist;
83
+ if (!inRange(x, y, -halfWidth, -halfHeight, halfWidth, halfHeight)) {
84
+ break;
85
+ }
86
+ startX = x;
87
+ startY = y;
88
+ }
89
+
90
+ // Get end XY
91
+ let endX = startX;
92
+ let endY = startY;
93
+ let endDist = halfMinSize;
94
+ const endHalfWidth = Math.random() * (halfOffsetMaxWidth - halfOffsetMinWidth) + halfOffsetMinWidth;
95
+ const endHalfHeight = Math.random() * (halfOffsetMaxHeight - halfOffsetMinHeight) + halfOffsetMinHeight;
96
+ do {
97
+ endX = Math.cos(randomAngle * Math.PI / 180) * endDist;
98
+ endY = Math.sin(randomAngle * Math.PI / 180) * endDist;
99
+ endDist += 1;
100
+ } while (inRange(endX, endY, -endHalfWidth, -endHalfHeight, endHalfWidth, endHalfHeight));
101
+ let size = Math.random() * 3 + 3;
102
+ if (height >= 20) {
103
+ size = Math.random() * 4 + 6;
104
+ }
105
+ return {
106
+ key: index + 1,
107
+ startX: `${startX}px`,
108
+ startY: `${startY}px`,
109
+ endX: `${endX}px`,
110
+ endY: `${endY}px`,
111
+ startSize: `${size}px`,
112
+ endSize: `${Math.random() > 0.75 ? size : 0}px`,
113
+ type: Math.random() > 0.6 ? 'outlined' : 'fill',
114
+ color: Math.random() > 0.5 ? colorPrimary : colorPrimaryWeak
115
+ };
116
+ }));
117
+ }, 50);
118
+ target.setAttribute(targetAttrName, 'true');
119
+ });
120
+ return () => {
121
+ _raf.default.cancel(id);
122
+ };
123
+ }, []);
124
+
125
+ // ======================== Clean =========================
126
+ React.useEffect(() => {
127
+ const id = setTimeout(() => {
128
+ target.removeAttribute(targetAttrName);
129
+ onFinish();
130
+ }, 600);
131
+ return () => {
132
+ clearTimeout(id);
133
+ };
134
+ }, []);
135
+
136
+ // ======================== Render ========================
137
+ if (!dots) {
138
+ return null;
139
+ }
140
+ return /*#__PURE__*/React.createElement("div", {
141
+ className: (0, _clsx.clsx)(prefixCls, hashId),
142
+ style: {
143
+ left,
144
+ top
145
+ }
146
+ }, /*#__PURE__*/React.createElement(_motion.CSSMotionList, {
147
+ component: false,
148
+ keys: dots,
149
+ motionAppear: true,
150
+ motionName: "happy-in-out"
151
+ }, ({
152
+ className: motionCls,
153
+ style: motionStyle,
154
+ key,
155
+ startX,
156
+ startY,
157
+ endX,
158
+ endY,
159
+ startSize,
160
+ endSize,
161
+ type,
162
+ color
163
+ }) => {
164
+ const name = `${dotPrefixCls}-${key}`;
165
+ const dotCls = (0, _clsx.clsx)(dotPrefixCls, motionCls, name);
166
+
167
+ // if (dotCls.includes('active')) {
168
+ // debugger;
169
+ // }
170
+
171
+ const dotStyle = {
172
+ [`--start-x`]: startX,
173
+ [`--start-y`]: startY,
174
+ [`--end-x`]: endX,
175
+ [`--end-y`]: endY,
176
+ [`--start-size`]: startSize,
177
+ [`--end-size`]: endSize
178
+ };
179
+ if (type === 'fill') {
180
+ dotStyle['--background'] = color;
181
+ } else {
182
+ dotStyle['--border'] = `1px solid ${color}`;
183
+ }
184
+ return /*#__PURE__*/React.createElement("div", {
185
+ className: dotCls,
186
+ style: {
187
+ ...motionStyle,
188
+ ...dotStyle
189
+ }
190
+ });
191
+ }));
192
+ }
@@ -0,0 +1,4 @@
1
+ import type { GlobalToken } from '@996-design/996-components';
2
+ export declare const TARGET_ATTR = "data-happy-wave-target";
3
+ declare const useStyle: (prefixCls: string, hashId: string, token: GlobalToken) => void;
4
+ export default useStyle;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.TARGET_ATTR = void 0;
7
+ var _cssinjs = require("@996-design/996-cssinjs");
8
+ const DEFAULT_THEME = (0, _cssinjs.createTheme)(token => token);
9
+ const TARGET_ATTR = exports.TARGET_ATTR = 'data-happy-wave-target';
10
+ const antWaveTargetEffect = new _cssinjs.Keyframes('antWaveTargetEffect', {
11
+ '0%': {
12
+ transform: 'scale(1)'
13
+ },
14
+ '10%': {
15
+ transform: 'scale(1.1)'
16
+ },
17
+ '35%': {
18
+ transform: 'scale(0.94)'
19
+ },
20
+ '60%': {
21
+ transform: 'scale(1.05)'
22
+ },
23
+ '85%': {
24
+ transform: 'scale(0.97)'
25
+ },
26
+ '100%': {
27
+ transform: 'scale(1)'
28
+ }
29
+ });
30
+ const antWaveDotEffect = new _cssinjs.Keyframes('antWaveDotEffect', {
31
+ '0%': {
32
+ opacity: 0,
33
+ left: `var(--start-x)`,
34
+ top: `var(--start-y)`,
35
+ width: `var(--start-size)`,
36
+ height: `var(--start-size)`,
37
+ background: `var(--background)`,
38
+ border: `var(--border)`
39
+ },
40
+ '25%': {
41
+ opacity: 1
42
+ },
43
+ '50%': {
44
+ opacity: 0.8
45
+ },
46
+ '100%': {
47
+ opacity: 0,
48
+ left: `var(--end-x)`,
49
+ top: `var(--end-y)`,
50
+ width: `var(--end-size)`,
51
+ height: `var(--end-size)`,
52
+ background: `var(--background)`,
53
+ border: `var(--border)`
54
+ }
55
+ });
56
+ const useStyle = (prefixCls, hashId, token) => {
57
+ const sharedConfig = {
58
+ theme: DEFAULT_THEME,
59
+ token
60
+ };
61
+ (0, _cssinjs.useStyleRegister)({
62
+ ...sharedConfig,
63
+ path: ['HappyWorkTheme', 'target']
64
+ }, () => ({
65
+ // ======================== Target ========================
66
+ [`[${TARGET_ATTR}-${hashId}], & [${TARGET_ATTR}-${hashId}]`]: {
67
+ animationName: antWaveTargetEffect,
68
+ animationDuration: `0.45s`,
69
+ animationTimingFunction: 'ease-in-out',
70
+ animationFillMode: 'backwards'
71
+ }
72
+ }));
73
+ (0, _cssinjs.useStyleRegister)({
74
+ ...sharedConfig,
75
+ hashId,
76
+ path: ['HappyWorkTheme', 'effect']
77
+ }, () => {
78
+ const dotPrefixCls = `.${prefixCls}`;
79
+ return [{
80
+ // ========================= Dots =========================
81
+ [dotPrefixCls]: {
82
+ position: 'fixed',
83
+ pointerEvents: 'none',
84
+ zIndex: 999999,
85
+ [`${dotPrefixCls}-dot`]: {
86
+ boxSizing: 'border-box',
87
+ position: 'absolute',
88
+ borderRadius: '100%',
89
+ opacity: 0,
90
+ transform: 'translate3d(-50%, -50%, 0)',
91
+ // Start Position
92
+ zIndex: 999999,
93
+ // =================== Basic Motion ===================
94
+ '&.happy-in-out': {
95
+ animationName: antWaveDotEffect,
96
+ animationDuration: token.motionDurationSlow,
97
+ // animationDuration: '10s',
98
+ animationTimingFunction: 'linear',
99
+ animationFillMode: 'backwards'
100
+ }
101
+ }
102
+ }
103
+ }];
104
+ });
105
+ };
106
+ var _default = exports.default = useStyle;
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ export interface HappyProviderProps {
3
+ disabled?: boolean;
4
+ }
5
+ declare const HappyProvider: React.FC<React.PropsWithChildren<HappyProviderProps>>;
6
+ export default HappyProvider;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ var _antd = require("@996-design/996-components");
10
+ var _useEvent = _interopRequireDefault(require("@rc-component/util/lib/hooks/useEvent"));
11
+ var React = _interopRequireWildcard(require("react"));
12
+ var _DotEffect = _interopRequireDefault(require("./DotEffect"));
13
+ var _render = require("@rc-component/util/lib/React/render");
14
+ const HappyProvider = props => {
15
+ const {
16
+ children,
17
+ disabled
18
+ } = props;
19
+ const showEffect = (0, _useEvent.default)((target, info) => {
20
+ const {
21
+ token,
22
+ hashId
23
+ } = info;
24
+
25
+ // Create holder
26
+ const holder = document.createElement('div');
27
+ holder.style.position = 'absolute';
28
+ holder.style.left = `0px`;
29
+ holder.style.top = `0px`;
30
+ document.body.appendChild(holder);
31
+ (0, _render.render)( /*#__PURE__*/React.createElement(_DotEffect.default, {
32
+ target: target,
33
+ token: token,
34
+ hashId: hashId,
35
+ onFinish: () => {
36
+ (0, _render.unmount)(holder).then(() => {
37
+ holder.remove();
38
+ });
39
+ }
40
+ }), holder);
41
+ });
42
+ const memoizedWaveConfig = React.useMemo(() => {
43
+ if (disabled) {
44
+ return {};
45
+ }
46
+ return {
47
+ showEffect
48
+ };
49
+ }, [disabled]);
50
+ return /*#__PURE__*/React.createElement(_antd.ConfigProvider, {
51
+ wave: memoizedWaveConfig
52
+ }, children);
53
+ };
54
+ var _default = exports.default = HappyProvider;
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import HappyProvider from './HappyProvider';
2
+ export { HappyProvider };
package/lib/index.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "HappyProvider", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _HappyProvider.default;
11
+ }
12
+ });
13
+ var _HappyProvider = _interopRequireDefault(require("./HappyProvider"));
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@996-design/996-happy-work-theme",
3
+ "version": "1.0.0",
4
+ "private": false,
5
+ "description": "Expressive interaction theme for 996 Design",
6
+ "keywords": [
7
+ "996-design",
8
+ "react",
9
+ "theme"
10
+ ],
11
+ "license": "MIT",
12
+ "main": "./lib/index",
13
+ "module": "./es/index",
14
+ "files": [
15
+ "es",
16
+ "lib",
17
+ "NOTICE.md",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "scripts": {
22
+ "check": "bun -e \"await import('./es/index.js')\"",
23
+ "build": "bun run check",
24
+ "check:standalone": "bun scripts/check-standalone.ts"
25
+ },
26
+ "dependencies": {
27
+ "@996-design/996-cssinjs": "^1.0.0",
28
+ "@996-design/996-fast-color": "^1.0.0",
29
+ "@babel/runtime": "^7.18.3",
30
+ "@rc-component/motion": "^1.1.6",
31
+ "@rc-component/util": "^1.5.0",
32
+ "clsx": "^2.1.1"
33
+ },
34
+ "peerDependencies": {
35
+ "@996-design/996-components": "^1.0.0",
36
+ "react": ">=18.0.0",
37
+ "react-dom": ">=18.0.0"
38
+ },
39
+ "engines": {
40
+ "node": ">=8.x"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public",
44
+ "registry": "https://registry.npmjs.org"
45
+ },
46
+ "packageManager": "pnpm@9.15.0",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+ssh://git@gitlab.asdnc.cn/996-design/996-happy-work-theme.git"
50
+ }
51
+ }