@bifrostui/react 1.4.3-beta.0 → 1.4.4-beta.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.
@@ -12,5 +12,5 @@ declare const Modal: React.ForwardRefExoticComponent<Omit<ViewProps & {
12
12
  keepMounted?: boolean;
13
13
  } & import("@bifrostui/types").ICommonProps & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
14
14
  ref?: React.Ref<HTMLDivElement>;
15
- }, "open" | "container" | "disablePortal" | keyof import("@bifrostui/types").ICommonProps | "onClose" | "keepMounted" | "BackdropProps" | "hideBackdrop" | "disableScrollLock">, "ref"> & React.RefAttributes<HTMLDivElement>>;
15
+ }, "open" | keyof import("@bifrostui/types").ICommonProps | "container" | "disablePortal" | "hideBackdrop" | "BackdropProps" | "onClose" | "disableScrollLock" | "keepMounted">, "ref"> & React.RefAttributes<HTMLDivElement>>;
16
16
  export default Modal;
@@ -3,11 +3,6 @@
3
3
  --mini-width: var(--bui-select-min-width, 100px);
4
4
  --font-size: var(--bui-select-font-size, var(--bui-title-size-3));
5
5
  --padding: var(--bui-select-selector-container, 0 14px);
6
- --option-container-padding: var(--bui-select-option-container-padding, 3px 0);
7
- --option-container-margin-top: var(--bui-select-option-margin-top, 6px);
8
- --option-padding: var(--bui-select-option-padding, 0 14px);
9
- --option-margin: var(--bui-select-option-margin, 0 3px);
10
- --option-height: var(--bui-select-option-height, 27px);
11
6
  position: relative;
12
7
  cursor: pointer;
13
8
  height: var(--height);
@@ -16,8 +11,8 @@
16
11
  border-radius: 5px;
17
12
  background-color: var(--bui-color-bg-view);
18
13
  font-family: var(--bui-font-family);
14
+ -webkit-tap-highlight-color: transparent;
19
15
  }
20
- .bui-select:active,
21
16
  .bui-select-active {
22
17
  box-shadow: 0 0 0 2px var(--bui-color-bg-default);
23
18
  }
@@ -32,6 +27,7 @@
32
27
  height: 0;
33
28
  border: 0;
34
29
  opacity: 0;
30
+ pointer-events: none;
35
31
  }
36
32
  .bui-select-placeholder {
37
33
  color: var(--bui-color-fg-disabled);
@@ -55,20 +51,32 @@
55
51
  top: 100%;
56
52
  left: 0;
57
53
  width: 100%;
58
- z-index: var(--bui-z-index-dropdown);
59
- margin-top: var(--option-container-margin-top);
54
+ font-size: var(--bui-select-font-size, var(--bui-title-size-3));
55
+ z-index: var(--bui-z-index-tooltip);
60
56
  border-radius: 3px;
61
57
  background-color: var(--bui-color-bg-view);
62
58
  padding: 2px;
63
59
  overflow: hidden;
64
60
  }
61
+ .bui-select-option-container-top {
62
+ margin-top: -6px;
63
+ }
64
+ .bui-select-option-container-bottom {
65
+ margin-top: 6px;
66
+ }
67
+ .bui-select-option-container-hide {
68
+ pointer-events: none;
69
+ }
65
70
  .bui-select-option-main {
66
71
  border-radius: 3px;
67
- padding: var(--option-container-padding);
72
+ padding: var(--bui-select-option-container-padding, 3px 0);
68
73
  box-shadow: 0 0 0 2px var(--bui-color-bg-default);
69
74
  overflow: hidden;
70
75
  }
71
76
  .bui-select-option {
77
+ --option-padding: var(--bui-select-option-padding, 0 14px);
78
+ --option-margin: var(--bui-select-option-margin, 0 3px);
79
+ --option-height: var(--bui-select-option-height, 27px);
72
80
  display: flex;
73
81
  align-items: center;
74
82
  height: var(--option-height);
@@ -67,8 +67,10 @@ var import_Fade = __toESM(require("../Fade"));
67
67
  var import_Slide = __toESM(require("../Slide"));
68
68
  var import_selectContext = __toESM(require("./selectContext"));
69
69
  var import_Backdrop = __toESM(require("../Backdrop"));
70
+ var import_Portal = __toESM(require("../Portal"));
70
71
  var import_Select2 = require("./Select.css");
71
72
  const prefixCls = "bui-select";
73
+ const defaultPlacement = "bottom";
72
74
  const Select = /* @__PURE__ */ import_react.default.forwardRef((props, ref) => {
73
75
  const _a = props, {
74
76
  className,
@@ -83,6 +85,7 @@ const Select = /* @__PURE__ */ import_react.default.forwardRef((props, ref) => {
83
85
  placeholder,
84
86
  icon,
85
87
  open,
88
+ scrollContainer,
86
89
  onChange,
87
90
  onClose,
88
91
  onOpen,
@@ -100,6 +103,7 @@ const Select = /* @__PURE__ */ import_react.default.forwardRef((props, ref) => {
100
103
  "placeholder",
101
104
  "icon",
102
105
  "open",
106
+ "scrollContainer",
103
107
  "onChange",
104
108
  "onClose",
105
109
  "onOpen",
@@ -110,19 +114,49 @@ const Select = /* @__PURE__ */ import_react.default.forwardRef((props, ref) => {
110
114
  defaultValue,
111
115
  onChange
112
116
  });
113
- const [isOpen, setIsOpen] = (0, import_react.useState)(false);
117
+ const [internalOpen, setInternalOpen] = (0, import_react.useState)(false);
114
118
  const [renderValue, setRenderValue] = (0, import_react.useState)("");
115
- const defaultIcon = isOpen ? /* @__PURE__ */ import_react.default.createElement(import_icons.CaretUpIcon, { className: `${prefixCls}-selector-icon`, htmlColor: "#9c9ca5" }) : /* @__PURE__ */ import_react.default.createElement(
116
- import_icons.CaretDownIcon,
117
- {
118
- className: `${prefixCls}-selector-icon`,
119
- htmlColor: "#9c9ca5"
119
+ const [placement, setPlacement] = (0, import_react.useState)(defaultPlacement);
120
+ const [optionStyle, setOptionStyle] = (0, import_react.useState)({});
121
+ const isOpen = open !== void 0 ? open : internalOpen;
122
+ const locatorRef = (0, import_react.useRef)(null);
123
+ const rootRef = (0, import_utils.useForkRef)(ref, locatorRef);
124
+ const ttId = (0, import_utils.useUniqueId)();
125
+ const dataId = `${prefixCls}-tt-${ttId}`;
126
+ const updateOptionStyle = (0, import_utils.throttle)(() => {
127
+ const curScrollRoot = scrollContainer();
128
+ if (!import_utils.isMini && curScrollRoot) {
129
+ const result = (0, import_utils.getStylesAndLocation)({
130
+ scrollRoot: curScrollRoot,
131
+ childrenRef: locatorRef,
132
+ arrowDirection: defaultPlacement,
133
+ arrowLocation: "none",
134
+ selector: `[data-id="${dataId}"]`,
135
+ offsetSpacing: 0
136
+ });
137
+ if (!result)
138
+ return;
139
+ const { styles, childrenStyle, newArrowDirection } = result;
140
+ setPlacement(newArrowDirection);
141
+ setOptionStyle(__spreadProps(__spreadValues({}, styles), { width: childrenStyle.width }));
120
142
  }
121
- );
143
+ }, 100);
144
+ const changeOpen = (newOpen) => {
145
+ if (newOpen) {
146
+ updateOptionStyle();
147
+ setTimeout(() => {
148
+ setInternalOpen(newOpen);
149
+ onOpen == null ? void 0 : onOpen();
150
+ }, 100);
151
+ } else {
152
+ onClose == null ? void 0 : onClose();
153
+ setInternalOpen(newOpen);
154
+ }
155
+ };
122
156
  const handleSelectClick = (e) => {
123
157
  if (disabled)
124
158
  return;
125
- setIsOpen(!isOpen);
159
+ changeOpen(!isOpen);
126
160
  if (typeof onClick === "function")
127
161
  onClick(e);
128
162
  };
@@ -133,28 +167,70 @@ const Select = /* @__PURE__ */ import_react.default.forwardRef((props, ref) => {
133
167
  } else {
134
168
  onChange == null ? void 0 : onChange(e, { value: optionValue });
135
169
  }
136
- setIsOpen(false);
170
+ changeOpen(false);
137
171
  };
138
- const handleBackdropTouchStart = () => {
139
- if (isOpen) {
140
- setIsOpen(false);
141
- }
172
+ const handleBackdropClick = () => {
173
+ changeOpen(false);
142
174
  };
143
175
  const selectContext = (0, import_react.useMemo)(
144
176
  () => ({ selectValue, setRenderValue, handleOptionClick }),
145
177
  [selectValue, onChange, setRenderValue]
146
178
  );
147
179
  (0, import_react.useEffect)(() => {
148
- if (open !== void 0)
149
- setIsOpen(open);
150
- }, [open]);
151
- (0, import_react.useEffect)(() => {
152
- if (isOpen) {
153
- onOpen == null ? void 0 : onOpen();
154
- } else {
155
- onClose == null ? void 0 : onClose();
180
+ if (!import_utils.isMini) {
181
+ window.addEventListener("resize", updateOptionStyle);
182
+ return () => {
183
+ window.removeEventListener("resize", updateOptionStyle);
184
+ };
156
185
  }
157
- }, [isOpen]);
186
+ }, []);
187
+ const defaultIcon = isOpen ? /* @__PURE__ */ import_react.default.createElement(import_icons.CaretUpIcon, { className: `${prefixCls}-selector-icon`, htmlColor: "#9c9ca5" }) : /* @__PURE__ */ import_react.default.createElement(
188
+ import_icons.CaretDownIcon,
189
+ {
190
+ className: `${prefixCls}-selector-icon`,
191
+ htmlColor: "#9c9ca5"
192
+ }
193
+ );
194
+ const renderOptions = () => {
195
+ var _a2;
196
+ return /* @__PURE__ */ import_react.default.createElement(
197
+ import_Fade.default,
198
+ {
199
+ in: isOpen,
200
+ timeout: {
201
+ enter: 150,
202
+ exit: 150
203
+ }
204
+ },
205
+ /* @__PURE__ */ import_react.default.createElement(
206
+ "div",
207
+ {
208
+ className: (0, import_clsx.default)(
209
+ `${prefixCls}-option-container`,
210
+ ...((_a2 = className == null ? void 0 : className.split(/\s+/)) == null ? void 0 : _a2.map((cls) => `${cls}-option-container`)) || [],
211
+ `${prefixCls}-option-container-${placement}`,
212
+ {
213
+ [`${prefixCls}-option-container-hide`]: !isOpen
214
+ }
215
+ ),
216
+ "data-id": dataId,
217
+ style: optionStyle
218
+ },
219
+ /* @__PURE__ */ import_react.default.createElement(
220
+ import_Slide.default,
221
+ {
222
+ in: isOpen,
223
+ direction: placement === "bottom" ? "down" : "up",
224
+ timeout: {
225
+ enter: 150,
226
+ exit: 150
227
+ }
228
+ },
229
+ /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_clsx.default)(`${prefixCls}-option-main`) }, children)
230
+ )
231
+ )
232
+ );
233
+ };
158
234
  return /* @__PURE__ */ import_react.default.createElement(import_selectContext.default.Provider, { value: selectContext }, /* @__PURE__ */ import_react.default.createElement(
159
235
  "div",
160
236
  __spreadProps(__spreadValues({
@@ -162,7 +238,7 @@ const Select = /* @__PURE__ */ import_react.default.forwardRef((props, ref) => {
162
238
  [`${prefixCls}-disabled`]: disabled,
163
239
  [`${prefixCls}-active`]: isOpen
164
240
  }),
165
- ref
241
+ ref: rootRef
166
242
  }, others), {
167
243
  onClick: handleSelectClick
168
244
  }),
@@ -179,34 +255,14 @@ const Select = /* @__PURE__ */ import_react.default.forwardRef((props, ref) => {
179
255
  })
180
256
  })
181
257
  ), icon || defaultIcon),
182
- /* @__PURE__ */ import_react.default.createElement(
183
- import_Fade.default,
184
- {
185
- in: isOpen,
186
- timeout: {
187
- enter: 150,
188
- exit: 150
189
- }
190
- },
191
- /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_clsx.default)(`${prefixCls}-option-container`) }, /* @__PURE__ */ import_react.default.createElement(
192
- import_Slide.default,
193
- {
194
- in: isOpen,
195
- timeout: {
196
- enter: 150,
197
- exit: 150
198
- }
199
- },
200
- /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_clsx.default)(`${prefixCls}-option-main`) }, children)
201
- ))
202
- )
203
- ), /* @__PURE__ */ import_react.default.createElement(
258
+ import_utils.isMini && renderOptions()
259
+ ), !import_utils.isMini && /* @__PURE__ */ import_react.default.createElement(import_Portal.default, { onRootElementMouted: updateOptionStyle }, renderOptions()), /* @__PURE__ */ import_react.default.createElement(
204
260
  import_Backdrop.default,
205
261
  __spreadProps(__spreadValues({
206
262
  open: isOpen,
207
263
  invisible: true,
208
- onTouchStart: handleBackdropTouchStart,
209
- onClick: handleBackdropTouchStart
264
+ onTouchStart: handleBackdropClick,
265
+ onClick: handleBackdropClick
210
266
  }, BackdropProps), {
211
267
  className: (0, import_clsx.default)(`${prefixCls}-backdrop`, {
212
268
  [BackdropProps == null ? void 0 : BackdropProps.className]: BackdropProps == null ? void 0 : BackdropProps.className
@@ -216,6 +272,9 @@ const Select = /* @__PURE__ */ import_react.default.forwardRef((props, ref) => {
216
272
  });
217
273
  Select.displayName = "BuiSelect";
218
274
  Select.defaultProps = {
219
- defaultValue: ""
275
+ defaultValue: "",
276
+ scrollContainer: () => {
277
+ return import_utils.isMini ? null : document.body;
278
+ }
220
279
  };
221
280
  var Select_default = Select;
@@ -76,6 +76,12 @@ export type SelectProps<D extends React.ElementType = 'div', P = {}> = OverrideP
76
76
  * 是否展开下拉框
77
77
  */
78
78
  open?: boolean;
79
+ /**
80
+ * 滚动容器
81
+ * 下拉框元素和children将会被append到scrollContainer中
82
+ * 默认是页面的根节点
83
+ */
84
+ scrollContainer?: () => Element | null;
79
85
  /**
80
86
  * 自定义选中后展示的内容
81
87
  */
@@ -12,5 +12,5 @@ declare const Modal: React.ForwardRefExoticComponent<Omit<ViewProps & {
12
12
  keepMounted?: boolean;
13
13
  } & import("@bifrostui/types").ICommonProps & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
14
14
  ref?: React.Ref<HTMLDivElement>;
15
- }, "open" | keyof import("@bifrostui/types").ICommonProps | "container" | "disablePortal" | "hideBackdrop" | "BackdropProps" | "onClose" | "disableScrollLock" | "keepMounted">, "ref"> & React.RefAttributes<HTMLDivElement>>;
15
+ }, keyof import("@bifrostui/types").ICommonProps | "open" | "container" | "disablePortal" | "hideBackdrop" | "BackdropProps" | "onClose" | "disableScrollLock" | "keepMounted">, "ref"> & React.RefAttributes<HTMLDivElement>>;
16
16
  export default Modal;
@@ -3,11 +3,6 @@
3
3
  --mini-width: var(--bui-select-min-width, 100px);
4
4
  --font-size: var(--bui-select-font-size, var(--bui-title-size-3));
5
5
  --padding: var(--bui-select-selector-container, 0 14px);
6
- --option-container-padding: var(--bui-select-option-container-padding, 3px 0);
7
- --option-container-margin-top: var(--bui-select-option-margin-top, 6px);
8
- --option-padding: var(--bui-select-option-padding, 0 14px);
9
- --option-margin: var(--bui-select-option-margin, 0 3px);
10
- --option-height: var(--bui-select-option-height, 27px);
11
6
  position: relative;
12
7
  cursor: pointer;
13
8
  height: var(--height);
@@ -16,8 +11,8 @@
16
11
  border-radius: 5px;
17
12
  background-color: var(--bui-color-bg-view);
18
13
  font-family: var(--bui-font-family);
14
+ -webkit-tap-highlight-color: transparent;
19
15
  }
20
- .bui-select:active,
21
16
  .bui-select-active {
22
17
  box-shadow: 0 0 0 2px var(--bui-color-bg-default);
23
18
  }
@@ -32,6 +27,7 @@
32
27
  height: 0;
33
28
  border: 0;
34
29
  opacity: 0;
30
+ pointer-events: none;
35
31
  }
36
32
  .bui-select-placeholder {
37
33
  color: var(--bui-color-fg-disabled);
@@ -55,20 +51,32 @@
55
51
  top: 100%;
56
52
  left: 0;
57
53
  width: 100%;
58
- z-index: var(--bui-z-index-dropdown);
59
- margin-top: var(--option-container-margin-top);
54
+ font-size: var(--bui-select-font-size, var(--bui-title-size-3));
55
+ z-index: var(--bui-z-index-tooltip);
60
56
  border-radius: 3px;
61
57
  background-color: var(--bui-color-bg-view);
62
58
  padding: 2px;
63
59
  overflow: hidden;
64
60
  }
61
+ .bui-select-option-container-top {
62
+ margin-top: -6px;
63
+ }
64
+ .bui-select-option-container-bottom {
65
+ margin-top: 6px;
66
+ }
67
+ .bui-select-option-container-hide {
68
+ pointer-events: none;
69
+ }
65
70
  .bui-select-option-main {
66
71
  border-radius: 3px;
67
- padding: var(--option-container-padding);
72
+ padding: var(--bui-select-option-container-padding, 3px 0);
68
73
  box-shadow: 0 0 0 2px var(--bui-color-bg-default);
69
74
  overflow: hidden;
70
75
  }
71
76
  .bui-select-option {
77
+ --option-padding: var(--bui-select-option-padding, 0 14px);
78
+ --option-margin: var(--bui-select-option-margin, 0 3px);
79
+ --option-height: var(--bui-select-option-height, 27px);
72
80
  display: flex;
73
81
  align-items: center;
74
82
  height: var(--option-height);
@@ -30,15 +30,24 @@ var __objRest = (source, exclude) => {
30
30
  return target;
31
31
  };
32
32
  import { CaretDownIcon, CaretUpIcon } from "@bifrostui/icons";
33
- import { useValue } from "@bifrostui/utils";
33
+ import {
34
+ getStylesAndLocation,
35
+ isMini,
36
+ throttle,
37
+ useForkRef,
38
+ useUniqueId,
39
+ useValue
40
+ } from "@bifrostui/utils";
34
41
  import clsx from "clsx";
35
- import React, { useEffect, useMemo, useState } from "react";
42
+ import React, { useEffect, useMemo, useRef, useState } from "react";
36
43
  import Fade from "../Fade";
37
44
  import Slide from "../Slide";
38
45
  import BuiSelectContext from "./selectContext";
39
46
  import Backdrop from "../Backdrop";
47
+ import Portal from "../Portal";
40
48
  import "./Select.css";
41
49
  const prefixCls = "bui-select";
50
+ const defaultPlacement = "bottom";
42
51
  const Select = /* @__PURE__ */ React.forwardRef((props, ref) => {
43
52
  const _a = props, {
44
53
  className,
@@ -53,6 +62,7 @@ const Select = /* @__PURE__ */ React.forwardRef((props, ref) => {
53
62
  placeholder,
54
63
  icon,
55
64
  open,
65
+ scrollContainer,
56
66
  onChange,
57
67
  onClose,
58
68
  onOpen,
@@ -70,6 +80,7 @@ const Select = /* @__PURE__ */ React.forwardRef((props, ref) => {
70
80
  "placeholder",
71
81
  "icon",
72
82
  "open",
83
+ "scrollContainer",
73
84
  "onChange",
74
85
  "onClose",
75
86
  "onOpen",
@@ -80,19 +91,49 @@ const Select = /* @__PURE__ */ React.forwardRef((props, ref) => {
80
91
  defaultValue,
81
92
  onChange
82
93
  });
83
- const [isOpen, setIsOpen] = useState(false);
94
+ const [internalOpen, setInternalOpen] = useState(false);
84
95
  const [renderValue, setRenderValue] = useState("");
85
- const defaultIcon = isOpen ? /* @__PURE__ */ React.createElement(CaretUpIcon, { className: `${prefixCls}-selector-icon`, htmlColor: "#9c9ca5" }) : /* @__PURE__ */ React.createElement(
86
- CaretDownIcon,
87
- {
88
- className: `${prefixCls}-selector-icon`,
89
- htmlColor: "#9c9ca5"
96
+ const [placement, setPlacement] = useState(defaultPlacement);
97
+ const [optionStyle, setOptionStyle] = useState({});
98
+ const isOpen = open !== void 0 ? open : internalOpen;
99
+ const locatorRef = useRef(null);
100
+ const rootRef = useForkRef(ref, locatorRef);
101
+ const ttId = useUniqueId();
102
+ const dataId = `${prefixCls}-tt-${ttId}`;
103
+ const updateOptionStyle = throttle(() => {
104
+ const curScrollRoot = scrollContainer();
105
+ if (!isMini && curScrollRoot) {
106
+ const result = getStylesAndLocation({
107
+ scrollRoot: curScrollRoot,
108
+ childrenRef: locatorRef,
109
+ arrowDirection: defaultPlacement,
110
+ arrowLocation: "none",
111
+ selector: `[data-id="${dataId}"]`,
112
+ offsetSpacing: 0
113
+ });
114
+ if (!result)
115
+ return;
116
+ const { styles, childrenStyle, newArrowDirection } = result;
117
+ setPlacement(newArrowDirection);
118
+ setOptionStyle(__spreadProps(__spreadValues({}, styles), { width: childrenStyle.width }));
90
119
  }
91
- );
120
+ }, 100);
121
+ const changeOpen = (newOpen) => {
122
+ if (newOpen) {
123
+ updateOptionStyle();
124
+ setTimeout(() => {
125
+ setInternalOpen(newOpen);
126
+ onOpen == null ? void 0 : onOpen();
127
+ }, 100);
128
+ } else {
129
+ onClose == null ? void 0 : onClose();
130
+ setInternalOpen(newOpen);
131
+ }
132
+ };
92
133
  const handleSelectClick = (e) => {
93
134
  if (disabled)
94
135
  return;
95
- setIsOpen(!isOpen);
136
+ changeOpen(!isOpen);
96
137
  if (typeof onClick === "function")
97
138
  onClick(e);
98
139
  };
@@ -103,28 +144,70 @@ const Select = /* @__PURE__ */ React.forwardRef((props, ref) => {
103
144
  } else {
104
145
  onChange == null ? void 0 : onChange(e, { value: optionValue });
105
146
  }
106
- setIsOpen(false);
147
+ changeOpen(false);
107
148
  };
108
- const handleBackdropTouchStart = () => {
109
- if (isOpen) {
110
- setIsOpen(false);
111
- }
149
+ const handleBackdropClick = () => {
150
+ changeOpen(false);
112
151
  };
113
152
  const selectContext = useMemo(
114
153
  () => ({ selectValue, setRenderValue, handleOptionClick }),
115
154
  [selectValue, onChange, setRenderValue]
116
155
  );
117
156
  useEffect(() => {
118
- if (open !== void 0)
119
- setIsOpen(open);
120
- }, [open]);
121
- useEffect(() => {
122
- if (isOpen) {
123
- onOpen == null ? void 0 : onOpen();
124
- } else {
125
- onClose == null ? void 0 : onClose();
157
+ if (!isMini) {
158
+ window.addEventListener("resize", updateOptionStyle);
159
+ return () => {
160
+ window.removeEventListener("resize", updateOptionStyle);
161
+ };
162
+ }
163
+ }, []);
164
+ const defaultIcon = isOpen ? /* @__PURE__ */ React.createElement(CaretUpIcon, { className: `${prefixCls}-selector-icon`, htmlColor: "#9c9ca5" }) : /* @__PURE__ */ React.createElement(
165
+ CaretDownIcon,
166
+ {
167
+ className: `${prefixCls}-selector-icon`,
168
+ htmlColor: "#9c9ca5"
126
169
  }
127
- }, [isOpen]);
170
+ );
171
+ const renderOptions = () => {
172
+ var _a2;
173
+ return /* @__PURE__ */ React.createElement(
174
+ Fade,
175
+ {
176
+ in: isOpen,
177
+ timeout: {
178
+ enter: 150,
179
+ exit: 150
180
+ }
181
+ },
182
+ /* @__PURE__ */ React.createElement(
183
+ "div",
184
+ {
185
+ className: clsx(
186
+ `${prefixCls}-option-container`,
187
+ ...((_a2 = className == null ? void 0 : className.split(/\s+/)) == null ? void 0 : _a2.map((cls) => `${cls}-option-container`)) || [],
188
+ `${prefixCls}-option-container-${placement}`,
189
+ {
190
+ [`${prefixCls}-option-container-hide`]: !isOpen
191
+ }
192
+ ),
193
+ "data-id": dataId,
194
+ style: optionStyle
195
+ },
196
+ /* @__PURE__ */ React.createElement(
197
+ Slide,
198
+ {
199
+ in: isOpen,
200
+ direction: placement === "bottom" ? "down" : "up",
201
+ timeout: {
202
+ enter: 150,
203
+ exit: 150
204
+ }
205
+ },
206
+ /* @__PURE__ */ React.createElement("div", { className: clsx(`${prefixCls}-option-main`) }, children)
207
+ )
208
+ )
209
+ );
210
+ };
128
211
  return /* @__PURE__ */ React.createElement(BuiSelectContext.Provider, { value: selectContext }, /* @__PURE__ */ React.createElement(
129
212
  "div",
130
213
  __spreadProps(__spreadValues({
@@ -132,7 +215,7 @@ const Select = /* @__PURE__ */ React.forwardRef((props, ref) => {
132
215
  [`${prefixCls}-disabled`]: disabled,
133
216
  [`${prefixCls}-active`]: isOpen
134
217
  }),
135
- ref
218
+ ref: rootRef
136
219
  }, others), {
137
220
  onClick: handleSelectClick
138
221
  }),
@@ -149,34 +232,14 @@ const Select = /* @__PURE__ */ React.forwardRef((props, ref) => {
149
232
  })
150
233
  })
151
234
  ), icon || defaultIcon),
152
- /* @__PURE__ */ React.createElement(
153
- Fade,
154
- {
155
- in: isOpen,
156
- timeout: {
157
- enter: 150,
158
- exit: 150
159
- }
160
- },
161
- /* @__PURE__ */ React.createElement("div", { className: clsx(`${prefixCls}-option-container`) }, /* @__PURE__ */ React.createElement(
162
- Slide,
163
- {
164
- in: isOpen,
165
- timeout: {
166
- enter: 150,
167
- exit: 150
168
- }
169
- },
170
- /* @__PURE__ */ React.createElement("div", { className: clsx(`${prefixCls}-option-main`) }, children)
171
- ))
172
- )
173
- ), /* @__PURE__ */ React.createElement(
235
+ isMini && renderOptions()
236
+ ), !isMini && /* @__PURE__ */ React.createElement(Portal, { onRootElementMouted: updateOptionStyle }, renderOptions()), /* @__PURE__ */ React.createElement(
174
237
  Backdrop,
175
238
  __spreadProps(__spreadValues({
176
239
  open: isOpen,
177
240
  invisible: true,
178
- onTouchStart: handleBackdropTouchStart,
179
- onClick: handleBackdropTouchStart
241
+ onTouchStart: handleBackdropClick,
242
+ onClick: handleBackdropClick
180
243
  }, BackdropProps), {
181
244
  className: clsx(`${prefixCls}-backdrop`, {
182
245
  [BackdropProps == null ? void 0 : BackdropProps.className]: BackdropProps == null ? void 0 : BackdropProps.className
@@ -186,7 +249,10 @@ const Select = /* @__PURE__ */ React.forwardRef((props, ref) => {
186
249
  });
187
250
  Select.displayName = "BuiSelect";
188
251
  Select.defaultProps = {
189
- defaultValue: ""
252
+ defaultValue: "",
253
+ scrollContainer: () => {
254
+ return isMini ? null : document.body;
255
+ }
190
256
  };
191
257
  var Select_default = Select;
192
258
  export {
@@ -76,6 +76,12 @@ export type SelectProps<D extends React.ElementType = 'div', P = {}> = OverrideP
76
76
  * 是否展开下拉框
77
77
  */
78
78
  open?: boolean;
79
+ /**
80
+ * 滚动容器
81
+ * 下拉框元素和children将会被append到scrollContainer中
82
+ * 默认是页面的根节点
83
+ */
84
+ scrollContainer?: () => Element | null;
79
85
  /**
80
86
  * 自定义选中后展示的内容
81
87
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bifrostui/react",
3
- "version": "1.4.3-beta.0",
3
+ "version": "1.4.4-beta.0",
4
4
  "description": "React components for building mobile application",
5
5
  "homepage": "http://bui.taopiaopiao.com",
6
6
  "license": "MIT",
@@ -33,10 +33,10 @@
33
33
  "clsx": "^1.2.1",
34
34
  "dayjs": "^1.11.7",
35
35
  "swiper": "^8.1.5",
36
- "@bifrostui/icons": "1.4.3-beta.0",
37
- "@bifrostui/styles": "1.4.3-beta.0",
38
- "@bifrostui/types": "1.4.3-beta.0",
39
- "@bifrostui/utils": "1.4.3-beta.0"
36
+ "@bifrostui/icons": "1.4.4-beta.0",
37
+ "@bifrostui/styles": "1.4.4-beta.0",
38
+ "@bifrostui/utils": "1.4.4-beta.0",
39
+ "@bifrostui/types": "1.4.4-beta.0"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@tarojs/components": "^3.0.0",