one-design-next 0.0.63 → 0.0.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,12 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _typeof from "@babel/runtime/helpers/esm/typeof";
3
- import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
4
3
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
4
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
5
5
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
6
6
  import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
7
- var _excluded = ["size", "disabled", "placeholder", "allowClear", "showSearch", "className", "style", "light", "visible", "onVisibleChange", "onChange", "value", "defaultValue", "suffixIcon", "mode", "options", "optionPopoverProps", "showInnerSearch", "searchValue", "onSearch", "autoClearSearchValue", "searchFilter", "searchRender", "searchLimit", "notFoundContent", "showCheckedStrategy", "displayRender", "dropdownClassName", "dropdownMatchSelectWidth", "separator", "optionRender", "changeOnSelect", "crossLevelSelect", "expandDirection", "maxTagCount", "maxTagPlaceholder", "direction", "placement", "getPopupContainer"];
7
+ var _excluded = ["size", "disabled", "placeholder", "allowClear", "showSearch", "className", "style", "light", "visible", "onVisibleChange", "onChange", "value", "defaultValue", "suffixIcon", "mode", "options", "optionPopoverProps", "showInnerSearch", "searchValue", "onSearch", "autoClearSearchValue", "searchFilter", "searchRender", "searchLimit", "notFoundContent", "showCheckedStrategy", "displayRender", "dropdownClassName", "dropdownMatchSelectWidth", "separator", "optionRender", "changeOnSelect", "crossLevelSelect", "maxTagCount", "maxTagPlaceholder", "direction", "placement", "getPopupContainer"];
8
8
  import clsx from 'clsx';
9
9
  import React, { useEffect, useMemo, useRef, useState } from 'react';
10
- import { flushSync } from 'react-dom';
11
10
  import Icon from "../icon";
12
11
  import "../select/style";
13
12
  import useIcons from "../select/useIcons";
@@ -16,7 +15,7 @@ import RcCascader, { SHOW_CHILD, SHOW_PARENT } from "./fork";
16
15
  import CascaderPanel from "./Panel";
17
16
  import SelectedSummary from "./SelectedSummary";
18
17
  import "./style";
19
- import { calculateOptionsDepth, DEFAULT_FIELD_NAMES, getExpandBuiltinPlacements, processOptions, resolveExpandDirection } from "./utils";
18
+ import { DEFAULT_FIELD_NAMES, processOptions } from "./utils";
20
19
  function getPathLeafLabel(path, optionList, valueField, childrenField) {
21
20
  var current = optionList;
22
21
  var leaf;
@@ -104,7 +103,6 @@ function CascaderInner(_ref) {
104
103
  changeOnSelectProp = _ref.changeOnSelect,
105
104
  _ref$crossLevelSelect = _ref.crossLevelSelect,
106
105
  crossLevelSelect = _ref$crossLevelSelect === void 0 ? false : _ref$crossLevelSelect,
107
- expandDirectionProp = _ref.expandDirection,
108
106
  maxTagCountProp = _ref.maxTagCount,
109
107
  maxTagPlaceholderProp = _ref.maxTagPlaceholder,
110
108
  directionProp = _ref.direction,
@@ -115,13 +113,6 @@ function CascaderInner(_ref) {
115
113
  var showInnerSearch = showInnerSearchProp !== null && showInnerSearchProp !== void 0 ? showInnerSearchProp : crossLevelSelect;
116
114
  // 跨层级多选:勾选后不自动清空搜索,避免搜索结果被收起
117
115
  var autoClearSearchValue = autoClearSearchValueProp !== null && autoClearSearchValueProp !== void 0 ? autoClearSearchValueProp : !(crossLevelSelect && mode === 'multiple');
118
- // 跨层级默认按位置自动适配展开方向
119
- var expandDirection = expandDirectionProp !== null && expandDirectionProp !== void 0 ? expandDirectionProp : crossLevelSelect ? 'auto' : 'ltr';
120
- var instanceId = React.useId().replace(/:/g, '');
121
- var _useState = useState(expandDirection === 'rtl' ? 'rtl' : 'ltr'),
122
- _useState2 = _slicedToArray(_useState, 2),
123
- resolvedDirection = _useState2[0],
124
- setResolvedDirection = _useState2[1];
125
116
 
126
117
  // 默认 fieldNames.label 为 labelWithPopover,下拉展示带 Popover 的节点,用户传入的 label 保留
127
118
  var mergedFieldNames = React.useMemo(function () {
@@ -149,37 +140,6 @@ function CascaderInner(_ref) {
149
140
  var processedOptions = React.useMemo(function () {
150
141
  return processOptions(options, mergedFieldNames, optionPopoverProps);
151
142
  }, [options, mergedFieldNames, optionPopoverProps]);
152
- var optionsDepth = useMemo(function () {
153
- return calculateOptionsDepth(processedOptions, mergedFieldNames);
154
- }, [processedOptions, mergedFieldNames]);
155
-
156
- // expandDirection 只控制弹层锚点(靠右时向左生长),列阅读顺序始终从左到右、层级加深向右
157
- var panelExpandSide = expandDirection === 'auto' ? resolvedDirection : expandDirection;
158
- var mergedDirection = directionProp !== null && directionProp !== void 0 ? directionProp : 'ltr';
159
-
160
- /**
161
- * rtl:弹层右对齐 trigger、向左生长。打开前(pointerdown / onOpenChange)
162
- * 已算好方向,配合 bottomRight + adjustX:0 避免首帧横向跳动。
163
- * 弹层默认仍挂 document.body(不传 getPopupContainer 时)。
164
- */
165
- var mergedPlacement = placementProp !== null && placementProp !== void 0 ? placementProp : panelExpandSide === 'rtl' ? 'bottomRight' : 'bottomLeft';
166
- var builtinPlacements = useMemo(function () {
167
- return getExpandBuiltinPlacements();
168
- }, []);
169
- var syncAutoExpandDirection = function syncAutoExpandDirection() {
170
- var _ref2, _root$querySelector;
171
- if (expandDirection !== 'auto') {
172
- return;
173
- }
174
- var root = document.querySelector(".odn-cascader-uid-".concat(instanceId));
175
- var selector = (_ref2 = (_root$querySelector = root === null || root === void 0 ? void 0 : root.querySelector('.odn-select-selector')) !== null && _root$querySelector !== void 0 ? _root$querySelector : root) !== null && _ref2 !== void 0 ? _ref2 : null;
176
- var nextDirection = resolveExpandDirection(selector, optionsDepth);
177
- flushSync(function () {
178
- setResolvedDirection(function (prev) {
179
- return prev === nextDirection ? prev : nextDirection;
180
- });
181
- });
182
- };
183
143
  var prefixCls = 'odn-select';
184
144
  var _useIcons = useIcons(_objectSpread(_objectSpread({}, restProps), {}, {
185
145
  hasFeedback: false,
@@ -191,44 +151,17 @@ function CascaderInner(_ref) {
191
151
  suffixIcon = _useIcons.suffixIcon,
192
152
  removeIcon = _useIcons.removeIcon,
193
153
  clearIcon = _useIcons.clearIcon;
194
- var cascaderClassName = [prefixCls, "".concat(prefixCls, "-").concat(size), disabled && "".concat(prefixCls, "-disabled"), light && "".concat(prefixCls, "-light"), !light && "".concat(prefixCls, "-outlined"), "".concat(prefixCls, "-show-arrow"), showInnerSearch && "".concat(prefixCls, "-show-inner-search"), 'odn-cascader', crossLevelSelect && 'odn-cascader-cross-level', "odn-cascader-uid-".concat(instanceId), panelExpandSide === 'rtl' && 'odn-cascader-expand-rtl', className].filter(Boolean).join(' ');
195
- var _useState3 = useState(visibleProp),
154
+ var cascaderClassName = [prefixCls, "".concat(prefixCls, "-").concat(size), disabled && "".concat(prefixCls, "-disabled"), light && "".concat(prefixCls, "-light"), !light && "".concat(prefixCls, "-outlined"), "".concat(prefixCls, "-show-arrow"), showInnerSearch && "".concat(prefixCls, "-show-inner-search"), 'odn-cascader', crossLevelSelect && 'odn-cascader-cross-level', className].filter(Boolean).join(' ');
155
+ var _useState = useState(visibleProp),
156
+ _useState2 = _slicedToArray(_useState, 2),
157
+ visible = _useState2[0],
158
+ setVisible = _useState2[1];
159
+ var _useState3 = useState(searchValueProp || ''),
196
160
  _useState4 = _slicedToArray(_useState3, 2),
197
- visible = _useState4[0],
198
- setVisible = _useState4[1];
199
- var _useState5 = useState(searchValueProp || ''),
200
- _useState6 = _slicedToArray(_useState5, 2),
201
- searchValue = _useState6[0],
202
- setSearchValue = _useState6[1];
161
+ searchValue = _useState4[0],
162
+ setSearchValue = _useState4[1];
203
163
  var dropdownSearchInputRef = useRef(null);
204
- useEffect(function () {
205
- if (expandDirection === 'ltr' || expandDirection === 'rtl') {
206
- setResolvedDirection(expandDirection);
207
- }
208
- }, [expandDirection]);
209
-
210
- // 在打开前(pointerdown)就算好 auto 方向,避免打开后再切换 rtl class / placement
211
- useEffect(function () {
212
- if (expandDirection !== 'auto') {
213
- return undefined;
214
- }
215
- var root = document.querySelector(".odn-cascader-uid-".concat(instanceId));
216
- if (!root) {
217
- return undefined;
218
- }
219
- var onPointerDown = function onPointerDown() {
220
- syncAutoExpandDirection();
221
- };
222
- root.addEventListener('pointerdown', onPointerDown, true);
223
- return function () {
224
- root.removeEventListener('pointerdown', onPointerDown, true);
225
- };
226
- // eslint-disable-next-line react-hooks/exhaustive-deps -- 仅在关键参数变化时重绑
227
- }, [expandDirection, instanceId, optionsDepth]);
228
164
  var handleVisibleChange = function handleVisibleChange(bool) {
229
- if (bool && expandDirection === 'auto') {
230
- syncAutoExpandDirection();
231
- }
232
165
  if (visibleProp === undefined) {
233
166
  setVisible(bool);
234
167
  }
@@ -315,8 +248,11 @@ function CascaderInner(_ref) {
315
248
  return optionList;
316
249
  };
317
250
  var mergedShowSearch = React.useMemo(function () {
251
+ if (!showInnerSearch && !showSearch) {
252
+ return false;
253
+ }
318
254
  if (!showInnerSearch) {
319
- return showInnerSearch;
255
+ return showSearch;
320
256
  }
321
257
  var searchConfig = {
322
258
  filter: searchFilter || function (inputValue, path) {
@@ -328,8 +264,8 @@ function CascaderInner(_ref) {
328
264
  limit: searchLimit
329
265
  };
330
266
  return searchConfig;
331
- }, [showInnerSearch, searchFilter, searchRender, searchLimit]);
332
- var commonProps = _objectSpread(_objectSpread(_objectSpread({}, restProps), {}, {
267
+ }, [showInnerSearch, showSearch, searchFilter, searchRender, searchLimit]);
268
+ var commonProps = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, restProps), {}, {
333
269
  fieldNames: mergedFieldNames,
334
270
  prefixCls: prefixCls,
335
271
  disabled: disabled,
@@ -394,14 +330,15 @@ function CascaderInner(_ref) {
394
330
  optionRender: optionRenderProp,
395
331
  changeOnSelect: !!changeOnSelectProp || crossLevelSelect,
396
332
  checkStrictly: crossLevelSelect,
333
+ showInnerSearch: showInnerSearch,
397
334
  maxTagCount: mergedMaxTagCount,
398
- maxTagPlaceholder: mergedMaxTagPlaceholder,
399
- direction: mergedDirection,
400
- placement: mergedPlacement
401
- }, getPopupContainerProp ? {
335
+ maxTagPlaceholder: mergedMaxTagPlaceholder
336
+ }, directionProp ? {
337
+ direction: directionProp
338
+ } : {}), placementProp ? {
339
+ placement: placementProp
340
+ } : {}), getPopupContainerProp ? {
402
341
  getPopupContainer: getPopupContainerProp
403
- } : {}), panelExpandSide === 'rtl' ? {
404
- builtinPlacements: builtinPlacements
405
342
  } : {});
406
343
  var dropdownRender = showInnerSearch ? function (menu) {
407
344
  var searchNode = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
@@ -3,8 +3,6 @@ html {
3
3
  --odn-cascader-control-width: 184px;
4
4
  --odn-cascader-control-item-width: 200px;
5
5
  --odn-cascader-dropdown-height: 232px;
6
- --odn-cascader-panel-motion-duration: 0.22s;
7
- --odn-cascader-panel-motion-ease: cubic-bezier(0.32, 0.72, 0, 1);
8
6
  --odn-cascader-option-selected-bg: var(--odn-color-blue-1);
9
7
  --odn-cascader-option-selected-font-weight: 400;
10
8
  --odn-cascader-option-padding-block: 7px;
@@ -15,6 +13,7 @@ html {
15
13
  --odn-cascader-panel-border-radius: 6px;
16
14
  }
17
15
 
16
+ /* stylelint-disable no-descending-specificity, no-duplicate-selectors */
18
17
  .odn-cascader {
19
18
  width: var(--odn-cascader-control-width);
20
19
  }
@@ -12,51 +12,3 @@ export declare const DEFAULT_FIELD_NAMES: FieldNames;
12
12
  export declare const processOptions: (options: DefaultOptionType[] | undefined, fieldNames?: FieldNames, optionPopoverProps?: Record<string, unknown>) => DefaultOptionType[] | undefined;
13
13
  export declare const calculateOptionsDepth: (options: DefaultOptionType[] | undefined, fieldNames?: FieldNames) => number;
14
14
  export declare const generateCommonStyle: (depth: number, autoMaxWidth: boolean, customStyle?: React.CSSProperties) => React.CSSProperties;
15
- export type ExpandDirection = 'ltr' | 'rtl' | 'auto';
16
- /**
17
- * Cascader 自管水平锚点(expandDirection),关闭 adjustX,
18
- * 避免 Trigger 首帧按溢出翻转后再纠正造成「先错后对」。
19
- */
20
- export declare const getExpandBuiltinPlacements: () => {
21
- bottomLeft: {
22
- points: [string, string];
23
- offset: number[];
24
- overflow: {
25
- adjustX: number;
26
- adjustY: number;
27
- };
28
- htmlRegion: "scroll";
29
- };
30
- bottomRight: {
31
- points: [string, string];
32
- offset: number[];
33
- overflow: {
34
- adjustX: number;
35
- adjustY: number;
36
- };
37
- htmlRegion: "scroll";
38
- };
39
- topLeft: {
40
- points: [string, string];
41
- offset: number[];
42
- overflow: {
43
- adjustX: number;
44
- adjustY: number;
45
- };
46
- htmlRegion: "scroll";
47
- };
48
- topRight: {
49
- points: [string, string];
50
- offset: number[];
51
- overflow: {
52
- adjustX: number;
53
- adjustY: number;
54
- };
55
- htmlRegion: "scroll";
56
- };
57
- };
58
- /**
59
- * 根据 selector 相对视口的位置,决定弹层左对齐向右生长(ltr)
60
- * 还是右对齐向左生长(rtl)。列阅读顺序始终从左到右。
61
- */
62
- export declare const resolveExpandDirection: (triggerEl: Element | null | undefined, depth: number, columnMinWidth?: number) => 'ltr' | 'rtl';
@@ -47,7 +47,7 @@ export var processOptions = function processOptions(options, fieldNames, optionP
47
47
  });
48
48
 
49
49
  // 记录一个自定义的固定的属性,用以处理 search 逻辑
50
- processedOption['labelForSearch'] = displayContent != null && (typeof displayContent === 'string' || typeof displayContent === 'number') ? String(displayContent) : '';
50
+ processedOption['labelForSearch'] = displayContent !== null && displayContent !== undefined && (typeof displayContent === 'string' || typeof displayContent === 'number') ? String(displayContent) : '';
51
51
 
52
52
  // 递归处理 children
53
53
  var childrenField = (fieldNames === null || fieldNames === void 0 ? void 0 : fieldNames.children) || 'children';
@@ -96,75 +96,4 @@ export var generateCommonStyle = function generateCommonStyle(depth, autoMaxWidt
96
96
  return _objectSpread({
97
97
  '--odn-cascader-panel-column-flex': autoMaxWidth ? "0 0 ".concat(100 / depth, "%") : '1 1 0%'
98
98
  }, customStyle);
99
- };
100
- var DEFAULT_COLUMN_MIN_WIDTH = 200;
101
-
102
- /**
103
- * Cascader 自管水平锚点(expandDirection),关闭 adjustX,
104
- * 避免 Trigger 首帧按溢出翻转后再纠正造成「先错后对」。
105
- */
106
- export var getExpandBuiltinPlacements = function getExpandBuiltinPlacements() {
107
- var adjustX = 0;
108
- var adjustY = 1;
109
- return {
110
- bottomLeft: {
111
- points: ['tl', 'bl'],
112
- offset: [0, 4],
113
- overflow: {
114
- adjustX: adjustX,
115
- adjustY: adjustY
116
- },
117
- htmlRegion: 'scroll'
118
- },
119
- bottomRight: {
120
- points: ['tr', 'br'],
121
- offset: [0, 4],
122
- overflow: {
123
- adjustX: adjustX,
124
- adjustY: adjustY
125
- },
126
- htmlRegion: 'scroll'
127
- },
128
- topLeft: {
129
- points: ['bl', 'tl'],
130
- offset: [0, -4],
131
- overflow: {
132
- adjustX: adjustX,
133
- adjustY: adjustY
134
- },
135
- htmlRegion: 'scroll'
136
- },
137
- topRight: {
138
- points: ['br', 'tr'],
139
- offset: [0, -4],
140
- overflow: {
141
- adjustX: adjustX,
142
- adjustY: adjustY
143
- },
144
- htmlRegion: 'scroll'
145
- }
146
- };
147
- };
148
-
149
- /**
150
- * 根据 selector 相对视口的位置,决定弹层左对齐向右生长(ltr)
151
- * 还是右对齐向左生长(rtl)。列阅读顺序始终从左到右。
152
- */
153
- export var resolveExpandDirection = function resolveExpandDirection(triggerEl, depth) {
154
- var columnMinWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COLUMN_MIN_WIDTH;
155
- if (!triggerEl || typeof window === 'undefined') {
156
- return 'ltr';
157
- }
158
- var rect = triggerEl.getBoundingClientRect();
159
- var columns = Math.max(1, Math.min(depth, 4));
160
- var neededWidth = columns * columnMinWidth;
161
- var spaceRight = window.innerWidth - rect.left;
162
- var spaceLeft = rect.right;
163
- if (spaceRight >= neededWidth) {
164
- return 'ltr';
165
- }
166
- if (spaceLeft > spaceRight) {
167
- return 'rtl';
168
- }
169
- return 'ltr';
170
99
  };
package/dist/index.d.ts CHANGED
@@ -43,7 +43,7 @@ export { RuyiLayout, type RuyiLayoutProps, type RuyiMenuItem } from './layout';
43
43
  export { MpLayout, type MpLayoutProps, type MpMenuItem, type MpTabItem, type MpSubTab } from './layout';
44
44
  export { HuxuanLayout, type HuxuanLayoutProps, type HuxuanNavItem, type HuxuanNavChild, type HuxuanActionItem } from './layout';
45
45
  export { default as ScrollArea, type ScrollAreaProps, type ScrollAreaRef } from './scroll-area';
46
- export { default as Select, type SelectProps } from './select';
46
+ export { default as Select, type SelectProps, type TokenPasteResult, type TokenValidationItem, } from './select';
47
47
  export { default as Slider, type SliderProps } from './slider';
48
48
  export { default as Switch, type SwitchProps } from './switch';
49
49
  export { default as Tabs } from './tabs';
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export type SelectFeedbackState = {
3
+ message: string;
4
+ undoable?: boolean;
5
+ };
6
+ export interface SelectFeedbackProps {
7
+ feedback: SelectFeedbackState | null;
8
+ onUndo?: () => void;
9
+ }
10
+ declare const SelectFeedback: React.FC<SelectFeedbackProps>;
11
+ export default SelectFeedback;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ var SelectFeedback = function SelectFeedback(_ref) {
3
+ var feedback = _ref.feedback,
4
+ onUndo = _ref.onUndo;
5
+ if (!feedback) {
6
+ return null;
7
+ }
8
+ return /*#__PURE__*/React.createElement("div", {
9
+ className: "odn-select-feedback",
10
+ role: "status",
11
+ "data-odn-select-feedback": true
12
+ }, /*#__PURE__*/React.createElement("span", {
13
+ className: "odn-select-feedback-message"
14
+ }, feedback.message), feedback.undoable ? /*#__PURE__*/React.createElement("button", {
15
+ type: "button",
16
+ className: "odn-select-feedback-undo",
17
+ onClick: onUndo
18
+ }, "\u64A4\u9500") : null);
19
+ };
20
+ export default SelectFeedback;
@@ -3,7 +3,8 @@ import { OptGroup, Option } from 'rc-select';
3
3
  import type { BaseOptionType, DefaultOptionType } from 'rc-select/lib/Select';
4
4
  import React from 'react';
5
5
  import './style';
6
- type RawValue = string | number;
6
+ import { type RawValue, type TokenPasteResult, type TokenValidationItem } from './tokenUtils';
7
+ export type { TokenPasteResult, TokenValidationItem };
7
8
  type SemanticName = 'root';
8
9
  type PopupSemantic = 'root';
9
10
  export interface LabeledValue {
@@ -47,6 +48,32 @@ export interface SelectProps<ValueType = any, OptionType extends BaseOptionType
47
48
  optionCheckPosition?: 'left' | 'right';
48
49
  showInnerSearch?: boolean;
49
50
  optionRender?: RcSelectProps['optionRender'];
51
+ /**
52
+ * 批量粘贴 / 输入分词分隔符。传入后启用增强粘贴:
53
+ * 拆分、去重、未匹配标红保留(可由 tokenMismatch 关闭)、反馈条。
54
+ */
55
+ tokenSeparators?: string[];
56
+ /**
57
+ * 未匹配 token 的处理。
58
+ * - `keep`:标红保留为 invalid chip(默认)
59
+ * - `drop`:丢弃未匹配项(对齐 rc-select multiple 默认行为)
60
+ */
61
+ tokenMismatch?: 'drop' | 'keep';
62
+ /** 是否展示批量粘贴 / 清空反馈条。传入 tokenSeparators 时默认 true */
63
+ tokenFeedback?: boolean;
64
+ /**
65
+ * 自定义批量校验(可异步)。不传则按当前 options 的 label/value 本地匹配。
66
+ */
67
+ validateTokens?: (tokens: string[]) => TokenValidationItem[] | Promise<TokenValidationItem[]>;
68
+ /** 批量粘贴处理完成回调 */
69
+ onTokenPaste?: (result: TokenPasteResult) => void;
70
+ /**
71
+ * 清空全部后是否展示「撤销」。
72
+ * 传入 tokenSeparators 时默认 true;也可单独开启(需 allowClear)。
73
+ */
74
+ clearUndo?: boolean;
75
+ /** 反馈条自动消失时长(ms) */
76
+ feedbackDuration?: number;
50
77
  }
51
78
  export interface SelectButtonProps {
52
79
  /** 是否显示箭头 */