@canlooks/can-ui 0.0.194 → 0.0.196

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.
@@ -14,5 +14,7 @@ export interface CounterProps extends Omit<FlexProps, 'defaultValue' | 'onChange
14
14
  decreaseProps?: ButtonProps;
15
15
  increaseProps?: ButtonProps;
16
16
  inputProps?: InputProps;
17
+ readOnly?: boolean;
18
+ disabled?: boolean;
17
19
  }
18
- export declare const Counter: import("react").MemoExoticComponent<({ size, min, max, step, precision, defaultValue, value, onChange, decreaseProps, increaseProps, inputProps, ...props }: CounterProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
20
+ export declare const Counter: import("react").MemoExoticComponent<({ size, min, max, step, precision, defaultValue, value, onChange, decreaseProps, increaseProps, inputProps, readOnly, disabled, ...props }: CounterProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
@@ -11,7 +11,7 @@ const flex_1 = require("../flex");
11
11
  const icon_1 = require("../icon");
12
12
  const faMinus_1 = require("@fortawesome/free-solid-svg-icons/faMinus");
13
13
  const faPlus_1 = require("@fortawesome/free-solid-svg-icons/faPlus");
14
- exports.Counter = (0, react_1.memo)(({ size, min = -Infinity, max = Infinity, step = 1, precision = 0, defaultValue = 0, value, onChange, decreaseProps, increaseProps, inputProps, ...props }) => {
14
+ exports.Counter = (0, react_1.memo)(({ size, min = -Infinity, max = Infinity, step = 1, precision = 0, defaultValue = 0, value, onChange, decreaseProps, increaseProps, inputProps, readOnly, disabled, ...props }) => {
15
15
  const [innerValue, setInnerValue] = (0, utils_1.useControlled)(defaultValue, value, onChange);
16
16
  const commonButtonProps = {
17
17
  size,
@@ -21,13 +21,13 @@ exports.Counter = (0, react_1.memo)(({ size, min = -Infinity, max = Infinity, st
21
21
  const clickHandler = (dir) => {
22
22
  setInnerValue(Math.max(min, Math.min(max, innerValue.current + dir * step)));
23
23
  };
24
- return ((0, jsx_runtime_1.jsxs)(flex_1.Flex, { compact: true, ...props, css: counter_style_1.style, className: (0, utils_1.clsx)(counter_style_1.classes.root, props.className), children: [(0, jsx_runtime_1.jsx)(button_1.Button, { disabled: innerValue.current <= min, ...(0, utils_1.mergeComponentProps)(commonButtonProps, decreaseProps, {
24
+ return ((0, jsx_runtime_1.jsxs)(flex_1.Flex, { compact: true, ...props, css: counter_style_1.style, className: (0, utils_1.clsx)(counter_style_1.classes.root, props.className), children: [(0, jsx_runtime_1.jsx)(button_1.Button, { readOnly: readOnly, disabled: disabled || innerValue.current <= min, ...(0, utils_1.mergeComponentProps)(commonButtonProps, decreaseProps, {
25
25
  onClick: () => clickHandler(-1)
26
- }), children: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faMinus_1.faMinus }) }), (0, jsx_runtime_1.jsx)(input_1.Input, { type: "number", widthAdaptable: true, size: size, min: min, max: max, step: step, precision: precision, ...(0, utils_1.mergeComponentProps)(inputProps, {
26
+ }), children: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faMinus_1.faMinus }) }), (0, jsx_runtime_1.jsx)(input_1.Input, { type: "number", widthAdaptable: true, size: size, min: min, max: max, step: step, precision: precision, readOnly: readOnly, disabled: disabled, ...(0, utils_1.mergeComponentProps)(inputProps, {
27
27
  className: counter_style_1.classes.input,
28
28
  value: innerValue.current,
29
29
  onChange: e => setInnerValue(+e.target.value)
30
- }) }), (0, jsx_runtime_1.jsx)(button_1.Button, { disabled: innerValue.current >= max, ...(0, utils_1.mergeComponentProps)(commonButtonProps, increaseProps, {
30
+ }) }), (0, jsx_runtime_1.jsx)(button_1.Button, { readOnly: readOnly, disabled: disabled || innerValue.current >= max, ...(0, utils_1.mergeComponentProps)(commonButtonProps, increaseProps, {
31
31
  onClick: () => clickHandler(1)
32
32
  }), children: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faPlus_1.faPlus }) })] }));
33
33
  });
@@ -108,6 +108,7 @@ exports.DataGridHead = (0, react_2.memo)(({ allowSelectAll, columnResizable, fla
108
108
  style: { maxWidth: 360 },
109
109
  trigger: 'click',
110
110
  autoClose: false,
111
+ placement: 'bottomLeft',
111
112
  content: ((0, jsx_runtime_1.jsx)(filterBubbleContent_1.FilterBubbleContent, { columnKey: _key, columnFilterProps: filter })),
112
113
  onClick: e => e.stopPropagation()
113
114
  }, filterBubbleProps), children: filterButton }) })] })
@@ -36,7 +36,7 @@ exports.FilterBubbleContent = (0, react_1.memo)(({ columnKey, columnFilterProps
36
36
  } }) }), columnFilterProps.showResetButton !== false &&
37
37
  (0, jsx_runtime_1.jsx)(flex_1.Flex, { gap: 6, justifyContent: "center", marginTop: 6, children: (0, jsx_runtime_1.jsx)(button_1.Button, { variant: "text", onClick: () => {
38
38
  hasChanged.current = true;
39
- formRef.current.resetField(columnKey);
39
+ formRef.current._resetFieldAndCallChange(columnKey);
40
40
  setOpen(false);
41
41
  }, children: "\u91CD\u7F6E" }) })] }));
42
42
  });
@@ -53,6 +53,8 @@ export type FormRef<V extends FormValue = FormValue> = {
53
53
  resetField(field: FieldPath): void;
54
54
  isFormTouched(): boolean;
55
55
  isFieldTouched(field: FieldPath): boolean;
56
+ /** @private 用于dataGrid内的filterBubbleContent组件的"重置"功能 */
57
+ _resetFieldAndCallChange(field: FieldPath): void;
56
58
  };
57
59
  export declare const Form: {
58
60
  <V extends FormValue, C extends ElementType = "form">(props: FormProps<V, C>): ReactElement;
@@ -116,7 +116,11 @@ inline, columnCount = 1, gap, columnGap, rowGap, ...props }) => {
116
116
  setFormValue(o => ({ ...o }));
117
117
  },
118
118
  isFormTouched: () => [...itemsContainer.current].some(([, item]) => item.isTouched),
119
- isFieldTouched: field => !!itemsContainer.current.get((0, utils_1.stringifyField)(field))?.isTouched
119
+ isFieldTouched: field => !!itemsContainer.current.get((0, utils_1.stringifyField)(field))?.isTouched,
120
+ _resetFieldAndCallChange(field) {
121
+ this.resetField(field);
122
+ syncOnChange.current?.(field, void 0, formValue.current);
123
+ }
120
124
  };
121
125
  (0, react_1.useImperativeHandle)(ref, () => formRef.current);
122
126
  return ((0, jsx_runtime_1.jsx)(Component, { ...props, ref: wrapperRef, css: form_style_1.style, className: (0, utils_1.clsx)(form_style_1.classes.root, props.className), onSubmit: submitHandler, children: (0, jsx_runtime_1.jsx)(FormContext, { value: (0, react_1.useMemo)(() => ({
@@ -8,7 +8,7 @@ const pagination_style_1 = require("./pagination.style");
8
8
  const pagination_1 = require("./pagination");
9
9
  exports.PaginationCounter = (0, react_1.memo)((props) => {
10
10
  const { total, page, pageSize } = (0, pagination_1.usePaginationContext)();
11
- const start = (page - 1) * pageSize + 1;
11
+ const start = Math.min((page - 1) * pageSize + 1, total);
12
12
  const end = Math.min(start + pageSize - 1, total);
13
13
  return ((0, jsx_runtime_1.jsxs)("div", { ...props, className: (0, utils_1.clsx)(pagination_style_1.classes.counter, props.className), children: ["\u7B2C ", start, "-", end, " \u6761/\u5171 ", total, " \u6761"] }));
14
14
  });
@@ -15,9 +15,11 @@ const PaginationContext = (0, react_1.createContext)({
15
15
  total: 0,
16
16
  pageCount: 1,
17
17
  page: 1,
18
- onPageChange(page) { },
18
+ onPageChange(page) {
19
+ },
19
20
  pageSize: 10,
20
- onPageSizeChange(pageSize) { }
21
+ onPageSizeChange(pageSize) {
22
+ }
21
23
  });
22
24
  function usePaginationContext() {
23
25
  return (0, react_1.useContext)(PaginationContext);
@@ -89,6 +89,7 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
89
89
  hold(open);
90
90
  setInnerOpen(open);
91
91
  };
92
+ const [derivedOpen, setDerivedOpen] = (0, utils_1.useDerivedState)(() => false, [innerOpen.current]);
92
93
  /**
93
94
  * --------------------------------------------------------------
94
95
  * 渲染条件
@@ -122,9 +123,7 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
122
123
  };
123
124
  const containerEl = (0, utils_1.useContainer)(container, effectContainer);
124
125
  const innerPopperRef = (0, react_1.useRef)(null);
125
- const [popperBounding, setPopperBounding] = (0, react_1.useState)();
126
126
  const [contextMenuEvent, setContextMenuEvent] = (0, utils_1.useSyncState)();
127
- const [openNextFrame, setOpenNextFrame] = (0, utils_1.useDerivedState)(!innerOpen.current, [innerOpen.current, contextMenuEvent.current]);
128
127
  const placeA = (0, react_1.useRef)(void 0);
129
128
  const placeB = (0, react_1.useRef)(void 0);
130
129
  const fitPosition = (options, beforeOpen) => {
@@ -144,21 +143,27 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
144
143
  switch (placement) {
145
144
  case 'topLeft':
146
145
  case 'leftTop':
146
+ top = void 0;
147
147
  bottom = -mouseY;
148
+ left = void 0;
148
149
  right = containerRect.width - mouseX;
149
150
  originX = '100%';
150
151
  originY = '100%';
151
152
  break;
152
153
  case 'topRight':
153
154
  case 'rightTop':
155
+ top = void 0;
154
156
  bottom = -mouseY;
155
157
  left = mouseX;
158
+ right = void 0;
156
159
  originX = '0%';
157
160
  originY = '100%';
158
161
  break;
159
162
  case 'bottomLeft':
160
163
  case 'leftBottom':
161
164
  top = mouseY;
165
+ bottom = void 0;
166
+ left = void 0;
162
167
  right = containerRect.width - mouseX;
163
168
  originX = '100%';
164
169
  originY = '0%';
@@ -166,40 +171,49 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
166
171
  case 'bottomRight':
167
172
  case 'rightBottom':
168
173
  top = mouseY;
174
+ bottom = void 0;
169
175
  left = mouseX;
176
+ right = void 0;
170
177
  originX = '0%';
171
178
  originY = '0%';
172
179
  break;
173
180
  case 'top':
174
181
  top = mouseY - popperHeight;
182
+ bottom = void 0;
175
183
  left = mouseX - popperWidth / 2;
184
+ right = void 0;
176
185
  originX = '50%';
177
186
  originY = '100%';
178
187
  break;
179
188
  case 'bottom':
180
189
  top = mouseY;
190
+ bottom = void 0;
181
191
  left = mouseX - popperWidth / 2;
192
+ right = void 0;
182
193
  originX = '50%';
183
194
  originY = '0%';
184
195
  break;
185
196
  case 'left':
186
197
  top = mouseY - popperHeight / 2;
198
+ bottom = void 0;
187
199
  left = mouseX - popperWidth;
200
+ right = void 0;
188
201
  originX = '100%';
189
202
  originY = '50%';
190
203
  break;
191
204
  case 'right':
192
205
  top = mouseY - popperHeight / 2;
206
+ bottom = void 0;
193
207
  left = mouseX;
208
+ right = void 0;
194
209
  originX = '0%';
195
210
  originY = '50%';
196
- break;
197
211
  }
198
212
  popperEl.style.top = typeof top === 'undefined' ? '' : top + 'px';
199
213
  popperEl.style.bottom = typeof bottom === 'undefined' ? '' : bottom + 'px';
200
214
  popperEl.style.left = typeof left === 'undefined' ? '' : left + 'px';
201
215
  popperEl.style.right = typeof right === 'undefined' ? '' : right + 'px';
202
- return (0, utils_1.isElementOverflowed)(popperEl, containerEl.current === document.body ? void 0 : containerEl.current);
216
+ return (0, utils_1.isElementOverflowed)(popperEl, containerEl.current);
203
217
  };
204
218
  }
205
219
  else {
@@ -208,7 +222,8 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
208
222
  const topEdge = anchorRect.top - containerRect.top;
209
223
  const bottomEdge = anchorRect.bottom - containerRect.top;
210
224
  const leftEdge = anchorRect.left - containerRect.left;
211
- const rightEdge = containerRect.left + containerRect.width - anchorRect.right;
225
+ const rightEdge = anchorRect.right - containerRect.left;
226
+ const containerWidth = containerRect.width;
212
227
  attempt = placement => {
213
228
  [pA, pB] = splitPlacement[placement];
214
229
  if (sizeAdaptable) {
@@ -239,7 +254,7 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
239
254
  break;
240
255
  case 'left':
241
256
  left = void 0;
242
- right = leftEdge - offset;
257
+ right = containerWidth - leftEdge + offset;
243
258
  originX = '100%';
244
259
  break;
245
260
  case 'right':
@@ -255,7 +270,7 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
255
270
  break;
256
271
  case 'right':
257
272
  left = void 0;
258
- right = rightEdge;
273
+ right = containerWidth - rightEdge;
259
274
  originX = '100%';
260
275
  break;
261
276
  case 'top':
@@ -265,7 +280,7 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
265
280
  break;
266
281
  case 'bottom':
267
282
  top = void 0;
268
- bottom = bottomEdge;
283
+ bottom = -bottomEdge;
269
284
  originY = '100%';
270
285
  break;
271
286
  default:
@@ -287,13 +302,15 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
287
302
  popperEl.style.right = typeof right === 'undefined' ? '' : right + 'px';
288
303
  popperEl.style.width = typeof width === 'undefined' ? '' : width + 'px';
289
304
  popperEl.style.height = typeof height === 'undefined' ? '' : height + 'px';
290
- return (0, utils_1.isElementOverflowed)(popperEl, containerEl.current === document.body ? void 0 : containerEl.current);
305
+ return (0, utils_1.isElementOverflowed)(popperEl, containerEl.current);
291
306
  };
292
307
  }
293
308
  if (options?.forcePlacement) {
294
309
  attempt(options.forcePlacement);
295
310
  }
296
311
  else {
312
+ popperEl.style.transition = 'none';
313
+ popperEl.style.transform = 'scale(1)';
297
314
  const attemptOrder = getAttemptOrder(placement);
298
315
  for (let i = 0; i < attemptOrder.length; i++) {
299
316
  const t = attempt(attemptOrder[i]);
@@ -303,28 +320,29 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
303
320
  }
304
321
  }
305
322
  beforeOpen?.();
323
+ placeA.current = pA;
324
+ placeB.current = pB;
306
325
  const settle = () => {
307
- setPopperBounding({
308
- top, bottom, left, right, width, height,
309
- transformOrigin: `${originX} ${originY}`
310
- });
311
- placeA.current = pA;
312
- placeB.current = pB;
326
+ popperEl.style.transition = popperEl.style.transform = '';
327
+ popperEl.style.transformOrigin = `${originX} ${originY}`;
328
+ setDerivedOpen(true);
313
329
  };
314
330
  if (options?.openAnimation) {
315
331
  popperEl.style.transform = variant === 'collapse'
316
332
  ? pA === 'top' || pA === 'bottom' ? 'scaleY(0)' : 'scaleX(0)'
317
333
  : 'scale(0)';
318
- animating.current = true;
319
- setOpenNextFrame(true);
334
+ requestAnimationFrame(() => {
335
+ animating.current = true;
336
+ settle();
337
+ });
338
+ }
339
+ else {
340
+ settle();
320
341
  }
321
- settle();
322
342
  };
323
343
  (0, react_1.useLayoutEffect)(() => {
324
- if (innerOpen.current) {
325
- fitPosition({ openAnimation: true }, triggerBeforeOpen);
326
- }
327
- }, [innerOpen.current, contextMenuEvent.current]);
344
+ innerOpen.current && fitPosition({ openAnimation: animation }, triggerBeforeOpen);
345
+ }, [innerOpen.current, contextMenuEvent.current, animation]);
328
346
  /**
329
347
  * --------------------------------------------------------------
330
348
  * 滚动跟随
@@ -347,9 +365,17 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
347
365
  };
348
366
  addEventListener('resize', windowResize);
349
367
  const scroll = () => {
350
- contextMenuEvent.current
351
- ? setOpenForce(false)
352
- : fitPosition({ forcePlacement: placeA.current + placeB.current });
368
+ if (contextMenuEvent.current) {
369
+ setOpenForce(false);
370
+ }
371
+ else {
372
+ let forcePlacement = placeA.current;
373
+ const pB = placeB.current;
374
+ if (pB) {
375
+ forcePlacement += pB[0].toUpperCase() + pB.slice(1);
376
+ }
377
+ fitPosition({ forcePlacement: forcePlacement });
378
+ }
353
379
  };
354
380
  // 为所有父元素添加滚动事件
355
381
  const scrollDisposer = (0, utils_1.listenAllPredecessorsScroll)(getAnchorElement(), scroll);
@@ -481,7 +507,11 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
481
507
  if (!anchorEl) {
482
508
  return;
483
509
  }
484
- const click = () => openAndHold(true);
510
+ const click = () => {
511
+ innerOpen.current
512
+ ? setOpenForce(false)
513
+ : openAndHold(true);
514
+ };
485
515
  anchorEl.addEventListener('click', click);
486
516
  return () => {
487
517
  anchorEl.removeEventListener('click', click);
@@ -554,14 +584,7 @@ function Popper({ ref, popperRef, anchorElement, container, effectContainer, con
554
584
  })
555
585
  : children, renderedOnce.current && containerEl.current && (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(clickAway_1.ClickAway, { disabled: !clickable && !enterable && !contextMenuable,
556
586
  // 右键菜单点击anchor需要关闭弹框
557
- targets: () => contextMenuEvent.current ? void 0 : getAnchorElement(), onClickAway: onClickAway, children: (0, jsx_runtime_1.jsx)("div", { css: popper_style_1.style, className: popper_style_1.classes.placeHelper, children: (0, jsx_runtime_1.jsx)("div", { ...props, ref: innerPopperRef, className: (0, utils_1.clsx)(popper_style_1.classes.root, props.className), style: {
558
- ...popperBounding,
559
- ...!openNextFrame.current && {
560
- transition: 'none',
561
- transform: 'scale(1)'
562
- },
563
- ...props.style
564
- }, "data-open": innerOpen.current, "data-variant": variant, "data-place-a": placeA.current, "data-place-b": placeB.current, "data-animation": animation, onPointerDown: e => {
587
+ targets: () => contextMenuEvent.current ? void 0 : getAnchorElement(), onClickAway: onClickAway, children: (0, jsx_runtime_1.jsx)("div", { css: popper_style_1.style, className: popper_style_1.classes.placeHelper, children: (0, jsx_runtime_1.jsx)("div", { ...props, ref: innerPopperRef, className: (0, utils_1.clsx)(popper_style_1.classes.root, props.className), "data-open": derivedOpen.current, "data-variant": variant, "data-place-a": placeA.current, "data-place-b": placeB.current, "data-animation": animation, onPointerDown: e => {
565
588
  props.onPointerDown?.(e);
566
589
  e.preventDefault();
567
590
  }, onTransitionEnd: onTransitionEnd, children: (0, jsx_runtime_1.jsx)(popperContext_1.PopperContext, { value: contextValue, children: content }) }) }) }), containerEl.current)] }));
@@ -49,7 +49,7 @@ export type OverflowEdge = 'top' | 'bottom' | 'left' | 'right';
49
49
  * @param container 容器
50
50
  * @returns 'top' | 'bottom' | 'left' | 'right' | false
51
51
  */
52
- export declare function isElementOverflowed(target: Element, container?: Element): OverflowEdge | false;
52
+ export declare function isElementOverflowed(target: Element, container?: Element | null): OverflowEdge | false;
53
53
  /**
54
54
  * 克隆Ref
55
55
  * @param refs
@@ -176,7 +176,7 @@ function isElementOverflowed(target, container) {
176
176
  }
177
177
  return false;
178
178
  };
179
- if (container) {
179
+ if (container && container !== document.body) {
180
180
  return judge(container.getBoundingClientRect());
181
181
  }
182
182
  const vWidth = window.innerWidth || document.documentElement.clientWidth;
@@ -14,5 +14,7 @@ export interface CounterProps extends Omit<FlexProps, 'defaultValue' | 'onChange
14
14
  decreaseProps?: ButtonProps;
15
15
  increaseProps?: ButtonProps;
16
16
  inputProps?: InputProps;
17
+ readOnly?: boolean;
18
+ disabled?: boolean;
17
19
  }
18
- export declare const Counter: import("react").MemoExoticComponent<({ size, min, max, step, precision, defaultValue, value, onChange, decreaseProps, increaseProps, inputProps, ...props }: CounterProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
20
+ export declare const Counter: import("react").MemoExoticComponent<({ size, min, max, step, precision, defaultValue, value, onChange, decreaseProps, increaseProps, inputProps, readOnly, disabled, ...props }: CounterProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
@@ -8,7 +8,7 @@ import { Flex } from '../flex/index.js';
8
8
  import { Icon } from '../icon/index.js';
9
9
  import { faMinus } from '@fortawesome/free-solid-svg-icons/faMinus';
10
10
  import { faPlus } from '@fortawesome/free-solid-svg-icons/faPlus';
11
- export const Counter = memo(({ size, min = -Infinity, max = Infinity, step = 1, precision = 0, defaultValue = 0, value, onChange, decreaseProps, increaseProps, inputProps, ...props }) => {
11
+ export const Counter = memo(({ size, min = -Infinity, max = Infinity, step = 1, precision = 0, defaultValue = 0, value, onChange, decreaseProps, increaseProps, inputProps, readOnly, disabled, ...props }) => {
12
12
  const [innerValue, setInnerValue] = useControlled(defaultValue, value, onChange);
13
13
  const commonButtonProps = {
14
14
  size,
@@ -18,13 +18,13 @@ export const Counter = memo(({ size, min = -Infinity, max = Infinity, step = 1,
18
18
  const clickHandler = (dir) => {
19
19
  setInnerValue(Math.max(min, Math.min(max, innerValue.current + dir * step)));
20
20
  };
21
- return (_jsxs(Flex, { compact: true, ...props, css: style, className: clsx(classes.root, props.className), children: [_jsx(Button, { disabled: innerValue.current <= min, ...mergeComponentProps(commonButtonProps, decreaseProps, {
21
+ return (_jsxs(Flex, { compact: true, ...props, css: style, className: clsx(classes.root, props.className), children: [_jsx(Button, { readOnly: readOnly, disabled: disabled || innerValue.current <= min, ...mergeComponentProps(commonButtonProps, decreaseProps, {
22
22
  onClick: () => clickHandler(-1)
23
- }), children: _jsx(Icon, { icon: faMinus }) }), _jsx(Input, { type: "number", widthAdaptable: true, size: size, min: min, max: max, step: step, precision: precision, ...mergeComponentProps(inputProps, {
23
+ }), children: _jsx(Icon, { icon: faMinus }) }), _jsx(Input, { type: "number", widthAdaptable: true, size: size, min: min, max: max, step: step, precision: precision, readOnly: readOnly, disabled: disabled, ...mergeComponentProps(inputProps, {
24
24
  className: classes.input,
25
25
  value: innerValue.current,
26
26
  onChange: e => setInnerValue(+e.target.value)
27
- }) }), _jsx(Button, { disabled: innerValue.current >= max, ...mergeComponentProps(commonButtonProps, increaseProps, {
27
+ }) }), _jsx(Button, { readOnly: readOnly, disabled: disabled || innerValue.current >= max, ...mergeComponentProps(commonButtonProps, increaseProps, {
28
28
  onClick: () => clickHandler(1)
29
29
  }), children: _jsx(Icon, { icon: faPlus }) })] }));
30
30
  });
@@ -105,6 +105,7 @@ export const DataGridHead = memo(({ allowSelectAll, columnResizable, flattedColu
105
105
  style: { maxWidth: 360 },
106
106
  trigger: 'click',
107
107
  autoClose: false,
108
+ placement: 'bottomLeft',
108
109
  content: (_jsx(FilterBubbleContent, { columnKey: _key, columnFilterProps: filter })),
109
110
  onClick: e => e.stopPropagation()
110
111
  }, filterBubbleProps), children: filterButton }) })] })
@@ -33,7 +33,7 @@ export const FilterBubbleContent = memo(({ columnKey, columnFilterProps }) => {
33
33
  } }) }), columnFilterProps.showResetButton !== false &&
34
34
  _jsx(Flex, { gap: 6, justifyContent: "center", marginTop: 6, children: _jsx(Button, { variant: "text", onClick: () => {
35
35
  hasChanged.current = true;
36
- formRef.current.resetField(columnKey);
36
+ formRef.current._resetFieldAndCallChange(columnKey);
37
37
  setOpen(false);
38
38
  }, children: "\u91CD\u7F6E" }) })] }));
39
39
  });
@@ -53,6 +53,8 @@ export type FormRef<V extends FormValue = FormValue> = {
53
53
  resetField(field: FieldPath): void;
54
54
  isFormTouched(): boolean;
55
55
  isFieldTouched(field: FieldPath): boolean;
56
+ /** @private 用于dataGrid内的filterBubbleContent组件的"重置"功能 */
57
+ _resetFieldAndCallChange(field: FieldPath): void;
56
58
  };
57
59
  export declare const Form: {
58
60
  <V extends FormValue, C extends ElementType = "form">(props: FormProps<V, C>): ReactElement;
@@ -110,7 +110,11 @@ inline, columnCount = 1, gap, columnGap, rowGap, ...props }) => {
110
110
  setFormValue(o => ({ ...o }));
111
111
  },
112
112
  isFormTouched: () => [...itemsContainer.current].some(([, item]) => item.isTouched),
113
- isFieldTouched: field => !!itemsContainer.current.get(stringifyField(field))?.isTouched
113
+ isFieldTouched: field => !!itemsContainer.current.get(stringifyField(field))?.isTouched,
114
+ _resetFieldAndCallChange(field) {
115
+ this.resetField(field);
116
+ syncOnChange.current?.(field, void 0, formValue.current);
117
+ }
114
118
  };
115
119
  useImperativeHandle(ref, () => formRef.current);
116
120
  return (_jsx(Component, { ...props, ref: wrapperRef, css: style, className: clsx(classes.root, props.className), onSubmit: submitHandler, children: _jsx(FormContext, { value: useMemo(() => ({
@@ -5,7 +5,7 @@ import { classes } from './pagination.style.js';
5
5
  import { usePaginationContext } from './pagination.js';
6
6
  export const PaginationCounter = memo((props) => {
7
7
  const { total, page, pageSize } = usePaginationContext();
8
- const start = (page - 1) * pageSize + 1;
8
+ const start = Math.min((page - 1) * pageSize + 1, total);
9
9
  const end = Math.min(start + pageSize - 1, total);
10
10
  return (_jsxs("div", { ...props, className: clsx(classes.counter, props.className), children: ["\u7B2C ", start, "-", end, " \u6761/\u5171 ", total, " \u6761"] }));
11
11
  });
@@ -11,9 +11,11 @@ const PaginationContext = createContext({
11
11
  total: 0,
12
12
  pageCount: 1,
13
13
  page: 1,
14
- onPageChange(page) { },
14
+ onPageChange(page) {
15
+ },
15
16
  pageSize: 10,
16
- onPageSizeChange(pageSize) { }
17
+ onPageSizeChange(pageSize) {
18
+ }
17
19
  });
18
20
  export function usePaginationContext() {
19
21
  return useContext(PaginationContext);
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
2
- import { cloneElement, isValidElement, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';
2
+ import { cloneElement, isValidElement, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
- import { clsx, cloneRef, listenAllPredecessorsScroll, toArray, useControlled, useDerivedState, useForceUpdate, useSync, useSyncState, useUnmounted, useContainer, isElementOverflowed, isChildOf, useUpdateEffect } from '../../utils/index.js';
4
+ import { clsx, cloneRef, listenAllPredecessorsScroll, toArray, useControlled, useForceUpdate, useSync, useSyncState, useUnmounted, useContainer, isElementOverflowed, isChildOf, useUpdateEffect, useDerivedState } from '../../utils/index.js';
5
5
  import { ClickAway } from '../clickAway/index.js';
6
6
  import { classes, style } from './popper.style.js';
7
7
  import { PopperContext, usePopperContext } from './popperContext.js';
@@ -86,6 +86,7 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
86
86
  hold(open);
87
87
  setInnerOpen(open);
88
88
  };
89
+ const [derivedOpen, setDerivedOpen] = useDerivedState(() => false, [innerOpen.current]);
89
90
  /**
90
91
  * --------------------------------------------------------------
91
92
  * 渲染条件
@@ -119,9 +120,7 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
119
120
  };
120
121
  const containerEl = useContainer(container, effectContainer);
121
122
  const innerPopperRef = useRef(null);
122
- const [popperBounding, setPopperBounding] = useState();
123
123
  const [contextMenuEvent, setContextMenuEvent] = useSyncState();
124
- const [openNextFrame, setOpenNextFrame] = useDerivedState(!innerOpen.current, [innerOpen.current, contextMenuEvent.current]);
125
124
  const placeA = useRef(void 0);
126
125
  const placeB = useRef(void 0);
127
126
  const fitPosition = (options, beforeOpen) => {
@@ -141,21 +140,27 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
141
140
  switch (placement) {
142
141
  case 'topLeft':
143
142
  case 'leftTop':
143
+ top = void 0;
144
144
  bottom = -mouseY;
145
+ left = void 0;
145
146
  right = containerRect.width - mouseX;
146
147
  originX = '100%';
147
148
  originY = '100%';
148
149
  break;
149
150
  case 'topRight':
150
151
  case 'rightTop':
152
+ top = void 0;
151
153
  bottom = -mouseY;
152
154
  left = mouseX;
155
+ right = void 0;
153
156
  originX = '0%';
154
157
  originY = '100%';
155
158
  break;
156
159
  case 'bottomLeft':
157
160
  case 'leftBottom':
158
161
  top = mouseY;
162
+ bottom = void 0;
163
+ left = void 0;
159
164
  right = containerRect.width - mouseX;
160
165
  originX = '100%';
161
166
  originY = '0%';
@@ -163,40 +168,49 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
163
168
  case 'bottomRight':
164
169
  case 'rightBottom':
165
170
  top = mouseY;
171
+ bottom = void 0;
166
172
  left = mouseX;
173
+ right = void 0;
167
174
  originX = '0%';
168
175
  originY = '0%';
169
176
  break;
170
177
  case 'top':
171
178
  top = mouseY - popperHeight;
179
+ bottom = void 0;
172
180
  left = mouseX - popperWidth / 2;
181
+ right = void 0;
173
182
  originX = '50%';
174
183
  originY = '100%';
175
184
  break;
176
185
  case 'bottom':
177
186
  top = mouseY;
187
+ bottom = void 0;
178
188
  left = mouseX - popperWidth / 2;
189
+ right = void 0;
179
190
  originX = '50%';
180
191
  originY = '0%';
181
192
  break;
182
193
  case 'left':
183
194
  top = mouseY - popperHeight / 2;
195
+ bottom = void 0;
184
196
  left = mouseX - popperWidth;
197
+ right = void 0;
185
198
  originX = '100%';
186
199
  originY = '50%';
187
200
  break;
188
201
  case 'right':
189
202
  top = mouseY - popperHeight / 2;
203
+ bottom = void 0;
190
204
  left = mouseX;
205
+ right = void 0;
191
206
  originX = '0%';
192
207
  originY = '50%';
193
- break;
194
208
  }
195
209
  popperEl.style.top = typeof top === 'undefined' ? '' : top + 'px';
196
210
  popperEl.style.bottom = typeof bottom === 'undefined' ? '' : bottom + 'px';
197
211
  popperEl.style.left = typeof left === 'undefined' ? '' : left + 'px';
198
212
  popperEl.style.right = typeof right === 'undefined' ? '' : right + 'px';
199
- return isElementOverflowed(popperEl, containerEl.current === document.body ? void 0 : containerEl.current);
213
+ return isElementOverflowed(popperEl, containerEl.current);
200
214
  };
201
215
  }
202
216
  else {
@@ -205,7 +219,8 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
205
219
  const topEdge = anchorRect.top - containerRect.top;
206
220
  const bottomEdge = anchorRect.bottom - containerRect.top;
207
221
  const leftEdge = anchorRect.left - containerRect.left;
208
- const rightEdge = containerRect.left + containerRect.width - anchorRect.right;
222
+ const rightEdge = anchorRect.right - containerRect.left;
223
+ const containerWidth = containerRect.width;
209
224
  attempt = placement => {
210
225
  [pA, pB] = splitPlacement[placement];
211
226
  if (sizeAdaptable) {
@@ -236,7 +251,7 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
236
251
  break;
237
252
  case 'left':
238
253
  left = void 0;
239
- right = leftEdge - offset;
254
+ right = containerWidth - leftEdge + offset;
240
255
  originX = '100%';
241
256
  break;
242
257
  case 'right':
@@ -252,7 +267,7 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
252
267
  break;
253
268
  case 'right':
254
269
  left = void 0;
255
- right = rightEdge;
270
+ right = containerWidth - rightEdge;
256
271
  originX = '100%';
257
272
  break;
258
273
  case 'top':
@@ -262,7 +277,7 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
262
277
  break;
263
278
  case 'bottom':
264
279
  top = void 0;
265
- bottom = bottomEdge;
280
+ bottom = -bottomEdge;
266
281
  originY = '100%';
267
282
  break;
268
283
  default:
@@ -284,13 +299,15 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
284
299
  popperEl.style.right = typeof right === 'undefined' ? '' : right + 'px';
285
300
  popperEl.style.width = typeof width === 'undefined' ? '' : width + 'px';
286
301
  popperEl.style.height = typeof height === 'undefined' ? '' : height + 'px';
287
- return isElementOverflowed(popperEl, containerEl.current === document.body ? void 0 : containerEl.current);
302
+ return isElementOverflowed(popperEl, containerEl.current);
288
303
  };
289
304
  }
290
305
  if (options?.forcePlacement) {
291
306
  attempt(options.forcePlacement);
292
307
  }
293
308
  else {
309
+ popperEl.style.transition = 'none';
310
+ popperEl.style.transform = 'scale(1)';
294
311
  const attemptOrder = getAttemptOrder(placement);
295
312
  for (let i = 0; i < attemptOrder.length; i++) {
296
313
  const t = attempt(attemptOrder[i]);
@@ -300,28 +317,29 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
300
317
  }
301
318
  }
302
319
  beforeOpen?.();
320
+ placeA.current = pA;
321
+ placeB.current = pB;
303
322
  const settle = () => {
304
- setPopperBounding({
305
- top, bottom, left, right, width, height,
306
- transformOrigin: `${originX} ${originY}`
307
- });
308
- placeA.current = pA;
309
- placeB.current = pB;
323
+ popperEl.style.transition = popperEl.style.transform = '';
324
+ popperEl.style.transformOrigin = `${originX} ${originY}`;
325
+ setDerivedOpen(true);
310
326
  };
311
327
  if (options?.openAnimation) {
312
328
  popperEl.style.transform = variant === 'collapse'
313
329
  ? pA === 'top' || pA === 'bottom' ? 'scaleY(0)' : 'scaleX(0)'
314
330
  : 'scale(0)';
315
- animating.current = true;
316
- setOpenNextFrame(true);
331
+ requestAnimationFrame(() => {
332
+ animating.current = true;
333
+ settle();
334
+ });
335
+ }
336
+ else {
337
+ settle();
317
338
  }
318
- settle();
319
339
  };
320
340
  useLayoutEffect(() => {
321
- if (innerOpen.current) {
322
- fitPosition({ openAnimation: true }, triggerBeforeOpen);
323
- }
324
- }, [innerOpen.current, contextMenuEvent.current]);
341
+ innerOpen.current && fitPosition({ openAnimation: animation }, triggerBeforeOpen);
342
+ }, [innerOpen.current, contextMenuEvent.current, animation]);
325
343
  /**
326
344
  * --------------------------------------------------------------
327
345
  * 滚动跟随
@@ -344,9 +362,17 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
344
362
  };
345
363
  addEventListener('resize', windowResize);
346
364
  const scroll = () => {
347
- contextMenuEvent.current
348
- ? setOpenForce(false)
349
- : fitPosition({ forcePlacement: placeA.current + placeB.current });
365
+ if (contextMenuEvent.current) {
366
+ setOpenForce(false);
367
+ }
368
+ else {
369
+ let forcePlacement = placeA.current;
370
+ const pB = placeB.current;
371
+ if (pB) {
372
+ forcePlacement += pB[0].toUpperCase() + pB.slice(1);
373
+ }
374
+ fitPosition({ forcePlacement: forcePlacement });
375
+ }
350
376
  };
351
377
  // 为所有父元素添加滚动事件
352
378
  const scrollDisposer = listenAllPredecessorsScroll(getAnchorElement(), scroll);
@@ -478,7 +504,11 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
478
504
  if (!anchorEl) {
479
505
  return;
480
506
  }
481
- const click = () => openAndHold(true);
507
+ const click = () => {
508
+ innerOpen.current
509
+ ? setOpenForce(false)
510
+ : openAndHold(true);
511
+ };
482
512
  anchorEl.addEventListener('click', click);
483
513
  return () => {
484
514
  anchorEl.removeEventListener('click', click);
@@ -551,14 +581,7 @@ export function Popper({ ref, popperRef, anchorElement, container, effectContain
551
581
  })
552
582
  : children, renderedOnce.current && containerEl.current && createPortal(_jsx(ClickAway, { disabled: !clickable && !enterable && !contextMenuable,
553
583
  // 右键菜单点击anchor需要关闭弹框
554
- targets: () => contextMenuEvent.current ? void 0 : getAnchorElement(), onClickAway: onClickAway, children: _jsx("div", { css: style, className: classes.placeHelper, children: _jsx("div", { ...props, ref: innerPopperRef, className: clsx(classes.root, props.className), style: {
555
- ...popperBounding,
556
- ...!openNextFrame.current && {
557
- transition: 'none',
558
- transform: 'scale(1)'
559
- },
560
- ...props.style
561
- }, "data-open": innerOpen.current, "data-variant": variant, "data-place-a": placeA.current, "data-place-b": placeB.current, "data-animation": animation, onPointerDown: e => {
584
+ targets: () => contextMenuEvent.current ? void 0 : getAnchorElement(), onClickAway: onClickAway, children: _jsx("div", { css: style, className: classes.placeHelper, children: _jsx("div", { ...props, ref: innerPopperRef, className: clsx(classes.root, props.className), "data-open": derivedOpen.current, "data-variant": variant, "data-place-a": placeA.current, "data-place-b": placeB.current, "data-animation": animation, onPointerDown: e => {
562
585
  props.onPointerDown?.(e);
563
586
  e.preventDefault();
564
587
  }, onTransitionEnd: onTransitionEnd, children: _jsx(PopperContext, { value: contextValue, children: content }) }) }) }), containerEl.current)] }));
@@ -49,7 +49,7 @@ export type OverflowEdge = 'top' | 'bottom' | 'left' | 'right';
49
49
  * @param container 容器
50
50
  * @returns 'top' | 'bottom' | 'left' | 'right' | false
51
51
  */
52
- export declare function isElementOverflowed(target: Element, container?: Element): OverflowEdge | false;
52
+ export declare function isElementOverflowed(target: Element, container?: Element | null): OverflowEdge | false;
53
53
  /**
54
54
  * 克隆Ref
55
55
  * @param refs
@@ -151,7 +151,7 @@ export function isElementOverflowed(target, container) {
151
151
  }
152
152
  return false;
153
153
  };
154
- if (container) {
154
+ if (container && container !== document.body) {
155
155
  return judge(container.getBoundingClientRect());
156
156
  }
157
157
  const vWidth = window.innerWidth || document.documentElement.clientWidth;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canlooks/can-ui",
3
- "version": "0.0.194",
3
+ "version": "0.0.196",
4
4
  "author": "C.CanLiang <canlooks@gmail.com>",
5
5
  "description": "My ui framework",
6
6
  "license": "MIT",