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