@class-kit/react 0.1.1 → 0.1.2
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/CHANGELOG.md +7 -0
- package/README.md +10 -2
- package/dist/components/affix.cjs.map +1 -1
- package/dist/components/affix.js.map +1 -1
- package/dist/components/backtop.cjs.map +1 -1
- package/dist/components/backtop.js.map +1 -1
- package/dist/components/badge.cjs.map +1 -1
- package/dist/components/badge.js.map +1 -1
- package/dist/components/barcode.cjs.map +1 -1
- package/dist/components/barcode.js.map +1 -1
- package/dist/components/breadcrumb.cjs.map +1 -1
- package/dist/components/breadcrumb.js.map +1 -1
- package/dist/components/button.cjs.map +1 -1
- package/dist/components/button.js.map +1 -1
- package/dist/components/calendar.cjs.map +1 -1
- package/dist/components/calendar.js.map +1 -1
- package/dist/components/canvas-editor.cjs.map +1 -1
- package/dist/components/canvas-editor.js.map +1 -1
- package/dist/components/canvas-image.cjs.map +1 -1
- package/dist/components/canvas-image.js.map +1 -1
- package/dist/components/chat-textarea.cjs +103 -0
- package/dist/components/chat-textarea.cjs.map +1 -0
- package/dist/components/chat-textarea.d.ts +3 -0
- package/dist/components/chat-textarea.d.ts.map +1 -0
- package/dist/components/chat-textarea.js +101 -0
- package/dist/components/chat-textarea.js.map +1 -0
- package/dist/components/chat-virtual-list.cjs +39 -7
- package/dist/components/chat-virtual-list.cjs.map +1 -1
- package/dist/components/chat-virtual-list.js +39 -7
- package/dist/components/chat-virtual-list.js.map +1 -1
- package/dist/components/checkbox.cjs.map +1 -1
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/checked.cjs.map +1 -1
- package/dist/components/checked.js.map +1 -1
- package/dist/components/code-preview.cjs +190 -0
- package/dist/components/code-preview.cjs.map +1 -0
- package/dist/components/code-preview.d.ts +3 -0
- package/dist/components/code-preview.d.ts.map +1 -0
- package/dist/components/code-preview.js +188 -0
- package/dist/components/code-preview.js.map +1 -0
- package/dist/components/color-picker.cjs +2 -2
- package/dist/components/color-picker.cjs.map +1 -1
- package/dist/components/color-picker.js +2 -2
- package/dist/components/color-picker.js.map +1 -1
- package/dist/components/comic-reader.cjs.map +1 -1
- package/dist/components/comic-reader.js.map +1 -1
- package/dist/components/config-provider.cjs.map +1 -1
- package/dist/components/config-provider.js.map +1 -1
- package/dist/components/config-table.cjs.map +1 -1
- package/dist/components/config-table.js.map +1 -1
- package/dist/components/countdown.cjs.map +1 -1
- package/dist/components/countdown.js.map +1 -1
- package/dist/components/danmaku.cjs.map +1 -1
- package/dist/components/danmaku.js.map +1 -1
- package/dist/components/date-picker.cjs.map +1 -1
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.cjs.map +1 -1
- package/dist/components/date-range-picker.js.map +1 -1
- package/dist/components/design-effect.cjs.map +1 -1
- package/dist/components/design-effect.js.map +1 -1
- package/dist/components/drag-drop-board.cjs +24 -0
- package/dist/components/drag-drop-board.cjs.map +1 -1
- package/dist/components/drag-drop-board.js +24 -0
- package/dist/components/drag-drop-board.js.map +1 -1
- package/dist/components/draggable.cjs.map +1 -1
- package/dist/components/draggable.js.map +1 -1
- package/dist/components/ellipsis-text.cjs.map +1 -1
- package/dist/components/ellipsis-text.js.map +1 -1
- package/dist/components/empty.cjs.map +1 -1
- package/dist/components/empty.js.map +1 -1
- package/dist/components/field.cjs.map +1 -1
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-preview.cjs.map +1 -1
- package/dist/components/file-preview.js.map +1 -1
- package/dist/components/floating-ball.cjs.map +1 -1
- package/dist/components/floating-ball.js.map +1 -1
- package/dist/components/form.cjs.map +1 -1
- package/dist/components/form.js.map +1 -1
- package/dist/components/gradient-text.cjs.map +1 -1
- package/dist/components/gradient-text.js.map +1 -1
- package/dist/components/height-transition.cjs +35 -0
- package/dist/components/height-transition.cjs.map +1 -0
- package/dist/components/height-transition.d.ts +3 -0
- package/dist/components/height-transition.d.ts.map +1 -0
- package/dist/components/height-transition.js +33 -0
- package/dist/components/height-transition.js.map +1 -0
- package/dist/components/input.cjs.map +1 -1
- package/dist/components/input.js.map +1 -1
- package/dist/components/lazy-image.cjs.map +1 -1
- package/dist/components/lazy-image.js.map +1 -1
- package/dist/components/live-room.cjs.map +1 -1
- package/dist/components/live-room.js.map +1 -1
- package/dist/components/loading.cjs.map +1 -1
- package/dist/components/loading.js.map +1 -1
- package/dist/components/marquee.cjs.map +1 -1
- package/dist/components/marquee.js.map +1 -1
- package/dist/components/masonry-virtual-list.cjs.map +1 -1
- package/dist/components/masonry-virtual-list.js.map +1 -1
- package/dist/components/menu.cjs +100 -0
- package/dist/components/menu.cjs.map +1 -0
- package/dist/components/menu.d.ts +3 -0
- package/dist/components/menu.d.ts.map +1 -0
- package/dist/components/menu.js +98 -0
- package/dist/components/menu.js.map +1 -0
- package/dist/components/modal.cjs.map +1 -1
- package/dist/components/modal.js.map +1 -1
- package/dist/components/multi-column-picker.cjs.map +1 -1
- package/dist/components/multi-column-picker.js.map +1 -1
- package/dist/components/novel-reader.cjs.map +1 -1
- package/dist/components/novel-reader.js.map +1 -1
- package/dist/components/number-input.cjs.map +1 -1
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/orbital-sphere.cjs +40 -0
- package/dist/components/orbital-sphere.cjs.map +1 -0
- package/dist/components/orbital-sphere.d.ts +3 -0
- package/dist/components/orbital-sphere.d.ts.map +1 -0
- package/dist/components/orbital-sphere.js +38 -0
- package/dist/components/orbital-sphere.js.map +1 -0
- package/dist/components/pagination.cjs.map +1 -1
- package/dist/components/pagination.js.map +1 -1
- package/dist/components/password-input.cjs.map +1 -1
- package/dist/components/password-input.js.map +1 -1
- package/dist/components/popconfirm.cjs +40 -6
- package/dist/components/popconfirm.cjs.map +1 -1
- package/dist/components/popconfirm.js +41 -7
- package/dist/components/popconfirm.js.map +1 -1
- package/dist/components/popup.cjs +2 -1
- package/dist/components/popup.cjs.map +1 -1
- package/dist/components/popup.js +2 -1
- package/dist/components/popup.js.map +1 -1
- package/dist/components/progress-bar.cjs.map +1 -1
- package/dist/components/progress-bar.js.map +1 -1
- package/dist/components/qr-code.cjs.map +1 -1
- package/dist/components/qr-code.js.map +1 -1
- package/dist/components/radio-group.cjs.map +1 -1
- package/dist/components/radio-group.js.map +1 -1
- package/dist/components/rating.cjs.map +1 -1
- package/dist/components/rating.js.map +1 -1
- package/dist/components/rolling-number.cjs.map +1 -1
- package/dist/components/rolling-number.js.map +1 -1
- package/dist/components/select.cjs.map +1 -1
- package/dist/components/select.js.map +1 -1
- package/dist/components/signature.cjs +1 -1
- package/dist/components/signature.cjs.map +1 -1
- package/dist/components/signature.js +1 -1
- package/dist/components/signature.js.map +1 -1
- package/dist/components/skeleton.cjs.map +1 -1
- package/dist/components/skeleton.js.map +1 -1
- package/dist/components/slide-captcha.cjs.map +1 -1
- package/dist/components/slide-captcha.js.map +1 -1
- package/dist/components/swiper.cjs.map +1 -1
- package/dist/components/swiper.js.map +1 -1
- package/dist/components/switch.cjs.map +1 -1
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table.cjs.map +1 -1
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.cjs.map +1 -1
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag.cjs.map +1 -1
- package/dist/components/tag.js.map +1 -1
- package/dist/components/textarea.cjs.map +1 -1
- package/dist/components/textarea.js.map +1 -1
- package/dist/components/tilt-card.cjs.map +1 -1
- package/dist/components/tilt-card.js.map +1 -1
- package/dist/components/timeline.cjs.map +1 -1
- package/dist/components/timeline.js.map +1 -1
- package/dist/components/toast.cjs +146 -14
- package/dist/components/toast.cjs.map +1 -1
- package/dist/components/toast.d.ts +1 -1
- package/dist/components/toast.d.ts.map +1 -1
- package/dist/components/toast.js +144 -15
- package/dist/components/toast.js.map +1 -1
- package/dist/components/tooltip.cjs +38 -5
- package/dist/components/tooltip.cjs.map +1 -1
- package/dist/components/tooltip.js +39 -6
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/typewriter-text.cjs.map +1 -1
- package/dist/components/typewriter-text.js.map +1 -1
- package/dist/components/upload.cjs.map +1 -1
- package/dist/components/upload.js.map +1 -1
- package/dist/components/verification-code.cjs.map +1 -1
- package/dist/components/verification-code.js.map +1 -1
- package/dist/components/video-detail-transition.cjs.map +1 -1
- package/dist/components/video-detail-transition.js.map +1 -1
- package/dist/components/video-player.cjs.map +1 -1
- package/dist/components/video-player.js.map +1 -1
- package/dist/components/virtual-list.cjs.map +1 -1
- package/dist/components/virtual-list.js.map +1 -1
- package/dist/components/virtual-select.cjs.map +1 -1
- package/dist/components/virtual-select.js.map +1 -1
- package/dist/components/virtual-table.cjs.map +1 -1
- package/dist/components/virtual-table.js.map +1 -1
- package/dist/{import-transform-jqLjtD6M.js → import-transform-Cw4K2Iky.js} +7 -1
- package/dist/import-transform-Cw4K2Iky.js.map +1 -0
- package/dist/{import-transform-DIRVOYvz.js → import-transform-ieMdZBuN.js} +7 -1
- package/dist/import-transform-ieMdZBuN.js.map +1 -0
- package/dist/import-transform.d.ts.map +1 -1
- package/dist/index.cjs +605 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +71 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +583 -39
- package/dist/index.js.map +1 -1
- package/dist/styles/base.css +168 -41
- package/dist/styles/components/barcode.css +206 -0
- package/dist/styles/components/button.css +7 -2
- package/dist/styles/components/calendar.css +0 -23
- package/dist/styles/components/canvas-editor.css +18 -21
- package/dist/styles/components/canvas-image.css +0 -23
- package/dist/styles/components/chat-textarea.css +124 -0
- package/dist/styles/components/chat-virtual-list.css +15 -26
- package/dist/styles/components/checkbox.css +39 -23
- package/dist/styles/components/checked.css +39 -23
- package/dist/styles/components/code-preview.css +208 -0
- package/dist/styles/components/color-picker.css +46 -27
- package/dist/styles/components/config-table.css +0 -23
- package/dist/styles/components/date-picker.css +39 -23
- package/dist/styles/components/date-range-picker.css +39 -23
- package/dist/styles/components/design-effect.css +5 -1
- package/dist/styles/components/drag-drop-board.css +6 -1
- package/dist/styles/components/field.css +39 -23
- package/dist/styles/components/form.css +39 -23
- package/dist/styles/components/gradient-text.css +4 -0
- package/dist/styles/components/height-transition.css +50 -0
- package/dist/styles/components/input.css +39 -23
- package/dist/styles/components/loading.css +47 -0
- package/dist/styles/components/menu.css +286 -0
- package/dist/styles/components/modal.css +2 -23
- package/dist/styles/components/number-input.css +39 -23
- package/dist/styles/components/orbital-sphere.css +224 -0
- package/dist/styles/components/password-input.css +39 -23
- package/dist/styles/components/popconfirm.css +5 -0
- package/dist/styles/components/popup.css +2 -23
- package/dist/styles/components/qr-code.css +206 -0
- package/dist/styles/components/radio-group.css +39 -23
- package/dist/styles/components/rating.css +39 -23
- package/dist/styles/components/select.css +39 -23
- package/dist/styles/components/signature.css +39 -23
- package/dist/styles/components/switch.css +39 -23
- package/dist/styles/components/table.css +0 -23
- package/dist/styles/components/tabs.css +10 -0
- package/dist/styles/components/textarea.css +39 -23
- package/dist/styles/components/tilt-card.css +2 -23
- package/dist/styles/components/toast.css +109 -48
- package/dist/styles/components/tooltip.css +8 -23
- package/dist/styles/components/typewriter-text.css +4 -0
- package/dist/styles/components/upload.css +39 -23
- package/dist/styles/components/verification-code.css +39 -23
- package/dist/styles/components/virtual-select.css +39 -23
- package/dist/styles/components/virtual-table.css +0 -23
- package/dist/styles/components.css +1250 -165
- package/dist/styles/themes/business-blue.css +375 -0
- package/dist/styles/themes/cartoon-3d.css +695 -0
- package/dist/styles/themes/creative-purple.css +376 -0
- package/dist/styles/themes/dark-tech.css +495 -0
- package/dist/styles/themes/liquid-glass.css +526 -21
- package/dist/styles/themes/minimal.css +406 -14
- package/dist/styles/themes/soft-pink.css +376 -0
- package/dist/styles.css +1250 -165
- package/dist/vite.cjs +1 -1
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +1 -1
- package/dist/vite.js.map +1 -1
- package/dist/webpack-loader.cjs +1 -1
- package/dist/webpack-loader.js +1 -1
- package/package.json +3 -3
- package/dist/import-transform-DIRVOYvz.js.map +0 -1
- package/dist/import-transform-jqLjtD6M.js.map +0 -1
- package/dist/styles/themes/amber.css +0 -19
- package/dist/styles/themes/emerald.css +0 -19
- package/dist/styles/themes/rose.css +0 -19
- package/dist/styles/themes/sky.css +0 -19
- package/dist/styles/themes/violet.css +0 -19
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import React, { useEffect, useMemo, useContext, useSyncExternalStore, createContext } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
|
-
import { ToastManager, configureClassComponents, FormController, getClassComponentsLocale, PasswordInputController, ColorPickerController, DatePickerController, DateRangePickerController, VerificationCodeController, SlideCaptchaController, VirtualSelectController, VirtualListController, BadgeController, TagController, SkeletonController, BreadcrumbController, PaginationController, getSafeTooltipPlacement, BacktopController, AffixController, ModalController, PopupController, TooltipController, TabsController, RollingNumberController, CountdownController, CalendarController, TypewriterTextController, DesignEffectController, GradientTextController, LazyImageController, TiltCardController, MarqueeController, ProgressController, SignatureController, VideoPlayerController, VideoDetailTransitionController, FilePreviewController, CanvasImageController, CanvasEditorController, TimelineController, DragController, DropController, GestureController, FloatingBallController, MultiColumnPickerController, SwiperController, MasonryVirtualListController, TableController, UploadController, NovelReaderController, ComicReaderController, DanmakuController, LiveRoomController, ChatVirtualListController } from '@class-kit/core';
|
|
5
|
-
export { AffixController, BacktopController, BadgeController, BreadcrumbController, CalendarController, CanvasEditorController, CanvasImageController, ChatVirtualListController, ColorPickerController, ComicReaderController, CountdownController, DanmakuController, DatePickerController, DateRangePickerController, DesignEffectController, DragController, DropController, FilePreviewController, FloatingBallController, FormController, GestureController, GradientTextController, LazyImageController, LiveRoomController, MasonryVirtualListController, ModalController, MultiColumnPickerController, NovelReaderController, PaginationController, PasswordInputController, PopupController, ProgressController, SignatureController, SkeletonController, SlideCaptchaController, SwiperController, TableController, TabsController, TagController, TiltCardController, TimelineController, ToastManager, TooltipController, TypewriterTextController, UploadController, VerificationCodeController, VideoDetailTransitionController, VideoPlayerController, VirtualListController, VirtualSelectController, configureClassComponents, getClassComponentsConfig, getClassComponentsLocale, resetClassComponentsConfig } from '@class-kit/core';
|
|
4
|
+
import { ToastManager, configureClassComponents, FormController, getClassComponentsLocale, PasswordInputController, ColorPickerController, DatePickerController, DateRangePickerController, VerificationCodeController, SlideCaptchaController, ChatTextareaController, VirtualSelectController, VirtualListController, BadgeController, TagController, SkeletonController, BreadcrumbController, MenuController, PaginationController, getSafeTooltipPlacement, BacktopController, AffixController, ModalController, PopupController, TooltipController, TabsController, RollingNumberController, CountdownController, CalendarController, TypewriterTextController, DesignEffectController, GradientTextController, LazyImageController, TiltCardController, OrbitalSphereController, HeightTransitionController, CodePreviewController, MarqueeController, ProgressController, SignatureController, VideoPlayerController, VideoDetailTransitionController, FilePreviewController, CanvasImageController, CanvasEditorController, TimelineController, DragController, DropController, GestureController, FloatingBallController, MultiColumnPickerController, SwiperController, MasonryVirtualListController, TableController, UploadController, NovelReaderController, ComicReaderController, DanmakuController, LiveRoomController, ChatVirtualListController } from '@class-kit/core';
|
|
5
|
+
export { AffixController, BacktopController, BadgeController, BreadcrumbController, CalendarController, CanvasEditorController, CanvasImageController, ChatTextareaController, ChatVirtualListController, CodePreviewController, ColorPickerController, ComicReaderController, CountdownController, DanmakuController, DatePickerController, DateRangePickerController, DesignEffectController, DragController, DropController, FilePreviewController, FloatingBallController, FormController, GestureController, GradientTextController, HeightTransitionController, LazyImageController, LiveRoomController, MasonryVirtualListController, MenuController, ModalController, MultiColumnPickerController, NovelReaderController, OrbitalSphereController, PaginationController, PasswordInputController, PopupController, ProgressController, SignatureController, SkeletonController, SlideCaptchaController, SwiperController, TableController, TabsController, TagController, TiltCardController, TimelineController, ToastManager, TooltipController, TypewriterTextController, UploadController, VerificationCodeController, VideoDetailTransitionController, VideoPlayerController, VirtualListController, VirtualSelectController, configureClassComponents, getClassComponentsConfig, getClassComponentsLocale, resetClassComponentsConfig } from '@class-kit/core';
|
|
6
6
|
|
|
7
7
|
const FormContext = /*#__PURE__*/ createContext(null);
|
|
8
8
|
const defaultToastManager = /*#__PURE__*/ new ToastManager();
|
|
@@ -174,23 +174,27 @@ function usePresence(open, duration) {
|
|
|
174
174
|
return [mounted, state];
|
|
175
175
|
}
|
|
176
176
|
function useAnimatedToasts(items, duration) {
|
|
177
|
-
const [rendered, setRendered] = React.useState(() => items.map((item) => ({ item, state: "enter" })));
|
|
177
|
+
const [rendered, setRendered] = React.useState(() => items.map((item) => ({ item, motion: false, state: "enter" })));
|
|
178
178
|
useEffect(() => {
|
|
179
179
|
let enteringIds = [];
|
|
180
180
|
setRendered((current) => {
|
|
181
181
|
const currentIds = new Set(current.map(({ item }) => item.id));
|
|
182
182
|
const incomingIds = new Set(items.map((item) => item.id));
|
|
183
|
+
const incomingById = new Map(items.map((item) => [item.id, item]));
|
|
183
184
|
enteringIds = items
|
|
184
185
|
.filter((item) => !currentIds.has(item.id))
|
|
185
186
|
.map((item) => item.id);
|
|
186
|
-
const
|
|
187
|
-
item,
|
|
188
|
-
|
|
187
|
+
const retainedOrExiting = current.map(({ item }) => ({
|
|
188
|
+
item: incomingById.get(item.id) ?? item,
|
|
189
|
+
motion: !incomingIds.has(item.id),
|
|
190
|
+
state: incomingIds.has(item.id)
|
|
191
|
+
? "enter"
|
|
192
|
+
: "exit",
|
|
189
193
|
}));
|
|
190
|
-
const
|
|
191
|
-
.filter((
|
|
192
|
-
.map((
|
|
193
|
-
return [...
|
|
194
|
+
const entering = items
|
|
195
|
+
.filter((item) => !currentIds.has(item.id))
|
|
196
|
+
.map((item) => ({ item, motion: true, state: "prepare" }));
|
|
197
|
+
return [...retainedOrExiting, ...entering];
|
|
194
198
|
});
|
|
195
199
|
if (!enteringIds.length)
|
|
196
200
|
return undefined;
|
|
@@ -201,6 +205,22 @@ function useAnimatedToasts(items, duration) {
|
|
|
201
205
|
});
|
|
202
206
|
return () => window.cancelAnimationFrame(frame);
|
|
203
207
|
}, [items]);
|
|
208
|
+
useEffect(() => {
|
|
209
|
+
if (!rendered.some((entry) => entry.motion && entry.state === "enter"))
|
|
210
|
+
return;
|
|
211
|
+
if (duration <= 0) {
|
|
212
|
+
setRendered((current) => current.map((entry) => entry.motion && entry.state === "enter"
|
|
213
|
+
? { ...entry, motion: false }
|
|
214
|
+
: entry));
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const timer = window.setTimeout(() => {
|
|
218
|
+
setRendered((current) => current.map((entry) => entry.motion && entry.state === "enter"
|
|
219
|
+
? { ...entry, motion: false }
|
|
220
|
+
: entry));
|
|
221
|
+
}, duration);
|
|
222
|
+
return () => window.clearTimeout(timer);
|
|
223
|
+
}, [duration, rendered]);
|
|
204
224
|
useEffect(() => {
|
|
205
225
|
if (!rendered.some((entry) => entry.state === "exit"))
|
|
206
226
|
return;
|
|
@@ -215,6 +235,80 @@ function useAnimatedToasts(items, duration) {
|
|
|
215
235
|
}, [duration, rendered]);
|
|
216
236
|
return rendered;
|
|
217
237
|
}
|
|
238
|
+
function normalizeToastMaxVisible(maxVisible) {
|
|
239
|
+
if (typeof maxVisible !== "number" || !Number.isFinite(maxVisible))
|
|
240
|
+
return 3;
|
|
241
|
+
return Math.max(1, Math.min(6, Math.floor(maxVisible)));
|
|
242
|
+
}
|
|
243
|
+
function isToastTopPosition(position) {
|
|
244
|
+
return (position === "top" || position === "top-left" || position === "top-right");
|
|
245
|
+
}
|
|
246
|
+
function useToastFlip(entries, duration, easing) {
|
|
247
|
+
const nodeMapRef = React.useRef(new Map());
|
|
248
|
+
const rectMapRef = React.useRef(new Map());
|
|
249
|
+
const frameRef = React.useRef(0);
|
|
250
|
+
const setNode = React.useCallback((id, node) => {
|
|
251
|
+
if (node)
|
|
252
|
+
nodeMapRef.current.set(id, node);
|
|
253
|
+
else
|
|
254
|
+
nodeMapRef.current.delete(id);
|
|
255
|
+
}, []);
|
|
256
|
+
React.useLayoutEffect(() => {
|
|
257
|
+
if (frameRef.current)
|
|
258
|
+
window.cancelAnimationFrame(frameRef.current);
|
|
259
|
+
const previousRects = rectMapRef.current;
|
|
260
|
+
const nextRects = new Map();
|
|
261
|
+
const activeIds = new Set(entries
|
|
262
|
+
.filter((entry) => entry.motion && entry.state !== "exit")
|
|
263
|
+
.map((entry) => entry.item.id));
|
|
264
|
+
nodeMapRef.current.forEach((node, id) => {
|
|
265
|
+
if (!activeIds.has(id))
|
|
266
|
+
return;
|
|
267
|
+
const rect = node.getBoundingClientRect();
|
|
268
|
+
nextRects.set(id, rect);
|
|
269
|
+
const previous = previousRects.get(id);
|
|
270
|
+
if (!previous)
|
|
271
|
+
return;
|
|
272
|
+
const deltaY = previous.top - rect.top;
|
|
273
|
+
if (Math.abs(deltaY) < 1)
|
|
274
|
+
return;
|
|
275
|
+
node.style.transition = "none";
|
|
276
|
+
node.style.setProperty("--cc-toast-stack-offset", `${deltaY}px`);
|
|
277
|
+
node.style.willChange = "transform, opacity";
|
|
278
|
+
});
|
|
279
|
+
frameRef.current = window.requestAnimationFrame(() => {
|
|
280
|
+
nodeMapRef.current.forEach((node, id) => {
|
|
281
|
+
if (!nextRects.has(id))
|
|
282
|
+
return;
|
|
283
|
+
node.style.transition = `transform ${duration}ms ${easing}, opacity ${duration}ms ${easing}, margin ${duration}ms ${easing}`;
|
|
284
|
+
node.style.removeProperty("--cc-toast-stack-offset");
|
|
285
|
+
window.setTimeout(() => {
|
|
286
|
+
node.style.transition = "";
|
|
287
|
+
node.style.willChange = "";
|
|
288
|
+
}, duration);
|
|
289
|
+
});
|
|
290
|
+
frameRef.current = 0;
|
|
291
|
+
});
|
|
292
|
+
rectMapRef.current = nextRects;
|
|
293
|
+
return () => {
|
|
294
|
+
if (frameRef.current)
|
|
295
|
+
window.cancelAnimationFrame(frameRef.current);
|
|
296
|
+
};
|
|
297
|
+
}, [duration, easing, entries]);
|
|
298
|
+
return setNode;
|
|
299
|
+
}
|
|
300
|
+
function useToastItems(manager) {
|
|
301
|
+
const snapshotRef = React.useRef(manager.getToasts());
|
|
302
|
+
const managerRef = React.useRef(manager);
|
|
303
|
+
if (managerRef.current !== manager) {
|
|
304
|
+
managerRef.current = manager;
|
|
305
|
+
snapshotRef.current = manager.getToasts();
|
|
306
|
+
}
|
|
307
|
+
return useSyncExternalStore(React.useCallback((notify) => manager.subscribe((items) => {
|
|
308
|
+
snapshotRef.current = items;
|
|
309
|
+
notify();
|
|
310
|
+
}), [manager]), React.useCallback(() => snapshotRef.current, [manager]), React.useCallback(() => snapshotRef.current, [manager]));
|
|
311
|
+
}
|
|
218
312
|
function resolveTabsDirection(tabs, previousId, nextId, direction) {
|
|
219
313
|
if (direction === "none")
|
|
220
314
|
return "none";
|
|
@@ -390,12 +484,12 @@ function PasswordInput({ name, label, className = "cc-field cc-password-field",
|
|
|
390
484
|
const Field = Input;
|
|
391
485
|
function ColorPicker({ name, label, className = "cc-field cc-color-picker", disabled, panelClassName = "cc-color-picker__panel", readOnly, initialValue, rules, showInputSteppers = false, validateOn, onChange, ...props }) {
|
|
392
486
|
const field = useOptionalField(name, {
|
|
393
|
-
initialValue: initialValue ?? "#
|
|
487
|
+
initialValue: initialValue ?? "#1d2129",
|
|
394
488
|
rules,
|
|
395
489
|
validateOn,
|
|
396
490
|
});
|
|
397
491
|
const interactivity = resolveFieldInteractivity(useOptionalFormInteractivity(), disabled, readOnly);
|
|
398
|
-
const controller = React.useMemo(() => new ColorPickerController(String(field.value || "#
|
|
492
|
+
const controller = React.useMemo(() => new ColorPickerController(String(field.value || "#1d2129")), [field.value]);
|
|
399
493
|
const state = controller.getState();
|
|
400
494
|
const rootRef = React.useRef(null);
|
|
401
495
|
const panelRef = React.useRef(null);
|
|
@@ -1079,6 +1173,82 @@ function Textarea({ name, label, className = "cc-field", labelClassName = "cc-fi
|
|
|
1079
1173
|
field.setValue(event.currentTarget.value);
|
|
1080
1174
|
}, ...options }), canClear ? (jsx("button", { "aria-label": clearLabel, className: "cc-field__clear cc-field__clear--textarea", type: "button", onClick: () => field.setValue(""), children: clearIcon })) : null] }), jsx(FieldError, { className: errorClassName, errorId: errorId, errors: field.errors })] }));
|
|
1081
1175
|
}
|
|
1176
|
+
function getTextareaMetrics(element) {
|
|
1177
|
+
const computed = window.getComputedStyle(element);
|
|
1178
|
+
const fontSize = Number.parseFloat(computed.fontSize) || 14;
|
|
1179
|
+
const lineHeight = Number.parseFloat(computed.lineHeight) || fontSize * 1.5;
|
|
1180
|
+
const paddingY = (Number.parseFloat(computed.paddingTop) || 0) +
|
|
1181
|
+
(Number.parseFloat(computed.paddingBottom) || 0);
|
|
1182
|
+
const borderY = (Number.parseFloat(computed.borderTopWidth) || 0) +
|
|
1183
|
+
(Number.parseFloat(computed.borderBottomWidth) || 0);
|
|
1184
|
+
return { borderY, lineHeight, paddingY };
|
|
1185
|
+
}
|
|
1186
|
+
const ChatTextarea = /*#__PURE__*/ React.forwardRef(function ChatTextarea({ className = "cc-chat-textarea", clearable = true, clearIcon = jsx(ClassIcon, { name: "x" }), clearLabel = getClassComponentsLocale().inputClearLabel, defaultValue = "", disabled, maxRows = 3, minRows = 1, onValueChange, placeholder, readOnly, style, textareaClassName = "cc-chat-textarea__control", textareaStyle, value, ...props }, ref) {
|
|
1187
|
+
const textareaRef = React.useRef(null);
|
|
1188
|
+
const controllerRef = React.useRef(new ChatTextareaController({
|
|
1189
|
+
maxRows,
|
|
1190
|
+
minRows,
|
|
1191
|
+
value: value ?? defaultValue,
|
|
1192
|
+
}));
|
|
1193
|
+
const controlled = value !== undefined;
|
|
1194
|
+
const [state, setState] = React.useState(() => controllerRef.current.getState());
|
|
1195
|
+
const resize = React.useCallback(() => {
|
|
1196
|
+
const element = textareaRef.current;
|
|
1197
|
+
if (!element || typeof window === "undefined")
|
|
1198
|
+
return;
|
|
1199
|
+
const { borderY, lineHeight, paddingY } = getTextareaMetrics(element);
|
|
1200
|
+
const minHeight = lineHeight * state.minRows + paddingY + borderY;
|
|
1201
|
+
const maxHeight = lineHeight * state.maxRows + paddingY + borderY;
|
|
1202
|
+
element.style.height = "auto";
|
|
1203
|
+
const nextHeight = Math.min(Math.max(element.scrollHeight, minHeight), maxHeight);
|
|
1204
|
+
element.style.height = `${nextHeight}px`;
|
|
1205
|
+
element.style.overflowY =
|
|
1206
|
+
element.scrollHeight > maxHeight + 1 ? "auto" : "hidden";
|
|
1207
|
+
}, [state.maxRows, state.minRows, state.value]);
|
|
1208
|
+
React.useImperativeHandle(ref, () => ({
|
|
1209
|
+
blur: () => textareaRef.current?.blur(),
|
|
1210
|
+
focus: () => textareaRef.current?.focus(),
|
|
1211
|
+
getElement: () => textareaRef.current,
|
|
1212
|
+
}), []);
|
|
1213
|
+
React.useEffect(() => {
|
|
1214
|
+
const next = controllerRef.current.update({
|
|
1215
|
+
maxRows,
|
|
1216
|
+
minRows,
|
|
1217
|
+
value: controlled ? value : state.value,
|
|
1218
|
+
});
|
|
1219
|
+
setState(next);
|
|
1220
|
+
}, [controlled, maxRows, minRows, value]);
|
|
1221
|
+
React.useLayoutEffect(() => {
|
|
1222
|
+
resize();
|
|
1223
|
+
}, [resize]);
|
|
1224
|
+
React.useEffect(() => {
|
|
1225
|
+
if (typeof ResizeObserver === "undefined" || !textareaRef.current)
|
|
1226
|
+
return undefined;
|
|
1227
|
+
const observer = new ResizeObserver(resize);
|
|
1228
|
+
observer.observe(textareaRef.current);
|
|
1229
|
+
return () => observer.disconnect();
|
|
1230
|
+
}, [resize]);
|
|
1231
|
+
const commit = (nextValue, event) => {
|
|
1232
|
+
const nextState = controllerRef.current.setValue(nextValue);
|
|
1233
|
+
if (!controlled)
|
|
1234
|
+
setState(nextState);
|
|
1235
|
+
onValueChange?.(nextValue, event);
|
|
1236
|
+
};
|
|
1237
|
+
const currentValue = controlled ? (value ?? "") : state.value;
|
|
1238
|
+
const canClear = clearable && currentValue !== "" && !disabled && !readOnly;
|
|
1239
|
+
return (jsxs("div", { className: className, "data-disabled": Boolean(disabled), "data-readonly": Boolean(readOnly), "data-scrollable": currentValue.length > 0, style: style, children: [jsx("textarea", { ...props, className: `${textareaClassName}${canClear ? " cc-chat-textarea__control--clearable" : ""}`, disabled: disabled, placeholder: placeholder, readOnly: readOnly, ref: textareaRef, rows: state.minRows, style: {
|
|
1240
|
+
"--cc-chat-textarea-max-rows": state.maxRows,
|
|
1241
|
+
"--cc-chat-textarea-min-rows": state.minRows,
|
|
1242
|
+
...textareaStyle,
|
|
1243
|
+
}, value: currentValue, onChange: (event) => {
|
|
1244
|
+
if (readOnly)
|
|
1245
|
+
return;
|
|
1246
|
+
commit(event.currentTarget.value, event);
|
|
1247
|
+
} }), canClear ? (jsx("button", { "aria-label": clearLabel, className: "cc-chat-textarea__clear", type: "button", onClick: (event) => {
|
|
1248
|
+
commit("", event);
|
|
1249
|
+
textareaRef.current?.focus();
|
|
1250
|
+
}, children: clearIcon })) : null] }));
|
|
1251
|
+
});
|
|
1082
1252
|
function getSelectMenuPosition(trigger, preferredHeight, anchorTopPlacement = false) {
|
|
1083
1253
|
if (!trigger || typeof window === "undefined") {
|
|
1084
1254
|
return { placement: "bottom", style: {} };
|
|
@@ -1495,6 +1665,53 @@ function Breadcrumb({ className = "cc-breadcrumb", items, separator = "/", ...pr
|
|
|
1495
1665
|
const state = useMemo(() => new BreadcrumbController(items).getState(), [items]);
|
|
1496
1666
|
return (jsx("nav", { className: className, "aria-label": "Breadcrumb", ...props, children: state.items.map((item, index) => (jsxs("span", { className: "cc-breadcrumb__item", children: [index > 0 ? (jsx("span", { className: "cc-breadcrumb__separator", children: separator })) : null, item.href && !item.disabled ? (jsx("a", { href: item.href, children: item.label })) : (jsx("span", { "data-disabled": item.disabled, children: item.label }))] }, String(item.key)))) }));
|
|
1497
1667
|
}
|
|
1668
|
+
function renderMenuIcon(item, collapsed, iconRender) {
|
|
1669
|
+
const rendered = iconRender?.(item);
|
|
1670
|
+
if (rendered !== undefined)
|
|
1671
|
+
return rendered;
|
|
1672
|
+
if (item.icon)
|
|
1673
|
+
return item.icon;
|
|
1674
|
+
return collapsed ? item.label.slice(0, 1) : null;
|
|
1675
|
+
}
|
|
1676
|
+
function renderMenuItems(items, collapsed, iconRender, onToggle, onSelect) {
|
|
1677
|
+
return items.map((item) => {
|
|
1678
|
+
const hasChildren = item.children.length > 0;
|
|
1679
|
+
const icon = renderMenuIcon(item, collapsed, iconRender);
|
|
1680
|
+
return (jsxs("li", { className: "cc-menu__item", "data-active": item.isActive, "data-disabled": item.disabled, "data-expanded": item.expanded, "data-level": item.level, children: [jsxs("button", { "aria-current": item.isActive ? "page" : undefined, "aria-expanded": hasChildren ? item.expanded : undefined, className: "cc-menu__button", disabled: item.disabled, title: collapsed ? item.label : undefined, type: "button", onClick: () => {
|
|
1681
|
+
if (hasChildren && !collapsed)
|
|
1682
|
+
onToggle(item.key);
|
|
1683
|
+
onSelect(item.key, item);
|
|
1684
|
+
}, children: [icon ? (jsx("span", { className: "cc-menu__icon", "aria-hidden": "true", children: icon })) : null, jsx("span", { className: "cc-menu__label", children: item.label }), hasChildren ? (jsx(ClassIcon, { className: "cc-menu__arrow", name: "chevronDown" })) : null] }), hasChildren ? (jsx(HeightTransition, { className: "cc-height-transition cc-menu__transition", contentClassName: "cc-height-transition__content cc-menu__transition-content", duration: 180, expanded: !collapsed && item.expanded, mode: "grid", children: jsx("ul", { className: "cc-menu__list cc-menu__list--child", children: renderMenuItems(item.children, collapsed, iconRender, onToggle, onSelect) }) })) : null] }, item.key));
|
|
1685
|
+
});
|
|
1686
|
+
}
|
|
1687
|
+
function Menu({ activeKey, className = "cc-menu", collapsed, collapsible = true, defaultExpandedKeys = [], iconRender, items, onCollapsedChange, onSelect, ...props }) {
|
|
1688
|
+
const controller = React.useMemo(() => new MenuController({
|
|
1689
|
+
activeKey,
|
|
1690
|
+
collapsed,
|
|
1691
|
+
defaultExpandedKeys,
|
|
1692
|
+
items,
|
|
1693
|
+
}), []);
|
|
1694
|
+
const [state, setState] = React.useState(() => controller.getState());
|
|
1695
|
+
React.useEffect(() => {
|
|
1696
|
+
setState(controller.update({
|
|
1697
|
+
activeKey,
|
|
1698
|
+
collapsed,
|
|
1699
|
+
defaultExpandedKeys,
|
|
1700
|
+
items,
|
|
1701
|
+
}));
|
|
1702
|
+
}, [activeKey, collapsed, controller, defaultExpandedKeys, items]);
|
|
1703
|
+
const commitSelect = React.useCallback((key, item) => {
|
|
1704
|
+
setState(controller.activate(key));
|
|
1705
|
+
onSelect?.(key, item);
|
|
1706
|
+
}, [controller, onSelect]);
|
|
1707
|
+
const toggleExpanded = React.useCallback((key) => setState(controller.toggleExpanded(key)), [controller]);
|
|
1708
|
+
const toggleCollapsed = React.useCallback(() => {
|
|
1709
|
+
const next = controller.toggleCollapsed();
|
|
1710
|
+
setState(next);
|
|
1711
|
+
onCollapsedChange?.(next.collapsed);
|
|
1712
|
+
}, [controller, onCollapsedChange]);
|
|
1713
|
+
return (jsxs("nav", { className: className, "data-collapsed": state.collapsed, "data-collapsible": collapsible, ...props, children: [collapsible ? (jsx("button", { "aria-label": state.collapsed ? "展开菜单" : "收起菜单", className: "cc-menu__collapse", type: "button", onClick: toggleCollapsed, children: jsx(ClassIcon, { name: state.collapsed ? "chevronRight" : "chevronLeft" }) })) : null, jsx("ul", { className: "cc-menu__list", children: renderMenuItems(state.items, state.collapsed, iconRender, toggleExpanded, commitSelect) })] }));
|
|
1714
|
+
}
|
|
1498
1715
|
function Pagination({ boundaryCount = 1, className = "cc-pagination", current = 1, pageSize = 10, siblingCount = 1, total = 0, previousIcon = jsx(ClassIcon, { name: "chevronLeft" }), nextIcon = jsx(ClassIcon, { name: "chevronRight" }), onChange, ...props }) {
|
|
1499
1716
|
const state = useMemo(() => new PaginationController({
|
|
1500
1717
|
boundaryCount,
|
|
@@ -1505,14 +1722,29 @@ function Pagination({ boundaryCount = 1, className = "cc-pagination", current =
|
|
|
1505
1722
|
}).getState(), [boundaryCount, current, pageSize, siblingCount, total]);
|
|
1506
1723
|
return (jsxs("div", { className: className, ...props, children: [jsx("button", { disabled: state.current <= 1, type: "button", onClick: () => onChange?.(state.current - 1), children: previousIcon }), state.pages.map((page, index) => page === "ellipsis" ? (jsx("span", { "aria-hidden": "true", className: "cc-pagination__ellipsis", children: "\u2022\u2022\u2022" }, `ellipsis-${index}`)) : (jsx("button", { "data-active": page === state.current, type: "button", onClick: () => onChange?.(page), children: page }, page))), jsx("button", { disabled: state.current >= state.pageCount, type: "button", onClick: () => onChange?.(state.current + 1), children: nextIcon })] }));
|
|
1507
1724
|
}
|
|
1508
|
-
function Popconfirm({ children, animation, autoAdjust = true, placement = "top", content = getClassComponentsLocale().popconfirmContent, confirmText = getClassComponentsLocale().popconfirmConfirmText, cancelText = getClassComponentsLocale().popconfirmCancelText, closeOnEsc = true, closeOnOutsideClick = true, onConfirm, }) {
|
|
1725
|
+
function Popconfirm({ children, animation, autoAdjust = true, placement = "top", content = getClassComponentsLocale().popconfirmContent, confirmText = getClassComponentsLocale().popconfirmConfirmText, cancelText = getClassComponentsLocale().popconfirmCancelText, closeOnEsc = true, closeOnOutsideClick = true, onConfirm, portal = true, }) {
|
|
1509
1726
|
const rootRef = React.useRef(null);
|
|
1510
1727
|
const panelRef = React.useRef(null);
|
|
1511
1728
|
const [open, setOpen] = React.useState(false);
|
|
1512
1729
|
const [safePlacement, setSafePlacement] = React.useState(placement);
|
|
1730
|
+
const [anchorStyle, setAnchorStyle] = React.useState({
|
|
1731
|
+
height: 0,
|
|
1732
|
+
left: -9999,
|
|
1733
|
+
top: -9999,
|
|
1734
|
+
width: 0,
|
|
1735
|
+
});
|
|
1513
1736
|
const motion = resolveAnimation(animation, "scale");
|
|
1514
1737
|
const [mounted, presence] = usePresence(open, motion.enabled ? motion.duration : 0);
|
|
1515
1738
|
const updatePlacement = React.useCallback(() => {
|
|
1739
|
+
if (rootRef.current) {
|
|
1740
|
+
const rect = rootRef.current.getBoundingClientRect();
|
|
1741
|
+
setAnchorStyle({
|
|
1742
|
+
height: rect.height,
|
|
1743
|
+
left: rect.left,
|
|
1744
|
+
top: rect.top,
|
|
1745
|
+
width: rect.width,
|
|
1746
|
+
});
|
|
1747
|
+
}
|
|
1516
1748
|
if (!autoAdjust || !rootRef.current || !panelRef.current) {
|
|
1517
1749
|
setSafePlacement(placement);
|
|
1518
1750
|
return;
|
|
@@ -1525,7 +1757,8 @@ function Popconfirm({ children, animation, autoAdjust = true, placement = "top",
|
|
|
1525
1757
|
requestAnimationFrame(updatePlacement);
|
|
1526
1758
|
const close = (event) => {
|
|
1527
1759
|
if (!closeOnOutsideClick ||
|
|
1528
|
-
rootRef.current?.contains(event.target)
|
|
1760
|
+
rootRef.current?.contains(event.target) ||
|
|
1761
|
+
panelRef.current?.contains(event.target))
|
|
1529
1762
|
return;
|
|
1530
1763
|
setOpen(false);
|
|
1531
1764
|
};
|
|
@@ -1550,10 +1783,27 @@ function Popconfirm({ children, animation, autoAdjust = true, placement = "top",
|
|
|
1550
1783
|
if (open)
|
|
1551
1784
|
updatePlacement();
|
|
1552
1785
|
}, [open, placement, updatePlacement]);
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1786
|
+
const rootClassName = [
|
|
1787
|
+
"cc-popconfirm",
|
|
1788
|
+
`cc-popconfirm--${safePlacement}`,
|
|
1789
|
+
].join(" ");
|
|
1790
|
+
const panelNode = mounted ? (jsxs("span", { className: "cc-popconfirm__panel", "data-state": presence, ref: panelRef, role: "dialog", children: [jsx("span", { children: content }), jsxs("span", { className: "cc-popconfirm__actions", children: [jsx("button", { type: "button", onClick: () => setOpen(false), children: cancelText }), jsx("button", { type: "button", onClick: () => {
|
|
1791
|
+
onConfirm?.();
|
|
1792
|
+
setOpen(false);
|
|
1793
|
+
}, children: confirmText })] })] })) : null;
|
|
1794
|
+
const rootNode = (jsxs("span", { className: rootClassName, "data-animation": motion.name, ref: rootRef, style: animationStyle(motion), children: [jsx("span", { onClick: () => setOpen(true), children: children }), portal ? null : panelNode] }));
|
|
1795
|
+
if (!portal)
|
|
1796
|
+
return rootNode;
|
|
1797
|
+
const portalNode = mounted ? (jsx("span", { className: `${rootClassName} cc-popconfirm--portal`, "data-animation": motion.name, style: {
|
|
1798
|
+
...animationStyle(motion),
|
|
1799
|
+
height: `${anchorStyle.height}px`,
|
|
1800
|
+
left: `${anchorStyle.left}px`,
|
|
1801
|
+
top: `${anchorStyle.top}px`,
|
|
1802
|
+
width: `${anchorStyle.width}px`,
|
|
1803
|
+
}, children: panelNode })) : null;
|
|
1804
|
+
return (jsxs(Fragment, { children: [rootNode, portalNode && typeof document !== "undefined"
|
|
1805
|
+
? createPortal(portalNode, document.body)
|
|
1806
|
+
: null] }));
|
|
1557
1807
|
}
|
|
1558
1808
|
function getBacktopTarget(target) {
|
|
1559
1809
|
if (typeof target === "string")
|
|
@@ -1785,13 +2035,14 @@ function Popup({ open, controller, placement = "bottom", title, children, animat
|
|
|
1785
2035
|
}, []);
|
|
1786
2036
|
if (!mounted)
|
|
1787
2037
|
return null;
|
|
1788
|
-
const popupContainer = containerRef?.current ??
|
|
2038
|
+
const popupContainer = containerRef?.current ??
|
|
2039
|
+
(typeof document !== "undefined" ? document.body : null);
|
|
1789
2040
|
const popupElement = (jsxs("div", { className: className, "data-animation": motion.name, "data-contained": popupContainer ? "true" : "false", "data-placement": popupState.placement, "data-state": animationState, role: "presentation", style: animationStyle(motion, style), ...props, children: [jsx("button", { "aria-label": "Close popup", className: overlayClassName, type: "button", onClick: closeOnOverlayClick ? close : undefined }), jsxs("section", { "aria-modal": "true", className: panelClassName, ref: panelRef, role: "dialog", tabIndex: -1, children: [title ? (jsxs("header", { className: "cc-popup__header", children: [jsx("span", { children: title }), jsx("button", { "aria-label": "Close popup", className: "cc-popup__close", type: "button", onClick: close, children: closeIcon })] })) : null, jsx("div", { className: "cc-popup__body", children: children })] })] }));
|
|
1790
2041
|
return popupContainer
|
|
1791
2042
|
? createPortal(popupElement, popupContainer)
|
|
1792
2043
|
: popupElement;
|
|
1793
2044
|
}
|
|
1794
|
-
function Tooltip({ content, children, animation, placement = "top", trigger = "hover", autoAdjust = true, closeOnEsc = true, closeOnOutsideClick = true, className, id, style, ...props }) {
|
|
2045
|
+
function Tooltip({ content, children, animation, placement = "top", trigger = "hover", autoAdjust = true, closeOnEsc = true, closeOnOutsideClick = true, portal = true, className, id, style, ...props }) {
|
|
1795
2046
|
const rootRef = React.useRef(null);
|
|
1796
2047
|
const contentRef = React.useRef(null);
|
|
1797
2048
|
const generatedId = React.useId();
|
|
@@ -1799,6 +2050,7 @@ function Tooltip({ content, children, animation, placement = "top", trigger = "h
|
|
|
1799
2050
|
const tooltipController = React.useMemo(() => new TooltipController(), []);
|
|
1800
2051
|
const [open, setOpen] = React.useState(() => tooltipController.isOpen());
|
|
1801
2052
|
const [safePlacement, setSafePlacement] = React.useState(placement);
|
|
2053
|
+
const [anchorStyle, setAnchorStyle] = React.useState(null);
|
|
1802
2054
|
const motion = resolveAnimation(animation, "fade");
|
|
1803
2055
|
useEffect(() => {
|
|
1804
2056
|
const unsubscribe = tooltipController.subscribe((state) => {
|
|
@@ -1810,6 +2062,15 @@ function Tooltip({ content, children, animation, placement = "top", trigger = "h
|
|
|
1810
2062
|
};
|
|
1811
2063
|
}, [tooltipController]);
|
|
1812
2064
|
const updatePlacement = React.useCallback(() => {
|
|
2065
|
+
if (rootRef.current) {
|
|
2066
|
+
const rect = rootRef.current.getBoundingClientRect();
|
|
2067
|
+
setAnchorStyle({
|
|
2068
|
+
height: rect.height,
|
|
2069
|
+
left: rect.left,
|
|
2070
|
+
top: rect.top,
|
|
2071
|
+
width: rect.width,
|
|
2072
|
+
});
|
|
2073
|
+
}
|
|
1813
2074
|
if (!autoAdjust || !rootRef.current || !contentRef.current) {
|
|
1814
2075
|
setSafePlacement(placement);
|
|
1815
2076
|
return;
|
|
@@ -1832,7 +2093,8 @@ function Tooltip({ content, children, animation, placement = "top", trigger = "h
|
|
|
1832
2093
|
return undefined;
|
|
1833
2094
|
const handlePointerDown = (event) => {
|
|
1834
2095
|
if (!closeOnOutsideClick ||
|
|
1835
|
-
rootRef.current?.contains(event.target)
|
|
2096
|
+
rootRef.current?.contains(event.target) ||
|
|
2097
|
+
contentRef.current?.contains(event.target))
|
|
1836
2098
|
return;
|
|
1837
2099
|
tooltipController.close();
|
|
1838
2100
|
};
|
|
@@ -1859,19 +2121,45 @@ function Tooltip({ content, children, animation, placement = "top", trigger = "h
|
|
|
1859
2121
|
onMouseEnter: () => tooltipController.open(),
|
|
1860
2122
|
onMouseLeave: () => tooltipController.close(),
|
|
1861
2123
|
};
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
2124
|
+
const rootClassName = [
|
|
2125
|
+
"cc-tooltip",
|
|
2126
|
+
`cc-tooltip--${safePlacement}`,
|
|
2127
|
+
className,
|
|
2128
|
+
]
|
|
2129
|
+
.filter(Boolean)
|
|
2130
|
+
.join(" ");
|
|
2131
|
+
const tooltipContent = (jsx("span", { className: "cc-tooltip__content", id: contentId, ref: contentRef, role: "tooltip", children: content }));
|
|
2132
|
+
const rootNode = (jsxs("span", { className: rootClassName, "aria-describedby": open ? contentId : undefined, "data-animation": motion.name, "data-open": open, ref: rootRef, style: animationStyle(motion, style), tabIndex: trigger === "click" ? 0 : undefined, ...props, ...triggerProps, children: [children, portal ? null : tooltipContent] }));
|
|
2133
|
+
if (!portal || typeof document === "undefined")
|
|
2134
|
+
return rootNode;
|
|
2135
|
+
const portalNode = open || anchorStyle ? (jsx("span", { className: `${rootClassName} cc-tooltip--portal`, "data-animation": motion.name, "data-open": open, style: {
|
|
2136
|
+
...animationStyle(motion),
|
|
2137
|
+
height: anchorStyle?.height ?? 0,
|
|
2138
|
+
left: anchorStyle?.left ?? -9999,
|
|
2139
|
+
top: anchorStyle?.top ?? -9999,
|
|
2140
|
+
width: anchorStyle?.width ?? 0,
|
|
2141
|
+
}, children: tooltipContent })) : null;
|
|
2142
|
+
return (jsxs(Fragment, { children: [rootNode, portalNode ? renderBodyPortal(portalNode) : null] }));
|
|
1865
2143
|
}
|
|
1866
|
-
function ToastViewport({ animation, manager = defaultToastManager, className = "cc-toast-viewport", position = "top-right", renderToast, style, ...props }) {
|
|
1867
|
-
const
|
|
2144
|
+
function ToastViewport({ animation, manager = defaultToastManager, className = "cc-toast-viewport", maxVisible, portal = false, position = "top-right", renderToast, style, ...props }) {
|
|
2145
|
+
const items = useToastItems(manager);
|
|
1868
2146
|
const motion = resolveAnimation(animation, "slide");
|
|
1869
|
-
const
|
|
2147
|
+
const resolvedMaxVisible = normalizeToastMaxVisible(maxVisible);
|
|
2148
|
+
const visibleItems = React.useMemo(() => {
|
|
2149
|
+
const positionItems = items.filter((item) => item.position === position);
|
|
2150
|
+
const visible = positionItems.slice(Math.max(0, positionItems.length - resolvedMaxVisible));
|
|
2151
|
+
return isToastTopPosition(position) ? [...visible].reverse() : visible;
|
|
2152
|
+
}, [items, position, resolvedMaxVisible]);
|
|
1870
2153
|
const renderedItems = useAnimatedToasts(visibleItems, motion.enabled ? motion.duration : 0);
|
|
1871
|
-
|
|
1872
|
-
|
|
2154
|
+
const setToastNode = useToastFlip(renderedItems, motion.enabled ? motion.duration : 0, motion.easing);
|
|
2155
|
+
const viewportNode = (jsx("div", { className: [className, `cc-toast-viewport--${position}`]
|
|
1873
2156
|
.filter(Boolean)
|
|
1874
|
-
.join(" "), role: "status", "aria-live": "polite", style: animationStyle(motion, style), ...props, children: renderedItems.map(({ item, state }) => (jsx(React.Fragment, { children: renderToast ? (renderToast(item, (id) => manager.dismiss(id), state)) : (jsxs("article", { className: `cc-toast cc-toast--${item.tone}`, "data-animation": motion.name, "data-
|
|
2157
|
+
.join(" "), role: "status", "aria-live": "polite", style: animationStyle(motion, style), ...props, children: renderedItems.map(({ item, motion: isMotionActive, state }, index) => (jsx(React.Fragment, { children: renderToast ? (renderToast(item, (id) => manager.dismiss(id), state)) : (jsxs("article", { className: `cc-toast cc-toast--${item.tone}`, "data-animation": motion.name, "data-motion": isMotionActive ? "true" : "false", "data-state": state, ref: (node) => setToastNode(item.id, node), style: {
|
|
2158
|
+
"--cc-toast-stack-index": index,
|
|
2159
|
+
}, children: [item.title ? (jsx("strong", { className: "cc-toast__title", children: item.title })) : null, jsx("span", { className: "cc-toast__message", children: item.message }), jsx("button", { "aria-label": "Dismiss toast", className: "cc-toast__close", type: "button", onClick: () => manager.dismiss(item.id), children: jsx(ClassIcon, { name: "x" }) })] })) }, item.id))) }));
|
|
2160
|
+
return portal
|
|
2161
|
+
? renderBodyPortal(viewportNode)
|
|
2162
|
+
: viewportNode;
|
|
1875
2163
|
}
|
|
1876
2164
|
function resolveTabsFlag(source, activeId) {
|
|
1877
2165
|
if (!source)
|
|
@@ -2265,6 +2553,212 @@ function TiltCard({ children, className = "cc-tilt-card", contentClassName = "cc
|
|
|
2265
2553
|
...style,
|
|
2266
2554
|
}, onPointerEnter: handlePointerEnter, onPointerLeave: handlePointerLeave, onPointerMove: handlePointerMove, ...props, children: jsxs("div", { className: surfaceClassName, children: [jsx("div", { className: contentClassName, children: children }), state.glare ? (jsx("span", { "aria-hidden": "true", className: glareClassName })) : null] }) }));
|
|
2267
2555
|
}
|
|
2556
|
+
function OrbitalSphere({ animated = true, className = "cc-orbital-sphere", cycleDuration = 12000, depth = 0.72, disabled = false, duration = 9000, itemClassName = "cc-orbital-sphere__item", itemContentClassName = "cc-orbital-sphere__item-content", itemSize = 72, items, onItemClick, radius = "50%", renderItem, shellClassName = "cc-orbital-sphere__shell", size = "360px", spread = 0.86, stageClassName = "cc-orbital-sphere__stage", style, visibleCount = 10, ...props }) {
|
|
2557
|
+
const state = React.useMemo(() => new OrbitalSphereController({
|
|
2558
|
+
animated,
|
|
2559
|
+
cycleDuration,
|
|
2560
|
+
depth,
|
|
2561
|
+
disabled,
|
|
2562
|
+
duration,
|
|
2563
|
+
itemSize,
|
|
2564
|
+
items,
|
|
2565
|
+
radius,
|
|
2566
|
+
size,
|
|
2567
|
+
spread,
|
|
2568
|
+
visibleCount,
|
|
2569
|
+
}).getState(), [
|
|
2570
|
+
animated,
|
|
2571
|
+
cycleDuration,
|
|
2572
|
+
depth,
|
|
2573
|
+
disabled,
|
|
2574
|
+
duration,
|
|
2575
|
+
itemSize,
|
|
2576
|
+
items,
|
|
2577
|
+
radius,
|
|
2578
|
+
size,
|
|
2579
|
+
spread,
|
|
2580
|
+
visibleCount,
|
|
2581
|
+
]);
|
|
2582
|
+
return (jsxs("div", { className: className, "data-animated": state.animated ? "true" : "false", "data-disabled": state.disabled ? "true" : "false", "data-overflow": state.items.length > state.visibleCount ? "true" : "false", style: { ...state.styleVars, ...style }, ...props, children: [jsx("span", { "aria-hidden": "true", className: shellClassName }), jsx("div", { className: stageClassName, children: state.items.map((item) => (jsx("button", { "aria-label": item.label, className: itemClassName, "data-tone": item.tone, disabled: state.disabled, style: {
|
|
2583
|
+
"--cc-orbital-index": item.index,
|
|
2584
|
+
...item.styleVars,
|
|
2585
|
+
}, type: "button", onClick: (event) => onItemClick?.(item, event), children: jsx("span", { className: itemContentClassName, children: renderItem?.(item) ?? item.content }) }, item.id))) })] }));
|
|
2586
|
+
}
|
|
2587
|
+
function HeightTransition({ children, className = "cc-height-transition", contentClassName = "cc-height-transition__content", duration = 220, easing, expanded = false, mode = "auto", style, ...props }) {
|
|
2588
|
+
const contentRef = React.useRef(null);
|
|
2589
|
+
const controller = React.useMemo(() => new HeightTransitionController({ duration, easing, expanded, mode }), []);
|
|
2590
|
+
const [state, setState] = React.useState(() => controller.getState());
|
|
2591
|
+
const [height, setHeight] = React.useState(0);
|
|
2592
|
+
React.useEffect(() => {
|
|
2593
|
+
setState(controller.update({ duration, easing, expanded, mode }));
|
|
2594
|
+
}, [controller, duration, easing, expanded, mode]);
|
|
2595
|
+
React.useLayoutEffect(() => {
|
|
2596
|
+
const element = contentRef.current;
|
|
2597
|
+
if (!element || typeof ResizeObserver === "undefined") {
|
|
2598
|
+
setHeight(element?.scrollHeight ?? 0);
|
|
2599
|
+
return undefined;
|
|
2600
|
+
}
|
|
2601
|
+
const observer = new ResizeObserver(() => setHeight(element.scrollHeight));
|
|
2602
|
+
observer.observe(element);
|
|
2603
|
+
setHeight(element.scrollHeight);
|
|
2604
|
+
return () => observer.disconnect();
|
|
2605
|
+
}, [children]);
|
|
2606
|
+
return (jsx("div", { className: className, "data-expanded": state.expanded, "data-mode": state.mode, style: {
|
|
2607
|
+
"--cc-height-transition-duration": `${state.duration}ms`,
|
|
2608
|
+
"--cc-height-transition-easing": state.easing,
|
|
2609
|
+
"--cc-height-transition-height": `${height}px`,
|
|
2610
|
+
...style,
|
|
2611
|
+
}, ...props, children: jsx("div", { className: contentClassName, ref: contentRef, children: children }) }));
|
|
2612
|
+
}
|
|
2613
|
+
function CodePreview({ className = "cc-code-preview", code, defaultExpanded = false, language = "Vue / TSX", onCopy, placement = "auto", strategy = "fixed", title = "示例源码", transitionDuration = 220, transitionEasing = "cubic-bezier(0.22, 0.8, 0.28, 1)", ...props }) {
|
|
2614
|
+
const rootRef = React.useRef(null);
|
|
2615
|
+
const panelRef = React.useRef(null);
|
|
2616
|
+
const controller = React.useMemo(() => new CodePreviewController({
|
|
2617
|
+
code,
|
|
2618
|
+
defaultExpanded,
|
|
2619
|
+
language,
|
|
2620
|
+
placement,
|
|
2621
|
+
title: String(title),
|
|
2622
|
+
}), []);
|
|
2623
|
+
const [state, setState] = React.useState(() => controller.getState());
|
|
2624
|
+
const [panelStyle, setPanelStyle] = React.useState();
|
|
2625
|
+
React.useEffect(() => {
|
|
2626
|
+
setState(controller.update({ code, language, placement, title: String(title) }));
|
|
2627
|
+
}, [code, controller, language, placement, title]);
|
|
2628
|
+
const updatePanelPosition = React.useCallback((estimate = false) => {
|
|
2629
|
+
const root = rootRef.current;
|
|
2630
|
+
const panel = panelRef.current;
|
|
2631
|
+
if (!root || (!panel && !estimate) || typeof window === "undefined")
|
|
2632
|
+
return undefined;
|
|
2633
|
+
const rect = root.getBoundingClientRect();
|
|
2634
|
+
const padding = 10;
|
|
2635
|
+
const gap = 10;
|
|
2636
|
+
const viewportWidth = document.documentElement.clientWidth || window.innerWidth;
|
|
2637
|
+
const viewportHeight = document.documentElement.clientHeight || window.innerHeight;
|
|
2638
|
+
const maxPanelHeight = Math.max(160, viewportHeight - padding * 2);
|
|
2639
|
+
const maxPanelWidth = Math.max(160, viewportWidth - padding * 2);
|
|
2640
|
+
const minPanelHeight = Math.min(160, maxPanelHeight);
|
|
2641
|
+
const panelContent = panel?.querySelector("pre");
|
|
2642
|
+
const measuredPanelHeight = Math.max(panel?.offsetHeight ?? 0, panel?.scrollHeight ?? 0, panelContent?.scrollHeight ?? 0, estimate ? 420 : 0);
|
|
2643
|
+
const preferredPanelHeight = Math.min(Math.max(160, measuredPanelHeight || 420), maxPanelHeight);
|
|
2644
|
+
const panelWidth = Math.min(Math.max(rect.width, panel?.offsetWidth || 720), maxPanelWidth);
|
|
2645
|
+
const availableBelow = Math.max(minPanelHeight, viewportHeight - rect.bottom - gap - padding);
|
|
2646
|
+
const availableAbove = Math.max(minPanelHeight, rect.top - gap - padding);
|
|
2647
|
+
const placementHeight = Math.min(preferredPanelHeight, Math.max(availableBelow, availableAbove));
|
|
2648
|
+
const next = controller.resolvePlacement({
|
|
2649
|
+
anchorBottom: rect.bottom,
|
|
2650
|
+
anchorLeft: rect.left,
|
|
2651
|
+
anchorRight: rect.right,
|
|
2652
|
+
anchorTop: rect.top,
|
|
2653
|
+
panelHeight: placementHeight,
|
|
2654
|
+
panelWidth,
|
|
2655
|
+
viewportHeight,
|
|
2656
|
+
viewportWidth,
|
|
2657
|
+
});
|
|
2658
|
+
setState(next);
|
|
2659
|
+
if (strategy !== "fixed") {
|
|
2660
|
+
setPanelStyle(undefined);
|
|
2661
|
+
return;
|
|
2662
|
+
}
|
|
2663
|
+
const clamp = (value, min, max) => Math.min(Math.max(min, value), max);
|
|
2664
|
+
const width = panelWidth;
|
|
2665
|
+
const maxLeft = Math.max(padding, viewportWidth - width - padding);
|
|
2666
|
+
const viewportPanelHeight = Math.min(preferredPanelHeight, maxPanelHeight);
|
|
2667
|
+
const maxTop = Math.max(padding, viewportHeight - viewportPanelHeight - padding);
|
|
2668
|
+
let left = clamp(rect.left, padding, maxLeft);
|
|
2669
|
+
let top = rect.bottom + gap;
|
|
2670
|
+
let maxHeight = Math.min(preferredPanelHeight, Math.max(minPanelHeight, viewportHeight - top - padding));
|
|
2671
|
+
let transformOrigin = "top left";
|
|
2672
|
+
if (next.resolvedPlacement === "top") {
|
|
2673
|
+
maxHeight = Math.min(preferredPanelHeight, availableAbove);
|
|
2674
|
+
top = Math.max(padding, rect.top - gap - maxHeight);
|
|
2675
|
+
transformOrigin = "bottom left";
|
|
2676
|
+
}
|
|
2677
|
+
else if (next.resolvedPlacement === "right") {
|
|
2678
|
+
left = clamp(rect.right + gap, padding, maxLeft);
|
|
2679
|
+
top = clamp(rect.top, padding, maxTop);
|
|
2680
|
+
maxHeight = viewportPanelHeight;
|
|
2681
|
+
transformOrigin = "top left";
|
|
2682
|
+
}
|
|
2683
|
+
else if (next.resolvedPlacement === "left") {
|
|
2684
|
+
left = clamp(rect.left - width - gap, padding, maxLeft);
|
|
2685
|
+
top = clamp(rect.top, padding, maxTop);
|
|
2686
|
+
maxHeight = viewportPanelHeight;
|
|
2687
|
+
transformOrigin = "top right";
|
|
2688
|
+
}
|
|
2689
|
+
setPanelStyle({
|
|
2690
|
+
left,
|
|
2691
|
+
maxHeight,
|
|
2692
|
+
top,
|
|
2693
|
+
transformOrigin,
|
|
2694
|
+
width,
|
|
2695
|
+
});
|
|
2696
|
+
return next;
|
|
2697
|
+
}, [controller, strategy]);
|
|
2698
|
+
const updatePanelPositionFromViewport = React.useCallback(() => {
|
|
2699
|
+
updatePanelPosition();
|
|
2700
|
+
}, [updatePanelPosition]);
|
|
2701
|
+
React.useLayoutEffect(() => {
|
|
2702
|
+
if (!state.expanded) {
|
|
2703
|
+
setPanelStyle(undefined);
|
|
2704
|
+
return undefined;
|
|
2705
|
+
}
|
|
2706
|
+
updatePanelPosition();
|
|
2707
|
+
window.addEventListener("resize", updatePanelPositionFromViewport);
|
|
2708
|
+
window.addEventListener("scroll", updatePanelPositionFromViewport, true);
|
|
2709
|
+
return () => {
|
|
2710
|
+
window.removeEventListener("resize", updatePanelPositionFromViewport);
|
|
2711
|
+
window.removeEventListener("scroll", updatePanelPositionFromViewport, true);
|
|
2712
|
+
};
|
|
2713
|
+
}, [
|
|
2714
|
+
code,
|
|
2715
|
+
state.expanded,
|
|
2716
|
+
updatePanelPosition,
|
|
2717
|
+
updatePanelPositionFromViewport,
|
|
2718
|
+
]);
|
|
2719
|
+
React.useEffect(() => {
|
|
2720
|
+
if (!state.expanded || typeof document === "undefined")
|
|
2721
|
+
return undefined;
|
|
2722
|
+
const close = () => {
|
|
2723
|
+
setPanelStyle(undefined);
|
|
2724
|
+
setState(controller.close());
|
|
2725
|
+
};
|
|
2726
|
+
const closeOnOutside = (event) => {
|
|
2727
|
+
const target = event.target;
|
|
2728
|
+
if (target &&
|
|
2729
|
+
(rootRef.current?.contains(target) ||
|
|
2730
|
+
panelRef.current?.contains(target)))
|
|
2731
|
+
return;
|
|
2732
|
+
close();
|
|
2733
|
+
};
|
|
2734
|
+
const closeOnEscape = (event) => {
|
|
2735
|
+
if (event.key === "Escape")
|
|
2736
|
+
close();
|
|
2737
|
+
};
|
|
2738
|
+
document.addEventListener("pointerdown", closeOnOutside, true);
|
|
2739
|
+
document.addEventListener("keydown", closeOnEscape, true);
|
|
2740
|
+
return () => {
|
|
2741
|
+
document.removeEventListener("pointerdown", closeOnOutside, true);
|
|
2742
|
+
document.removeEventListener("keydown", closeOnEscape, true);
|
|
2743
|
+
};
|
|
2744
|
+
}, [controller, state.expanded]);
|
|
2745
|
+
const copy = async () => {
|
|
2746
|
+
await (onCopy ? onCopy(code) : navigator.clipboard?.writeText(code));
|
|
2747
|
+
setState(controller.copied());
|
|
2748
|
+
window.setTimeout(() => setState(controller.resetCopied()), 1200);
|
|
2749
|
+
};
|
|
2750
|
+
const panel = (jsx("div", { className: "cc-code-preview__panel", "data-placement": state.resolvedPlacement, "data-strategy": strategy, "data-expanded": state.expanded, ref: panelRef, style: panelStyle, children: jsx(HeightTransition, { className: "cc-height-transition cc-code-preview__transition", contentClassName: "cc-height-transition__content cc-code-preview__panel-content", duration: transitionDuration, easing: transitionEasing, expanded: state.expanded, mode: "auto", children: jsx("pre", { children: jsx("code", { children: state.code }) }) }) }));
|
|
2751
|
+
return (jsxs("div", { className: className, "data-expanded": state.expanded, "data-placement": state.resolvedPlacement, "data-strategy": strategy, ref: rootRef, ...props, children: [jsxs("div", { className: "cc-code-preview__bar", children: [jsxs("div", { className: "cc-code-preview__meta", children: [jsx("span", { className: "cc-code-preview__title", children: title }), jsx("span", { className: "cc-code-preview__lang", children: state.language })] }), jsxs("div", { className: "cc-code-preview__actions", children: [jsx("button", { type: "button", onClick: () => {
|
|
2752
|
+
const next = controller.toggle();
|
|
2753
|
+
if (!next.expanded) {
|
|
2754
|
+
setPanelStyle(undefined);
|
|
2755
|
+
setState(next);
|
|
2756
|
+
return;
|
|
2757
|
+
}
|
|
2758
|
+
setState(updatePanelPosition(true) ?? next);
|
|
2759
|
+
window.requestAnimationFrame(() => updatePanelPosition());
|
|
2760
|
+
}, children: state.expanded ? "收起" : "展开" }), jsx("button", { type: "button", onClick: () => void copy(), children: state.copied ? "已复制" : "复制" })] })] }), strategy === "fixed" ? renderBodyPortal(panel) : panel] }));
|
|
2761
|
+
}
|
|
2268
2762
|
function QRCode({ value, size = 160, margin = 2, darkColor = "#1f1a2e", lightColor = "#ffffff", className = "cc-code cc-qr-code", errorCorrectionLevel = "M", errorText = "QR code unavailable", logoSrc, logoAlt = "QR code logo", logoSize = Math.round(size * 0.22), logoPadding = 6, logoRadius = 8, logoBackground = "#ffffff", renderError, ...props }) {
|
|
2269
2763
|
const [svg, setSvg] = React.useState("");
|
|
2270
2764
|
const [error, setError] = React.useState(null);
|
|
@@ -2700,7 +3194,7 @@ function signaturePointFromEvent(canvas, event) {
|
|
|
2700
3194
|
y: event.clientY - rect.top,
|
|
2701
3195
|
};
|
|
2702
3196
|
}
|
|
2703
|
-
const Signature = /*#__PURE__*/ React.forwardRef(function Signature({ backgroundColor, canvasClassName = "cc-signature__canvas", className = "cc-signature", clearText = getClassComponentsLocale().signatureClearText, disabled = false, errorClassName, exportType = "image/png", fieldClassName = "cc-field cc-signature-field", height = 220, initialValue, label, labelClassName = "cc-field__label", lineWidth = 3, name, penColor = "#
|
|
3197
|
+
const Signature = /*#__PURE__*/ React.forwardRef(function Signature({ backgroundColor, canvasClassName = "cc-signature__canvas", className = "cc-signature", clearText = getClassComponentsLocale().signatureClearText, disabled = false, errorClassName, exportType = "image/png", fieldClassName = "cc-field cc-signature-field", height = 220, initialValue, label, labelClassName = "cc-field__label", lineWidth = 3, name, penColor = "#1d2129", readOnly = false, rules, showToolbar = true, style, toolbarClassName = "cc-signature__toolbar", undoText = getClassComponentsLocale().signatureUndoText, validateOn, width = "100%", onChange, onClear, onEnd, onUndo, ...props }, ref) {
|
|
2704
3198
|
const formContext = React.useContext(FormContext);
|
|
2705
3199
|
const formState = useSyncExternalStore((listener) => formContext
|
|
2706
3200
|
? formContext.controller.subscribe(listener)
|
|
@@ -3483,6 +3977,28 @@ function Draggable({ axis = "xy", boundaryRef, children, className = "cc-draggab
|
|
|
3483
3977
|
? children({ dragging: state.dragging, position: state.position })
|
|
3484
3978
|
: children }));
|
|
3485
3979
|
}
|
|
3980
|
+
function readDragDropPreviewStyleVars(element) {
|
|
3981
|
+
if (!element || typeof window === "undefined")
|
|
3982
|
+
return {};
|
|
3983
|
+
const styles = window.getComputedStyle(element);
|
|
3984
|
+
const read = (name) => styles.getPropertyValue(name).trim();
|
|
3985
|
+
const slotDraggingBackground = read("--cc-drag-drop-slot-dragging-background");
|
|
3986
|
+
const slotDraggingBorderColor = read("--cc-drag-drop-slot-dragging-border-color");
|
|
3987
|
+
const previewBackground = read("--cc-drag-drop-preview-background");
|
|
3988
|
+
const previewBorderColor = read("--cc-drag-drop-preview-border-color");
|
|
3989
|
+
const values = {
|
|
3990
|
+
"--cc-drag-drop-preview-background": previewBackground && !previewBackground.includes("var(")
|
|
3991
|
+
? previewBackground
|
|
3992
|
+
: slotDraggingBackground,
|
|
3993
|
+
"--cc-drag-drop-preview-border-color": previewBorderColor && !previewBorderColor.includes("var(")
|
|
3994
|
+
? previewBorderColor
|
|
3995
|
+
: slotDraggingBorderColor,
|
|
3996
|
+
"--cc-drag-drop-preview-color": read("--cc-drag-drop-preview-color"),
|
|
3997
|
+
"--cc-drag-drop-preview-shadow": read("--cc-drag-drop-preview-shadow"),
|
|
3998
|
+
"--cc-drag-drop-motion-duration": read("--cc-drag-drop-motion-duration"),
|
|
3999
|
+
};
|
|
4000
|
+
return Object.fromEntries(Object.entries(values).filter(([, value]) => value.length > 0));
|
|
4001
|
+
}
|
|
3486
4002
|
function reorderDropItems(items, fromIndex, toIndex, mode) {
|
|
3487
4003
|
if (fromIndex < 0 || toIndex < 0 || fromIndex === toIndex)
|
|
3488
4004
|
return [...items];
|
|
@@ -3749,6 +4265,7 @@ function DragDropBoard({ columns, items, mode = "insert", renderItem, className
|
|
|
3749
4265
|
offsetY: event.clientY - rect.top,
|
|
3750
4266
|
originX: rect.left,
|
|
3751
4267
|
originY: rect.top,
|
|
4268
|
+
styleVars: readDragDropPreviewStyleVars(boardRef.current),
|
|
3752
4269
|
width: rect.width,
|
|
3753
4270
|
x: rect.left,
|
|
3754
4271
|
y: rect.top,
|
|
@@ -3796,6 +4313,7 @@ function DragDropBoard({ columns, items, mode = "insert", renderItem, className
|
|
|
3796
4313
|
}, onPointerUp: endDrag, onPointerCancel: cancelDrag, children: jsx("div", { className: "cc-drag-drop-board__item", children: renderItem(item, { dragging, over }) }) }, item.id));
|
|
3797
4314
|
}), preview
|
|
3798
4315
|
? renderBodyPortal(jsx("div", { "aria-hidden": "true", className: "cc-drag-drop-board__preview", "data-dropping": preview.dropping, "data-returning": preview.returning, ref: previewRef, style: {
|
|
4316
|
+
...preview.styleVars,
|
|
3799
4317
|
height: preview.height,
|
|
3800
4318
|
transform: `translate3d(${preview.x}px, ${preview.y}px, 0)`,
|
|
3801
4319
|
width: preview.width,
|
|
@@ -4650,7 +5168,9 @@ function MasonryVirtualList({ columns, data, estimateSize = 220, gap = 16, heade
|
|
|
4650
5168
|
item,
|
|
4651
5169
|
}) }, item.key))) })] }) }));
|
|
4652
5170
|
}
|
|
4653
|
-
|
|
5171
|
+
const CHAT_PREPEND_MOMENTUM_LOCK_MS = 420;
|
|
5172
|
+
const CHAT_PREPEND_STABILIZE_FRAMES = 24;
|
|
5173
|
+
function ChatVirtualListInner({ data, bottomBuffer = 8, bottomThreshold = 64, defaultStickToBottom = true, enablePullUp = false, estimateSize = 72, getKey, height = 420, itemClassName = "cc-chat-virtual-list__item", itemContent, listClassName = "cc-chat-virtual-list__inner", appendScrollBehavior = "smooth", pullUpClassName = "cc-chat-virtual-list__pull-up", pullUpContent, pullUpLoading = false, pullUpMinDuration = 420, pullUpThreshold = 48, stickToBottomOnAppend = true, stickToBottomOnUpdate = true, topLoadingClassName = "cc-chat-virtual-list__top-loading", topLoadingContent = "", topBuffer = 10, topThreshold = 96, className = "cc-chat-virtual-list", viewportClassName = "cc-chat-virtual-list__viewport", onPullUp, onReachTop, onRangeChange, style, ...props }, ref) {
|
|
4654
5174
|
const viewportRef = React.useRef(null);
|
|
4655
5175
|
const pullUpRef = React.useRef(null);
|
|
4656
5176
|
const observersRef = React.useRef(new Map());
|
|
@@ -4703,7 +5223,19 @@ function ChatVirtualListInner({ data, bottomBuffer = 8, bottomThreshold = 64, de
|
|
|
4703
5223
|
}
|
|
4704
5224
|
releaseTopLoadingLock();
|
|
4705
5225
|
}, [releaseTopLoadingLock]);
|
|
4706
|
-
const clearPendingPrependAnchor = React.useCallback(() => {
|
|
5226
|
+
const clearPendingPrependAnchor = React.useCallback((force = false) => {
|
|
5227
|
+
const pendingAnchor = pendingPrependAnchorRef.current;
|
|
5228
|
+
if (!force && pendingAnchor) {
|
|
5229
|
+
const remaining = pendingAnchor.releaseAt - Date.now();
|
|
5230
|
+
if (remaining > 0) {
|
|
5231
|
+
if (prependTimerRef.current !== undefined)
|
|
5232
|
+
window.clearTimeout(prependTimerRef.current);
|
|
5233
|
+
prependTimerRef.current = window.setTimeout(() => {
|
|
5234
|
+
clearPendingPrependAnchor(true);
|
|
5235
|
+
}, remaining);
|
|
5236
|
+
return;
|
|
5237
|
+
}
|
|
5238
|
+
}
|
|
4707
5239
|
pendingPrependAnchorRef.current = null;
|
|
4708
5240
|
if (prependStabilizeFrameRef.current !== undefined) {
|
|
4709
5241
|
window.cancelAnimationFrame(prependStabilizeFrameRef.current);
|
|
@@ -4735,19 +5267,23 @@ function ChatVirtualListInner({ data, bottomBuffer = 8, bottomThreshold = 64, de
|
|
|
4735
5267
|
if (prependStabilizeFrameRef.current !== undefined) {
|
|
4736
5268
|
window.cancelAnimationFrame(prependStabilizeFrameRef.current);
|
|
4737
5269
|
}
|
|
4738
|
-
let remainingFrames =
|
|
5270
|
+
let remainingFrames = CHAT_PREPEND_STABILIZE_FRAMES;
|
|
4739
5271
|
const stabilize = () => {
|
|
4740
|
-
|
|
5272
|
+
const pendingAnchor = pendingPrependAnchorRef.current;
|
|
5273
|
+
if (!pendingAnchor) {
|
|
4741
5274
|
prependStabilizeFrameRef.current = undefined;
|
|
4742
5275
|
return;
|
|
4743
5276
|
}
|
|
4744
5277
|
applyPendingPrependAnchor();
|
|
4745
5278
|
remainingFrames -= 1;
|
|
5279
|
+
if (remainingFrames <= 0 && pendingAnchor.releaseAt <= Date.now()) {
|
|
5280
|
+
prependStabilizeFrameRef.current = undefined;
|
|
5281
|
+
return;
|
|
5282
|
+
}
|
|
4746
5283
|
prependStabilizeFrameRef.current =
|
|
4747
5284
|
window.requestAnimationFrame(stabilize);
|
|
4748
5285
|
};
|
|
4749
|
-
prependStabilizeFrameRef.current =
|
|
4750
|
-
window.requestAnimationFrame(stabilize);
|
|
5286
|
+
prependStabilizeFrameRef.current = window.requestAnimationFrame(stabilize);
|
|
4751
5287
|
}, [applyPendingPrependAnchor]);
|
|
4752
5288
|
const scheduleTopLoadingFallback = React.useCallback(() => {
|
|
4753
5289
|
if (topLoadingFallbackTimerRef.current !== undefined) {
|
|
@@ -4894,6 +5430,7 @@ function ChatVirtualListInner({ data, bottomBuffer = 8, bottomThreshold = 64, de
|
|
|
4894
5430
|
anchorOffset: previousAnchor.offset,
|
|
4895
5431
|
measuredKeys: new Set(),
|
|
4896
5432
|
prependKeys: new Set(keys.slice(0, prependCount)),
|
|
5433
|
+
releaseAt: Date.now() + CHAT_PREPEND_MOMENTUM_LOCK_MS,
|
|
4897
5434
|
targetScrollTop: nextScrollTop,
|
|
4898
5435
|
}
|
|
4899
5436
|
: null;
|
|
@@ -5060,12 +5597,19 @@ function ChatVirtualListInner({ data, bottomBuffer = 8, bottomThreshold = 64, de
|
|
|
5060
5597
|
useEffect(() => {
|
|
5061
5598
|
onRangeChange?.({ endIndex: range.endIndex, startIndex: range.startIndex });
|
|
5062
5599
|
}, [onRangeChange, range.endIndex, range.startIndex]);
|
|
5600
|
+
const hasPendingKeySync = () => {
|
|
5601
|
+
const previousKeys = previousKeysRef.current;
|
|
5602
|
+
return (previousKeys.length !== keys.length ||
|
|
5603
|
+
previousKeys.some((itemKey, index) => !Object.is(itemKey, keys[index])));
|
|
5604
|
+
};
|
|
5063
5605
|
const observeItem = (index, key, element) => {
|
|
5064
5606
|
observersRef.current.get(key)?.disconnect();
|
|
5065
5607
|
observersRef.current.delete(key);
|
|
5066
5608
|
if (!element)
|
|
5067
5609
|
return;
|
|
5068
5610
|
const measure = () => {
|
|
5611
|
+
if (!pendingPrependAnchorRef.current && hasPendingKeySync())
|
|
5612
|
+
return;
|
|
5069
5613
|
const previousTotal = listControllerRef.current.getTotalSize();
|
|
5070
5614
|
const previousItem = listControllerRef.current.getItem(index);
|
|
5071
5615
|
const viewport = viewportRef.current;
|
|
@@ -5128,7 +5672,7 @@ function ChatVirtualListInner({ data, bottomBuffer = 8, bottomThreshold = 64, de
|
|
|
5128
5672
|
return (jsxs("div", { className: className, "data-top-loading": topLoadingPending ? "true" : undefined, style: {
|
|
5129
5673
|
"--cc-chat-virtual-list-height": resolvedHeight,
|
|
5130
5674
|
...style,
|
|
5131
|
-
}, ...props, children: [jsx(
|
|
5675
|
+
}, ...props, children: [jsx(Loading, { "aria-hidden": !topLoadingPending, className: topLoadingClassName, "data-active": topLoadingPending ? "true" : "false", role: topLoadingPending ? "status" : undefined, text: topLoadingContent }), jsxs("div", { className: viewportClassName, "data-top-loading": topLoadingPending ? "true" : undefined, ref: viewportRef, onScroll: (event) => {
|
|
5132
5676
|
if (pendingPrependAnchorRef.current) {
|
|
5133
5677
|
const stabilized = applyPendingPrependAnchor();
|
|
5134
5678
|
if (stabilized)
|
|
@@ -5875,5 +6419,5 @@ function LiveRoom({ chats = EMPTY_LIVE_CHATS, className = "cc-live-room", danmak
|
|
|
5875
6419
|
} }), jsx("button", { "aria-label": getClassComponentsLocale().liveRoomSendLabel, title: getClassComponentsLocale().liveRoomSendLabel, type: "button", onClick: send, children: jsx(LiveRoomIcon, { name: "send" }) })] })] })] }));
|
|
5876
6420
|
}
|
|
5877
6421
|
|
|
5878
|
-
export { Affix, Backtop, Badge, Barcode, Breadcrumb, Button, Calendar, CanvasEditor, CanvasImage, ChatVirtualList, Checkbox, Checked, ClassConfigProvider, ColorPicker, ComicReader, ConfigTable, Countdown, Danmaku, DatePicker, DateRangePicker, DesignEffect, DragDropBoard, Draggable, EllipsisText, Empty, Field, FilePreview, FloatingBall, FormProvider, GradientText, Input, LazyImage, LiveRoom, Loading, Marquee, MasonryVirtualList, Modal, MultiColumnPicker, NovelReader, NumberInput, Pagination, PasswordInput, Popconfirm, Popup, ProgressBar, QRCode, RadioGroup, Rating, RollingNumber, Select, Signature, Skeleton, SlideCaptcha, Swiper, Switch, Table, Tabs, Tag, Textarea, TiltCard, Timeline, ToastViewport, Tooltip, TypewriterText, Upload, VerificationCode, VideoDetailTransition, VideoPlayer, VirtualList, VirtualSelect, VirtualTable, defaultToastManager, useField, useForm, useFormState };
|
|
6422
|
+
export { Affix, Backtop, Badge, Barcode, Breadcrumb, Button, Calendar, CanvasEditor, CanvasImage, ChatTextarea, ChatVirtualList, Checkbox, Checked, ClassConfigProvider, CodePreview, ColorPicker, ComicReader, ConfigTable, Countdown, Danmaku, DatePicker, DateRangePicker, DesignEffect, DragDropBoard, Draggable, EllipsisText, Empty, Field, FilePreview, FloatingBall, FormProvider, GradientText, HeightTransition, Input, LazyImage, LiveRoom, Loading, Marquee, MasonryVirtualList, Menu, Modal, MultiColumnPicker, NovelReader, NumberInput, OrbitalSphere, Pagination, PasswordInput, Popconfirm, Popup, ProgressBar, QRCode, RadioGroup, Rating, RollingNumber, Select, Signature, Skeleton, SlideCaptcha, Swiper, Switch, Table, Tabs, Tag, Textarea, TiltCard, Timeline, ToastViewport, Tooltip, TypewriterText, Upload, VerificationCode, VideoDetailTransition, VideoPlayer, VirtualList, VirtualSelect, VirtualTable, defaultToastManager, useField, useForm, useFormState };
|
|
5879
6423
|
//# sourceMappingURL=index.js.map
|