@lobehub/ui 2.20.0 → 2.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
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"];
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", "segmentMode"];
5
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
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
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; }
@@ -62,6 +62,8 @@ var TypewriterEffect = /*#__PURE__*/memo(function (_ref) {
62
62
  startOnVisible = _ref$startOnVisible === void 0 ? false : _ref$startOnVisible,
63
63
  _ref$reverseMode = _ref.reverseMode,
64
64
  reverseMode = _ref$reverseMode === void 0 ? false : _ref$reverseMode,
65
+ _ref$segmentMode = _ref.segmentMode,
66
+ segmentMode = _ref$segmentMode === void 0 ? 'grapheme' : _ref$segmentMode,
65
67
  props = _objectWithoutProperties(_ref, _excluded);
66
68
  var _useStyles = useStyles(),
67
69
  styles = _useStyles.styles,
@@ -94,6 +96,28 @@ var TypewriterEffect = /*#__PURE__*/memo(function (_ref) {
94
96
  var textArray = useMemo(function () {
95
97
  return Array.isArray(sentences) ? sentences : [sentences];
96
98
  }, [sentences]);
99
+
100
+ // Helper function to split text based on segment mode
101
+ var splitText = useCallback(function (text) {
102
+ // Use Intl.Segmenter if available
103
+ if (typeof Intl !== 'undefined' && 'Segmenter' in Intl) {
104
+ var segmenter = new Intl.Segmenter(undefined, {
105
+ granularity: segmentMode
106
+ });
107
+ return Array.from(segmenter.segment(text), function (segment) {
108
+ return segment.segment;
109
+ });
110
+ }
111
+
112
+ // Fallback when Intl.Segmenter is not available
113
+ if (segmentMode === 'word') {
114
+ // Simple word splitting fallback
115
+ return text.split(/(\s+)/).filter(Boolean);
116
+ }
117
+
118
+ // Grapheme fallback
119
+ return Array.from(text);
120
+ }, [segmentMode]);
97
121
  var getRandomSpeed = useCallback(function () {
98
122
  if (!variableSpeed) return typingSpeed;
99
123
  var min = variableSpeed.min,
@@ -129,7 +153,9 @@ var TypewriterEffect = /*#__PURE__*/memo(function (_ref) {
129
153
  if (!isVisible) return;
130
154
  var timeout;
131
155
  var currentText = textArray[currentTextIndex];
132
- var processedText = reverseMode ? currentText.split('').reverse().join('') : currentText;
156
+ // Split text based on segment mode
157
+ var textSegments = splitText(currentText);
158
+ var processedText = reverseMode ? textSegments.reverse().join('') : currentText;
133
159
 
134
160
  // Handle delete pause state
135
161
  if (isDeletePausing) {
@@ -161,15 +187,17 @@ var TypewriterEffect = /*#__PURE__*/memo(function (_ref) {
161
187
  } else {
162
188
  timeout = setTimeout(function () {
163
189
  setDisplayedText(function (prev) {
164
- return prev.slice(0, -1);
190
+ var segments = splitText(prev);
191
+ return segments.slice(0, -1).join('');
165
192
  });
166
193
  }, deletingSpeed);
167
194
  }
168
195
  } else {
169
- if (currentCharIndex < processedText.length) {
196
+ var processedSegments = splitText(processedText);
197
+ if (currentCharIndex < processedSegments.length) {
170
198
  timeout = setTimeout(function () {
171
199
  setDisplayedText(function (prev) {
172
- return prev + processedText[currentCharIndex];
200
+ return prev + processedSegments[currentCharIndex];
173
201
  });
174
202
  setCurrentCharIndex(function (prev) {
175
203
  return prev + 1;
@@ -191,7 +219,7 @@ var TypewriterEffect = /*#__PURE__*/memo(function (_ref) {
191
219
  return function () {
192
220
  return clearTimeout(timeout);
193
221
  };
194
- }, [currentCharIndex, displayedText, isDeleting, isDeletePausing, typingSpeed, deletingSpeed, deletePauseDuration, pauseDuration, textArray, currentTextIndex, loop, initialDelay, isVisible, reverseMode, variableSpeed, onSentenceComplete, getRandomSpeed]);
222
+ }, [currentCharIndex, displayedText, isDeleting, isDeletePausing, typingSpeed, deletingSpeed, deletePauseDuration, pauseDuration, textArray, currentTextIndex, loop, initialDelay, isVisible, reverseMode, variableSpeed, onSentenceComplete, getRandomSpeed, splitText]);
195
223
  var getCursorStyle = function getCursorStyle() {
196
224
  if (cursorCharacter) return styles.cursorCustom;
197
225
  switch (cursorStyle) {
@@ -213,8 +241,9 @@ var TypewriterEffect = /*#__PURE__*/memo(function (_ref) {
213
241
  }
214
242
  }
215
243
  };
216
- var isTyping = currentCharIndex < textArray[currentTextIndex].length && !isDeleting;
217
- var isAfterTyping = currentCharIndex === textArray[currentTextIndex].length && !isDeleting;
244
+ var currentTextLength = splitText(textArray[currentTextIndex]).length;
245
+ var isTyping = currentCharIndex < currentTextLength && !isDeleting;
246
+ var isAfterTyping = currentCharIndex === currentTextLength && !isDeleting;
218
247
  var shouldHideCursor = function () {
219
248
  if (hideCursorWhileTyping === true) return true; // 完全隐藏
220
249
  if (hideCursorWhileTyping === 'typing') return isTyping || isDeleting; // 打字和删除时隐藏
@@ -224,8 +253,8 @@ var TypewriterEffect = /*#__PURE__*/memo(function (_ref) {
224
253
  var textColor = getCurrentTextColor();
225
254
  var finalCursorColor = getCurrentCursorColor();
226
255
 
227
- // Split displayed text into characters for animation
228
- var characters = displayedText.split('');
256
+ // Split displayed text for animation
257
+ var characters = splitText(displayedText);
229
258
  return /*#__PURE__*/createElement(Component, _objectSpread({
230
259
  className: cx(styles.container, className),
231
260
  ref: containerRef
@@ -1,2 +1,2 @@
1
- export type { CursorStyle, TypewriterEffectProps } from './type';
1
+ export type { CursorStyle, SegmentMode, TypewriterEffectProps } from './type';
2
2
  export { default } from './TypewriterEffect';
@@ -1,5 +1,6 @@
1
1
  import type { ElementType, ReactNode } from 'react';
2
2
  export type CursorStyle = 'pipe' | 'underscore' | 'dot' | 'block';
3
+ export type SegmentMode = 'grapheme' | 'word';
3
4
  export interface TypewriterEffectProps {
4
5
  /**
5
6
  * Custom element type for the container
@@ -85,6 +86,13 @@ export interface TypewriterEffectProps {
85
86
  * @default false
86
87
  */
87
88
  reverseMode?: boolean;
89
+ /**
90
+ * Segment mode for text splitting
91
+ * - 'grapheme': split by character (emoji-safe)
92
+ * - 'word': split by word
93
+ * @default 'grapheme'
94
+ */
95
+ segmentMode?: SegmentMode;
88
96
  /**
89
97
  * Array of sentences to display
90
98
  */
@@ -7,4 +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';
10
+ export { type CursorStyle, type SegmentMode, default as TypewriterEffect, type TypewriterEffectProps, } from './TypewriterEffect';
@@ -1,7 +1,7 @@
1
1
  var FONT_EMOJI = "\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Apple Color Emoji\",\"Twemoji Mozilla\",\"Noto Color Emoji\",\"Android Emoji\"";
2
2
  var FONT_EN = "\"HarmonyOS Sans\",\"Segoe UI\",\"SF Pro Display\",-apple-system,BlinkMacSystemFont,Roboto,Oxygen,Ubuntu,Cantarell,\"Open Sans\",\"Helvetica Neue\",sans-serif";
3
3
  var FONT_CN = "\"HarmonyOS Sans SC\",\"PingFang SC\",\"Hiragino Sans GB\",\"Microsoft Yahei UI\",\"Microsoft Yahei\",\"Source Han Sans CN\",sans-serif";
4
- var FONT_CODE = "Hack,ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace";
4
+ var FONT_CODE = "Hack,ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas";
5
5
  export var baseToken = {
6
6
  borderRadius: 8,
7
7
  borderRadiusLG: 12,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/ui",
3
- "version": "2.20.0",
3
+ "version": "2.20.1",
4
4
  "description": "Lobe UI is an open-source UI component library for building AIGC web apps",
5
5
  "keywords": [
6
6
  "lobehub",