@canvas-components/react-components 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { forwardRef, useRef, useEffect, useImperativeHandle, createContext, useState, useMemo, useLayoutEffect, useContext, useId } from 'react';
1
+ import * as React from 'react';
2
+ import { forwardRef, useRef, useEffect, useImperativeHandle, createContext, useState, useMemo, useLayoutEffect, useContext } from 'react';
2
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
4
  import { createPortal } from 'react-dom';
4
5
 
@@ -602,6 +603,770 @@ function resolvePopupSurfaceRect(element, contentScale = 1) {
602
603
  };
603
604
  }
604
605
 
606
+ // src/components/virtual-list/style.css
607
+ styleInject('@import "../../styles/variables.css";\n.canvas-react-virtual-list {\n position: relative;\n overflow-y: auto;\n}\n.canvas-react-virtual-list-inner {\n position: relative;\n min-width: 100%;\n}\n.canvas-react-virtual-list-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 0 11px;\n color: #9ca3af;\n font-size: var(--canvas-react-font-size);\n}\n');
608
+ var ReactVirtualList = forwardRef(function ReactVirtualListInner(props, ref) {
609
+ const {
610
+ className,
611
+ empty,
612
+ height,
613
+ innerClassName,
614
+ itemHeight,
615
+ itemKey,
616
+ items,
617
+ overscan = 2,
618
+ renderItem,
619
+ style,
620
+ virtual = true
621
+ } = props;
622
+ const hostRef = useRef(null);
623
+ const [scrollTop, setScrollTop] = useState(0);
624
+ const useVirtual = virtual && items.length * itemHeight > height;
625
+ const startIndex = useVirtual ? Math.max(0, Math.floor(scrollTop / itemHeight) - overscan) : 0;
626
+ const endIndex = useVirtual ? Math.min(
627
+ items.length - 1,
628
+ Math.ceil((scrollTop + height) / itemHeight) + overscan
629
+ ) : items.length - 1;
630
+ const visibleItems = useMemo(
631
+ () => items.slice(startIndex, endIndex + 1),
632
+ [endIndex, items, startIndex]
633
+ );
634
+ useImperativeHandle(ref, () => ({
635
+ scrollToIndex: (index) => {
636
+ const element = hostRef.current;
637
+ if (!element || index < 0) {
638
+ return;
639
+ }
640
+ const itemTop = index * itemHeight;
641
+ const itemBottom = itemTop + itemHeight;
642
+ const viewportTop = element.scrollTop;
643
+ const viewportBottom = viewportTop + height;
644
+ if (itemTop < viewportTop) {
645
+ element.scrollTop = itemTop;
646
+ return;
647
+ }
648
+ if (itemBottom > viewportBottom) {
649
+ element.scrollTop = itemBottom - height;
650
+ }
651
+ },
652
+ element: hostRef.current
653
+ }));
654
+ return /* @__PURE__ */ jsx(
655
+ "div",
656
+ {
657
+ ref: hostRef,
658
+ className: joinClassNames(`${REACT_COMPONENT_PREFIX}-virtual-list`, className),
659
+ style: { height, ...style },
660
+ onScroll: (event) => {
661
+ setScrollTop(event.currentTarget.scrollTop);
662
+ },
663
+ children: items.length === 0 ? /* @__PURE__ */ jsx("div", { className: `${REACT_COMPONENT_PREFIX}-virtual-list-empty`, children: empty ?? "\u6682\u65E0\u6570\u636E" }) : /* @__PURE__ */ jsx(
664
+ "div",
665
+ {
666
+ className: joinClassNames(
667
+ `${REACT_COMPONENT_PREFIX}-virtual-list-inner`,
668
+ innerClassName
669
+ ),
670
+ style: { height: items.length * itemHeight },
671
+ children: visibleItems.map((item, index) => {
672
+ const itemIndex = startIndex + index;
673
+ return renderItem(item, itemIndex, {
674
+ style: useVirtual ? {
675
+ position: "absolute",
676
+ top: itemIndex * itemHeight,
677
+ left: 0,
678
+ right: 0,
679
+ height: itemHeight
680
+ } : {
681
+ height: itemHeight
682
+ }
683
+ });
684
+ })
685
+ }
686
+ )
687
+ }
688
+ );
689
+ });
690
+
691
+ // src/components/select/style.css
692
+ styleInject('@import "../../styles/variables.css";\n.canvas-react-select-wrap {\n position: relative;\n display: inline-flex;\n width: 100%;\n height: 100%;\n}\n.canvas-react-select {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: var(--canvas-react-control-height);\n padding: var(--canvas-react-control-padding-block, 0px) var(--canvas-react-control-padding-inline, 11px);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n outline: none;\n cursor: pointer;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-select-input-wrap {\n flex: 1 1 auto;\n width: 100%;\n height: 100%;\n border: none;\n background: transparent;\n box-shadow: none;\n}\n.canvas-react-select .canvas-react-input-affix-wrapper {\n height: 100%;\n min-height: 0;\n}\n.canvas-react-select-input-wrap:hover,\n.canvas-react-select-input-wrap:focus-within {\n border-color: transparent;\n box-shadow: none;\n}\n.canvas-react-select-input {\n width: 100%;\n min-width: 0;\n height: 100%;\n padding: 0;\n line-height: normal;\n}\n.canvas-react-select-input::placeholder {\n color: #9ca3af;\n}\n.canvas-react-select:hover {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-select:focus {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-select-open {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-select-disabled {\n color: #9ca3af;\n background: #fafafa;\n cursor: not-allowed;\n}\n.canvas-react-select-actions {\n position: relative;\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n width: 1em;\n min-width: 12px;\n height: 1em;\n min-height: 12px;\n margin-left: max(6px, calc(var(--canvas-react-control-padding-inline, 11px) * 0.5));\n}\n.canvas-react-select-arrow {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 0.5em;\n height: 0.5em;\n min-width: 6px;\n min-height: 6px;\n border-right: 1.5px solid var(--canvas-react-color-text-muted);\n border-bottom: 1.5px solid var(--canvas-react-color-text-muted);\n transform: translate(-50%, -58%) rotate(45deg);\n opacity: 1;\n transition:\n opacity 0.18s ease,\n transform 0.18s ease,\n border-color 0.18s ease;\n}\n.canvas-react-select:hover .canvas-react-select-arrow,\n.canvas-react-select-open .canvas-react-select-arrow {\n border-color: #6b7280;\n}\n.canvas-react-select-arrow-open {\n border-color: #6b7280;\n transform: translate(-50%, -42%) rotate(225deg);\n}\n.canvas-react-select-clear {\n position: absolute;\n top: 50%;\n left: 50%;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 12px;\n height: 12px;\n padding: 0;\n border: none;\n background: transparent;\n color: #9ca3af;\n opacity: 0;\n pointer-events: none;\n cursor: pointer;\n transform: translate(-50%, -50%) rotate(0deg);\n transition:\n color 0.2s ease,\n opacity 0.2s ease,\n transform 0.18s ease;\n}\n.canvas-react-select-clear:hover {\n color: #6b7280;\n transform: translate(-50%, -50%) rotate(90deg);\n}\n.canvas-react-select:hover .canvas-react-select-clear,\n.canvas-react-select-open .canvas-react-select-clear,\n.canvas-react-select:focus-within .canvas-react-select-clear {\n opacity: 1;\n pointer-events: auto;\n}\n.canvas-react-select:hover .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-select-open .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-select:focus-within .canvas-react-select-actions-clearable .canvas-react-select-arrow {\n opacity: 0;\n}\n.canvas-react-select-clear-icon,\n.canvas-react-select-clear-icon::before {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 8px;\n height: 1.25px;\n margin-top: -0.625px;\n margin-left: -4px;\n border-radius: 999px;\n background: currentColor;\n content: "";\n}\n.canvas-react-select-clear-icon {\n transform: rotate(45deg);\n}\n.canvas-react-select-clear-icon::before {\n transform: rotate(90deg);\n}\n.canvas-react-select-dropdown {\n padding: 4px;\n}\n.canvas-react-select-list {\n position: relative;\n overflow-y: auto;\n}\n.canvas-react-select-list-inner {\n position: relative;\n}\n.canvas-react-select-option {\n display: flex;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n padding: 0 11px;\n border-radius: var(--canvas-react-radius-sm);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n cursor: pointer;\n}\n.canvas-react-select-option:hover,\n.canvas-react-select-option-active {\n background: var(--canvas-react-color-bg-hover);\n}\n.canvas-react-select-option-selected {\n background: var(--canvas-react-color-bg-active);\n}\n.canvas-react-select-option-searching {\n color: var(--canvas-react-color-text);\n}\n.canvas-react-select-option-searching:hover,\n.canvas-react-select-option-searching.canvas-react-select-option-active {\n background: var(--canvas-react-color-bg-active);\n}\n.canvas-react-select-option-disabled {\n color: #9ca3af;\n cursor: not-allowed;\n}\n.canvas-react-select-option-highlight {\n color: var(--canvas-react-color-primary);\n font-weight: 600;\n}\n.canvas-react-select-option-disabled .canvas-react-select-option-highlight {\n color: inherit;\n}\n.canvas-react-select-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 0 11px;\n color: #9ca3af;\n font-size: var(--canvas-react-font-size);\n}\n');
693
+ var ReactSelect = forwardRef(
694
+ function ReactSelect2(props, ref) {
695
+ const {
696
+ autoFocus,
697
+ allowCustomValue = false,
698
+ className,
699
+ disabled,
700
+ filterOption,
701
+ onBlur,
702
+ onChange,
703
+ onInputValueChange,
704
+ onPressEnter,
705
+ onFocus,
706
+ onKeyDown,
707
+ options,
708
+ optionHeight = 32,
709
+ listHeight = 224,
710
+ placeholder,
711
+ popupClassName,
712
+ popupZIndex,
713
+ allowClear = true,
714
+ showArrow = true,
715
+ showSearch = false,
716
+ style,
717
+ value,
718
+ virtual = true,
719
+ ...restProps
720
+ } = props;
721
+ const triggerRef = useRef(null);
722
+ const inputRef = useRef(null);
723
+ const listRef = useRef(null);
724
+ const skipFocusOpenRef = useRef(false);
725
+ const [open, setOpen] = useState(false);
726
+ const selectedIndex = useMemo(
727
+ () => options.findIndex(
728
+ (option) => String(option.value) === String(value ?? "")
729
+ ),
730
+ [options, value]
731
+ );
732
+ const selectedOption = selectedIndex >= 0 ? options[selectedIndex] : void 0;
733
+ const [keyword, setKeyword] = useState("");
734
+ const [searching, setSearching] = useState(false);
735
+ const searchKeyword = searching ? keyword : "";
736
+ const filteredOptions = useMemo(
737
+ () => filterSelectOptions(options, searchKeyword, showSearch, filterOption),
738
+ [filterOption, options, searchKeyword, showSearch]
739
+ );
740
+ const [activeIndex, setActiveIndex] = useState(() => {
741
+ return selectedIndex >= 0 ? selectedIndex : 0;
742
+ });
743
+ useImperativeHandle(ref, () => inputRef.current);
744
+ useEffect(() => {
745
+ if (autoFocus) {
746
+ inputRef.current?.focus();
747
+ }
748
+ }, [autoFocus]);
749
+ useLayoutEffect(() => {
750
+ if (open && showSearch && !searching) {
751
+ inputRef.current?.select();
752
+ }
753
+ }, [open, searching, showSearch]);
754
+ useEffect(() => {
755
+ const nextIndex = filteredOptions.findIndex(
756
+ (option) => String(option.value) === String(value ?? "")
757
+ );
758
+ setActiveIndex(nextIndex >= 0 ? nextIndex : 0);
759
+ }, [filteredOptions, value]);
760
+ useEffect(() => {
761
+ if (!open) {
762
+ return;
763
+ }
764
+ listRef.current?.scrollToIndex(activeIndex);
765
+ }, [activeIndex, listHeight, open, optionHeight]);
766
+ const selectOption = (option, trigger) => {
767
+ onChange?.(String(option.value), { trigger });
768
+ setKeyword(option.label);
769
+ setSearching(false);
770
+ setOpen(false);
771
+ inputRef.current?.focus();
772
+ };
773
+ const hasValue = value != null && String(value).length > 0;
774
+ const showClear = allowClear && !disabled && hasValue;
775
+ const handleClear = (event) => {
776
+ event.preventDefault();
777
+ event.stopPropagation();
778
+ skipFocusOpenRef.current = true;
779
+ setKeyword("");
780
+ setSearching(false);
781
+ setOpen(false);
782
+ onChange?.("", { trigger: "clear" });
783
+ inputRef.current?.blur();
784
+ };
785
+ const openSelect = () => {
786
+ setKeyword(
787
+ resolveSelectKeywordOnOpen(
788
+ selectedOption?.label ?? (allowCustomValue ? String(value ?? "") : void 0)
789
+ )
790
+ );
791
+ setSearching(false);
792
+ setOpen(true);
793
+ };
794
+ return /* @__PURE__ */ jsxs("span", { className: `${REACT_COMPONENT_PREFIX}-select-wrap`, children: [
795
+ /* @__PURE__ */ jsxs(
796
+ "div",
797
+ {
798
+ ref: triggerRef,
799
+ className: joinClassNames(
800
+ `${REACT_COMPONENT_PREFIX}-select`,
801
+ open && `${REACT_COMPONENT_PREFIX}-select-open`,
802
+ disabled && `${REACT_COMPONENT_PREFIX}-select-disabled`,
803
+ className
804
+ ),
805
+ style,
806
+ onClick: (event) => {
807
+ if (disabled) {
808
+ return;
809
+ }
810
+ if (event.target?.closest(
811
+ `.${REACT_COMPONENT_PREFIX}-select-clear`
812
+ )) {
813
+ return;
814
+ }
815
+ if (event.target?.closest(
816
+ `.${REACT_COMPONENT_PREFIX}-select-arrow`
817
+ )) {
818
+ return;
819
+ }
820
+ inputRef.current?.focus();
821
+ if (!open) {
822
+ openSelect();
823
+ }
824
+ },
825
+ children: [
826
+ /* @__PURE__ */ jsx(
827
+ ReactInput,
828
+ {
829
+ ...restProps,
830
+ ref: inputRef,
831
+ allowClear: false,
832
+ disabled,
833
+ readOnly: !showSearch,
834
+ value: open && showSearch ? keyword : selectedOption?.label ?? (allowCustomValue ? String(value ?? "") : ""),
835
+ className: joinClassNames(`${REACT_COMPONENT_PREFIX}-select-input`),
836
+ wrapperClassName: `${REACT_COMPONENT_PREFIX}-select-input-wrap`,
837
+ placeholder,
838
+ onFocus: (event) => {
839
+ if (skipFocusOpenRef.current) {
840
+ skipFocusOpenRef.current = false;
841
+ onFocus?.(event);
842
+ return;
843
+ }
844
+ if (!open) {
845
+ openSelect();
846
+ }
847
+ onFocus?.(event);
848
+ },
849
+ onBlur: (event) => {
850
+ setOpen(false);
851
+ if ((!keyword.trim() || !showSearch) && selectedOption) {
852
+ setKeyword(selectedOption.label);
853
+ }
854
+ onBlur?.(event);
855
+ },
856
+ onChange: (event) => {
857
+ if (!showSearch) {
858
+ return;
859
+ }
860
+ setKeyword(event.target.value);
861
+ setSearching(true);
862
+ onInputValueChange?.(event.target.value);
863
+ setOpen(true);
864
+ },
865
+ onKeyDown: (event) => {
866
+ onKeyDown?.(event);
867
+ if (event.defaultPrevented) {
868
+ return;
869
+ }
870
+ if (disabled) {
871
+ return;
872
+ }
873
+ if (event.key === "ArrowDown") {
874
+ event.preventDefault();
875
+ if (!open) {
876
+ openSelect();
877
+ return;
878
+ }
879
+ setActiveIndex(
880
+ (prev) => Math.min(prev + 1, Math.max(filteredOptions.length - 1, 0))
881
+ );
882
+ return;
883
+ }
884
+ if (event.key === "ArrowUp") {
885
+ event.preventDefault();
886
+ if (!open) {
887
+ openSelect();
888
+ return;
889
+ }
890
+ setActiveIndex((prev) => Math.max(prev - 1, 0));
891
+ return;
892
+ }
893
+ if (event.key === "Enter") {
894
+ event.preventDefault();
895
+ if (!open) {
896
+ openSelect();
897
+ return;
898
+ }
899
+ const targetOption = resolveSelectEnterOption(filteredOptions);
900
+ if (targetOption && !targetOption.disabled) {
901
+ selectOption(targetOption, "keyboard");
902
+ } else if (allowCustomValue && keyword.trim()) {
903
+ void Promise.resolve(onPressEnter?.(keyword.trim()));
904
+ }
905
+ return;
906
+ }
907
+ if (event.key === "Escape") {
908
+ setKeyword(selectedOption?.label ?? "");
909
+ setSearching(false);
910
+ setOpen(false);
911
+ }
912
+ }
913
+ }
914
+ ),
915
+ showClear || showArrow ? /* @__PURE__ */ jsxs(
916
+ "span",
917
+ {
918
+ className: joinClassNames(
919
+ `${REACT_COMPONENT_PREFIX}-select-actions`,
920
+ showClear && `${REACT_COMPONENT_PREFIX}-select-actions-clearable`
921
+ ),
922
+ children: [
923
+ showClear ? /* @__PURE__ */ jsx(
924
+ "button",
925
+ {
926
+ type: "button",
927
+ className: `${REACT_COMPONENT_PREFIX}-select-clear`,
928
+ "aria-label": "\u6E05\u7A7A",
929
+ tabIndex: -1,
930
+ onMouseDown: (event) => {
931
+ event.preventDefault();
932
+ event.stopPropagation();
933
+ },
934
+ onClick: handleClear,
935
+ children: /* @__PURE__ */ jsx(
936
+ "span",
937
+ {
938
+ className: `${REACT_COMPONENT_PREFIX}-select-clear-icon`
939
+ }
940
+ )
941
+ }
942
+ ) : null,
943
+ showArrow ? /* @__PURE__ */ jsx(
944
+ "span",
945
+ {
946
+ className: joinClassNames(
947
+ `${REACT_COMPONENT_PREFIX}-select-arrow`,
948
+ open && `${REACT_COMPONENT_PREFIX}-select-arrow-open`
949
+ )
950
+ }
951
+ ) : null
952
+ ]
953
+ }
954
+ ) : null
955
+ ]
956
+ }
957
+ ),
958
+ /* @__PURE__ */ jsx(
959
+ ReactPopup,
960
+ {
961
+ open,
962
+ anchorRef: triggerRef,
963
+ matchAnchorWidth: true,
964
+ zIndex: popupZIndex,
965
+ surfaceClassName: joinClassNames(
966
+ `${REACT_COMPONENT_PREFIX}-select-dropdown`,
967
+ popupClassName
968
+ ),
969
+ onOpenChange: setOpen,
970
+ children: /* @__PURE__ */ jsx(
971
+ ReactVirtualList,
972
+ {
973
+ ref: listRef,
974
+ items: filteredOptions,
975
+ height: Math.min(
976
+ listHeight,
977
+ Math.max(filteredOptions.length, 1) * optionHeight
978
+ ),
979
+ itemHeight: optionHeight,
980
+ virtual,
981
+ className: `${REACT_COMPONENT_PREFIX}-select-list`,
982
+ innerClassName: `${REACT_COMPONENT_PREFIX}-select-list-inner`,
983
+ empty: /* @__PURE__ */ jsx("div", { className: `${REACT_COMPONENT_PREFIX}-select-empty`, children: "\u6682\u65E0\u6570\u636E" }),
984
+ itemKey: (option) => String(option.value),
985
+ renderItem: (option, optionIndex, meta) => {
986
+ const isSelected = String(option.value) === String(value ?? "");
987
+ const isActive = optionIndex === activeIndex;
988
+ const isSearching = showSearch && searchKeyword.trim().length > 0;
989
+ return /* @__PURE__ */ jsx(
990
+ "div",
991
+ {
992
+ className: joinClassNames(
993
+ `${REACT_COMPONENT_PREFIX}-select-option`,
994
+ isSelected && `${REACT_COMPONENT_PREFIX}-select-option-selected`,
995
+ isActive && `${REACT_COMPONENT_PREFIX}-select-option-active`,
996
+ isSearching && `${REACT_COMPONENT_PREFIX}-select-option-searching`,
997
+ option.disabled && `${REACT_COMPONENT_PREFIX}-select-option-disabled`
998
+ ),
999
+ style: meta.style,
1000
+ onMouseDown: (event) => {
1001
+ event.preventDefault();
1002
+ },
1003
+ onMouseEnter: () => {
1004
+ setActiveIndex(optionIndex);
1005
+ },
1006
+ onClick: () => {
1007
+ if (option.disabled) {
1008
+ return;
1009
+ }
1010
+ selectOption(option, "mouse");
1011
+ },
1012
+ children: renderSelectOptionLabel(
1013
+ option.label,
1014
+ showSearch ? searchKeyword : ""
1015
+ )
1016
+ },
1017
+ String(option.value)
1018
+ );
1019
+ }
1020
+ }
1021
+ )
1022
+ }
1023
+ )
1024
+ ] });
1025
+ }
1026
+ );
1027
+ function filterSelectOptions(options, input, showSearch, filterOption) {
1028
+ if (!showSearch) {
1029
+ return options;
1030
+ }
1031
+ const search = input.trim();
1032
+ if (!search) {
1033
+ return options;
1034
+ }
1035
+ if (filterOption) {
1036
+ return options.filter((option) => filterOption(search, option));
1037
+ }
1038
+ const normalizedSearch = search.toLowerCase();
1039
+ return options.filter((option) => {
1040
+ return option.label.toLowerCase().includes(normalizedSearch) || String(option.value).toLowerCase().includes(normalizedSearch);
1041
+ });
1042
+ }
1043
+ function resolveSelectEnterOption(options) {
1044
+ return options.find((option) => !option.disabled);
1045
+ }
1046
+ function resolveSelectKeywordOnOpen(selectedLabel) {
1047
+ return selectedLabel ?? "";
1048
+ }
1049
+ function splitSelectOptionLabel(label, input) {
1050
+ const search = input.trim();
1051
+ if (!search) {
1052
+ return [{ text: label, highlighted: false }];
1053
+ }
1054
+ const matcher = new RegExp(escapeRegExp(search), "gi");
1055
+ const parts = [];
1056
+ let cursor = 0;
1057
+ let match = matcher.exec(label);
1058
+ while (match) {
1059
+ if (match.index > cursor) {
1060
+ parts.push({
1061
+ text: label.slice(cursor, match.index),
1062
+ highlighted: false
1063
+ });
1064
+ }
1065
+ parts.push({ text: match[0], highlighted: true });
1066
+ cursor = match.index + match[0].length;
1067
+ match = matcher.exec(label);
1068
+ }
1069
+ if (cursor < label.length) {
1070
+ parts.push({ text: label.slice(cursor), highlighted: false });
1071
+ }
1072
+ return parts.length > 0 ? parts : [{ text: label, highlighted: false }];
1073
+ }
1074
+ function renderSelectOptionLabel(label, input) {
1075
+ return splitSelectOptionLabel(label, input).map(
1076
+ (part, index) => part.highlighted ? /* @__PURE__ */ jsx(
1077
+ "span",
1078
+ {
1079
+ className: `${REACT_COMPONENT_PREFIX}-select-option-highlight`,
1080
+ children: part.text
1081
+ },
1082
+ `${part.text}-${index}`
1083
+ ) : part.text
1084
+ );
1085
+ }
1086
+ function escapeRegExp(value) {
1087
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1088
+ }
1089
+ var operators = [
1090
+ { label: "\u4E0D\u7B5B\u9009", value: "none" },
1091
+ { label: "\u7B49\u4E8E", value: "eq" },
1092
+ { label: "\u4E0D\u7B49\u4E8E", value: "neq" },
1093
+ { label: "\u5927\u4E8E", value: "gt" },
1094
+ { label: "\u5927\u4E8E\u7B49\u4E8E", value: "gte" },
1095
+ { label: "\u5C0F\u4E8E", value: "lt" },
1096
+ { label: "\u5C0F\u4E8E\u7B49\u4E8E", value: "lte" },
1097
+ { label: "\u533A\u95F4", value: "between" },
1098
+ { label: "\u4E0D\u5728\u533A\u95F4", value: "notBetween" },
1099
+ { label: "\u5F00\u5934\u662F", value: "startsWith" },
1100
+ { label: "\u5F00\u5934\u4E0D\u662F", value: "notStartsWith" },
1101
+ { label: "\u7ED3\u5C3E\u662F", value: "endsWith" },
1102
+ { label: "\u7ED3\u5C3E\u4E0D\u662F", value: "notEndsWith" },
1103
+ { label: "\u5305\u542B", value: "includes" },
1104
+ { label: "\u4E0D\u5305\u542B", value: "notIncludes" },
1105
+ { label: "\u4E3A\u7A7A", value: "blank" },
1106
+ { label: "\u4E0D\u4E3A\u7A7A", value: "notBlank" }
1107
+ ];
1108
+ function ReactFilterPanel(props) {
1109
+ const { request } = props;
1110
+ const [draft, setDraft] = useState(request?.value ?? null);
1111
+ const [tab, setTab] = useState(resolveTab(request?.value));
1112
+ const [options, setOptions] = useState(request?.options ?? []);
1113
+ const [loading, setLoading] = useState(Boolean(request?.loadOptions));
1114
+ useEffect(() => {
1115
+ setDraft(request?.value ?? null);
1116
+ setTab(resolveTab(request?.value));
1117
+ setOptions(request?.options ?? []);
1118
+ setLoading(Boolean(request?.loadOptions));
1119
+ }, [request]);
1120
+ useEffect(() => {
1121
+ if (!request?.loadOptions) return;
1122
+ const controller = new AbortController();
1123
+ setLoading(true);
1124
+ void Promise.resolve(request.loadOptions(controller.signal)).then((items) => {
1125
+ if (!controller.signal.aborted) {
1126
+ setOptions(items);
1127
+ setLoading(false);
1128
+ }
1129
+ }).catch(() => {
1130
+ if (!controller.signal.aborted) {
1131
+ setOptions([]);
1132
+ setLoading(false);
1133
+ }
1134
+ });
1135
+ return () => controller.abort();
1136
+ }, [request]);
1137
+ const visibleOptions = useMemo(() => {
1138
+ const values = options.filter((item) => item.kind !== "all");
1139
+ const keyword = draft?.keyword.trim().toLowerCase() ?? "";
1140
+ if (!keyword) return values;
1141
+ return values.filter((item) => {
1142
+ const label = item.label.toLowerCase();
1143
+ const value = item.value.toLowerCase();
1144
+ return draft?.searchExact ? label === keyword || value === keyword : label.includes(keyword) || value.includes(keyword);
1145
+ });
1146
+ }, [draft?.keyword, draft?.searchExact, options]);
1147
+ if (!request || !draft) return null;
1148
+ const selected = new Set(draft.selectedKeys ?? []);
1149
+ const visibleKeys = visibleOptions.map((item) => item.value);
1150
+ const selectedCount = visibleKeys.filter((value) => selected.has(value)).length;
1151
+ const allChecked = visibleKeys.length > 0 && selectedCount === visibleKeys.length;
1152
+ const allCount = request.options.find((item) => item.kind === "all")?.count ?? visibleOptions.filter((item) => item.kind === "value").reduce((sum, item) => sum + item.count, 0);
1153
+ const update = (patch) => setDraft((current) => ({ ...current ?? request.value, ...patch }));
1154
+ const toggle = (keys, checked) => {
1155
+ const next = new Set(draft.selectedKeys ?? []);
1156
+ keys.forEach((key) => checked ? next.add(key) : next.delete(key));
1157
+ const value = { ...draft, filterType: "value", selectedKeys: Array.from(next) };
1158
+ setDraft(value);
1159
+ if (request.filterOptionImmediateApply) request.onApply(value);
1160
+ };
1161
+ const apply = () => {
1162
+ request.onApply({ ...draft, filterType: tab });
1163
+ request.onClose();
1164
+ };
1165
+ return /* @__PURE__ */ jsx(
1166
+ ReactPopup,
1167
+ {
1168
+ open: true,
1169
+ anchorRect: request.anchorRect,
1170
+ offset: 8,
1171
+ matchAnchorWidth: false,
1172
+ minWidth: 300,
1173
+ onOpenChange: (open) => {
1174
+ if (!open) request.onClose();
1175
+ },
1176
+ surfaceStyle: { width: 300, height: 460, padding: 12, overflow: "hidden", boxSizing: "border-box" },
1177
+ children: /* @__PURE__ */ jsxs("div", { style: { height: "100%", display: "flex", flexDirection: "column", minHeight: 0 }, children: [
1178
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 14, fontWeight: 600, color: "#111827" }, children: [
1179
+ request.texts.title,
1180
+ " \xB7 ",
1181
+ request.columnTitle
1182
+ ] }),
1183
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 8, marginTop: 12 }, children: [
1184
+ /* @__PURE__ */ jsx("button", { type: "button", style: tabStyle(tab === "value"), onClick: () => {
1185
+ setTab("value");
1186
+ update({ filterType: "value" });
1187
+ }, children: request.texts.valueFilterTab }),
1188
+ /* @__PURE__ */ jsx("button", { type: "button", style: tabStyle(tab === "condition"), onClick: () => {
1189
+ setTab("condition");
1190
+ update({ filterType: "condition" });
1191
+ }, children: request.texts.conditionFilterTab })
1192
+ ] }),
1193
+ tab === "value" ? /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 12, marginTop: 12, minHeight: 290, alignContent: "start", flex: "1 1 auto" }, children: [
1194
+ /* @__PURE__ */ jsx(
1195
+ ReactInput,
1196
+ {
1197
+ value: draft.keyword,
1198
+ placeholder: request.texts.searchPlaceholder,
1199
+ onChange: (event) => update({ keyword: event.target.value, filterType: "value" }),
1200
+ onPressEnter: apply,
1201
+ style: { width: "100%" }
1202
+ }
1203
+ ),
1204
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, paddingBottom: 8, borderBottom: "1px solid #f0f0f0" }, children: [
1205
+ /* @__PURE__ */ jsxs("label", { style: checkLabelStyle, children: [
1206
+ /* @__PURE__ */ jsx(
1207
+ ReactCheckbox,
1208
+ {
1209
+ checked: allChecked,
1210
+ indeterminate: selectedCount > 0 && !allChecked,
1211
+ onChange: (event) => toggle(visibleKeys, !!event.target.checked)
1212
+ }
1213
+ ),
1214
+ /* @__PURE__ */ jsxs("span", { children: [
1215
+ request.texts.allOptionLabel,
1216
+ " (",
1217
+ allCount,
1218
+ ")"
1219
+ ] })
1220
+ ] }),
1221
+ /* @__PURE__ */ jsxs("label", { style: checkLabelStyle, children: [
1222
+ /* @__PURE__ */ jsx(
1223
+ ReactCheckbox,
1224
+ {
1225
+ checked: !!draft.searchExact,
1226
+ onChange: (event) => update({ searchExact: !!event.target.checked, filterType: "value" })
1227
+ }
1228
+ ),
1229
+ /* @__PURE__ */ jsx("span", { children: request.texts.exactToggleLabel })
1230
+ ] })
1231
+ ] }),
1232
+ /* @__PURE__ */ jsx("div", { style: { minHeight: 232, borderRadius: 8, border: "1px solid #f0f0f0", background: "#fafafa", padding: 6 }, children: loading || visibleOptions.length === 0 ? /* @__PURE__ */ jsx("div", { style: { minHeight: 220, display: "flex", alignItems: "center", justifyContent: "center", color: "#9ca3af", fontSize: 12 }, children: loading ? request.texts.loadingOptions : request.texts.emptyOptions }) : /* @__PURE__ */ jsx(
1233
+ ReactVirtualList,
1234
+ {
1235
+ items: visibleOptions,
1236
+ height: Math.min(220, visibleOptions.length * 40),
1237
+ itemHeight: 40,
1238
+ itemKey: (item) => item.value,
1239
+ renderItem: (item, _index, meta) => /* @__PURE__ */ jsxs(
1240
+ "label",
1241
+ {
1242
+ className: "react-list-table-filter-option",
1243
+ style: { ...optionStyle, ...meta.style },
1244
+ children: [
1245
+ /* @__PURE__ */ jsx(
1246
+ ReactCheckbox,
1247
+ {
1248
+ checked: selected.has(item.value),
1249
+ onChange: (event) => toggle([item.value], !!event.target.checked)
1250
+ }
1251
+ ),
1252
+ /* @__PURE__ */ jsx("span", { title: optionLabel(item, request.texts), style: optionTextStyle, children: optionLabel(item, request.texts) }),
1253
+ /* @__PURE__ */ jsx("span", { style: { color: "#9ca3af", fontSize: 12 }, children: item.count })
1254
+ ]
1255
+ },
1256
+ item.value
1257
+ )
1258
+ }
1259
+ ) })
1260
+ ] }) : /* @__PURE__ */ jsxs("div", { style: { marginTop: 12, display: "grid", gap: 12, minHeight: 290, alignContent: "start", flex: "1 1 auto" }, children: [
1261
+ /* @__PURE__ */ jsx(
1262
+ ConditionEditor,
1263
+ {
1264
+ label: request.texts.firstConditionLabel,
1265
+ operator: draft.conditionOperator ?? "none",
1266
+ value: draft.conditionValue ?? "",
1267
+ secondValue: draft.conditionSecondValue ?? "",
1268
+ texts: request.texts,
1269
+ onChange: (patch) => update(patch),
1270
+ onSubmit: apply
1271
+ }
1272
+ ),
1273
+ /* @__PURE__ */ jsxs("div", { children: [
1274
+ /* @__PURE__ */ jsx("div", { style: fieldLabelStyle, children: request.texts.relationLabel }),
1275
+ /* @__PURE__ */ jsx(
1276
+ ReactSelect,
1277
+ {
1278
+ value: draft.conditionRelation === "or" ? "or" : "and",
1279
+ allowClear: false,
1280
+ options: [{ label: request.texts.relationAndLabel, value: "and" }, { label: request.texts.relationOrLabel, value: "or" }],
1281
+ onChange: (value) => update({ conditionRelation: value, filterType: "condition" }),
1282
+ style: { width: "100%" }
1283
+ }
1284
+ )
1285
+ ] }),
1286
+ /* @__PURE__ */ jsx(
1287
+ ConditionEditor,
1288
+ {
1289
+ second: true,
1290
+ label: request.texts.secondConditionLabel,
1291
+ operator: draft.secondConditionOperator ?? "none",
1292
+ value: draft.secondConditionValue ?? "",
1293
+ secondValue: draft.secondConditionSecondValue ?? "",
1294
+ texts: request.texts,
1295
+ onChange: (patch) => update(patch),
1296
+ onSubmit: apply
1297
+ }
1298
+ )
1299
+ ] }),
1300
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
1301
+ /* @__PURE__ */ jsx("button", { type: "button", style: actionStyle(false), onClick: () => {
1302
+ request.onReset();
1303
+ request.onClose();
1304
+ }, children: request.texts.resetAction }),
1305
+ /* @__PURE__ */ jsx("button", { type: "button", style: actionStyle(true), onClick: apply, children: request.texts.applyAction })
1306
+ ] })
1307
+ ] })
1308
+ }
1309
+ );
1310
+ }
1311
+ function ConditionEditor(props) {
1312
+ const prefix = props.second ? "secondCondition" : "condition";
1313
+ const hidesValue = ["none", "blank", "notBlank"].includes(props.operator);
1314
+ const needsSecond = ["between", "notBetween"].includes(props.operator);
1315
+ return /* @__PURE__ */ jsxs("div", { children: [
1316
+ /* @__PURE__ */ jsx("div", { style: fieldLabelStyle, children: props.label }),
1317
+ /* @__PURE__ */ jsx(
1318
+ ReactSelect,
1319
+ {
1320
+ value: props.operator,
1321
+ options: operators,
1322
+ allowClear: false,
1323
+ onChange: (value) => props.onChange({ [`${prefix}Operator`]: value, filterType: "condition" }),
1324
+ style: { width: "100%" }
1325
+ }
1326
+ ),
1327
+ hidesValue ? null : /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 8, marginTop: 8 }, children: [
1328
+ /* @__PURE__ */ jsx(
1329
+ ReactInput,
1330
+ {
1331
+ value: props.value,
1332
+ placeholder: props.texts.firstValuePlaceholder,
1333
+ onPressEnter: props.onSubmit,
1334
+ onChange: (event) => props.onChange({ [`${prefix}Value`]: event.target.value, filterType: "condition" }),
1335
+ style: { width: "100%" }
1336
+ }
1337
+ ),
1338
+ needsSecond ? /* @__PURE__ */ jsx(
1339
+ ReactInput,
1340
+ {
1341
+ value: props.secondValue,
1342
+ placeholder: props.texts.secondValuePlaceholder,
1343
+ onPressEnter: props.onSubmit,
1344
+ onChange: (event) => props.onChange({ [`${prefix}SecondValue`]: event.target.value, filterType: "condition" }),
1345
+ style: { width: "100%" }
1346
+ }
1347
+ ) : null
1348
+ ] })
1349
+ ] });
1350
+ }
1351
+ function resolveTab(value) {
1352
+ return value?.filterType === "condition" || value?.conditionOperator && value.conditionOperator !== "none" ? "condition" : "value";
1353
+ }
1354
+ function optionLabel(item, texts) {
1355
+ if (item.kind === "blank") return texts.blankOptionLabel;
1356
+ if (item.kind === "notBlank") return texts.notBlankOptionLabel;
1357
+ return item.label;
1358
+ }
1359
+ var checkLabelStyle = { display: "inline-flex", alignItems: "center", gap: 8, color: "#374151", fontSize: 14 };
1360
+ var optionStyle = { display: "flex", alignItems: "center", gap: 8, minHeight: 40, padding: "4px 8px", borderRadius: 6, color: "#374151", fontSize: 14, cursor: "pointer", boxSizing: "border-box" };
1361
+ var optionTextStyle = { display: "block", flex: "1 1 0", width: 0, minWidth: 0, overflow: "hidden", whiteSpace: "nowrap", textOverflow: "ellipsis" };
1362
+ var fieldLabelStyle = { marginBottom: 6, fontSize: 12, color: "#6b7280" };
1363
+ function tabStyle(active) {
1364
+ return { flex: 1, height: 32, border: active ? "1px solid #1677ff" : "1px solid #d9d9d9", borderRadius: 6, background: active ? "#e6f4ff" : "#fff", color: active ? "#1677ff" : "#374151", cursor: "pointer" };
1365
+ }
1366
+ function actionStyle(primary) {
1367
+ return { minWidth: 72, height: 32, padding: "0 12px", borderRadius: 6, border: primary ? "1px solid #1677ff" : "1px solid #d9d9d9", background: primary ? "#1677ff" : "#fff", color: primary ? "#fff" : "#374151", cursor: "pointer" };
1368
+ }
1369
+
605
1370
  // src/components/color/style.css
606
1371
  styleInject(".canvas-react-color-wrap {\n display: inline-flex;\n width: 100%;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n}\n.canvas-react-color {\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: var(--canvas-react-control-height);\n min-height: 0;\n box-sizing: border-box;\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n cursor: pointer;\n}\n.canvas-react-color:hover {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-color-open,\n.canvas-react-color:focus-within {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-color-disabled {\n color: #9ca3af;\n background: var(--canvas-react-color-bg-soft);\n cursor: not-allowed;\n}\n.canvas-react-color-preview {\n flex: 0 0 auto;\n width: calc(24px * var(--canvas-react-content-zoom, 1));\n height: calc(24px * var(--canvas-react-content-zoom, 1));\n margin-left: 3px;\n box-sizing: border-box;\n border: 1px solid rgba(0, 0, 0, 0.12);\n border-radius: 4px;\n}\n.canvas-react-color-input-wrap {\n flex: 1;\n min-width: 0;\n height: 100%;\n min-height: 0;\n border: 0;\n box-shadow: none;\n}\n.canvas-react-color .canvas-react-input-affix-wrapper {\n height: 100%;\n min-height: 0;\n}\n.canvas-react-color-input-wrap:hover,\n.canvas-react-color-input-wrap:focus-within {\n border-color: transparent;\n box-shadow: none;\n}\n.canvas-react-color-input {\n cursor: pointer;\n text-transform: uppercase;\n}\n.canvas-react-color-arrow {\n flex: 0 0 auto;\n width: 0.5em;\n height: 0.5em;\n min-width: 6px;\n min-height: 6px;\n margin-right: var(--canvas-react-control-padding-inline, 11px);\n border-right: 1.5px solid var(--canvas-react-color-text-muted);\n border-bottom: 1.5px solid var(--canvas-react-color-text-muted);\n transform: rotate(45deg) translateY(-2px);\n transition: transform 0.18s ease;\n}\n.canvas-react-color-arrow-open {\n transform: rotate(225deg) translate(-1px, -1px);\n}\n.canvas-react-color-dropdown {\n overflow: hidden;\n}\n.canvas-react-color-panel {\n padding: 12px;\n box-sizing: border-box;\n}\n.canvas-react-color-saturation {\n position: relative;\n height: 150px;\n overflow: hidden;\n border-radius: 6px;\n cursor: crosshair;\n background-image:\n linear-gradient(\n to top,\n #000,\n transparent),\n linear-gradient(\n to right,\n #fff,\n transparent);\n touch-action: none;\n}\n.canvas-react-color-saturation-thumb {\n position: absolute;\n width: 12px;\n height: 12px;\n border: 2px solid #fff;\n border-radius: 50%;\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.28), 0 1px 3px rgba(0, 0, 0, 0.28);\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n.canvas-react-color-controls {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-top: 12px;\n}\n.canvas-react-color-current {\n flex: 0 0 28px;\n height: 28px;\n box-sizing: border-box;\n border: 1px solid rgba(0, 0, 0, 0.12);\n border-radius: 50%;\n}\n.canvas-react-color-hue {\n width: 100%;\n height: 12px;\n margin: 0;\n appearance: none;\n border-radius: 999px;\n background:\n linear-gradient(\n to right,\n #f00,\n #ff0,\n #0f0,\n #0ff,\n #00f,\n #f0f,\n #f00);\n cursor: pointer;\n}\n.canvas-react-color-hue::-webkit-slider-thumb {\n width: 14px;\n height: 14px;\n appearance: none;\n border: 2px solid #fff;\n border-radius: 50%;\n background: transparent;\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.28);\n}\n.canvas-react-color-value-row {\n display: grid;\n grid-template-columns: 36px 1fr;\n align-items: center;\n gap: 8px;\n margin-top: 12px;\n color: var(--canvas-react-color-text-muted);\n font-size: 12px;\n}\n.canvas-react-color-value-row .canvas-react-input-affix-wrapper {\n height: 28px;\n}\n.canvas-react-color-presets {\n display: grid;\n grid-template-columns: repeat(8, 20px);\n gap: 7px;\n margin-top: 12px;\n}\n.canvas-react-color-preset {\n width: 20px;\n height: 20px;\n padding: 0;\n box-sizing: border-box;\n border: 1px solid rgba(0, 0, 0, 0.12);\n border-radius: 4px;\n cursor: pointer;\n transition: transform 0.16s ease, box-shadow 0.16s ease;\n}\n.canvas-react-color-preset:hover {\n transform: scale(1.12);\n}\n.canvas-react-color-preset-selected {\n box-shadow: 0 0 0 2px #fff, 0 0 0 3px var(--canvas-react-color-primary);\n}\n");
607
1372
  var DEFAULT_COLOR = "#1677ff";
@@ -3763,6 +4528,165 @@ function compareDateTimeValue(left, right) {
3763
4528
  return left.localeCompare(right);
3764
4529
  }
3765
4530
 
4531
+ // src/components/number-input/style.css
4532
+ styleInject('@import "../../styles/variables.css";\n.canvas-react-number-input-affix-wrapper {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: var(--canvas-react-control-height);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n outline: none;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-number-input-affix-wrapper:hover {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-number-input-affix-wrapper:focus-within {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-number-input-affix-wrapper-disabled {\n background: #fafafa;\n color: #9ca3af;\n cursor: not-allowed;\n}\n.canvas-react-number-input {\n box-sizing: border-box;\n flex: 1 1 auto;\n width: 100%;\n min-width: 0;\n height: 100%;\n padding: var(--canvas-react-control-padding-block, 0px) var(--canvas-react-control-padding-inline, 11px);\n border: none;\n background: transparent;\n color: inherit;\n font-size: inherit;\n outline: none;\n appearance: textfield;\n -moz-appearance: textfield;\n}\n.canvas-react-number-input::placeholder {\n color: #9ca3af;\n}\n.canvas-react-number-input::-webkit-outer-spin-button,\n.canvas-react-number-input::-webkit-inner-spin-button {\n margin: 0;\n -webkit-appearance: none;\n}\n.canvas-react-number-input-suffix {\n display: inline-flex;\n align-items: center;\n padding-right: var(--canvas-react-control-padding-inline, 11px);\n}\n.canvas-react-number-input-clear {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 12px;\n height: 12px;\n padding: 0;\n border: none;\n background: transparent;\n color: #9ca3af;\n opacity: 0;\n pointer-events: none;\n cursor: pointer;\n transition:\n color 0.2s ease,\n opacity 0.2s ease,\n transform 0.18s ease;\n}\n.canvas-react-number-input-affix-wrapper:hover .canvas-react-number-input-clear,\n.canvas-react-number-input-affix-wrapper:focus-within .canvas-react-number-input-clear {\n opacity: 1;\n pointer-events: auto;\n}\n.canvas-react-number-input-clear:hover {\n color: #6b7280;\n transform: rotate(90deg);\n}\n.canvas-react-number-input-clear-icon,\n.canvas-react-number-input-clear-icon::before {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 8px;\n height: 1.25px;\n margin-top: -0.625px;\n margin-left: -4px;\n border-radius: 999px;\n background: currentColor;\n content: "";\n}\n.canvas-react-number-input-clear-icon {\n transform: rotate(45deg);\n}\n.canvas-react-number-input-clear-icon::before {\n transform: rotate(90deg);\n}\n');
4533
+ var ReactNumberInput = forwardRef(
4534
+ function ReactNumberInput2(props, ref) {
4535
+ const {
4536
+ className,
4537
+ disabled,
4538
+ onBlur,
4539
+ onChange,
4540
+ onKeyDown,
4541
+ onPressEnter,
4542
+ style,
4543
+ value,
4544
+ ...restProps
4545
+ } = props;
4546
+ const [inputValue, setInputValue] = useState(toDisplayValue(value));
4547
+ useEffect(() => {
4548
+ setInputValue(toDisplayValue(value));
4549
+ }, [value]);
4550
+ return /* @__PURE__ */ jsx(
4551
+ "span",
4552
+ {
4553
+ className: joinClassNames(
4554
+ `${REACT_COMPONENT_PREFIX}-number-input-affix-wrapper`,
4555
+ disabled && `${REACT_COMPONENT_PREFIX}-number-input-affix-wrapper-disabled`
4556
+ ),
4557
+ style,
4558
+ children: /* @__PURE__ */ jsx(
4559
+ "input",
4560
+ {
4561
+ ...restProps,
4562
+ ref,
4563
+ disabled,
4564
+ type: "number",
4565
+ value: inputValue,
4566
+ className: joinClassNames(
4567
+ `${REACT_COMPONENT_PREFIX}-number-input`,
4568
+ className
4569
+ ),
4570
+ onChange: (event) => {
4571
+ const nextText = event.target.value;
4572
+ setInputValue(nextText);
4573
+ onChange?.(parseNumberValue(nextText));
4574
+ },
4575
+ onBlur: (event) => {
4576
+ setInputValue(toDisplayValue(parseNumberValue(event.target.value)));
4577
+ onBlur?.(event);
4578
+ },
4579
+ onKeyDown: (event) => {
4580
+ onKeyDown?.(event);
4581
+ if (event.key === "Enter") {
4582
+ onPressEnter?.(event);
4583
+ }
4584
+ }
4585
+ }
4586
+ )
4587
+ }
4588
+ );
4589
+ }
4590
+ );
4591
+ function parseNumberValue(value) {
4592
+ if (value.trim().length === 0) {
4593
+ return null;
4594
+ }
4595
+ const nextValue = Number(value);
4596
+ return Number.isFinite(nextValue) ? nextValue : null;
4597
+ }
4598
+ function toDisplayValue(value) {
4599
+ return value == null ? "" : String(value);
4600
+ }
4601
+
4602
+ // src/components/input-range/style.css
4603
+ styleInject('@import "../../styles/variables.css";\n.canvas-react-input-range {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: var(--canvas-react-control-height);\n overflow: hidden;\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n outline: none;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-input-range:hover {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-input-range:focus-within {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-input-range-disabled {\n background: #fafafa;\n color: #9ca3af;\n cursor: not-allowed;\n}\n.canvas-react-input-range > .canvas-react-number-input-affix-wrapper,\n.canvas-react-input-range > .canvas-react-number-input-affix-wrapper:hover,\n.canvas-react-input-range > .canvas-react-number-input-affix-wrapper:focus-within {\n flex: 1 1 0;\n width: 0;\n height: 100%;\n border: 0;\n border-radius: 0;\n box-shadow: none;\n}\n.canvas-react-input-range-separator {\n flex: 0 0 auto;\n color: #9ca3af;\n line-height: 1;\n}\n');
4604
+ var ReactInputRange = forwardRef(function ReactInputRange2(props, ref) {
4605
+ const {
4606
+ autoFocus,
4607
+ className,
4608
+ disabled,
4609
+ max,
4610
+ min,
4611
+ onBlur,
4612
+ onChange,
4613
+ onFocus,
4614
+ onKeyDown,
4615
+ onPressEnter,
4616
+ placeholder = ["\u6700\u5C0F\u503C", "\u6700\u5927\u503C"],
4617
+ rangeSeparator = "~",
4618
+ step,
4619
+ style,
4620
+ value = [null, null],
4621
+ ...restProps
4622
+ } = props;
4623
+ const rootRef = useRef(null);
4624
+ const startInputRef = useRef(null);
4625
+ useImperativeHandle(ref, () => startInputRef.current);
4626
+ useEffect(() => {
4627
+ if (autoFocus) {
4628
+ startInputRef.current?.focus();
4629
+ }
4630
+ }, [autoFocus]);
4631
+ const handleBlur = (event) => {
4632
+ const nextTarget = event.relatedTarget;
4633
+ if (nextTarget && rootRef.current?.contains(nextTarget)) {
4634
+ return;
4635
+ }
4636
+ onBlur?.(event);
4637
+ };
4638
+ return /* @__PURE__ */ jsxs(
4639
+ "span",
4640
+ {
4641
+ ref: rootRef,
4642
+ className: joinClassNames(
4643
+ `${REACT_COMPONENT_PREFIX}-input-range`,
4644
+ disabled && `${REACT_COMPONENT_PREFIX}-input-range-disabled`,
4645
+ className
4646
+ ),
4647
+ style,
4648
+ children: [
4649
+ /* @__PURE__ */ jsx(
4650
+ ReactNumberInput,
4651
+ {
4652
+ ...restProps,
4653
+ ref: startInputRef,
4654
+ value: value[0],
4655
+ disabled,
4656
+ min,
4657
+ max,
4658
+ step,
4659
+ placeholder: placeholder[0],
4660
+ onChange: (nextValue) => onChange?.([nextValue, value[1]]),
4661
+ onFocus,
4662
+ onBlur: handleBlur,
4663
+ onKeyDown,
4664
+ onPressEnter
4665
+ }
4666
+ ),
4667
+ /* @__PURE__ */ jsx("span", { className: `${REACT_COMPONENT_PREFIX}-input-range-separator`, children: rangeSeparator }),
4668
+ /* @__PURE__ */ jsx(
4669
+ ReactNumberInput,
4670
+ {
4671
+ ...restProps,
4672
+ value: value[1],
4673
+ disabled,
4674
+ min,
4675
+ max,
4676
+ step,
4677
+ placeholder: placeholder[1],
4678
+ onChange: (nextValue) => onChange?.([value[0], nextValue]),
4679
+ onFocus,
4680
+ onBlur: handleBlur,
4681
+ onKeyDown,
4682
+ onPressEnter
4683
+ }
4684
+ )
4685
+ ]
4686
+ }
4687
+ );
4688
+ });
4689
+
3766
4690
  // src/components/image-preview/style.css
3767
4691
  styleInject(".canvas-react-image-preview {\n position: fixed;\n inset: 0;\n z-index: 1100;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 48px;\n background: rgba(0, 0, 0, 0.72);\n backdrop-filter: blur(2px);\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n.canvas-react-image-preview-entered {\n opacity: 1;\n}\n.canvas-react-image-preview-leave {\n opacity: 0;\n}\n.canvas-react-image-preview-image {\n max-width: 90vw;\n max-height: 86vh;\n object-fit: contain;\n border-radius: 4px;\n box-shadow: 0 12px 48px rgba(0, 0, 0, 0.32);\n opacity: 0;\n transition: transform 0.2s ease, opacity 0.2s ease;\n user-select: none;\n}\n.canvas-react-image-preview-entered .canvas-react-image-preview-image {\n opacity: 1;\n}\n.canvas-react-image-preview-leave .canvas-react-image-preview-image {\n opacity: 0;\n}\n.canvas-react-image-preview-close {\n position: fixed;\n top: 20px;\n right: 24px;\n width: 40px;\n height: 40px;\n padding: 0;\n border: 0;\n border-radius: 50%;\n color: #fff;\n background: rgba(255, 255, 255, 0.14);\n font: 30px/38px sans-serif;\n cursor: pointer;\n}\n.canvas-react-image-preview-toolbar {\n position: fixed;\n bottom: 28px;\n left: 50%;\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 10px;\n color: #fff;\n background: rgba(0, 0, 0, 0.64);\n border-radius: 22px;\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.24);\n transform: translateX(-50%);\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n.canvas-react-image-preview-entered .canvas-react-image-preview-toolbar {\n opacity: 1;\n}\n.canvas-react-image-preview-tool {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: 0;\n border-radius: 6px;\n color: inherit;\n background: transparent;\n font: 20px/1 sans-serif;\n cursor: pointer;\n}\n.canvas-react-image-preview-tool:hover:not(:disabled) {\n background: rgba(255, 255, 255, 0.16);\n}\n.canvas-react-image-preview-tool:disabled {\n color: rgba(255, 255, 255, 0.35);\n cursor: not-allowed;\n}\n.canvas-react-image-preview-scale {\n min-width: 48px;\n color: rgba(255, 255, 255, 0.88);\n font-size: 12px;\n text-align: center;\n}\n");
3768
4692
  function ReactImagePreview(props) {
@@ -4287,740 +5211,622 @@ var ReactMonthPicker = forwardRef(
4287
5211
  );
4288
5212
  })
4289
5213
  }
4290
- )
4291
- ]
4292
- }
4293
- )
4294
- }
4295
- )
4296
- ] });
4297
- }
4298
- );
4299
- function parseMonthValue(value) {
4300
- if (!value) {
4301
- return null;
4302
- }
4303
- const matched = value.match(/^(\d{4})-(\d{2})$/);
4304
- if (!matched) {
4305
- return null;
4306
- }
4307
- const month = matched[2];
4308
- if (!MONTHS4.includes(month)) {
4309
- return null;
4310
- }
4311
- return {
4312
- month,
4313
- year: Number(matched[1])
4314
- };
4315
- }
4316
- function resolveDecadeStart4(year) {
4317
- return Math.floor(year / 10) * 10;
4318
- }
4319
-
4320
- // src/components/number-input/style.css
4321
- styleInject('@import "../../styles/variables.css";\n.canvas-react-number-input-affix-wrapper {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: var(--canvas-react-control-height);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n outline: none;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-number-input-affix-wrapper:hover {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-number-input-affix-wrapper:focus-within {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-number-input-affix-wrapper-disabled {\n background: #fafafa;\n color: #9ca3af;\n cursor: not-allowed;\n}\n.canvas-react-number-input {\n box-sizing: border-box;\n flex: 1 1 auto;\n width: 100%;\n min-width: 0;\n height: 100%;\n padding: var(--canvas-react-control-padding-block, 0px) var(--canvas-react-control-padding-inline, 11px);\n border: none;\n background: transparent;\n color: inherit;\n font-size: inherit;\n outline: none;\n appearance: textfield;\n -moz-appearance: textfield;\n}\n.canvas-react-number-input::placeholder {\n color: #9ca3af;\n}\n.canvas-react-number-input::-webkit-outer-spin-button,\n.canvas-react-number-input::-webkit-inner-spin-button {\n margin: 0;\n -webkit-appearance: none;\n}\n.canvas-react-number-input-suffix {\n display: inline-flex;\n align-items: center;\n padding-right: var(--canvas-react-control-padding-inline, 11px);\n}\n.canvas-react-number-input-clear {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 12px;\n height: 12px;\n padding: 0;\n border: none;\n background: transparent;\n color: #9ca3af;\n opacity: 0;\n pointer-events: none;\n cursor: pointer;\n transition:\n color 0.2s ease,\n opacity 0.2s ease,\n transform 0.18s ease;\n}\n.canvas-react-number-input-affix-wrapper:hover .canvas-react-number-input-clear,\n.canvas-react-number-input-affix-wrapper:focus-within .canvas-react-number-input-clear {\n opacity: 1;\n pointer-events: auto;\n}\n.canvas-react-number-input-clear:hover {\n color: #6b7280;\n transform: rotate(90deg);\n}\n.canvas-react-number-input-clear-icon,\n.canvas-react-number-input-clear-icon::before {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 8px;\n height: 1.25px;\n margin-top: -0.625px;\n margin-left: -4px;\n border-radius: 999px;\n background: currentColor;\n content: "";\n}\n.canvas-react-number-input-clear-icon {\n transform: rotate(45deg);\n}\n.canvas-react-number-input-clear-icon::before {\n transform: rotate(90deg);\n}\n');
4322
- var ReactNumberInput = forwardRef(
4323
- function ReactNumberInput2(props, ref) {
4324
- const {
4325
- className,
4326
- disabled,
4327
- onBlur,
4328
- onChange,
4329
- onKeyDown,
4330
- onPressEnter,
4331
- style,
4332
- value,
4333
- ...restProps
4334
- } = props;
4335
- const [inputValue, setInputValue] = useState(toDisplayValue(value));
4336
- useEffect(() => {
4337
- setInputValue(toDisplayValue(value));
4338
- }, [value]);
4339
- return /* @__PURE__ */ jsx(
4340
- "span",
4341
- {
4342
- className: joinClassNames(
4343
- `${REACT_COMPONENT_PREFIX}-number-input-affix-wrapper`,
4344
- disabled && `${REACT_COMPONENT_PREFIX}-number-input-affix-wrapper-disabled`
4345
- ),
4346
- style,
4347
- children: /* @__PURE__ */ jsx(
4348
- "input",
4349
- {
4350
- ...restProps,
4351
- ref,
4352
- disabled,
4353
- type: "number",
4354
- value: inputValue,
4355
- className: joinClassNames(
4356
- `${REACT_COMPONENT_PREFIX}-number-input`,
4357
- className
4358
- ),
4359
- onChange: (event) => {
4360
- const nextText = event.target.value;
4361
- setInputValue(nextText);
4362
- onChange?.(parseNumberValue(nextText));
4363
- },
4364
- onBlur: (event) => {
4365
- setInputValue(toDisplayValue(parseNumberValue(event.target.value)));
4366
- onBlur?.(event);
4367
- },
4368
- onKeyDown: (event) => {
4369
- onKeyDown?.(event);
4370
- if (event.key === "Enter") {
4371
- onPressEnter?.(event);
4372
- }
5214
+ )
5215
+ ]
4373
5216
  }
4374
- }
4375
- )
4376
- }
4377
- );
5217
+ )
5218
+ }
5219
+ )
5220
+ ] });
4378
5221
  }
4379
5222
  );
4380
- function parseNumberValue(value) {
4381
- if (value.trim().length === 0) {
5223
+ function parseMonthValue(value) {
5224
+ if (!value) {
4382
5225
  return null;
4383
5226
  }
4384
- const nextValue = Number(value);
4385
- return Number.isFinite(nextValue) ? nextValue : null;
5227
+ const matched = value.match(/^(\d{4})-(\d{2})$/);
5228
+ if (!matched) {
5229
+ return null;
5230
+ }
5231
+ const month = matched[2];
5232
+ if (!MONTHS4.includes(month)) {
5233
+ return null;
5234
+ }
5235
+ return {
5236
+ month,
5237
+ year: Number(matched[1])
5238
+ };
4386
5239
  }
4387
- function toDisplayValue(value) {
4388
- return value == null ? "" : String(value);
5240
+ function resolveDecadeStart4(year) {
5241
+ return Math.floor(year / 10) * 10;
5242
+ }
5243
+ var compatibleIdSeed = 0;
5244
+ function useCompatibleId(prefix = "canvas-react-id") {
5245
+ const nativeUseId = React.useId;
5246
+ const fallbackIdRef = React.useRef();
5247
+ if (!fallbackIdRef.current) {
5248
+ compatibleIdSeed += 1;
5249
+ fallbackIdRef.current = `${prefix}-${compatibleIdSeed}`;
5250
+ }
5251
+ return nativeUseId ? nativeUseId() : fallbackIdRef.current;
4389
5252
  }
4390
5253
 
4391
- // src/components/input-number/style.css
4392
- styleInject('@import "../../styles/variables.css";\n.canvas-react-input-number {\n box-sizing: border-box;\n display: inline-flex;\n align-items: stretch;\n width: 100%;\n min-width: 0;\n height: var(--canvas-react-control-height);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n overflow: hidden;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-input-number:hover {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-input-number-focused {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-input-number-disabled {\n background: #fafafa;\n color: #9ca3af;\n cursor: not-allowed;\n}\n.canvas-react-input-number-handler {\n position: relative;\n display: flex;\n flex: 0 0 28px;\n align-items: center;\n justify-content: center;\n margin: 0;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--canvas-react-color-text-muted);\n cursor: pointer;\n transition: color 0.16s ease, background-color 0.16s ease;\n}\n.canvas-react-input-number-handler-down {\n border-right: 1px solid var(--canvas-react-color-border);\n}\n.canvas-react-input-number-handler-up {\n border-left: 1px solid var(--canvas-react-color-border);\n}\n.canvas-react-input-number-handler:hover:not(:disabled) {\n color: var(--canvas-react-color-primary);\n background: rgba(22, 119, 255, 0.06);\n}\n.canvas-react-input-number-handler:disabled {\n color: #c4c7cf;\n cursor: not-allowed;\n}\n.canvas-react-input-number-handler-icon {\n position: relative;\n display: block;\n width: 10px;\n height: 10px;\n}\n.canvas-react-input-number-handler-icon::before,\n.canvas-react-input-number-handler-icon::after {\n content: "";\n position: absolute;\n top: 50%;\n left: 50%;\n background: currentColor;\n border-radius: 1px;\n transform: translate(-50%, -50%);\n}\n.canvas-react-input-number-handler-icon::before {\n width: 10px;\n height: 1.5px;\n}\n.canvas-react-input-number-handler-up .canvas-react-input-number-handler-icon::after {\n width: 1.5px;\n height: 10px;\n}\n.canvas-react-input-number-input-wrap {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n min-width: 0;\n height: 100%;\n}\n.canvas-react-input-number-input {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n height: 100%;\n padding: 0 8px;\n border: none;\n background: transparent;\n color: inherit;\n font-size: inherit;\n outline: none;\n text-align: center;\n appearance: textfield;\n -moz-appearance: textfield;\n}\n.canvas-react-input-number-input::placeholder {\n color: #9ca3af;\n}\n.canvas-react-input-number-input::-webkit-outer-spin-button,\n.canvas-react-input-number-input::-webkit-inner-spin-button {\n margin: 0;\n -webkit-appearance: none;\n}\n.canvas-react-input-number-addon {\n flex: 0 0 auto;\n padding-right: 8px;\n color: var(--canvas-react-color-text-muted);\n font-size: 12px;\n line-height: 1;\n user-select: none;\n}\n');
4393
- var ReactInputNumber = forwardRef(
4394
- function ReactInputNumber2(props, ref) {
4395
- const {
4396
- addonAfter,
4397
- className,
4398
- defaultValue = null,
4399
- disabled,
4400
- formatter,
4401
- max,
4402
- min,
4403
- onBlur,
4404
- onChange,
4405
- onCommit,
4406
- onFocus,
4407
- onKeyDown,
4408
- parser,
4409
- precision,
4410
- step = 1,
4411
- style,
4412
- value,
4413
- ...restProps
4414
- } = props;
4415
- const isControlled = value !== void 0;
4416
- const [innerValue, setInnerValue] = useState(
4417
- isControlled ? value ?? null : defaultValue
4418
- );
4419
- const currentValue = isControlled ? value ?? null : innerValue;
4420
- const [draftText, setDraftText] = useState(
4421
- formatDisplayValue(
4422
- currentValue,
4423
- formatter,
4424
- resolvePrecision(precision, step),
4425
- step
4426
- )
4427
- );
4428
- const [focused, setFocused] = useState(false);
4429
- const resolvedPrecision = useMemo(
4430
- () => resolvePrecision(precision, step),
4431
- [precision, step]
4432
- );
4433
- useEffect(() => {
4434
- if (!focused) {
4435
- setDraftText(
4436
- formatDisplayValue(currentValue, formatter, resolvedPrecision, step)
4437
- );
4438
- }
4439
- }, [currentValue, focused, formatter, resolvedPrecision, step]);
4440
- const commitValue = (nextValue) => {
4441
- const normalized = normalizeNumberValue(nextValue, {
4442
- min,
4443
- max,
4444
- precision: resolvedPrecision
4445
- });
4446
- if (!isControlled) {
4447
- setInnerValue(normalized);
5254
+ // src/components/modal/style.css
5255
+ styleInject('@import "../../styles/variables.css";\n.canvas-react-modal-root,\n.canvas-react-modal-root * {\n box-sizing: border-box;\n}\n.canvas-react-modal-root {\n position: fixed;\n inset: 0;\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n line-height: 1.5;\n}\n.canvas-react-modal-mask {\n position: absolute;\n inset: 0;\n background: rgba(0, 0, 0, 0.45);\n}\n.canvas-react-modal-wrap {\n position: absolute;\n inset: 0;\n overflow: auto;\n padding: 100px 24px 24px;\n pointer-events: none;\n}\n.canvas-react-modal-root-centered .canvas-react-modal-wrap {\n display: flex;\n align-items: center;\n padding-top: 24px;\n}\n.canvas-react-modal-root-fullscreen .canvas-react-modal-wrap {\n padding: 0;\n overflow: hidden;\n}\n.canvas-react-modal {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 520px;\n max-width: calc(100vw - 48px);\n max-height: calc(100vh - 124px);\n margin: 0 auto;\n overflow: hidden;\n border-radius: var(--canvas-react-radius-md, 8px);\n background: var(--canvas-react-color-bg, #ffffff);\n box-shadow: 0 12px 40px rgba(15, 23, 42, 0.22);\n outline: none;\n pointer-events: auto;\n}\n.canvas-react-modal-root-centered .canvas-react-modal {\n max-height: calc(100vh - 48px);\n}\n.canvas-react-modal.canvas-react-modal-fullscreen {\n width: 100% !important;\n max-width: none;\n height: 100%;\n max-height: none;\n border-radius: 0;\n}\n.canvas-react-modal-header {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n min-height: 56px;\n padding: 0 16px 0 24px;\n border-bottom: 1px solid var(--canvas-react-color-border);\n}\n.canvas-react-modal-title {\n min-width: 0;\n flex: 1 1 auto;\n color: var(--canvas-react-color-text);\n font-size: 16px;\n font-weight: 600;\n overflow-wrap: anywhere;\n}\n.canvas-react-modal-tools {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 4px;\n margin-left: 16px;\n}\n.canvas-react-modal-tool {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: 0;\n border-radius: var(--canvas-react-radius-sm, 6px);\n background: transparent;\n color: var(--canvas-react-color-text-muted);\n cursor: pointer;\n transition: background-color 0.18s ease, color 0.18s ease;\n}\n.canvas-react-modal-tool:hover {\n background: var(--canvas-react-color-bg-hover);\n color: var(--canvas-react-color-text);\n}\n.canvas-react-modal-tool:focus-visible,\n.canvas-react-modal-button:focus-visible {\n outline: 2px solid var(--canvas-react-color-primary);\n outline-offset: 2px;\n}\n.canvas-react-modal-fullscreen-icon {\n position: relative;\n display: block;\n width: 15px;\n height: 15px;\n border: 1.5px solid currentColor;\n}\n.canvas-react-modal-fullscreen-icon-exit::before {\n position: absolute;\n inset: 3px -4px -4px 3px;\n border-right: 1.5px solid currentColor;\n border-bottom: 1.5px solid currentColor;\n content: "";\n}\n.canvas-react-modal-close-icon {\n position: relative;\n display: block;\n width: 16px;\n height: 16px;\n}\n.canvas-react-modal-close-icon::before,\n.canvas-react-modal-close-icon::after {\n position: absolute;\n top: 7px;\n left: 1px;\n width: 14px;\n height: 1.5px;\n border-radius: 1px;\n background: currentColor;\n content: "";\n}\n.canvas-react-modal-close-icon::before {\n transform: rotate(45deg);\n}\n.canvas-react-modal-close-icon::after {\n transform: rotate(-45deg);\n}\n.canvas-react-modal-body {\n min-height: 0;\n flex: 1 1 auto;\n overflow: auto;\n padding: 20px 24px;\n}\n.canvas-react-modal-footer {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 24px;\n border-top: 1px solid var(--canvas-react-color-border);\n}\n.canvas-react-modal-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: var(--canvas-react-control-height, 32px);\n min-width: 64px;\n padding: 0 var(--canvas-react-control-padding-inline, 11px);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm, 6px);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font: inherit;\n line-height: 1;\n white-space: nowrap;\n cursor: pointer;\n transition:\n border-color 0.18s ease,\n background-color 0.18s ease,\n color 0.18s ease,\n opacity 0.18s ease;\n}\n.canvas-react-modal-button:hover {\n border-color: var(--canvas-react-color-primary-hover);\n color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-modal-button-primary {\n border-color: var(--canvas-react-color-primary);\n background: var(--canvas-react-color-primary);\n color: #ffffff;\n}\n.canvas-react-modal-button-primary:hover {\n border-color: var(--canvas-react-color-primary-hover);\n background: var(--canvas-react-color-primary-hover);\n color: #ffffff;\n}\n.canvas-react-modal-button:disabled {\n opacity: 0.56;\n cursor: not-allowed;\n}\n.canvas-react-modal-loading {\n width: 14px;\n height: 14px;\n border: 2px solid rgba(255, 255, 255, 0.45);\n border-top-color: #ffffff;\n border-radius: 50%;\n animation: canvas-react-modal-loading 0.8s linear infinite;\n}\n.canvas-react-modal-motion-enter-active,\n.canvas-react-modal-motion-leave-active {\n transition: opacity 0.2s ease;\n}\n.canvas-react-modal-motion-enter-active .canvas-react-modal,\n.canvas-react-modal-motion-leave-active .canvas-react-modal {\n transition: opacity 0.2s ease, transform 0.2s cubic-bezier(0.16, 1, 0.3, 1);\n}\n.canvas-react-modal-motion-enter-from,\n.canvas-react-modal-motion-leave-to {\n opacity: 0;\n}\n.canvas-react-modal-motion-enter-from .canvas-react-modal,\n.canvas-react-modal-motion-leave-to .canvas-react-modal {\n opacity: 0;\n transform: scale(0.96) translateY(-8px);\n}\n@keyframes canvas-react-modal-loading {\n to {\n transform: rotate(360deg);\n }\n}\n@media (max-width: 575px) {\n .canvas-react-modal-wrap {\n padding: 24px 12px;\n }\n .canvas-react-modal {\n max-width: calc(100vw - 24px);\n max-height: calc(100vh - 48px);\n }\n .canvas-react-modal-header {\n padding-right: 12px;\n padding-left: 16px;\n }\n .canvas-react-modal-body {\n padding: 16px;\n }\n .canvas-react-modal-footer {\n padding: 12px 16px;\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .canvas-react-modal-motion-enter-active,\n .canvas-react-modal-motion-leave-active,\n .canvas-react-modal-motion-enter-active .canvas-react-modal,\n .canvas-react-modal-motion-leave-active .canvas-react-modal {\n transition-duration: 0.01ms;\n }\n}\n');
5256
+ var MODAL_MOTION_DURATION = 200;
5257
+ var FOCUSABLE_SELECTOR = [
5258
+ "a[href]",
5259
+ "button:not([disabled])",
5260
+ "input:not([disabled])",
5261
+ "select:not([disabled])",
5262
+ "textarea:not([disabled])",
5263
+ '[tabindex]:not([tabindex="-1"])'
5264
+ ].join(",");
5265
+ var bodyScrollLockCount = 0;
5266
+ var bodyOverflowBeforeLock = "";
5267
+ function ReactModal(props) {
5268
+ const {
5269
+ afterClose,
5270
+ bodyStyle,
5271
+ cancelButtonProps,
5272
+ cancelText = "\u53D6\u6D88",
5273
+ centered = false,
5274
+ children,
5275
+ className,
5276
+ closable = true,
5277
+ confirmLoading,
5278
+ defaultFullscreen = false,
5279
+ focusTriggerAfterClose = true,
5280
+ footer,
5281
+ fullscreen,
5282
+ fullscreenable = true,
5283
+ getContainer,
5284
+ keyboard = true,
5285
+ mask = true,
5286
+ maskClosable = true,
5287
+ maskStyle,
5288
+ okButtonProps,
5289
+ okText = "\u786E\u5B9A",
5290
+ onCancel,
5291
+ onFullscreenChange,
5292
+ onOk,
5293
+ open,
5294
+ rootClassName,
5295
+ style,
5296
+ title,
5297
+ width = 520,
5298
+ zIndex = 1e3
5299
+ } = props;
5300
+ const transition = useReactTransition({
5301
+ duration: MODAL_MOTION_DURATION,
5302
+ name: `${REACT_COMPONENT_PREFIX}-modal-motion`,
5303
+ show: open
5304
+ });
5305
+ const [innerFullscreen, setInnerFullscreen] = useState(defaultFullscreen);
5306
+ const [innerConfirmLoading, setInnerConfirmLoading] = useState(false);
5307
+ const panelRef = useRef(null);
5308
+ const restoreFocusRef = useRef(null);
5309
+ const wasRenderedRef = useRef(false);
5310
+ const titleId = useCompatibleId(`${REACT_COMPONENT_PREFIX}-modal-title`);
5311
+ const controlledFullscreen = fullscreen !== void 0;
5312
+ const mergedFullscreen = controlledFullscreen ? Boolean(fullscreen) : innerFullscreen;
5313
+ const mergedConfirmLoading = confirmLoading ?? innerConfirmLoading;
5314
+ const hasTitle = title !== null && title !== void 0 && title !== false;
5315
+ useEffect(() => {
5316
+ if (!transition.rendered) {
5317
+ if (wasRenderedRef.current) {
5318
+ wasRenderedRef.current = false;
5319
+ afterClose?.();
5320
+ if (focusTriggerAfterClose) {
5321
+ restoreFocusRef.current?.focus();
5322
+ }
5323
+ restoreFocusRef.current = null;
4448
5324
  }
4449
- onChange?.(normalized);
4450
- onCommit?.(normalized);
4451
- setDraftText(
4452
- formatDisplayValue(normalized, formatter, resolvedPrecision, step)
4453
- );
4454
- return normalized;
5325
+ return;
5326
+ }
5327
+ if (!wasRenderedRef.current) {
5328
+ wasRenderedRef.current = true;
5329
+ restoreFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
5330
+ }
5331
+ lockBodyScroll();
5332
+ return unlockBodyScroll;
5333
+ }, [afterClose, focusTriggerAfterClose, transition.rendered]);
5334
+ useEffect(() => {
5335
+ if (!open || !transition.rendered) {
5336
+ return;
5337
+ }
5338
+ const frameId = window.requestAnimationFrame(() => {
5339
+ panelRef.current?.focus();
5340
+ });
5341
+ return () => {
5342
+ window.cancelAnimationFrame(frameId);
4455
5343
  };
4456
- const stepBy = (direction) => {
4457
- if (disabled) {
5344
+ }, [open, transition.rendered]);
5345
+ useEffect(() => {
5346
+ if (!transition.rendered) {
5347
+ return;
5348
+ }
5349
+ const handleKeyDown = (event) => {
5350
+ if (event.key === "Escape" && keyboard && open) {
5351
+ event.preventDefault();
5352
+ onCancel?.(event);
4458
5353
  return;
4459
5354
  }
4460
- const base = currentValue == null || !Number.isFinite(currentValue) ? 0 : currentValue;
4461
- const next = base + direction * step;
4462
- commitValue(next);
5355
+ if (event.key !== "Tab" || !open) {
5356
+ return;
5357
+ }
5358
+ trapFocus(event, panelRef.current);
4463
5359
  };
4464
- const atMin = currentValue != null && min != null && currentValue <= min + Number.EPSILON;
4465
- const atMax = currentValue != null && max != null && currentValue >= max - Number.EPSILON;
4466
- return /* @__PURE__ */ jsxs(
4467
- "span",
5360
+ document.addEventListener("keydown", handleKeyDown);
5361
+ return () => {
5362
+ document.removeEventListener("keydown", handleKeyDown);
5363
+ };
5364
+ }, [keyboard, onCancel, open, transition.rendered]);
5365
+ const setFullscreen = (nextFullscreen) => {
5366
+ if (!controlledFullscreen) {
5367
+ setInnerFullscreen(nextFullscreen);
5368
+ }
5369
+ if (nextFullscreen !== mergedFullscreen) {
5370
+ onFullscreenChange?.(nextFullscreen);
5371
+ }
5372
+ };
5373
+ const handleOk = (event) => {
5374
+ if (mergedConfirmLoading || okButtonProps?.disabled) {
5375
+ return;
5376
+ }
5377
+ const result = onOk?.(event);
5378
+ if (!isPromiseLike(result)) {
5379
+ return;
5380
+ }
5381
+ setInnerConfirmLoading(true);
5382
+ Promise.resolve(result).catch(() => void 0).finally(() => {
5383
+ setInnerConfirmLoading(false);
5384
+ });
5385
+ };
5386
+ if (!transition.rendered || typeof document === "undefined") {
5387
+ return null;
5388
+ }
5389
+ const container = resolveContainer(getContainer);
5390
+ if (!container) {
5391
+ return null;
5392
+ }
5393
+ const {
5394
+ className: okButtonClassName,
5395
+ disabled: okButtonDisabled,
5396
+ ...restOkButtonProps
5397
+ } = okButtonProps ?? {};
5398
+ const {
5399
+ className: cancelButtonClassName,
5400
+ disabled: cancelButtonDisabled,
5401
+ ...restCancelButtonProps
5402
+ } = cancelButtonProps ?? {};
5403
+ const defaultFooter = /* @__PURE__ */ jsxs(Fragment, { children: [
5404
+ /* @__PURE__ */ jsx(
5405
+ "button",
4468
5406
  {
5407
+ ...restCancelButtonProps,
5408
+ type: "button",
4469
5409
  className: joinClassNames(
4470
- `${REACT_COMPONENT_PREFIX}-input-number`,
4471
- focused && `${REACT_COMPONENT_PREFIX}-input-number-focused`,
4472
- disabled && `${REACT_COMPONENT_PREFIX}-input-number-disabled`,
4473
- className
5410
+ `${REACT_COMPONENT_PREFIX}-modal-button`,
5411
+ cancelButtonClassName
4474
5412
  ),
4475
- style,
5413
+ disabled: mergedConfirmLoading || cancelButtonDisabled,
5414
+ onClick: onCancel,
5415
+ children: cancelText
5416
+ }
5417
+ ),
5418
+ /* @__PURE__ */ jsxs(
5419
+ "button",
5420
+ {
5421
+ ...restOkButtonProps,
5422
+ type: "button",
5423
+ className: joinClassNames(
5424
+ `${REACT_COMPONENT_PREFIX}-modal-button`,
5425
+ `${REACT_COMPONENT_PREFIX}-modal-button-primary`,
5426
+ okButtonClassName
5427
+ ),
5428
+ disabled: mergedConfirmLoading || okButtonDisabled,
5429
+ onClick: handleOk,
4476
5430
  children: [
4477
- /* @__PURE__ */ jsx(
4478
- "button",
5431
+ mergedConfirmLoading ? /* @__PURE__ */ jsx(
5432
+ "span",
4479
5433
  {
4480
- type: "button",
4481
- tabIndex: -1,
4482
- disabled: disabled || atMin,
4483
- className: joinClassNames(
4484
- `${REACT_COMPONENT_PREFIX}-input-number-handler`,
4485
- `${REACT_COMPONENT_PREFIX}-input-number-handler-down`
4486
- ),
4487
- "aria-label": "\u51CF\u5C11",
4488
- onMouseDown: (event) => {
4489
- event.preventDefault();
4490
- },
4491
- onClick: () => {
4492
- stepBy(-1);
4493
- },
4494
- children: /* @__PURE__ */ jsx(
4495
- "span",
4496
- {
4497
- className: `${REACT_COMPONENT_PREFIX}-input-number-handler-icon`,
4498
- "aria-hidden": "true"
4499
- }
4500
- )
5434
+ className: `${REACT_COMPONENT_PREFIX}-modal-loading`,
5435
+ "aria-hidden": "true"
4501
5436
  }
4502
- ),
4503
- /* @__PURE__ */ jsxs("span", { className: `${REACT_COMPONENT_PREFIX}-input-number-input-wrap`, children: [
4504
- /* @__PURE__ */ jsx(
4505
- "input",
4506
- {
4507
- ...restProps,
4508
- ref,
4509
- disabled,
4510
- inputMode: "decimal",
4511
- value: draftText,
4512
- className: `${REACT_COMPONENT_PREFIX}-input-number-input`,
4513
- onFocus: (event) => {
4514
- setFocused(true);
4515
- onFocus?.(event);
4516
- },
4517
- onChange: (event) => {
4518
- const nextText = event.target.value;
4519
- setDraftText(nextText);
4520
- const parsed = parser ? parser(nextText) : parseNumberText(nextText);
4521
- if (!isControlled) {
4522
- setInnerValue(parsed);
4523
- }
4524
- onChange?.(parsed);
4525
- },
4526
- onBlur: (event) => {
4527
- setFocused(false);
4528
- const parsed = parser ? parser(event.target.value) : parseNumberText(event.target.value);
4529
- commitValue(parsed);
4530
- onBlur?.(event);
4531
- },
4532
- onKeyDown: (event) => {
4533
- if (event.key === "ArrowUp") {
4534
- event.preventDefault();
4535
- stepBy(1);
4536
- } else if (event.key === "ArrowDown") {
4537
- event.preventDefault();
4538
- stepBy(-1);
4539
- } else if (event.key === "Enter") {
4540
- const parsed = parser ? parser(event.currentTarget.value) : parseNumberText(event.currentTarget.value);
4541
- commitValue(parsed);
4542
- }
4543
- onKeyDown?.(event);
5437
+ ) : null,
5438
+ /* @__PURE__ */ jsx("span", { children: okText })
5439
+ ]
5440
+ }
5441
+ )
5442
+ ] });
5443
+ return createPortal(
5444
+ /* @__PURE__ */ jsxs(
5445
+ "div",
5446
+ {
5447
+ className: joinClassNames(
5448
+ `${REACT_COMPONENT_PREFIX}-modal-root`,
5449
+ centered && `${REACT_COMPONENT_PREFIX}-modal-root-centered`,
5450
+ mergedFullscreen && `${REACT_COMPONENT_PREFIX}-modal-root-fullscreen`,
5451
+ transition.className,
5452
+ rootClassName
5453
+ ),
5454
+ style: { zIndex },
5455
+ children: [
5456
+ mask ? /* @__PURE__ */ jsx(
5457
+ "div",
5458
+ {
5459
+ className: `${REACT_COMPONENT_PREFIX}-modal-mask`,
5460
+ style: maskStyle,
5461
+ "aria-hidden": "true",
5462
+ onMouseDown: (event) => {
5463
+ if (maskClosable && event.target === event.currentTarget) {
5464
+ onCancel?.(event);
4544
5465
  }
4545
5466
  }
4546
- ),
4547
- addonAfter != null ? /* @__PURE__ */ jsx("span", { className: `${REACT_COMPONENT_PREFIX}-input-number-addon`, children: addonAfter }) : null
4548
- ] }),
4549
- /* @__PURE__ */ jsx(
4550
- "button",
5467
+ }
5468
+ ) : null,
5469
+ /* @__PURE__ */ jsx("div", { className: `${REACT_COMPONENT_PREFIX}-modal-wrap`, children: /* @__PURE__ */ jsxs(
5470
+ "div",
4551
5471
  {
4552
- type: "button",
4553
- tabIndex: -1,
4554
- disabled: disabled || atMax,
5472
+ ref: panelRef,
4555
5473
  className: joinClassNames(
4556
- `${REACT_COMPONENT_PREFIX}-input-number-handler`,
4557
- `${REACT_COMPONENT_PREFIX}-input-number-handler-up`
5474
+ `${REACT_COMPONENT_PREFIX}-modal`,
5475
+ mergedFullscreen && `${REACT_COMPONENT_PREFIX}-modal-fullscreen`,
5476
+ className
4558
5477
  ),
4559
- "aria-label": "\u589E\u52A0",
4560
- onMouseDown: (event) => {
4561
- event.preventDefault();
4562
- },
4563
- onClick: () => {
4564
- stepBy(1);
4565
- },
4566
- children: /* @__PURE__ */ jsx(
4567
- "span",
4568
- {
4569
- className: `${REACT_COMPONENT_PREFIX}-input-number-handler-icon`,
4570
- "aria-hidden": "true"
4571
- }
4572
- )
5478
+ style: { width, ...style },
5479
+ role: "dialog",
5480
+ "aria-modal": "true",
5481
+ "aria-label": hasTitle ? void 0 : "\u5BF9\u8BDD\u6846",
5482
+ "aria-labelledby": hasTitle ? titleId : void 0,
5483
+ tabIndex: -1,
5484
+ children: [
5485
+ hasTitle || closable || fullscreenable ? /* @__PURE__ */ jsxs("div", { className: `${REACT_COMPONENT_PREFIX}-modal-header`, children: [
5486
+ /* @__PURE__ */ jsx(
5487
+ "div",
5488
+ {
5489
+ id: hasTitle ? titleId : void 0,
5490
+ className: `${REACT_COMPONENT_PREFIX}-modal-title`,
5491
+ children: title
5492
+ }
5493
+ ),
5494
+ /* @__PURE__ */ jsxs("div", { className: `${REACT_COMPONENT_PREFIX}-modal-tools`, children: [
5495
+ fullscreenable ? /* @__PURE__ */ jsx(
5496
+ "button",
5497
+ {
5498
+ type: "button",
5499
+ className: `${REACT_COMPONENT_PREFIX}-modal-tool`,
5500
+ title: mergedFullscreen ? "\u9000\u51FA\u5168\u5C4F" : "\u5168\u5C4F",
5501
+ "aria-label": mergedFullscreen ? "\u9000\u51FA\u5168\u5C4F" : "\u5168\u5C4F",
5502
+ "aria-pressed": mergedFullscreen,
5503
+ onClick: () => setFullscreen(!mergedFullscreen),
5504
+ children: /* @__PURE__ */ jsx(
5505
+ "span",
5506
+ {
5507
+ className: joinClassNames(
5508
+ `${REACT_COMPONENT_PREFIX}-modal-fullscreen-icon`,
5509
+ mergedFullscreen && `${REACT_COMPONENT_PREFIX}-modal-fullscreen-icon-exit`
5510
+ ),
5511
+ "aria-hidden": "true"
5512
+ }
5513
+ )
5514
+ }
5515
+ ) : null,
5516
+ closable ? /* @__PURE__ */ jsx(
5517
+ "button",
5518
+ {
5519
+ type: "button",
5520
+ className: `${REACT_COMPONENT_PREFIX}-modal-tool`,
5521
+ title: "\u5173\u95ED",
5522
+ "aria-label": "\u5173\u95ED",
5523
+ onClick: onCancel,
5524
+ children: /* @__PURE__ */ jsx(
5525
+ "span",
5526
+ {
5527
+ className: `${REACT_COMPONENT_PREFIX}-modal-close-icon`,
5528
+ "aria-hidden": "true"
5529
+ }
5530
+ )
5531
+ }
5532
+ ) : null
5533
+ ] })
5534
+ ] }) : null,
5535
+ /* @__PURE__ */ jsx(
5536
+ "div",
5537
+ {
5538
+ className: `${REACT_COMPONENT_PREFIX}-modal-body`,
5539
+ style: bodyStyle,
5540
+ children
5541
+ }
5542
+ ),
5543
+ footer === false ? null : /* @__PURE__ */ jsx("div", { className: `${REACT_COMPONENT_PREFIX}-modal-footer`, children: footer ?? defaultFooter })
5544
+ ]
4573
5545
  }
4574
- )
5546
+ ) })
4575
5547
  ]
4576
5548
  }
4577
- );
4578
- }
4579
- );
4580
- function parseNumberText(value) {
4581
- const text = value.trim().replace(/%/g, "");
4582
- if (!text) {
4583
- return null;
4584
- }
4585
- const nextValue = Number(text);
4586
- return Number.isFinite(nextValue) ? nextValue : null;
5549
+ ),
5550
+ container
5551
+ );
4587
5552
  }
4588
- function resolvePrecision(precision, step) {
4589
- if (typeof precision === "number" && Number.isInteger(precision) && precision >= 0) {
4590
- return precision;
4591
- }
4592
- const stepText = String(step);
4593
- if (!stepText.includes(".")) {
4594
- return 0;
5553
+ function resolveContainer(getContainer) {
5554
+ if (typeof document === "undefined") {
5555
+ return null;
4595
5556
  }
4596
- return stepText.split(".")[1]?.length ?? 0;
5557
+ return typeof getContainer === "function" ? getContainer() : getContainer ?? document.body;
4597
5558
  }
4598
- function normalizeNumberValue(value, options) {
4599
- if (value == null || !Number.isFinite(value)) {
4600
- return null;
5559
+ function trapFocus(event, panel) {
5560
+ if (!panel) {
5561
+ return;
4601
5562
  }
4602
- let next = value;
4603
- if (options.min != null) {
4604
- next = Math.max(options.min, next);
5563
+ const focusableElements = Array.from(
5564
+ panel.querySelectorAll(FOCUSABLE_SELECTOR)
5565
+ ).filter((element) => element.offsetParent !== null);
5566
+ if (focusableElements.length === 0) {
5567
+ event.preventDefault();
5568
+ panel.focus();
5569
+ return;
4605
5570
  }
4606
- if (options.max != null) {
4607
- next = Math.min(options.max, next);
5571
+ const first = focusableElements[0];
5572
+ const last = focusableElements[focusableElements.length - 1];
5573
+ const active = document.activeElement;
5574
+ if (event.shiftKey && (active === first || !panel.contains(active))) {
5575
+ event.preventDefault();
5576
+ last.focus();
5577
+ } else if (!event.shiftKey && (active === last || !panel.contains(active))) {
5578
+ event.preventDefault();
5579
+ first.focus();
4608
5580
  }
4609
- const factor = 10 ** options.precision;
4610
- return Math.round(next * factor) / factor;
4611
5581
  }
4612
- function formatDisplayValue(value, formatter, precision, step) {
4613
- if (formatter) {
4614
- return formatter(value);
5582
+ function lockBodyScroll() {
5583
+ if (bodyScrollLockCount === 0) {
5584
+ bodyOverflowBeforeLock = document.body.style.overflow;
5585
+ document.body.style.overflow = "hidden";
4615
5586
  }
4616
- if (value == null || !Number.isFinite(value)) {
4617
- return "";
5587
+ bodyScrollLockCount += 1;
5588
+ }
5589
+ function unlockBodyScroll() {
5590
+ bodyScrollLockCount = Math.max(0, bodyScrollLockCount - 1);
5591
+ if (bodyScrollLockCount === 0) {
5592
+ document.body.style.overflow = bodyOverflowBeforeLock;
4618
5593
  }
4619
- const digits = resolvePrecision(precision, step);
4620
- return digits > 0 ? value.toFixed(digits) : String(Math.round(value));
5594
+ }
5595
+ function isPromiseLike(value) {
5596
+ return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
4621
5597
  }
4622
5598
 
4623
- // src/components/virtual-list/style.css
4624
- styleInject('@import "../../styles/variables.css";\n.canvas-react-virtual-list {\n position: relative;\n overflow-y: auto;\n}\n.canvas-react-virtual-list-inner {\n position: relative;\n min-width: 100%;\n}\n.canvas-react-virtual-list-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 0 11px;\n color: #9ca3af;\n font-size: var(--canvas-react-font-size);\n}\n');
4625
- var ReactVirtualList = forwardRef(function ReactVirtualListInner(props, ref) {
4626
- const {
4627
- className,
4628
- empty,
4629
- height,
4630
- innerClassName,
4631
- itemHeight,
4632
- itemKey,
4633
- items,
4634
- overscan = 2,
4635
- renderItem,
4636
- style,
4637
- virtual = true
4638
- } = props;
4639
- const hostRef = useRef(null);
4640
- const [scrollTop, setScrollTop] = useState(0);
4641
- const useVirtual = virtual && items.length * itemHeight > height;
4642
- const startIndex = useVirtual ? Math.max(0, Math.floor(scrollTop / itemHeight) - overscan) : 0;
4643
- const endIndex = useVirtual ? Math.min(
4644
- items.length - 1,
4645
- Math.ceil((scrollTop + height) / itemHeight) + overscan
4646
- ) : items.length - 1;
4647
- const visibleItems = useMemo(
4648
- () => items.slice(startIndex, endIndex + 1),
4649
- [endIndex, items, startIndex]
4650
- );
4651
- useImperativeHandle(ref, () => ({
4652
- scrollToIndex: (index) => {
4653
- const element = hostRef.current;
4654
- if (!element || index < 0) {
4655
- return;
4656
- }
4657
- const itemTop = index * itemHeight;
4658
- const itemBottom = itemTop + itemHeight;
4659
- const viewportTop = element.scrollTop;
4660
- const viewportBottom = viewportTop + height;
4661
- if (itemTop < viewportTop) {
4662
- element.scrollTop = itemTop;
4663
- return;
4664
- }
4665
- if (itemBottom > viewportBottom) {
4666
- element.scrollTop = itemBottom - height;
4667
- }
4668
- },
4669
- element: hostRef.current
4670
- }));
4671
- return /* @__PURE__ */ jsx(
4672
- "div",
4673
- {
4674
- ref: hostRef,
4675
- className: joinClassNames(`${REACT_COMPONENT_PREFIX}-virtual-list`, className),
4676
- style: { height, ...style },
4677
- onScroll: (event) => {
4678
- setScrollTop(event.currentTarget.scrollTop);
4679
- },
4680
- children: items.length === 0 ? /* @__PURE__ */ jsx("div", { className: `${REACT_COMPONENT_PREFIX}-virtual-list-empty`, children: empty ?? "\u6682\u65E0\u6570\u636E" }) : /* @__PURE__ */ jsx(
4681
- "div",
4682
- {
4683
- className: joinClassNames(
4684
- `${REACT_COMPONENT_PREFIX}-virtual-list-inner`,
4685
- innerClassName
4686
- ),
4687
- style: { height: items.length * itemHeight },
4688
- children: visibleItems.map((item, index) => {
4689
- const itemIndex = startIndex + index;
4690
- return renderItem(item, itemIndex, {
4691
- style: useVirtual ? {
4692
- position: "absolute",
4693
- top: itemIndex * itemHeight,
4694
- left: 0,
4695
- right: 0,
4696
- height: itemHeight
4697
- } : {
4698
- height: itemHeight
4699
- }
4700
- });
4701
- })
4702
- }
4703
- )
4704
- }
4705
- );
4706
- });
4707
-
4708
- // src/components/select/style.css
4709
- styleInject('@import "../../styles/variables.css";\n.canvas-react-select-wrap {\n position: relative;\n display: inline-flex;\n width: 100%;\n height: 100%;\n}\n.canvas-react-select {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: var(--canvas-react-control-height);\n padding: var(--canvas-react-control-padding-block, 0px) var(--canvas-react-control-padding-inline, 11px);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n outline: none;\n cursor: pointer;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-select-input-wrap {\n flex: 1 1 auto;\n width: 100%;\n height: 100%;\n border: none;\n background: transparent;\n box-shadow: none;\n}\n.canvas-react-select .canvas-react-input-affix-wrapper {\n height: 100%;\n min-height: 0;\n}\n.canvas-react-select-input-wrap:hover,\n.canvas-react-select-input-wrap:focus-within {\n border-color: transparent;\n box-shadow: none;\n}\n.canvas-react-select-input {\n width: 100%;\n min-width: 0;\n height: 100%;\n padding: 0;\n line-height: normal;\n}\n.canvas-react-select-input::placeholder {\n color: #9ca3af;\n}\n.canvas-react-select:hover {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-select:focus {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-select-open {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-select-disabled {\n color: #9ca3af;\n background: #fafafa;\n cursor: not-allowed;\n}\n.canvas-react-select-actions {\n position: relative;\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n width: 1em;\n min-width: 12px;\n height: 1em;\n min-height: 12px;\n margin-left: max(6px, calc(var(--canvas-react-control-padding-inline, 11px) * 0.5));\n}\n.canvas-react-select-arrow {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 0.5em;\n height: 0.5em;\n min-width: 6px;\n min-height: 6px;\n border-right: 1.5px solid var(--canvas-react-color-text-muted);\n border-bottom: 1.5px solid var(--canvas-react-color-text-muted);\n transform: translate(-50%, -58%) rotate(45deg);\n opacity: 1;\n transition:\n opacity 0.18s ease,\n transform 0.18s ease,\n border-color 0.18s ease;\n}\n.canvas-react-select:hover .canvas-react-select-arrow,\n.canvas-react-select-open .canvas-react-select-arrow {\n border-color: #6b7280;\n}\n.canvas-react-select-arrow-open {\n border-color: #6b7280;\n transform: translate(-50%, -42%) rotate(225deg);\n}\n.canvas-react-select-clear {\n position: absolute;\n top: 50%;\n left: 50%;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 12px;\n height: 12px;\n padding: 0;\n border: none;\n background: transparent;\n color: #9ca3af;\n opacity: 0;\n pointer-events: none;\n cursor: pointer;\n transform: translate(-50%, -50%) rotate(0deg);\n transition:\n color 0.2s ease,\n opacity 0.2s ease,\n transform 0.18s ease;\n}\n.canvas-react-select-clear:hover {\n color: #6b7280;\n transform: translate(-50%, -50%) rotate(90deg);\n}\n.canvas-react-select:hover .canvas-react-select-clear,\n.canvas-react-select-open .canvas-react-select-clear,\n.canvas-react-select:focus-within .canvas-react-select-clear {\n opacity: 1;\n pointer-events: auto;\n}\n.canvas-react-select:hover .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-select-open .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-select:focus-within .canvas-react-select-actions-clearable .canvas-react-select-arrow {\n opacity: 0;\n}\n.canvas-react-select-clear-icon,\n.canvas-react-select-clear-icon::before {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 8px;\n height: 1.25px;\n margin-top: -0.625px;\n margin-left: -4px;\n border-radius: 999px;\n background: currentColor;\n content: "";\n}\n.canvas-react-select-clear-icon {\n transform: rotate(45deg);\n}\n.canvas-react-select-clear-icon::before {\n transform: rotate(90deg);\n}\n.canvas-react-select-dropdown {\n padding: 4px;\n}\n.canvas-react-select-list {\n position: relative;\n overflow-y: auto;\n}\n.canvas-react-select-list-inner {\n position: relative;\n}\n.canvas-react-select-option {\n display: flex;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n padding: 0 11px;\n border-radius: var(--canvas-react-radius-sm);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n cursor: pointer;\n}\n.canvas-react-select-option:hover,\n.canvas-react-select-option-active {\n background: var(--canvas-react-color-bg-hover);\n}\n.canvas-react-select-option-selected {\n background: var(--canvas-react-color-bg-active);\n color: var(--canvas-react-color-primary);\n}\n.canvas-react-select-option-disabled {\n color: #9ca3af;\n cursor: not-allowed;\n}\n.canvas-react-select-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 0 11px;\n color: #9ca3af;\n font-size: var(--canvas-react-font-size);\n}\n');
4710
- var ReactSelect = forwardRef(
4711
- function ReactSelect2(props, ref) {
5599
+ // src/components/input-number/style.css
5600
+ styleInject('@import "../../styles/variables.css";\n.canvas-react-input-number {\n box-sizing: border-box;\n display: inline-flex;\n align-items: stretch;\n width: 100%;\n min-width: 0;\n height: var(--canvas-react-control-height);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n overflow: hidden;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-input-number:hover {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-input-number-focused {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-input-number-disabled {\n background: #fafafa;\n color: #9ca3af;\n cursor: not-allowed;\n}\n.canvas-react-input-number-handler {\n position: relative;\n display: flex;\n flex: 0 0 28px;\n align-items: center;\n justify-content: center;\n margin: 0;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--canvas-react-color-text-muted);\n cursor: pointer;\n transition: color 0.16s ease, background-color 0.16s ease;\n}\n.canvas-react-input-number-handler-down {\n border-right: 1px solid var(--canvas-react-color-border);\n}\n.canvas-react-input-number-handler-up {\n border-left: 1px solid var(--canvas-react-color-border);\n}\n.canvas-react-input-number-handler:hover:not(:disabled) {\n color: var(--canvas-react-color-primary);\n background: rgba(22, 119, 255, 0.06);\n}\n.canvas-react-input-number-handler:disabled {\n color: #c4c7cf;\n cursor: not-allowed;\n}\n.canvas-react-input-number-handler-icon {\n position: relative;\n display: block;\n width: 10px;\n height: 10px;\n}\n.canvas-react-input-number-handler-icon::before,\n.canvas-react-input-number-handler-icon::after {\n content: "";\n position: absolute;\n top: 50%;\n left: 50%;\n background: currentColor;\n border-radius: 1px;\n transform: translate(-50%, -50%);\n}\n.canvas-react-input-number-handler-icon::before {\n width: 10px;\n height: 1.5px;\n}\n.canvas-react-input-number-handler-up .canvas-react-input-number-handler-icon::after {\n width: 1.5px;\n height: 10px;\n}\n.canvas-react-input-number-input-wrap {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n min-width: 0;\n height: 100%;\n}\n.canvas-react-input-number-input {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n height: 100%;\n padding: 0 8px;\n border: none;\n background: transparent;\n color: inherit;\n font-size: inherit;\n outline: none;\n text-align: center;\n appearance: textfield;\n -moz-appearance: textfield;\n}\n.canvas-react-input-number-input::placeholder {\n color: #9ca3af;\n}\n.canvas-react-input-number-input::-webkit-outer-spin-button,\n.canvas-react-input-number-input::-webkit-inner-spin-button {\n margin: 0;\n -webkit-appearance: none;\n}\n.canvas-react-input-number-addon {\n flex: 0 0 auto;\n padding-right: 8px;\n color: var(--canvas-react-color-text-muted);\n font-size: 12px;\n line-height: 1;\n user-select: none;\n}\n');
5601
+ var ReactInputNumber = forwardRef(
5602
+ function ReactInputNumber2(props, ref) {
4712
5603
  const {
4713
- autoFocus,
5604
+ addonAfter,
4714
5605
  className,
5606
+ defaultValue = null,
4715
5607
  disabled,
5608
+ formatter,
5609
+ max,
5610
+ min,
4716
5611
  onBlur,
4717
5612
  onChange,
5613
+ onCommit,
4718
5614
  onFocus,
4719
5615
  onKeyDown,
4720
- options,
4721
- optionHeight = 32,
4722
- listHeight = 224,
4723
- placeholder,
4724
- popupClassName,
4725
- allowClear = true,
4726
- showArrow = true,
4727
- showSearch = false,
5616
+ parser,
5617
+ precision,
5618
+ step = 1,
4728
5619
  style,
4729
5620
  value,
4730
- virtual = true,
4731
5621
  ...restProps
4732
5622
  } = props;
4733
- const triggerRef = useRef(null);
4734
- const inputRef = useRef(null);
4735
- const listRef = useRef(null);
4736
- const skipFocusOpenRef = useRef(false);
4737
- const [open, setOpen] = useState(false);
4738
- const selectedIndex = useMemo(
4739
- () => options.findIndex((option) => String(option.value) === String(value ?? "")),
4740
- [options, value]
5623
+ const isControlled = value !== void 0;
5624
+ const [innerValue, setInnerValue] = useState(
5625
+ isControlled ? value ?? null : defaultValue
5626
+ );
5627
+ const currentValue = isControlled ? value ?? null : innerValue;
5628
+ const [draftText, setDraftText] = useState(
5629
+ formatDisplayValue(
5630
+ currentValue,
5631
+ formatter,
5632
+ resolvePrecision(precision, step),
5633
+ step
5634
+ )
5635
+ );
5636
+ const [focused, setFocused] = useState(false);
5637
+ const resolvedPrecision = useMemo(
5638
+ () => resolvePrecision(precision, step),
5639
+ [precision, step]
4741
5640
  );
4742
- const selectedOption = selectedIndex >= 0 ? options[selectedIndex] : void 0;
4743
- const [keyword, setKeyword] = useState(selectedOption?.label ?? "");
4744
- const filteredOptions = useMemo(() => {
4745
- if (!showSearch) {
4746
- return options;
4747
- }
4748
- const search = keyword.trim().toLowerCase();
4749
- if (!search) {
4750
- return options;
4751
- }
4752
- return options.filter((option) => {
4753
- return option.label.toLowerCase().includes(search) || String(option.value).toLowerCase().includes(search);
4754
- });
4755
- }, [keyword, options]);
4756
- const [activeIndex, setActiveIndex] = useState(() => {
4757
- return selectedIndex >= 0 ? selectedIndex : 0;
4758
- });
4759
- useImperativeHandle(ref, () => inputRef.current);
4760
- useEffect(() => {
4761
- if (autoFocus) {
4762
- inputRef.current?.focus();
4763
- }
4764
- }, [autoFocus]);
4765
5641
  useEffect(() => {
4766
- if (!open) {
4767
- setKeyword(selectedOption?.label ?? "");
5642
+ if (!focused) {
5643
+ setDraftText(
5644
+ formatDisplayValue(currentValue, formatter, resolvedPrecision, step)
5645
+ );
4768
5646
  }
4769
- }, [open, selectedOption]);
4770
- useEffect(() => {
4771
- const nextIndex = filteredOptions.findIndex(
4772
- (option) => String(option.value) === String(value ?? "")
5647
+ }, [currentValue, focused, formatter, resolvedPrecision, step]);
5648
+ const commitValue = (nextValue) => {
5649
+ const normalized = normalizeNumberValue(nextValue, {
5650
+ min,
5651
+ max,
5652
+ precision: resolvedPrecision
5653
+ });
5654
+ if (!isControlled) {
5655
+ setInnerValue(normalized);
5656
+ }
5657
+ onChange?.(normalized);
5658
+ onCommit?.(normalized);
5659
+ setDraftText(
5660
+ formatDisplayValue(normalized, formatter, resolvedPrecision, step)
4773
5661
  );
4774
- setActiveIndex(nextIndex >= 0 ? nextIndex : 0);
4775
- }, [filteredOptions, value]);
4776
- useEffect(() => {
4777
- if (!open) {
5662
+ return normalized;
5663
+ };
5664
+ const stepBy = (direction) => {
5665
+ if (disabled) {
4778
5666
  return;
4779
5667
  }
4780
- listRef.current?.scrollToIndex(activeIndex);
4781
- }, [activeIndex, listHeight, open, optionHeight]);
4782
- const selectOption = (option) => {
4783
- onChange?.(String(option.value));
4784
- setKeyword(option.label);
4785
- setOpen(false);
4786
- inputRef.current?.focus();
4787
- };
4788
- const hasValue = value != null && String(value).length > 0;
4789
- const showClear = allowClear && !disabled && hasValue;
4790
- const handleClear = (event) => {
4791
- event.preventDefault();
4792
- event.stopPropagation();
4793
- skipFocusOpenRef.current = true;
4794
- setKeyword("");
4795
- setOpen(false);
4796
- onChange?.("");
4797
- inputRef.current?.blur();
5668
+ const base = currentValue == null || !Number.isFinite(currentValue) ? 0 : currentValue;
5669
+ const next = base + direction * step;
5670
+ commitValue(next);
4798
5671
  };
4799
- return /* @__PURE__ */ jsxs("span", { className: `${REACT_COMPONENT_PREFIX}-select-wrap`, children: [
4800
- /* @__PURE__ */ jsxs(
4801
- "div",
4802
- {
4803
- ref: triggerRef,
4804
- className: joinClassNames(
4805
- `${REACT_COMPONENT_PREFIX}-select`,
4806
- open && `${REACT_COMPONENT_PREFIX}-select-open`,
4807
- disabled && `${REACT_COMPONENT_PREFIX}-select-disabled`,
4808
- className
4809
- ),
4810
- style,
4811
- onClick: (event) => {
4812
- if (disabled) {
4813
- return;
4814
- }
4815
- if (event.target?.closest(
4816
- `.${REACT_COMPONENT_PREFIX}-select-clear`
4817
- )) {
4818
- return;
4819
- }
4820
- if (event.target?.closest(
4821
- `.${REACT_COMPONENT_PREFIX}-select-arrow`
4822
- )) {
4823
- return;
4824
- }
4825
- inputRef.current?.focus();
4826
- if (!open) {
4827
- setOpen(true);
5672
+ const atMin = currentValue != null && min != null && currentValue <= min + Number.EPSILON;
5673
+ const atMax = currentValue != null && max != null && currentValue >= max - Number.EPSILON;
5674
+ return /* @__PURE__ */ jsxs(
5675
+ "span",
5676
+ {
5677
+ className: joinClassNames(
5678
+ `${REACT_COMPONENT_PREFIX}-input-number`,
5679
+ focused && `${REACT_COMPONENT_PREFIX}-input-number-focused`,
5680
+ disabled && `${REACT_COMPONENT_PREFIX}-input-number-disabled`,
5681
+ className
5682
+ ),
5683
+ style,
5684
+ children: [
5685
+ /* @__PURE__ */ jsx(
5686
+ "button",
5687
+ {
5688
+ type: "button",
5689
+ tabIndex: -1,
5690
+ disabled: disabled || atMin,
5691
+ className: joinClassNames(
5692
+ `${REACT_COMPONENT_PREFIX}-input-number-handler`,
5693
+ `${REACT_COMPONENT_PREFIX}-input-number-handler-down`
5694
+ ),
5695
+ "aria-label": "\u51CF\u5C11",
5696
+ onMouseDown: (event) => {
5697
+ event.preventDefault();
5698
+ },
5699
+ onClick: () => {
5700
+ stepBy(-1);
5701
+ },
5702
+ children: /* @__PURE__ */ jsx(
5703
+ "span",
5704
+ {
5705
+ className: `${REACT_COMPONENT_PREFIX}-input-number-handler-icon`,
5706
+ "aria-hidden": "true"
5707
+ }
5708
+ )
4828
5709
  }
4829
- },
4830
- children: [
5710
+ ),
5711
+ /* @__PURE__ */ jsxs("span", { className: `${REACT_COMPONENT_PREFIX}-input-number-input-wrap`, children: [
4831
5712
  /* @__PURE__ */ jsx(
4832
- ReactInput,
5713
+ "input",
4833
5714
  {
4834
5715
  ...restProps,
4835
- ref: inputRef,
4836
- allowClear: false,
5716
+ ref,
4837
5717
  disabled,
4838
- readOnly: !showSearch,
4839
- value: open && showSearch ? keyword : selectedOption?.label ?? "",
4840
- className: joinClassNames(`${REACT_COMPONENT_PREFIX}-select-input`),
4841
- wrapperClassName: `${REACT_COMPONENT_PREFIX}-select-input-wrap`,
4842
- placeholder,
5718
+ inputMode: "decimal",
5719
+ value: draftText,
5720
+ className: `${REACT_COMPONENT_PREFIX}-input-number-input`,
4843
5721
  onFocus: (event) => {
4844
- if (skipFocusOpenRef.current) {
4845
- skipFocusOpenRef.current = false;
4846
- onFocus?.(event);
4847
- return;
4848
- }
4849
- if (!open) {
4850
- setOpen(true);
4851
- }
4852
- if (!open && showSearch) {
4853
- setKeyword(selectedOption?.label ?? "");
4854
- }
5722
+ setFocused(true);
4855
5723
  onFocus?.(event);
4856
5724
  },
4857
- onBlur: (event) => {
4858
- setOpen(false);
4859
- if ((!keyword.trim() || !showSearch) && selectedOption) {
4860
- setKeyword(selectedOption.label);
4861
- }
4862
- onBlur?.(event);
4863
- },
4864
5725
  onChange: (event) => {
4865
- if (!showSearch) {
4866
- return;
5726
+ const nextText = event.target.value;
5727
+ setDraftText(nextText);
5728
+ const parsed = parser ? parser(nextText) : parseNumberText(nextText);
5729
+ if (!isControlled) {
5730
+ setInnerValue(parsed);
4867
5731
  }
4868
- setKeyword(event.target.value);
4869
- setOpen(true);
5732
+ onChange?.(parsed);
4870
5733
  },
4871
- onKeyDown: (event) => {
4872
- onKeyDown?.(event);
4873
- if (event.defaultPrevented) {
4874
- return;
4875
- }
4876
- if (disabled) {
4877
- return;
4878
- }
4879
- if (event.key === "ArrowDown") {
4880
- event.preventDefault();
4881
- if (!open) {
4882
- setOpen(true);
4883
- return;
4884
- }
4885
- setActiveIndex(
4886
- (prev) => Math.min(prev + 1, Math.max(filteredOptions.length - 1, 0))
4887
- );
4888
- return;
4889
- }
4890
- if (event.key === "ArrowUp") {
4891
- event.preventDefault();
4892
- if (!open) {
4893
- setOpen(true);
4894
- return;
4895
- }
4896
- setActiveIndex((prev) => Math.max(prev - 1, 0));
4897
- return;
4898
- }
4899
- if (event.key === "Enter") {
4900
- event.preventDefault();
4901
- if (!open) {
4902
- setOpen(true);
4903
- return;
4904
- }
4905
- const targetOption = filteredOptions[activeIndex];
4906
- if (targetOption && !targetOption.disabled) {
4907
- selectOption(targetOption);
4908
- }
4909
- return;
4910
- }
4911
- if (event.key === "Escape") {
4912
- setKeyword(selectedOption?.label ?? "");
4913
- setOpen(false);
4914
- }
4915
- }
4916
- }
4917
- ),
4918
- showClear || showArrow ? /* @__PURE__ */ jsxs(
4919
- "span",
4920
- {
4921
- className: joinClassNames(
4922
- `${REACT_COMPONENT_PREFIX}-select-actions`,
4923
- showClear && `${REACT_COMPONENT_PREFIX}-select-actions-clearable`
4924
- ),
4925
- children: [
4926
- showClear ? /* @__PURE__ */ jsx(
4927
- "button",
4928
- {
4929
- type: "button",
4930
- className: `${REACT_COMPONENT_PREFIX}-select-clear`,
4931
- "aria-label": "\u6E05\u7A7A",
4932
- tabIndex: -1,
4933
- onMouseDown: (event) => {
4934
- event.preventDefault();
4935
- event.stopPropagation();
4936
- },
4937
- onClick: handleClear,
4938
- children: /* @__PURE__ */ jsx(
4939
- "span",
4940
- {
4941
- className: `${REACT_COMPONENT_PREFIX}-select-clear-icon`
4942
- }
4943
- )
4944
- }
4945
- ) : null,
4946
- showArrow ? /* @__PURE__ */ jsx(
4947
- "span",
4948
- {
4949
- className: joinClassNames(
4950
- `${REACT_COMPONENT_PREFIX}-select-arrow`,
4951
- open && `${REACT_COMPONENT_PREFIX}-select-arrow-open`
4952
- )
4953
- }
4954
- ) : null
4955
- ]
4956
- }
4957
- ) : null
4958
- ]
4959
- }
4960
- ),
4961
- /* @__PURE__ */ jsx(
4962
- ReactPopup,
4963
- {
4964
- open,
4965
- anchorRef: triggerRef,
4966
- matchAnchorWidth: true,
4967
- surfaceClassName: joinClassNames(
4968
- `${REACT_COMPONENT_PREFIX}-select-dropdown`,
4969
- popupClassName
4970
- ),
4971
- onOpenChange: setOpen,
4972
- children: /* @__PURE__ */ jsx(
4973
- ReactVirtualList,
5734
+ onBlur: (event) => {
5735
+ setFocused(false);
5736
+ const parsed = parser ? parser(event.target.value) : parseNumberText(event.target.value);
5737
+ commitValue(parsed);
5738
+ onBlur?.(event);
5739
+ },
5740
+ onKeyDown: (event) => {
5741
+ if (event.key === "ArrowUp") {
5742
+ event.preventDefault();
5743
+ stepBy(1);
5744
+ } else if (event.key === "ArrowDown") {
5745
+ event.preventDefault();
5746
+ stepBy(-1);
5747
+ } else if (event.key === "Enter") {
5748
+ const parsed = parser ? parser(event.currentTarget.value) : parseNumberText(event.currentTarget.value);
5749
+ commitValue(parsed);
5750
+ }
5751
+ onKeyDown?.(event);
5752
+ }
5753
+ }
5754
+ ),
5755
+ addonAfter != null ? /* @__PURE__ */ jsx("span", { className: `${REACT_COMPONENT_PREFIX}-input-number-addon`, children: addonAfter }) : null
5756
+ ] }),
5757
+ /* @__PURE__ */ jsx(
5758
+ "button",
4974
5759
  {
4975
- ref: listRef,
4976
- items: filteredOptions,
4977
- height: Math.min(
4978
- listHeight,
4979
- Math.max(filteredOptions.length, 1) * optionHeight
5760
+ type: "button",
5761
+ tabIndex: -1,
5762
+ disabled: disabled || atMax,
5763
+ className: joinClassNames(
5764
+ `${REACT_COMPONENT_PREFIX}-input-number-handler`,
5765
+ `${REACT_COMPONENT_PREFIX}-input-number-handler-up`
4980
5766
  ),
4981
- itemHeight: optionHeight,
4982
- virtual,
4983
- className: `${REACT_COMPONENT_PREFIX}-select-list`,
4984
- innerClassName: `${REACT_COMPONENT_PREFIX}-select-list-inner`,
4985
- empty: /* @__PURE__ */ jsx("div", { className: `${REACT_COMPONENT_PREFIX}-select-empty`, children: "\u6682\u65E0\u6570\u636E" }),
4986
- itemKey: (option) => String(option.value),
4987
- renderItem: (option, optionIndex, meta) => {
4988
- const isSelected = String(option.value) === String(value ?? "");
4989
- const isActive = optionIndex === activeIndex;
4990
- return /* @__PURE__ */ jsx(
4991
- "div",
4992
- {
4993
- className: joinClassNames(
4994
- `${REACT_COMPONENT_PREFIX}-select-option`,
4995
- isSelected && `${REACT_COMPONENT_PREFIX}-select-option-selected`,
4996
- isActive && `${REACT_COMPONENT_PREFIX}-select-option-active`,
4997
- option.disabled && `${REACT_COMPONENT_PREFIX}-select-option-disabled`
4998
- ),
4999
- style: meta.style,
5000
- onMouseDown: (event) => {
5001
- event.preventDefault();
5002
- },
5003
- onMouseEnter: () => {
5004
- setActiveIndex(optionIndex);
5005
- },
5006
- onClick: () => {
5007
- if (option.disabled) {
5008
- return;
5009
- }
5010
- selectOption(option);
5011
- },
5012
- children: option.label
5013
- },
5014
- String(option.value)
5015
- );
5016
- }
5767
+ "aria-label": "\u589E\u52A0",
5768
+ onMouseDown: (event) => {
5769
+ event.preventDefault();
5770
+ },
5771
+ onClick: () => {
5772
+ stepBy(1);
5773
+ },
5774
+ children: /* @__PURE__ */ jsx(
5775
+ "span",
5776
+ {
5777
+ className: `${REACT_COMPONENT_PREFIX}-input-number-handler-icon`,
5778
+ "aria-hidden": "true"
5779
+ }
5780
+ )
5017
5781
  }
5018
5782
  )
5019
- }
5020
- )
5021
- ] });
5783
+ ]
5784
+ }
5785
+ );
5022
5786
  }
5023
5787
  );
5788
+ function parseNumberText(value) {
5789
+ const text = value.trim().replace(/%/g, "");
5790
+ if (!text) {
5791
+ return null;
5792
+ }
5793
+ const nextValue = Number(text);
5794
+ return Number.isFinite(nextValue) ? nextValue : null;
5795
+ }
5796
+ function resolvePrecision(precision, step) {
5797
+ if (typeof precision === "number" && Number.isInteger(precision) && precision >= 0) {
5798
+ return precision;
5799
+ }
5800
+ const stepText = String(step);
5801
+ if (!stepText.includes(".")) {
5802
+ return 0;
5803
+ }
5804
+ return stepText.split(".")[1]?.length ?? 0;
5805
+ }
5806
+ function normalizeNumberValue(value, options) {
5807
+ if (value == null || !Number.isFinite(value)) {
5808
+ return null;
5809
+ }
5810
+ let next = value;
5811
+ if (options.min != null) {
5812
+ next = Math.max(options.min, next);
5813
+ }
5814
+ if (options.max != null) {
5815
+ next = Math.min(options.max, next);
5816
+ }
5817
+ const factor = 10 ** options.precision;
5818
+ return Math.round(next * factor) / factor;
5819
+ }
5820
+ function formatDisplayValue(value, formatter, precision, step) {
5821
+ if (formatter) {
5822
+ return formatter(value);
5823
+ }
5824
+ if (value == null || !Number.isFinite(value)) {
5825
+ return "";
5826
+ }
5827
+ const digits = resolvePrecision(precision, step);
5828
+ return digits > 0 ? value.toFixed(digits) : String(Math.round(value));
5829
+ }
5024
5830
 
5025
5831
  // src/components/pagination/style.css
5026
5832
  styleInject('@import "../../styles/variables.css";\n.canvas-react-pagination {\n display: flex;\n align-items: center;\n flex-wrap: nowrap;\n gap: 8px;\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n white-space: nowrap;\n}\n.canvas-react-pagination-pages {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n flex-wrap: nowrap;\n}\n.canvas-react-pagination-button,\n.canvas-react-pagination-page {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 32px;\n height: 32px;\n padding: 0 10px;\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n cursor: pointer;\n transition:\n border-color 0.2s ease,\n color 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-pagination-button {\n position: relative;\n width: 32px;\n min-width: 32px;\n padding: 0;\n}\n.canvas-react-pagination-button:hover,\n.canvas-react-pagination-page:hover {\n border-color: var(--canvas-react-color-primary-hover);\n color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-pagination-page-active {\n border-color: var(--canvas-react-color-primary);\n background: var(--canvas-react-color-bg-active);\n color: var(--canvas-react-color-primary);\n}\n.canvas-react-pagination-button:disabled,\n.canvas-react-pagination-page:disabled {\n opacity: 0.48;\n cursor: not-allowed;\n}\n.canvas-react-pagination-ellipsis {\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-pagination-arrow {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 7px;\n height: 7px;\n border-right: 1.5px solid var(--canvas-react-color-text-muted);\n border-bottom: 1.5px solid var(--canvas-react-color-text-muted);\n transition:\n border-color 0.18s ease,\n transform 0.18s ease,\n opacity 0.18s ease;\n}\n.canvas-react-pagination-arrow-prev {\n transform: translate(-42%, -50%) rotate(135deg);\n}\n.canvas-react-pagination-arrow-next {\n transform: translate(-58%, -50%) rotate(-45deg);\n}\n.canvas-react-pagination-button:hover .canvas-react-pagination-arrow {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-pagination-button:disabled .canvas-react-pagination-arrow {\n opacity: 0.56;\n}\n.canvas-react-pagination-quick {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n flex-wrap: nowrap;\n}\n.canvas-react-pagination-total {\n color: var(--canvas-react-color-text-muted);\n}\n');
@@ -5225,8 +6031,8 @@ function ReactPopconfirm(props) {
5225
6031
  const triggerRef = useRef(null);
5226
6032
  const [innerOpen, setInnerOpen] = useState(defaultOpen);
5227
6033
  const [innerConfirmLoading, setInnerConfirmLoading] = useState(false);
5228
- const titleId = useId();
5229
- const descriptionId = useId();
6034
+ const titleId = useCompatibleId("canvas-react-popconfirm-title");
6035
+ const descriptionId = useCompatibleId("canvas-react-popconfirm-description");
5230
6036
  const controlled = open !== void 0;
5231
6037
  const mergedOpen = controlled ? Boolean(open) : innerOpen;
5232
6038
  const popupOpen = mergedOpen && !disabled;
@@ -5266,7 +6072,7 @@ function ReactPopconfirm(props) {
5266
6072
  return;
5267
6073
  }
5268
6074
  const result = onConfirm?.(event);
5269
- if (isPromiseLike(result)) {
6075
+ if (isPromiseLike2(result)) {
5270
6076
  setInnerConfirmLoading(true);
5271
6077
  Promise.resolve(result).then(() => {
5272
6078
  setOpen(false);
@@ -5414,7 +6220,7 @@ function ReactPopconfirm(props) {
5414
6220
  )
5415
6221
  ] });
5416
6222
  }
5417
- function isPromiseLike(value) {
6223
+ function isPromiseLike2(value) {
5418
6224
  return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
5419
6225
  }
5420
6226
 
@@ -5802,6 +6608,413 @@ function parseQuarterValue(value) {
5802
6608
  function resolveDecadeStart5(year) {
5803
6609
  return Math.floor(year / 10) * 10;
5804
6610
  }
6611
+
6612
+ // src/components/resizable-panels/style.css
6613
+ styleInject('@import "../../styles/variables.css";\n.canvas-react-resizable-panels {\n display: flex;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n overflow: auto;\n background: var(--canvas-react-color-bg, #ffffff);\n}\n.canvas-react-resizable-panels-horizontal {\n flex-direction: row;\n}\n.canvas-react-resizable-panels-vertical {\n flex-direction: column;\n}\n.canvas-react-resizable-panels-resizing {\n cursor: inherit;\n}\n.canvas-react-resizable-panels-item {\n display: contents;\n}\n.canvas-react-resizable-panel {\n min-width: 0;\n min-height: 0;\n overflow: auto;\n}\n.canvas-react-resizable-panels-animated:not(.canvas-react-resizable-panels-resizing) .canvas-react-resizable-panel {\n transition:\n flex-basis 0.22s cubic-bezier(0.2, 0, 0, 1),\n width 0.22s cubic-bezier(0.2, 0, 0, 1),\n min-width 0.22s cubic-bezier(0.2, 0, 0, 1),\n max-width 0.22s cubic-bezier(0.2, 0, 0, 1),\n height 0.22s cubic-bezier(0.2, 0, 0, 1),\n min-height 0.22s cubic-bezier(0.2, 0, 0, 1),\n max-height 0.22s cubic-bezier(0.2, 0, 0, 1),\n opacity 0.14s ease;\n}\n.canvas-react-resizable-panel-collapsed {\n visibility: hidden;\n overflow: hidden;\n opacity: 0;\n pointer-events: none;\n}\n.canvas-react-resizable-panels-animated:not(.canvas-react-resizable-panels-resizing) .canvas-react-resizable-panel-collapsed {\n transition:\n flex-basis 0.22s cubic-bezier(0.2, 0, 0, 1),\n width 0.22s cubic-bezier(0.2, 0, 0, 1),\n min-width 0.22s cubic-bezier(0.2, 0, 0, 1),\n max-width 0.22s cubic-bezier(0.2, 0, 0, 1),\n height 0.22s cubic-bezier(0.2, 0, 0, 1),\n min-height 0.22s cubic-bezier(0.2, 0, 0, 1),\n max-height 0.22s cubic-bezier(0.2, 0, 0, 1),\n opacity 0.14s ease,\n visibility 0s linear 0.22s;\n}\n.canvas-react-resizable-panels-divider {\n position: relative;\n z-index: 1;\n flex: 0 0 9px;\n touch-action: none;\n outline: none;\n}\n.canvas-react-resizable-panels-divider-horizontal {\n align-self: stretch;\n width: 9px;\n min-height: 24px;\n cursor: col-resize;\n}\n.canvas-react-resizable-panels-divider-vertical {\n width: auto;\n min-width: 24px;\n height: 9px;\n cursor: row-resize;\n}\n.canvas-react-resizable-panels-animated .canvas-react-resizable-panels-divider {\n transition:\n flex-basis 0.22s cubic-bezier(0.2, 0, 0, 1),\n width 0.22s cubic-bezier(0.2, 0, 0, 1),\n height 0.22s cubic-bezier(0.2, 0, 0, 1),\n opacity 0.14s ease;\n}\n.canvas-react-resizable-panels-divider-collapsed {\n flex-basis: 0;\n overflow: hidden;\n opacity: 0;\n pointer-events: none;\n}\n.canvas-react-resizable-panels-divider-horizontal.canvas-react-resizable-panels-divider-collapsed {\n width: 0;\n min-width: 0;\n}\n.canvas-react-resizable-panels-divider-vertical.canvas-react-resizable-panels-divider-collapsed {\n height: 0;\n min-height: 0;\n}\n.canvas-react-resizable-panels-divider-line {\n position: absolute;\n background: var(--canvas-react-color-border, #d9d9d9);\n transition:\n width 0.16s ease,\n height 0.16s ease,\n background-color 0.16s ease,\n transform 0.16s ease;\n}\n.canvas-react-resizable-panels-divider-horizontal .canvas-react-resizable-panels-divider-line {\n inset: 0 auto 0 4px;\n width: 1px;\n}\n.canvas-react-resizable-panels-divider-vertical .canvas-react-resizable-panels-divider-line {\n inset: 4px 0 auto;\n height: 1px;\n}\n.canvas-react-resizable-panels-divider-horizontal:hover .canvas-react-resizable-panels-divider-line,\n.canvas-react-resizable-panels-divider-horizontal:focus-visible .canvas-react-resizable-panels-divider-line,\n.canvas-react-resizable-panels-divider-horizontal.canvas-react-resizable-panels-divider-active .canvas-react-resizable-panels-divider-line {\n width: 3px;\n background: var(--canvas-react-color-primary, #1677ff);\n transform: translateX(-1px);\n}\n.canvas-react-resizable-panels-divider-vertical:hover .canvas-react-resizable-panels-divider-line,\n.canvas-react-resizable-panels-divider-vertical:focus-visible .canvas-react-resizable-panels-divider-line,\n.canvas-react-resizable-panels-divider-vertical.canvas-react-resizable-panels-divider-active .canvas-react-resizable-panels-divider-line {\n height: 3px;\n background: var(--canvas-react-color-primary, #1677ff);\n transform: translateY(-1px);\n}\n.canvas-react-resizable-panels-divider:focus-visible {\n box-shadow: inset 0 0 0 2px rgba(22, 119, 255, 0.12);\n}\n.canvas-react-resizable-panels-divider-disabled {\n cursor: default;\n}\n.canvas-react-resizable-panels-divider-horizontal.canvas-react-resizable-panels-divider-disabled .canvas-react-resizable-panels-divider-line,\n.canvas-react-resizable-panels-divider-horizontal.canvas-react-resizable-panels-divider-disabled:hover .canvas-react-resizable-panels-divider-line {\n width: 1px;\n background: var(--canvas-react-color-border, #d9d9d9);\n transform: none;\n}\n.canvas-react-resizable-panels-divider-vertical.canvas-react-resizable-panels-divider-disabled .canvas-react-resizable-panels-divider-line,\n.canvas-react-resizable-panels-divider-vertical.canvas-react-resizable-panels-divider-disabled:hover .canvas-react-resizable-panels-divider-line {\n height: 1px;\n background: var(--canvas-react-color-border, #d9d9d9);\n transform: none;\n}\n@media (prefers-reduced-motion: reduce) {\n .canvas-react-resizable-panels-animated .canvas-react-resizable-panel,\n .canvas-react-resizable-panels-animated .canvas-react-resizable-panels-divider,\n .canvas-react-resizable-panels-divider-line {\n transition-duration: 0.01ms;\n transition-delay: 0s;\n }\n}\n');
6614
+ var DEFAULT_MIN_SIZE = 80;
6615
+ var DEFAULT_KEYBOARD_STEP = 10;
6616
+ function ReactResizablePanels(props) {
6617
+ const {
6618
+ animated = false,
6619
+ className,
6620
+ defaultSizes,
6621
+ direction = "horizontal",
6622
+ keyboardStep = DEFAULT_KEYBOARD_STEP,
6623
+ onResizeEnd,
6624
+ onResizeStart,
6625
+ onSizesChange,
6626
+ panels,
6627
+ sizes,
6628
+ style
6629
+ } = props;
6630
+ const [innerSizes, setInnerSizes] = useState(
6631
+ () => ({
6632
+ ...defaultSizes
6633
+ })
6634
+ );
6635
+ const [resizingDividerId, setResizingDividerId] = useState(
6636
+ null
6637
+ );
6638
+ const panelRefs = useRef({});
6639
+ const resizeSessionRef = useRef(null);
6640
+ const controlled = sizes !== void 0;
6641
+ const mergedSizes = controlled ? sizes : innerSizes;
6642
+ const visiblePanels = panels.filter((panel) => panel.visible !== false);
6643
+ useEffect(
6644
+ () => () => {
6645
+ const session = resizeSessionRef.current;
6646
+ if (!session) {
6647
+ return;
6648
+ }
6649
+ document.body.style.cursor = session.previousBodyCursor;
6650
+ document.body.style.userSelect = session.previousBodyUserSelect;
6651
+ resizeSessionRef.current = null;
6652
+ },
6653
+ []
6654
+ );
6655
+ const applySizes = (nextSizes, info) => {
6656
+ if (!controlled) {
6657
+ setInnerSizes(nextSizes);
6658
+ }
6659
+ if (resizeSessionRef.current) {
6660
+ resizeSessionRef.current.latestSizes = nextSizes;
6661
+ }
6662
+ onSizesChange?.(nextSizes, info);
6663
+ };
6664
+ const resizePair = (params) => {
6665
+ const { afterPanel, beforePanel, delta, startAfterSize, startBeforeSize } = params;
6666
+ const nextPair = resolveResizablePanelSizes({
6667
+ afterMaxSize: afterPanel.maxSize,
6668
+ afterMinSize: afterPanel.minSize,
6669
+ beforeMaxSize: beforePanel.maxSize,
6670
+ beforeMinSize: beforePanel.minSize,
6671
+ delta,
6672
+ startAfterSize,
6673
+ startBeforeSize
6674
+ });
6675
+ const info = createResizeInfo(beforePanel.id, afterPanel.id, direction);
6676
+ const nextSizes = {
6677
+ ...mergedSizes,
6678
+ [beforePanel.id]: nextPair.beforeSize,
6679
+ [afterPanel.id]: nextPair.afterSize
6680
+ };
6681
+ applySizes(nextSizes, info);
6682
+ return nextSizes;
6683
+ };
6684
+ const startResize = (event, beforePanel, afterPanel) => {
6685
+ if (event.button !== 0) {
6686
+ return;
6687
+ }
6688
+ const beforeElement = panelRefs.current[beforePanel.id];
6689
+ const afterElement = panelRefs.current[afterPanel.id];
6690
+ if (!beforeElement || !afterElement) {
6691
+ return;
6692
+ }
6693
+ event.preventDefault();
6694
+ event.currentTarget.setPointerCapture(event.pointerId);
6695
+ const startBeforeSize = resolveElementSize(beforeElement, direction);
6696
+ const startAfterSize = resolveElementSize(afterElement, direction);
6697
+ const info = createResizeInfo(beforePanel.id, afterPanel.id, direction);
6698
+ resizeSessionRef.current = {
6699
+ ...info,
6700
+ latestSizes: {
6701
+ ...mergedSizes,
6702
+ [beforePanel.id]: startBeforeSize,
6703
+ [afterPanel.id]: startAfterSize
6704
+ },
6705
+ pointerId: event.pointerId,
6706
+ previousBodyCursor: document.body.style.cursor,
6707
+ previousBodyUserSelect: document.body.style.userSelect,
6708
+ startAfterSize,
6709
+ startBeforeSize,
6710
+ startPointerPosition: resolvePointerPosition(event, direction)
6711
+ };
6712
+ document.body.style.cursor = resolveResizeCursor(direction);
6713
+ document.body.style.userSelect = "none";
6714
+ setResizingDividerId(beforePanel.id);
6715
+ onResizeStart?.(info);
6716
+ };
6717
+ const moveResize = (event, beforePanel, afterPanel) => {
6718
+ const session = resizeSessionRef.current;
6719
+ if (!session || session.pointerId !== event.pointerId) {
6720
+ return;
6721
+ }
6722
+ resizePair({
6723
+ afterPanel,
6724
+ beforePanel,
6725
+ delta: resolvePointerPosition(event, direction) - session.startPointerPosition,
6726
+ startAfterSize: session.startAfterSize,
6727
+ startBeforeSize: session.startBeforeSize
6728
+ });
6729
+ };
6730
+ const finishResize = (event) => {
6731
+ const session = resizeSessionRef.current;
6732
+ if (!session || session.pointerId !== event.pointerId) {
6733
+ return;
6734
+ }
6735
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) {
6736
+ event.currentTarget.releasePointerCapture(event.pointerId);
6737
+ }
6738
+ document.body.style.cursor = session.previousBodyCursor;
6739
+ document.body.style.userSelect = session.previousBodyUserSelect;
6740
+ resizeSessionRef.current = null;
6741
+ setResizingDividerId(null);
6742
+ onResizeEnd?.(session.latestSizes, {
6743
+ afterPanelId: session.afterPanelId,
6744
+ beforePanelId: session.beforePanelId,
6745
+ direction: session.direction
6746
+ });
6747
+ };
6748
+ const handleDividerKeyDown = (event, beforePanel, afterPanel) => {
6749
+ const deltaDirection = resolveKeyboardDeltaDirection(event.key, direction);
6750
+ if (deltaDirection === 0) {
6751
+ return;
6752
+ }
6753
+ const beforeElement = panelRefs.current[beforePanel.id];
6754
+ const afterElement = panelRefs.current[afterPanel.id];
6755
+ if (!beforeElement || !afterElement) {
6756
+ return;
6757
+ }
6758
+ event.preventDefault();
6759
+ const step = normalizePositiveNumber(keyboardStep, DEFAULT_KEYBOARD_STEP);
6760
+ const nextSizes = resizePair({
6761
+ afterPanel,
6762
+ beforePanel,
6763
+ delta: deltaDirection * step,
6764
+ startAfterSize: resolveElementSize(afterElement, direction),
6765
+ startBeforeSize: resolveElementSize(beforeElement, direction)
6766
+ });
6767
+ onResizeEnd?.(
6768
+ nextSizes,
6769
+ createResizeInfo(beforePanel.id, afterPanel.id, direction)
6770
+ );
6771
+ };
6772
+ return /* @__PURE__ */ jsx(
6773
+ "div",
6774
+ {
6775
+ className: joinClassNames(
6776
+ `${REACT_COMPONENT_PREFIX}-resizable-panels`,
6777
+ `${REACT_COMPONENT_PREFIX}-resizable-panels-${direction}`,
6778
+ animated && `${REACT_COMPONENT_PREFIX}-resizable-panels-animated`,
6779
+ resizingDividerId !== null && `${REACT_COMPONENT_PREFIX}-resizable-panels-resizing`,
6780
+ className
6781
+ ),
6782
+ style,
6783
+ children: visiblePanels.map((panel, index) => {
6784
+ const nextPanel = visiblePanels[index + 1];
6785
+ const configuredSize = mergedSizes[panel.id] ?? panel.size;
6786
+ const collapsed = panel.collapsed === true;
6787
+ const minSize = collapsed ? 0 : normalizePositiveNumber(panel.minSize, DEFAULT_MIN_SIZE);
6788
+ const maxSize = collapsed ? 0 : normalizeMaxSize(panel.maxSize, minSize);
6789
+ const panelStyle = collapsed ? resolveCollapsedPanelStyle(direction) : resolvePanelStyle({
6790
+ configuredSize,
6791
+ direction,
6792
+ isLast: index === visiblePanels.length - 1,
6793
+ maxSize,
6794
+ minSize
6795
+ });
6796
+ const dividerCollapsed = nextPanel ? collapsed || nextPanel.collapsed === true : false;
6797
+ const dividerDisabled = panel.resizable === false || dividerCollapsed;
6798
+ return /* @__PURE__ */ jsxs(
6799
+ "div",
6800
+ {
6801
+ className: `${REACT_COMPONENT_PREFIX}-resizable-panels-item`,
6802
+ children: [
6803
+ /* @__PURE__ */ jsx(
6804
+ "div",
6805
+ {
6806
+ ref: (element) => {
6807
+ panelRefs.current[panel.id] = element;
6808
+ },
6809
+ className: joinClassNames(
6810
+ `${REACT_COMPONENT_PREFIX}-resizable-panel`,
6811
+ collapsed && `${REACT_COMPONENT_PREFIX}-resizable-panel-collapsed`,
6812
+ panel.className
6813
+ ),
6814
+ style: {
6815
+ ...panelStyle,
6816
+ ...panel.style,
6817
+ ...collapsed ? panelStyle : void 0
6818
+ },
6819
+ "data-panel-id": panel.id,
6820
+ "aria-hidden": collapsed || void 0,
6821
+ children: panel.content
6822
+ }
6823
+ ),
6824
+ nextPanel ? /* @__PURE__ */ jsx(
6825
+ "div",
6826
+ {
6827
+ className: joinClassNames(
6828
+ `${REACT_COMPONENT_PREFIX}-resizable-panels-divider`,
6829
+ `${REACT_COMPONENT_PREFIX}-resizable-panels-divider-${direction}`,
6830
+ dividerDisabled && `${REACT_COMPONENT_PREFIX}-resizable-panels-divider-disabled`,
6831
+ dividerCollapsed && `${REACT_COMPONENT_PREFIX}-resizable-panels-divider-collapsed`,
6832
+ resizingDividerId === panel.id && `${REACT_COMPONENT_PREFIX}-resizable-panels-divider-active`
6833
+ ),
6834
+ role: "separator",
6835
+ "aria-label": `\u8C03\u6574 ${panel.id} \u4E0E ${nextPanel.id} \u7684${direction === "horizontal" ? "\u5BBD\u5EA6" : "\u9AD8\u5EA6"}`,
6836
+ "aria-disabled": dividerDisabled,
6837
+ "aria-orientation": direction === "horizontal" ? "vertical" : "horizontal",
6838
+ "aria-valuemin": minSize,
6839
+ "aria-valuemax": Number.isFinite(maxSize) ? maxSize : void 0,
6840
+ "aria-valuenow": configuredSize == null ? void 0 : Math.round(configuredSize),
6841
+ tabIndex: dividerDisabled ? -1 : 0,
6842
+ onKeyDown: (event) => {
6843
+ if (!dividerDisabled) {
6844
+ handleDividerKeyDown(event, panel, nextPanel);
6845
+ }
6846
+ },
6847
+ onPointerCancel: finishResize,
6848
+ onPointerDown: (event) => {
6849
+ if (!dividerDisabled) {
6850
+ startResize(event, panel, nextPanel);
6851
+ }
6852
+ },
6853
+ onPointerMove: (event) => {
6854
+ if (!dividerDisabled) {
6855
+ moveResize(event, panel, nextPanel);
6856
+ }
6857
+ },
6858
+ onPointerUp: finishResize,
6859
+ children: /* @__PURE__ */ jsx(
6860
+ "span",
6861
+ {
6862
+ className: `${REACT_COMPONENT_PREFIX}-resizable-panels-divider-line`,
6863
+ "aria-hidden": "true"
6864
+ }
6865
+ )
6866
+ }
6867
+ ) : null
6868
+ ]
6869
+ },
6870
+ panel.id
6871
+ );
6872
+ })
6873
+ }
6874
+ );
6875
+ }
6876
+ function resolveResizablePanelSizes(params) {
6877
+ const {
6878
+ afterMaxSize,
6879
+ afterMinSize,
6880
+ beforeMaxSize,
6881
+ beforeMinSize,
6882
+ delta,
6883
+ startAfterSize,
6884
+ startBeforeSize
6885
+ } = params;
6886
+ const safeBeforeMin = normalizePositiveNumber(
6887
+ beforeMinSize,
6888
+ DEFAULT_MIN_SIZE
6889
+ );
6890
+ const safeAfterMin = normalizePositiveNumber(afterMinSize, DEFAULT_MIN_SIZE);
6891
+ const safeBeforeMax = normalizeMaxSize(beforeMaxSize, safeBeforeMin);
6892
+ const safeAfterMax = normalizeMaxSize(afterMaxSize, safeAfterMin);
6893
+ const minDelta = Math.max(
6894
+ safeBeforeMin - startBeforeSize,
6895
+ startAfterSize - safeAfterMax
6896
+ );
6897
+ const maxDelta = Math.min(
6898
+ safeBeforeMax - startBeforeSize,
6899
+ startAfterSize - safeAfterMin
6900
+ );
6901
+ const safeDelta = clamp3(
6902
+ Number.isFinite(delta) ? delta : 0,
6903
+ minDelta,
6904
+ maxDelta
6905
+ );
6906
+ return {
6907
+ afterSize: Math.round((startAfterSize - safeDelta) * 100) / 100,
6908
+ beforeSize: Math.round((startBeforeSize + safeDelta) * 100) / 100
6909
+ };
6910
+ }
6911
+ function createResizeInfo(beforePanelId, afterPanelId, direction) {
6912
+ return { afterPanelId, beforePanelId, direction };
6913
+ }
6914
+ function resolveElementSize(element, direction) {
6915
+ const rect = element.getBoundingClientRect();
6916
+ return direction === "horizontal" ? rect.width : rect.height;
6917
+ }
6918
+ function resolvePointerPosition(event, direction) {
6919
+ return direction === "horizontal" ? event.clientX : event.clientY;
6920
+ }
6921
+ function resolveResizeCursor(direction) {
6922
+ return direction === "horizontal" ? "col-resize" : "row-resize";
6923
+ }
6924
+ function resolveKeyboardDeltaDirection(key, direction) {
6925
+ if (direction === "horizontal") {
6926
+ return key === "ArrowLeft" ? -1 : key === "ArrowRight" ? 1 : 0;
6927
+ }
6928
+ return key === "ArrowUp" ? -1 : key === "ArrowDown" ? 1 : 0;
6929
+ }
6930
+ function resolveCollapsedPanelStyle(direction) {
6931
+ return direction === "horizontal" ? { flex: "0 0 0px", maxWidth: 0, minWidth: 0, width: 0 } : { flex: "0 0 0px", height: 0, maxHeight: 0, minHeight: 0 };
6932
+ }
6933
+ function resolvePanelStyle(params) {
6934
+ const { configuredSize, direction, isLast, maxSize, minSize } = params;
6935
+ const size = normalizeOptionalSize(configuredSize, minSize, maxSize);
6936
+ const flex = size == null ? "1 1 0" : isLast ? `1 1 ${size}px` : `0 0 ${size}px`;
6937
+ return direction === "horizontal" ? {
6938
+ flex,
6939
+ maxWidth: Number.isFinite(maxSize) ? maxSize : void 0,
6940
+ minWidth: minSize,
6941
+ width: size
6942
+ } : {
6943
+ flex,
6944
+ height: size,
6945
+ maxHeight: Number.isFinite(maxSize) ? maxSize : void 0,
6946
+ minHeight: minSize
6947
+ };
6948
+ }
6949
+ function normalizeOptionalSize(value, minSize, maxSize) {
6950
+ if (typeof value !== "number" || !Number.isFinite(value)) {
6951
+ return void 0;
6952
+ }
6953
+ return clamp3(value, minSize, maxSize);
6954
+ }
6955
+ function normalizePositiveNumber(value, fallback) {
6956
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
6957
+ }
6958
+ function normalizeMaxSize(value, minSize) {
6959
+ return typeof value === "number" && Number.isFinite(value) ? Math.max(value, minSize) : Number.POSITIVE_INFINITY;
6960
+ }
6961
+ function clamp3(value, min, max) {
6962
+ if (min > max) {
6963
+ return min;
6964
+ }
6965
+ return Math.min(Math.max(value, min), max);
6966
+ }
6967
+ var ReactAutoComplete = forwardRef(function ReactAutoComplete2(props, ref) {
6968
+ const {
6969
+ onChange,
6970
+ onInputValueChange,
6971
+ onPressEnter,
6972
+ options: initialOptions,
6973
+ value,
6974
+ ...restProps
6975
+ } = props;
6976
+ const [options, setOptions] = useState(initialOptions);
6977
+ useEffect(() => {
6978
+ setOptions(initialOptions);
6979
+ }, [initialOptions]);
6980
+ return /* @__PURE__ */ jsx(
6981
+ ReactSelect,
6982
+ {
6983
+ ...restProps,
6984
+ ref,
6985
+ allowCustomValue: true,
6986
+ showSearch: true,
6987
+ value,
6988
+ options,
6989
+ onChange: (nextValue, info) => {
6990
+ onChange?.(
6991
+ options.find((option) => String(option.value) === String(nextValue))?.value ?? nextValue,
6992
+ info
6993
+ );
6994
+ },
6995
+ onInputValueChange: (input) => {
6996
+ onInputValueChange?.(input);
6997
+ onChange?.(input, { trigger: "input" });
6998
+ },
6999
+ onPressEnter: async (input) => {
7000
+ const nextOptions = await onPressEnter?.(input);
7001
+ if (nextOptions) {
7002
+ setOptions(nextOptions);
7003
+ }
7004
+ onChange?.(
7005
+ nextOptions ? resolveAutoCompleteValue(input, nextOptions) : input,
7006
+ { trigger: "keyboard" }
7007
+ );
7008
+ }
7009
+ }
7010
+ );
7011
+ });
7012
+ function resolveAutoCompleteValue(input, options) {
7013
+ const normalizedInput = input.toLowerCase();
7014
+ return options.find(
7015
+ (option) => option.label.toLowerCase() === normalizedInput || String(option.value).toLowerCase() === normalizedInput
7016
+ )?.value ?? input;
7017
+ }
5805
7018
  var ReactTimePicker = forwardRef(
5806
7019
  function ReactTimePicker2(props, ref) {
5807
7020
  const {
@@ -6685,6 +7898,6 @@ function resolveDecadeStart6(year) {
6685
7898
  return Math.floor(year / 10) * 10;
6686
7899
  }
6687
7900
 
6688
- export { REACT_COMPONENT_PREFIX, ReactCheckbox, ReactColorPicker, ReactContentScaleProvider, ReactDatePicker, ReactDateRangePicker, ReactDateTimePicker, ReactDateTimeRangePicker, ReactImagePreview, ReactInput, ReactInputNumber, ReactMonthPicker, ReactNumberInput, ReactPagination, ReactPopconfirm, ReactPopup, ReactQuarterPicker, ReactSelect, ReactTimePicker, ReactTimeRangePicker, ReactTransition, ReactVirtualList, ReactYearPicker, useReactContentScale, useReactTransition };
7901
+ export { REACT_COMPONENT_PREFIX, ReactAutoComplete, ReactCheckbox, ReactColorPicker, ReactContentScaleProvider, ReactDatePicker, ReactDateRangePicker, ReactDateTimePicker, ReactDateTimeRangePicker, ReactFilterPanel, ReactImagePreview, ReactInput, ReactInputNumber, ReactInputRange, ReactModal, ReactMonthPicker, ReactNumberInput, ReactPagination, ReactPopconfirm, ReactPopup, ReactQuarterPicker, ReactResizablePanels, ReactSelect, ReactTimePicker, ReactTimeRangePicker, ReactTransition, ReactVirtualList, ReactYearPicker, resolveResizablePanelSizes, useReactContentScale, useReactTransition };
6689
7902
  //# sourceMappingURL=index.js.map
6690
7903
  //# sourceMappingURL=index.js.map