@lobehub/ui 2.18.4 → 2.20.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.
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import type { TypewriterEffectProps } from './type';
3
+ declare const TypewriterEffect: import("react").NamedExoticComponent<TypewriterEffectProps>;
4
+ export default TypewriterEffect;
@@ -0,0 +1,285 @@
1
+ 'use client';
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
+ var _excluded = ["sentences", "as", "typingSpeed", "initialDelay", "pauseDuration", "deletingSpeed", "deletePauseDuration", "loop", "className", "color", "showCursor", "hideCursorWhileTyping", "cursorCharacter", "cursorClassName", "cursorColor", "cursorBlinkDuration", "cursorFade", "cursorStyle", "textColors", "variableSpeed", "onSentenceComplete", "startOnVisible", "reverseMode"];
5
+ 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; }
6
+ 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; }
7
+ 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; }
8
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
9
+ 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); }
10
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
11
+ 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."); }
12
+ 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); }
13
+ 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; }
14
+ 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; } }
15
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
16
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
17
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
18
+ import { motion } from 'framer-motion';
19
+ import { createElement, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
20
+ import { useStyles } from "./style";
21
+ import { jsx as _jsx } from "react/jsx-runtime";
22
+ import { Fragment as _Fragment } from "react/jsx-runtime";
23
+ import { jsxs as _jsxs } from "react/jsx-runtime";
24
+ var TypewriterEffect = /*#__PURE__*/memo(function (_ref) {
25
+ var sentences = _ref.sentences,
26
+ _ref$as = _ref.as,
27
+ Component = _ref$as === void 0 ? 'div' : _ref$as,
28
+ _ref$typingSpeed = _ref.typingSpeed,
29
+ typingSpeed = _ref$typingSpeed === void 0 ? 100 : _ref$typingSpeed,
30
+ _ref$initialDelay = _ref.initialDelay,
31
+ initialDelay = _ref$initialDelay === void 0 ? 0 : _ref$initialDelay,
32
+ _ref$pauseDuration = _ref.pauseDuration,
33
+ pauseDuration = _ref$pauseDuration === void 0 ? 2000 : _ref$pauseDuration,
34
+ _ref$deletingSpeed = _ref.deletingSpeed,
35
+ deletingSpeed = _ref$deletingSpeed === void 0 ? 50 : _ref$deletingSpeed,
36
+ _ref$deletePauseDurat = _ref.deletePauseDuration,
37
+ deletePauseDuration = _ref$deletePauseDurat === void 0 ? 0 : _ref$deletePauseDurat,
38
+ _ref$loop = _ref.loop,
39
+ loop = _ref$loop === void 0 ? true : _ref$loop,
40
+ _ref$className = _ref.className,
41
+ className = _ref$className === void 0 ? '' : _ref$className,
42
+ color = _ref.color,
43
+ _ref$showCursor = _ref.showCursor,
44
+ showCursor = _ref$showCursor === void 0 ? true : _ref$showCursor,
45
+ _ref$hideCursorWhileT = _ref.hideCursorWhileTyping,
46
+ hideCursorWhileTyping = _ref$hideCursorWhileT === void 0 ? false : _ref$hideCursorWhileT,
47
+ cursorCharacter = _ref.cursorCharacter,
48
+ _ref$cursorClassName = _ref.cursorClassName,
49
+ cursorClassName = _ref$cursorClassName === void 0 ? '' : _ref$cursorClassName,
50
+ cursorColor = _ref.cursorColor,
51
+ _ref$cursorBlinkDurat = _ref.cursorBlinkDuration,
52
+ cursorBlinkDuration = _ref$cursorBlinkDurat === void 0 ? 0.8 : _ref$cursorBlinkDurat,
53
+ _ref$cursorFade = _ref.cursorFade,
54
+ cursorFade = _ref$cursorFade === void 0 ? true : _ref$cursorFade,
55
+ _ref$cursorStyle = _ref.cursorStyle,
56
+ cursorStyle = _ref$cursorStyle === void 0 ? 'pipe' : _ref$cursorStyle,
57
+ _ref$textColors = _ref.textColors,
58
+ textColors = _ref$textColors === void 0 ? [] : _ref$textColors,
59
+ variableSpeed = _ref.variableSpeed,
60
+ onSentenceComplete = _ref.onSentenceComplete,
61
+ _ref$startOnVisible = _ref.startOnVisible,
62
+ startOnVisible = _ref$startOnVisible === void 0 ? false : _ref$startOnVisible,
63
+ _ref$reverseMode = _ref.reverseMode,
64
+ reverseMode = _ref$reverseMode === void 0 ? false : _ref$reverseMode,
65
+ props = _objectWithoutProperties(_ref, _excluded);
66
+ var _useStyles = useStyles(),
67
+ styles = _useStyles.styles,
68
+ cx = _useStyles.cx;
69
+ var _useState = useState(''),
70
+ _useState2 = _slicedToArray(_useState, 2),
71
+ displayedText = _useState2[0],
72
+ setDisplayedText = _useState2[1];
73
+ var _useState3 = useState(0),
74
+ _useState4 = _slicedToArray(_useState3, 2),
75
+ currentCharIndex = _useState4[0],
76
+ setCurrentCharIndex = _useState4[1];
77
+ var _useState5 = useState(false),
78
+ _useState6 = _slicedToArray(_useState5, 2),
79
+ isDeleting = _useState6[0],
80
+ setIsDeleting = _useState6[1];
81
+ var _useState7 = useState(0),
82
+ _useState8 = _slicedToArray(_useState7, 2),
83
+ currentTextIndex = _useState8[0],
84
+ setCurrentTextIndex = _useState8[1];
85
+ var _useState9 = useState(!startOnVisible),
86
+ _useState10 = _slicedToArray(_useState9, 2),
87
+ isVisible = _useState10[0],
88
+ setIsVisible = _useState10[1];
89
+ var _useState11 = useState(false),
90
+ _useState12 = _slicedToArray(_useState11, 2),
91
+ isDeletePausing = _useState12[0],
92
+ setIsDeletePausing = _useState12[1];
93
+ var containerRef = useRef(null);
94
+ var textArray = useMemo(function () {
95
+ return Array.isArray(sentences) ? sentences : [sentences];
96
+ }, [sentences]);
97
+ var getRandomSpeed = useCallback(function () {
98
+ if (!variableSpeed) return typingSpeed;
99
+ var min = variableSpeed.min,
100
+ max = variableSpeed.max;
101
+ return Math.random() * (max - min) + min;
102
+ }, [variableSpeed, typingSpeed]);
103
+ var getCurrentTextColor = function getCurrentTextColor() {
104
+ if (textColors.length > 0) {
105
+ return textColors[currentTextIndex % textColors.length];
106
+ }
107
+ return color;
108
+ };
109
+ var getCurrentCursorColor = function getCurrentCursorColor() {
110
+ return cursorColor || color;
111
+ };
112
+ useEffect(function () {
113
+ if (!startOnVisible || !containerRef.current) return;
114
+ var observer = new IntersectionObserver(function (entries) {
115
+ entries.forEach(function (entry) {
116
+ if (entry.isIntersecting) {
117
+ setIsVisible(true);
118
+ }
119
+ });
120
+ }, {
121
+ threshold: 0.1
122
+ });
123
+ observer.observe(containerRef.current);
124
+ return function () {
125
+ return observer.disconnect();
126
+ };
127
+ }, [startOnVisible]);
128
+ useEffect(function () {
129
+ if (!isVisible) return;
130
+ var timeout;
131
+ var currentText = textArray[currentTextIndex];
132
+ var processedText = reverseMode ? currentText.split('').reverse().join('') : currentText;
133
+
134
+ // Handle delete pause state
135
+ if (isDeletePausing) {
136
+ timeout = setTimeout(function () {
137
+ setIsDeletePausing(false);
138
+ }, deletePauseDuration);
139
+ return function () {
140
+ return clearTimeout(timeout);
141
+ };
142
+ }
143
+ var executeTypingAnimation = function executeTypingAnimation() {
144
+ if (isDeleting) {
145
+ if (displayedText === '') {
146
+ setIsDeleting(false);
147
+ if (currentTextIndex === textArray.length - 1 && !loop) {
148
+ return;
149
+ }
150
+ if (onSentenceComplete) {
151
+ onSentenceComplete(textArray[currentTextIndex], currentTextIndex);
152
+ }
153
+ setCurrentTextIndex(function (prev) {
154
+ return (prev + 1) % textArray.length;
155
+ });
156
+ setCurrentCharIndex(0);
157
+ if (deletePauseDuration > 0) {
158
+ setIsDeletePausing(true);
159
+ return;
160
+ }
161
+ } else {
162
+ timeout = setTimeout(function () {
163
+ setDisplayedText(function (prev) {
164
+ return prev.slice(0, -1);
165
+ });
166
+ }, deletingSpeed);
167
+ }
168
+ } else {
169
+ if (currentCharIndex < processedText.length) {
170
+ timeout = setTimeout(function () {
171
+ setDisplayedText(function (prev) {
172
+ return prev + processedText[currentCharIndex];
173
+ });
174
+ setCurrentCharIndex(function (prev) {
175
+ return prev + 1;
176
+ });
177
+ }, variableSpeed ? getRandomSpeed() : typingSpeed);
178
+ } else if (textArray.length >= 1) {
179
+ if (!loop && currentTextIndex === textArray.length - 1) return;
180
+ timeout = setTimeout(function () {
181
+ setIsDeleting(true);
182
+ }, pauseDuration);
183
+ }
184
+ }
185
+ };
186
+ if (currentCharIndex === 0 && !isDeleting && displayedText === '') {
187
+ timeout = setTimeout(executeTypingAnimation, initialDelay);
188
+ } else {
189
+ executeTypingAnimation();
190
+ }
191
+ return function () {
192
+ return clearTimeout(timeout);
193
+ };
194
+ }, [currentCharIndex, displayedText, isDeleting, isDeletePausing, typingSpeed, deletingSpeed, deletePauseDuration, pauseDuration, textArray, currentTextIndex, loop, initialDelay, isVisible, reverseMode, variableSpeed, onSentenceComplete, getRandomSpeed]);
195
+ var getCursorStyle = function getCursorStyle() {
196
+ if (cursorCharacter) return styles.cursorCustom;
197
+ switch (cursorStyle) {
198
+ case 'block':
199
+ {
200
+ return styles.cursorBlock;
201
+ }
202
+ case 'dot':
203
+ {
204
+ return styles.cursorDot;
205
+ }
206
+ case 'underscore':
207
+ {
208
+ return styles.cursorUnderscore;
209
+ }
210
+ case 'pipe':
211
+ {
212
+ return styles.cursor;
213
+ }
214
+ }
215
+ };
216
+ var isTyping = currentCharIndex < textArray[currentTextIndex].length && !isDeleting;
217
+ var isAfterTyping = currentCharIndex === textArray[currentTextIndex].length && !isDeleting;
218
+ var shouldHideCursor = function () {
219
+ if (hideCursorWhileTyping === true) return true; // 完全隐藏
220
+ if (hideCursorWhileTyping === 'typing') return isTyping || isDeleting; // 打字和删除时隐藏
221
+ if (hideCursorWhileTyping === 'afterTyping') return isAfterTyping; // 打字完成后隐藏
222
+ return false;
223
+ }();
224
+ var textColor = getCurrentTextColor();
225
+ var finalCursorColor = getCurrentCursorColor();
226
+
227
+ // Split displayed text into characters for animation
228
+ var characters = displayedText.split('');
229
+ return /*#__PURE__*/createElement(Component, _objectSpread({
230
+ className: cx(styles.container, className),
231
+ ref: containerRef
232
+ }, props), /*#__PURE__*/_jsxs(_Fragment, {
233
+ children: [/*#__PURE__*/_jsx("span", {
234
+ className: styles.text,
235
+ style: textColor ? {
236
+ color: textColor
237
+ } : undefined,
238
+ children: characters.map(function (char, index) {
239
+ return /*#__PURE__*/_jsx(motion.span, {
240
+ animate: {
241
+ opacity: 1
242
+ },
243
+ initial: {
244
+ opacity: 0
245
+ },
246
+ style: {
247
+ display: 'inline-block'
248
+ },
249
+ transition: {
250
+ duration: typingSpeed / 500,
251
+ ease: 'easeInOut'
252
+ },
253
+ children: char === ' ' ? "\xA0" : char
254
+ }, "".concat(currentTextIndex, "-").concat(index));
255
+ })
256
+ }), showCursor && (cursorFade ? /*#__PURE__*/_jsx(motion.span, {
257
+ animate: {
258
+ opacity: shouldHideCursor ? 0 : 1
259
+ },
260
+ className: cx(getCursorStyle(), cursorClassName),
261
+ initial: {
262
+ opacity: 0
263
+ },
264
+ style: finalCursorColor ? {
265
+ backgroundColor: finalCursorColor
266
+ } : undefined,
267
+ transition: {
268
+ duration: shouldHideCursor ? 0.2 : cursorBlinkDuration,
269
+ ease: 'easeInOut',
270
+ repeat: shouldHideCursor ? 0 : Number.POSITIVE_INFINITY,
271
+ repeatType: 'reverse'
272
+ },
273
+ children: cursorCharacter
274
+ }) : /*#__PURE__*/_jsx("span", {
275
+ className: cx(getCursorStyle(), cursorClassName),
276
+ style: {
277
+ backgroundColor: finalCursorColor,
278
+ opacity: shouldHideCursor ? 0 : 1
279
+ },
280
+ children: cursorCharacter
281
+ }))]
282
+ }));
283
+ });
284
+ TypewriterEffect.displayName = 'TypewriterEffect';
285
+ export default TypewriterEffect;
@@ -0,0 +1,2 @@
1
+ export type { CursorStyle, TypewriterEffectProps } from './type';
2
+ export { default } from './TypewriterEffect';
@@ -0,0 +1 @@
1
+ export { default } from "./TypewriterEffect";
@@ -0,0 +1,10 @@
1
+ export declare const useStyles: (props?: unknown) => import("antd-style").ReturnStyles<{
2
+ container: import("antd-style").SerializedStyles;
3
+ cursor: import("antd-style").SerializedStyles;
4
+ cursorBlock: import("antd-style").SerializedStyles;
5
+ cursorCustom: import("antd-style").SerializedStyles;
6
+ cursorDot: import("antd-style").SerializedStyles;
7
+ cursorHidden: import("antd-style").SerializedStyles;
8
+ cursorUnderscore: import("antd-style").SerializedStyles;
9
+ text: import("antd-style").SerializedStyles;
10
+ }>;
@@ -0,0 +1,18 @@
1
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8;
2
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
+ import { createStyles } from 'antd-style';
4
+ export var useStyles = createStyles(function (_ref) {
5
+ var css = _ref.css,
6
+ token = _ref.token,
7
+ isDarkMode = _ref.isDarkMode;
8
+ return {
9
+ container: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: inline-block;\n white-space: pre-wrap;\n "]))),
10
+ cursor: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n transform: translateY(10%);\n\n display: inline-block;\n align-items: center;\n\n width: 3px;\n height: 1em;\n margin-inline-start: 0.25rem;\n border-radius: 2px;\n\n opacity: 1;\n background-color: ", ";\n "])), token.colorPrimary),
11
+ cursorBlock: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n transform: translateY(10%);\n\n display: inline-block;\n align-items: center;\n\n width: 0.5em;\n height: 1em;\n margin-inline-start: 0.25rem;\n border-radius: 2px;\n\n opacity: 1;\n background-color: ", ";\n "])), token.colorPrimary),
12
+ cursorCustom: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n display: inline-block;\n align-items: center;\n margin-inline-start: 0.25rem;\n opacity: 1;\n "]))),
13
+ cursorDot: css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n display: inline-block;\n align-items: center;\n\n width: 0.75em;\n height: 0.75em;\n margin-inline-start: 0.25rem;\n border-radius: 50%;\n\n opacity: 1;\n background-color: ", ";\n "])), token.colorPrimary),
14
+ cursorHidden: css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n display: none;\n "]))),
15
+ cursorUnderscore: css(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n transform: translateY(0.3em);\n\n display: inline-block;\n align-items: center;\n\n width: 0.6em;\n height: 0.15em;\n margin-inline-start: 0.25rem;\n border-radius: 2px;\n\n opacity: 1;\n background-color: ", ";\n "])), token.colorPrimary),
16
+ text: css(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n color: ", ";\n "])), isDarkMode ? token.colorTextLightSolid : token.colorText)
17
+ };
18
+ });
@@ -0,0 +1,118 @@
1
+ import type { ElementType, ReactNode } from 'react';
2
+ export type CursorStyle = 'pipe' | 'underscore' | 'dot' | 'block';
3
+ export interface TypewriterEffectProps {
4
+ /**
5
+ * Custom element type for the container
6
+ * @default 'div'
7
+ */
8
+ as?: ElementType;
9
+ /**
10
+ * Additional class name for the container
11
+ */
12
+ className?: string;
13
+ /**
14
+ * Text color
15
+ */
16
+ color?: string;
17
+ /**
18
+ * Cursor blink duration in seconds
19
+ * @default 0.8
20
+ */
21
+ cursorBlinkDuration?: number;
22
+ /**
23
+ * Custom cursor character or ReactNode
24
+ * @default undefined (uses cursorStyle)
25
+ */
26
+ cursorCharacter?: string | ReactNode;
27
+ /**
28
+ * Additional class name for the cursor
29
+ */
30
+ cursorClassName?: string;
31
+ /**
32
+ * Cursor color (defaults to color if not provided)
33
+ */
34
+ cursorColor?: string;
35
+ /**
36
+ * Cursor fade animation
37
+ * @default true
38
+ */
39
+ cursorFade?: boolean;
40
+ /**
41
+ * Style of the cursor (ignored if cursorCharacter is provided)
42
+ * @default 'pipe'
43
+ */
44
+ cursorStyle?: CursorStyle;
45
+ /**
46
+ * Pause duration after deleting complete before next sentence (milliseconds)
47
+ * @default 0
48
+ */
49
+ deletePauseDuration?: number;
50
+ /**
51
+ * Speed of deleting characters (milliseconds per character)
52
+ * @default 50
53
+ */
54
+ deletingSpeed?: number;
55
+ /**
56
+ * Hide cursor behavior
57
+ * - false: always show cursor
58
+ * - 'typing': hide cursor while typing
59
+ * - 'afterTyping': hide cursor after typing complete (during pause)
60
+ * - true: completely hide cursor
61
+ * @default false
62
+ */
63
+ hideCursorWhileTyping?: boolean | 'typing' | 'afterTyping';
64
+ /**
65
+ * Initial delay before starting animation (milliseconds)
66
+ * @default 0
67
+ */
68
+ initialDelay?: number;
69
+ /**
70
+ * Whether to loop through sentences
71
+ * @default true
72
+ */
73
+ loop?: boolean;
74
+ /**
75
+ * Callback when a sentence is completed
76
+ */
77
+ onSentenceComplete?: (sentence: string, index: number) => void;
78
+ /**
79
+ * Pause duration after typing complete before deleting (milliseconds)
80
+ * @default 2000
81
+ */
82
+ pauseDuration?: number;
83
+ /**
84
+ * Reverse mode: type from end to start
85
+ * @default false
86
+ */
87
+ reverseMode?: boolean;
88
+ /**
89
+ * Array of sentences to display
90
+ */
91
+ sentences: string[];
92
+ /**
93
+ * Whether to show cursor
94
+ * @default true
95
+ */
96
+ showCursor?: boolean;
97
+ /**
98
+ * Start animation when element becomes visible
99
+ * @default false
100
+ */
101
+ startOnVisible?: boolean;
102
+ /**
103
+ * Colors for each sentence (cycles through array)
104
+ */
105
+ textColors?: string[];
106
+ /**
107
+ * Speed of typing characters (milliseconds per character)
108
+ * @default 100
109
+ */
110
+ typingSpeed?: number;
111
+ /**
112
+ * Variable typing speed range
113
+ */
114
+ variableSpeed?: {
115
+ max: number;
116
+ min: number;
117
+ };
118
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -7,3 +7,4 @@ export { default as GridBackground, type GridBackgroundProps, GridShowcase, type
7
7
  export { default as Hero, type HeroAction, type HeroProps } from './Hero';
8
8
  export { default as Spotlight, type SpotlightProps } from './Spotlight';
9
9
  export { default as SpotlightCard, type SpotlightCardProps } from './SpotlightCard';
10
+ export { type CursorStyle, default as TypewriterEffect, type TypewriterEffectProps, } from './TypewriterEffect';
@@ -6,4 +6,5 @@ export { default as GradientButton } from "./GradientButton";
6
6
  export { default as GridBackground, GridShowcase } from "./GridBackground";
7
7
  export { default as Hero } from "./Hero";
8
8
  export { default as Spotlight } from "./Spotlight";
9
- export { default as SpotlightCard } from "./SpotlightCard";
9
+ export { default as SpotlightCard } from "./SpotlightCard";
10
+ export { default as TypewriterEffect } from "./TypewriterEffect";
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import type { LoadingDotsProps } from './type';
3
+ declare const LoadingDots: import("react").NamedExoticComponent<LoadingDotsProps>;
4
+ export default LoadingDots;
@@ -0,0 +1,125 @@
1
+ 'use client';
2
+
3
+ import { memo } from 'react';
4
+ import { useStyles } from "./style";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { Fragment as _Fragment } from "react/jsx-runtime";
7
+ import { jsxs as _jsxs } from "react/jsx-runtime";
8
+ var LoadingDots = /*#__PURE__*/memo(function (_ref) {
9
+ var _ref$size = _ref.size,
10
+ size = _ref$size === void 0 ? 8 : _ref$size,
11
+ color = _ref.color,
12
+ _ref$variant = _ref.variant,
13
+ variant = _ref$variant === void 0 ? 'dots' : _ref$variant,
14
+ className = _ref.className;
15
+ var _useStyles = useStyles({
16
+ color: color,
17
+ size: size
18
+ }),
19
+ styles = _useStyles.styles,
20
+ cx = _useStyles.cx;
21
+ var renderDots = function renderDots() {
22
+ switch (variant) {
23
+ case 'pulse':
24
+ {
25
+ return /*#__PURE__*/_jsx("div", {
26
+ className: styles.pulseDot,
27
+ style: {
28
+ animationDelay: '0s'
29
+ }
30
+ });
31
+ }
32
+ case 'wave':
33
+ {
34
+ return /*#__PURE__*/_jsxs(_Fragment, {
35
+ children: [/*#__PURE__*/_jsx("div", {
36
+ className: styles.waveDot,
37
+ style: {
38
+ animationDelay: '0s'
39
+ }
40
+ }), /*#__PURE__*/_jsx("div", {
41
+ className: styles.waveDot,
42
+ style: {
43
+ animationDelay: '0.12s'
44
+ }
45
+ }), /*#__PURE__*/_jsx("div", {
46
+ className: styles.waveDot,
47
+ style: {
48
+ animationDelay: '0.24s'
49
+ }
50
+ })]
51
+ });
52
+ }
53
+ case 'orbit':
54
+ {
55
+ return /*#__PURE__*/_jsxs("div", {
56
+ className: styles.orbitContainer,
57
+ children: [/*#__PURE__*/_jsx("div", {
58
+ className: styles.orbitDot,
59
+ style: {
60
+ animationDelay: '0s'
61
+ }
62
+ }), /*#__PURE__*/_jsx("div", {
63
+ className: styles.orbitDot,
64
+ style: {
65
+ animationDelay: '-0.4s'
66
+ }
67
+ }), /*#__PURE__*/_jsx("div", {
68
+ className: styles.orbitDot,
69
+ style: {
70
+ animationDelay: '-0.8s'
71
+ }
72
+ })]
73
+ });
74
+ }
75
+ case 'typing':
76
+ {
77
+ return /*#__PURE__*/_jsxs(_Fragment, {
78
+ children: [/*#__PURE__*/_jsx("div", {
79
+ className: styles.typingDot,
80
+ style: {
81
+ animationDelay: '0s'
82
+ }
83
+ }), /*#__PURE__*/_jsx("div", {
84
+ className: styles.typingDot,
85
+ style: {
86
+ animationDelay: '0.15s'
87
+ }
88
+ }), /*#__PURE__*/_jsx("div", {
89
+ className: styles.typingDot,
90
+ style: {
91
+ animationDelay: '0.3s'
92
+ }
93
+ })]
94
+ });
95
+ }
96
+ default:
97
+ {
98
+ return /*#__PURE__*/_jsxs(_Fragment, {
99
+ children: [/*#__PURE__*/_jsx("div", {
100
+ className: styles.defaultDot,
101
+ style: {
102
+ animationDelay: '0s'
103
+ }
104
+ }), /*#__PURE__*/_jsx("div", {
105
+ className: styles.defaultDot,
106
+ style: {
107
+ animationDelay: '0.15s'
108
+ }
109
+ }), /*#__PURE__*/_jsx("div", {
110
+ className: styles.defaultDot,
111
+ style: {
112
+ animationDelay: '0.3s'
113
+ }
114
+ })]
115
+ });
116
+ }
117
+ }
118
+ };
119
+ return /*#__PURE__*/_jsx("div", {
120
+ className: cx(variant === 'orbit' ? styles.orbitWrapper : styles.container, className),
121
+ children: renderDots()
122
+ });
123
+ });
124
+ LoadingDots.displayName = 'LoadingDots';
125
+ export default LoadingDots;
@@ -0,0 +1,2 @@
1
+ export { default } from './LoadingDots';
2
+ export type * from './type';
@@ -0,0 +1 @@
1
+ export { default } from "./LoadingDots";
@@ -0,0 +1,13 @@
1
+ export declare const useStyles: (props?: {
2
+ color?: string | undefined;
3
+ size: number;
4
+ } | undefined) => import("antd-style").ReturnStyles<{
5
+ container: import("antd-style").SerializedStyles;
6
+ defaultDot: import("antd-style").SerializedStyles;
7
+ orbitContainer: import("antd-style").SerializedStyles;
8
+ orbitDot: import("antd-style").SerializedStyles;
9
+ orbitWrapper: import("antd-style").SerializedStyles;
10
+ pulseDot: import("antd-style").SerializedStyles;
11
+ typingDot: import("antd-style").SerializedStyles;
12
+ waveDot: import("antd-style").SerializedStyles;
13
+ }>;
@@ -0,0 +1,25 @@
1
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8;
2
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
+ import { createStyles } from 'antd-style';
4
+ export var useStyles = createStyles(function (_ref, _ref2) {
5
+ var token = _ref.token,
6
+ css = _ref.css;
7
+ var size = _ref2.size,
8
+ color = _ref2.color;
9
+ var dotColor = color || token.colorPrimary;
10
+ return {
11
+ container: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: row;\n gap: 6px;\n align-items: center;\n justify-content: center;\n\n padding: ", "px;\n "])), token.paddingXS),
12
+ // Default variant (fade)
13
+ defaultDot: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n width: ", "px;\n height: ", "px;\n border-radius: 50%;\n\n background-color: ", ";\n\n animation: fade-animation 1.2s ease-in-out infinite;\n\n @keyframes fade-animation {\n 0%,\n 100% {\n opacity: 0.3;\n }\n\n 50% {\n opacity: 1;\n }\n }\n "])), size, size, dotColor),
14
+ orbitContainer: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n position: relative;\n width: ", "px;\n height: ", "px;\n "])), size * 4, size * 4),
15
+ orbitDot: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n position: absolute;\n inset-block-start: 50%;\n inset-inline-start: 50%;\n transform-origin: ", "px 0;\n\n width: ", "px;\n height: ", "px;\n margin-block-start: -", "px;\n margin-inline-start: -", "px;\n border-radius: 50%;\n\n background-color: ", ";\n\n animation: orbit-animation 1.2s linear infinite;\n\n @keyframes orbit-animation {\n 0% {\n transform: rotate(0deg) translateX(", "px);\n }\n\n 100% {\n transform: rotate(360deg) translateX(", "px);\n }\n }\n "])), size * 2, size, size, size / 2, size / 2, dotColor, size * 2, size * 2),
16
+ // Orbit variant
17
+ orbitWrapper: css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n position: relative;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: ", "px;\n height: ", "px;\n padding: ", "px;\n "])), size * 5, size * 5, token.paddingXS),
18
+ // Pulse variant
19
+ pulseDot: css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n width: ", "px;\n height: ", "px;\n border-radius: 50%;\n\n background-color: ", ";\n\n animation: pulse-animation 1.2s ease-in-out infinite;\n\n @keyframes pulse-animation {\n 0%,\n 100% {\n transform: scale(0.8);\n opacity: 0.3;\n }\n\n 50% {\n transform: scale(1.3);\n opacity: 1;\n }\n }\n "])), size, size, dotColor),
20
+ // Typing variant
21
+ typingDot: css(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n width: ", "px;\n height: ", "px;\n border-radius: 50%;\n\n background-color: ", ";\n\n animation: typing-animation 1.2s ease-in-out infinite;\n\n @keyframes typing-animation {\n 0%,\n 100% {\n transform: scale(0.6);\n opacity: 0.2;\n }\n\n 25% {\n transform: scale(1);\n opacity: 1;\n }\n\n 50%,\n 75% {\n transform: scale(0.6);\n opacity: 0.2;\n }\n }\n "])), size, size, dotColor),
22
+ // Wave variant
23
+ waveDot: css(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n width: ", "px;\n height: ", "px;\n border-radius: 50%;\n\n background-color: ", ";\n\n animation: wave-animation 1.24s ease-in-out infinite;\n\n @keyframes wave-animation {\n 0%,\n 100% {\n transform: translateY(0);\n }\n\n 25% {\n transform: translateY(-", "px);\n }\n\n 50% {\n transform: translateY(0);\n }\n }\n "])), size, size, dotColor, size * 1.5)
24
+ };
25
+ });
@@ -0,0 +1,22 @@
1
+ export type LoadingDotsVariant = 'dots' | 'pulse' | 'wave' | 'orbit' | 'typing';
2
+ export interface LoadingDotsProps {
3
+ /**
4
+ * 自定义类名
5
+ */
6
+ className?: string;
7
+ /**
8
+ * 点的颜色
9
+ * @description 如果不提供,将使用主题的 colorPrimary
10
+ */
11
+ color?: string;
12
+ /**
13
+ * 点的大小(直径)
14
+ * @default 8
15
+ */
16
+ size?: number;
17
+ /**
18
+ * 动画变体
19
+ * @default 'dots'
20
+ */
21
+ variant?: LoadingDotsVariant;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -5,6 +5,7 @@ export { default as ChatItem, type ChatItemProps } from './ChatItem';
5
5
  export { ChatActionsBar, type ChatActionsBarProps, default as ChatList, type ChatListProps, type OnActionsClick, type OnAvatatsClick, type OnMessageChange, type RenderAction, type RenderErrorMessage, type RenderItem, type RenderMessage, type RenderMessageExtra, } from './ChatList';
6
6
  export { default as EditableMessage, type EditableMessageProps } from './EditableMessage';
7
7
  export { default as EditableMessageList, type EditableMessageListProps, } from './EditableMessageList';
8
+ export { default as LoadingDots, type LoadingDotsProps } from './LoadingDots';
8
9
  export { default as MessageInput, type MessageInputProps } from './MessageInput';
9
10
  export { default as MessageModal, type MessageModalProps } from './MessageModal';
10
11
  export { default as TokenTag, type TokenTagProps } from './TokenTag';
package/es/chat/index.js CHANGED
@@ -5,6 +5,7 @@ export { default as ChatItem } from "./ChatItem";
5
5
  export { ChatActionsBar, default as ChatList } from "./ChatList";
6
6
  export { default as EditableMessage } from "./EditableMessage";
7
7
  export { default as EditableMessageList } from "./EditableMessageList";
8
+ export { default as LoadingDots } from "./LoadingDots";
8
9
  export { default as MessageInput } from "./MessageInput";
9
10
  export { default as MessageModal } from "./MessageModal";
10
11
  export { default as TokenTag } from "./TokenTag";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/ui",
3
- "version": "2.18.4",
3
+ "version": "2.20.0",
4
4
  "description": "Lobe UI is an open-source UI component library for building AIGC web apps",
5
5
  "keywords": [
6
6
  "lobehub",