@choice-ui/react 1.5.6 → 1.5.7
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/components/dropdown/dist/index.js +41 -16
- package/dist/components/dropdown/src/dropdown.js +41 -16
- package/dist/components/menus/dist/index.js +23 -18
- package/dist/components/menus/src/components/menu-trigger.js +24 -18
- package/dist/components/multi-select/dist/index.js +16 -11
- package/dist/components/multi-select/src/multi-select.js +16 -11
- package/dist/components/popover/dist/index.js +5 -2
- package/dist/components/popover/src/components/popover-trigger.js +5 -2
- package/dist/components/select/dist/index.js +33 -17
- package/dist/components/select/src/select.js +33 -17
- package/dist/components/slot/dist/index.d.ts +7 -11
- package/dist/components/slot/dist/index.js +45 -43
- package/dist/components/slot/src/slot.d.ts +7 -13
- package/dist/components/slot/src/slot.js +49 -47
- package/dist/components/tooltip/dist/index.js +7 -2
- package/dist/components/tooltip/src/components/tooltip-trigger.js +8 -3
- package/package.json +1 -1
|
@@ -279,27 +279,52 @@ var DropdownComponent = memo(function DropdownComponent2(props) {
|
|
|
279
279
|
}),
|
|
280
280
|
[activeIndex, getItemProps, handleClose, isControlledOpen, readOnly, selection, variant]
|
|
281
281
|
);
|
|
282
|
+
const parentActiveIndex = parent == null ? void 0 : parent.activeIndex;
|
|
283
|
+
const parentGetItemProps = parent == null ? void 0 : parent.getItemProps;
|
|
284
|
+
const slotProps = useMemo(() => {
|
|
285
|
+
const referenceProps = getReferenceProps(
|
|
286
|
+
parentGetItemProps ? parentGetItemProps({
|
|
287
|
+
onFocus: handleFocus
|
|
288
|
+
}) : {}
|
|
289
|
+
);
|
|
290
|
+
return {
|
|
291
|
+
tabIndex: !isNested ? void 0 : parentActiveIndex === item.index ? 0 : -1,
|
|
292
|
+
role: isNested ? "menuitem" : void 0,
|
|
293
|
+
"data-open": isControlledOpen ? "" : void 0,
|
|
294
|
+
"data-nested": isNested ? "" : void 0,
|
|
295
|
+
"data-focus-inside": hasFocusInside ? "" : void 0,
|
|
296
|
+
onTouchStart: handleTouchStart,
|
|
297
|
+
onPointerMove: handlePointerMove,
|
|
298
|
+
"aria-haspopup": "menu",
|
|
299
|
+
"aria-expanded": isControlledOpen,
|
|
300
|
+
"aria-controls": menuId,
|
|
301
|
+
...referenceProps
|
|
302
|
+
};
|
|
303
|
+
}, [
|
|
304
|
+
isNested,
|
|
305
|
+
parentActiveIndex,
|
|
306
|
+
parentGetItemProps,
|
|
307
|
+
item.index,
|
|
308
|
+
isControlledOpen,
|
|
309
|
+
hasFocusInside,
|
|
310
|
+
handleTouchStart,
|
|
311
|
+
handlePointerMove,
|
|
312
|
+
menuId,
|
|
313
|
+
getReferenceProps,
|
|
314
|
+
handleFocus
|
|
315
|
+
]);
|
|
316
|
+
const slotChildren = useMemo(() => {
|
|
317
|
+
const element = isNested ? subTriggerElement : triggerElement;
|
|
318
|
+
if (!element) return null;
|
|
319
|
+
return cloneElement(element, { active: isControlledOpen });
|
|
320
|
+
}, [isNested, subTriggerElement, triggerElement, isControlledOpen]);
|
|
282
321
|
return /* @__PURE__ */ jsxs(FloatingNode, { id: nodeId, children: [
|
|
283
322
|
!isCoordinateMode && !hasExternalTrigger && /* @__PURE__ */ jsx(
|
|
284
323
|
Slot,
|
|
285
324
|
{
|
|
286
325
|
ref: refs.setReference,
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
"data-open": isControlledOpen ? "" : void 0,
|
|
290
|
-
"data-nested": isNested ? "" : void 0,
|
|
291
|
-
"data-focus-inside": hasFocusInside ? "" : void 0,
|
|
292
|
-
onTouchStart: handleTouchStart,
|
|
293
|
-
onPointerMove: handlePointerMove,
|
|
294
|
-
"aria-haspopup": "menu",
|
|
295
|
-
"aria-expanded": isControlledOpen,
|
|
296
|
-
"aria-controls": menuId,
|
|
297
|
-
...getReferenceProps(
|
|
298
|
-
parent ? parent.getItemProps({
|
|
299
|
-
onFocus: handleFocus
|
|
300
|
-
}) : {}
|
|
301
|
-
),
|
|
302
|
-
children: isNested ? subTriggerElement && cloneElement(subTriggerElement, { active: isControlledOpen }) : triggerElement && cloneElement(triggerElement, { active: isControlledOpen })
|
|
326
|
+
...slotProps,
|
|
327
|
+
children: slotChildren
|
|
303
328
|
}
|
|
304
329
|
),
|
|
305
330
|
/* @__PURE__ */ jsx(
|
|
@@ -279,27 +279,52 @@ const DropdownComponent = memo(function DropdownComponent2(props) {
|
|
|
279
279
|
}),
|
|
280
280
|
[activeIndex, getItemProps, handleClose, isControlledOpen, readOnly, selection, variant]
|
|
281
281
|
);
|
|
282
|
+
const parentActiveIndex = parent == null ? void 0 : parent.activeIndex;
|
|
283
|
+
const parentGetItemProps = parent == null ? void 0 : parent.getItemProps;
|
|
284
|
+
const slotProps = useMemo(() => {
|
|
285
|
+
const referenceProps = getReferenceProps(
|
|
286
|
+
parentGetItemProps ? parentGetItemProps({
|
|
287
|
+
onFocus: handleFocus
|
|
288
|
+
}) : {}
|
|
289
|
+
);
|
|
290
|
+
return {
|
|
291
|
+
tabIndex: !isNested ? void 0 : parentActiveIndex === item.index ? 0 : -1,
|
|
292
|
+
role: isNested ? "menuitem" : void 0,
|
|
293
|
+
"data-open": isControlledOpen ? "" : void 0,
|
|
294
|
+
"data-nested": isNested ? "" : void 0,
|
|
295
|
+
"data-focus-inside": hasFocusInside ? "" : void 0,
|
|
296
|
+
onTouchStart: handleTouchStart,
|
|
297
|
+
onPointerMove: handlePointerMove,
|
|
298
|
+
"aria-haspopup": "menu",
|
|
299
|
+
"aria-expanded": isControlledOpen,
|
|
300
|
+
"aria-controls": menuId,
|
|
301
|
+
...referenceProps
|
|
302
|
+
};
|
|
303
|
+
}, [
|
|
304
|
+
isNested,
|
|
305
|
+
parentActiveIndex,
|
|
306
|
+
parentGetItemProps,
|
|
307
|
+
item.index,
|
|
308
|
+
isControlledOpen,
|
|
309
|
+
hasFocusInside,
|
|
310
|
+
handleTouchStart,
|
|
311
|
+
handlePointerMove,
|
|
312
|
+
menuId,
|
|
313
|
+
getReferenceProps,
|
|
314
|
+
handleFocus
|
|
315
|
+
]);
|
|
316
|
+
const slotChildren = useMemo(() => {
|
|
317
|
+
const element = isNested ? subTriggerElement : triggerElement;
|
|
318
|
+
if (!element) return null;
|
|
319
|
+
return cloneElement(element, { active: isControlledOpen });
|
|
320
|
+
}, [isNested, subTriggerElement, triggerElement, isControlledOpen]);
|
|
282
321
|
return /* @__PURE__ */ jsxs(FloatingNode, { id: nodeId, children: [
|
|
283
322
|
!isCoordinateMode && !hasExternalTrigger && /* @__PURE__ */ jsx(
|
|
284
323
|
Slot,
|
|
285
324
|
{
|
|
286
325
|
ref: refs.setReference,
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
"data-open": isControlledOpen ? "" : void 0,
|
|
290
|
-
"data-nested": isNested ? "" : void 0,
|
|
291
|
-
"data-focus-inside": hasFocusInside ? "" : void 0,
|
|
292
|
-
onTouchStart: handleTouchStart,
|
|
293
|
-
onPointerMove: handlePointerMove,
|
|
294
|
-
"aria-haspopup": "menu",
|
|
295
|
-
"aria-expanded": isControlledOpen,
|
|
296
|
-
"aria-controls": menuId,
|
|
297
|
-
...getReferenceProps(
|
|
298
|
-
parent ? parent.getItemProps({
|
|
299
|
-
onFocus: handleFocus
|
|
300
|
-
}) : {}
|
|
301
|
-
),
|
|
302
|
-
children: isNested ? subTriggerElement && cloneElement(subTriggerElement, { active: isControlledOpen }) : triggerElement && cloneElement(triggerElement, { active: isControlledOpen })
|
|
326
|
+
...slotProps,
|
|
327
|
+
children: slotChildren
|
|
303
328
|
}
|
|
304
329
|
),
|
|
305
330
|
/* @__PURE__ */ jsx(
|
|
@@ -6,8 +6,8 @@ import { Kbd } from "../../kbd/dist/index.js";
|
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
import { SearchInput } from "../../search-input/dist/index.js";
|
|
8
8
|
import { Slot } from "../../slot/dist/index.js";
|
|
9
|
-
import { Input } from "../../input/dist/index.js";
|
|
10
9
|
import { useEventCallback } from "usehooks-ts";
|
|
10
|
+
import { Input } from "../../input/dist/index.js";
|
|
11
11
|
import { useListItem, useFloatingTree, useFloatingNodeId, useFloatingParentNodeId } from "@floating-ui/react";
|
|
12
12
|
import { useIsomorphicLayoutEffect } from "../../../shared/hooks/use-isomorphic-layout-effect/use-isomorphic-layout-effect.js";
|
|
13
13
|
import { tcv, tcx } from "../../../shared/utils/tcx/tcx.js";
|
|
@@ -638,24 +638,29 @@ var MenuTrigger = memo(
|
|
|
638
638
|
isEmpty: empty,
|
|
639
639
|
size: size2
|
|
640
640
|
});
|
|
641
|
-
const
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
rest
|
|
651
|
-
|
|
641
|
+
const handleClick = useEventCallback((e) => {
|
|
642
|
+
var _a;
|
|
643
|
+
e.stopPropagation();
|
|
644
|
+
e.preventDefault();
|
|
645
|
+
(_a = rest.onClick) == null ? void 0 : _a.call(rest, e);
|
|
646
|
+
});
|
|
647
|
+
const slotProps = useMemo(() => {
|
|
648
|
+
if (enterForwardedProps) {
|
|
649
|
+
return {
|
|
650
|
+
...rest,
|
|
651
|
+
active,
|
|
652
|
+
selected,
|
|
653
|
+
disabled,
|
|
654
|
+
onClick: handleClick
|
|
655
|
+
};
|
|
652
656
|
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
657
|
+
return {
|
|
658
|
+
...rest,
|
|
659
|
+
...active !== void 0 ? { "data-active": active } : {},
|
|
660
|
+
...selected !== void 0 ? { "data-selected": selected } : {},
|
|
661
|
+
...disabled !== void 0 ? { "data-disabled": disabled } : {}
|
|
662
|
+
};
|
|
663
|
+
}, [enterForwardedProps, rest, active, selected, disabled, handleClick]);
|
|
659
664
|
return asChild ? /* @__PURE__ */ jsx(
|
|
660
665
|
Slot,
|
|
661
666
|
{
|
|
@@ -2,7 +2,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Button } from "../../../button/dist/index.js";
|
|
3
3
|
import { Slot } from "../../../slot/dist/index.js";
|
|
4
4
|
import { ChevronDownSmall } from "@choiceform/icons-react";
|
|
5
|
-
import { memo, forwardRef } from "react";
|
|
5
|
+
import { memo, forwardRef, useMemo } from "react";
|
|
6
|
+
import { useEventCallback } from "usehooks-ts";
|
|
6
7
|
import { MenuTriggerTv } from "../tv.js";
|
|
7
8
|
import { tcx } from "../../../../shared/utils/tcx/tcx.js";
|
|
8
9
|
const MenuTrigger = memo(
|
|
@@ -28,24 +29,29 @@ const MenuTrigger = memo(
|
|
|
28
29
|
isEmpty: empty,
|
|
29
30
|
size
|
|
30
31
|
});
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
rest
|
|
41
|
-
|
|
32
|
+
const handleClick = useEventCallback((e) => {
|
|
33
|
+
var _a;
|
|
34
|
+
e.stopPropagation();
|
|
35
|
+
e.preventDefault();
|
|
36
|
+
(_a = rest.onClick) == null ? void 0 : _a.call(rest, e);
|
|
37
|
+
});
|
|
38
|
+
const slotProps = useMemo(() => {
|
|
39
|
+
if (enterForwardedProps) {
|
|
40
|
+
return {
|
|
41
|
+
...rest,
|
|
42
|
+
active,
|
|
43
|
+
selected,
|
|
44
|
+
disabled,
|
|
45
|
+
onClick: handleClick
|
|
46
|
+
};
|
|
42
47
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
return {
|
|
49
|
+
...rest,
|
|
50
|
+
...active !== void 0 ? { "data-active": active } : {},
|
|
51
|
+
...selected !== void 0 ? { "data-selected": selected } : {},
|
|
52
|
+
...disabled !== void 0 ? { "data-disabled": disabled } : {}
|
|
53
|
+
};
|
|
54
|
+
}, [enterForwardedProps, rest, active, selected, disabled, handleClick]);
|
|
49
55
|
return asChild ? /* @__PURE__ */ jsx(
|
|
50
56
|
Slot,
|
|
51
57
|
{
|
|
@@ -740,6 +740,21 @@ var MultiSelectComponent = memo(
|
|
|
740
740
|
chipVariant,
|
|
741
741
|
valueDisabledMap
|
|
742
742
|
]);
|
|
743
|
+
const handleTouchStart = useEventCallback(() => {
|
|
744
|
+
setTouch(true);
|
|
745
|
+
});
|
|
746
|
+
const handlePointerMove = useEventCallback(({ pointerType }) => {
|
|
747
|
+
if (pointerType !== "touch") {
|
|
748
|
+
setTouch(false);
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
const slotProps = useMemo(() => {
|
|
752
|
+
return getReferenceProps({
|
|
753
|
+
disabled,
|
|
754
|
+
onTouchStart: handleTouchStart,
|
|
755
|
+
onPointerMove: handlePointerMove
|
|
756
|
+
});
|
|
757
|
+
}, [getReferenceProps, disabled, handleTouchStart, handlePointerMove]);
|
|
743
758
|
if (!triggerElement || !contentElement) {
|
|
744
759
|
console.error(
|
|
745
760
|
"MultiSelect requires both MultiSelect.Trigger and MultiSelect.Content components as children"
|
|
@@ -751,17 +766,7 @@ var MultiSelectComponent = memo(
|
|
|
751
766
|
Slot,
|
|
752
767
|
{
|
|
753
768
|
ref: refs.setReference,
|
|
754
|
-
...
|
|
755
|
-
disabled,
|
|
756
|
-
onTouchStart() {
|
|
757
|
-
setTouch(true);
|
|
758
|
-
},
|
|
759
|
-
onPointerMove({ pointerType }) {
|
|
760
|
-
if (pointerType !== "touch") {
|
|
761
|
-
setTouch(false);
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
}),
|
|
769
|
+
...slotProps,
|
|
765
770
|
children: enhancedTriggerElement
|
|
766
771
|
}
|
|
767
772
|
),
|
|
@@ -355,6 +355,21 @@ const MultiSelectComponent = memo(
|
|
|
355
355
|
chipVariant,
|
|
356
356
|
valueDisabledMap
|
|
357
357
|
]);
|
|
358
|
+
const handleTouchStart = useEventCallback(() => {
|
|
359
|
+
setTouch(true);
|
|
360
|
+
});
|
|
361
|
+
const handlePointerMove = useEventCallback(({ pointerType }) => {
|
|
362
|
+
if (pointerType !== "touch") {
|
|
363
|
+
setTouch(false);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
const slotProps = useMemo(() => {
|
|
367
|
+
return getReferenceProps({
|
|
368
|
+
disabled,
|
|
369
|
+
onTouchStart: handleTouchStart,
|
|
370
|
+
onPointerMove: handlePointerMove
|
|
371
|
+
});
|
|
372
|
+
}, [getReferenceProps, disabled, handleTouchStart, handlePointerMove]);
|
|
358
373
|
if (!triggerElement || !contentElement) {
|
|
359
374
|
console.error(
|
|
360
375
|
"MultiSelect requires both MultiSelect.Trigger and MultiSelect.Content components as children"
|
|
@@ -366,17 +381,7 @@ const MultiSelectComponent = memo(
|
|
|
366
381
|
Slot,
|
|
367
382
|
{
|
|
368
383
|
ref: refs.setReference,
|
|
369
|
-
...
|
|
370
|
-
disabled,
|
|
371
|
-
onTouchStart() {
|
|
372
|
-
setTouch(true);
|
|
373
|
-
},
|
|
374
|
-
onPointerMove({ pointerType }) {
|
|
375
|
-
if (pointerType !== "touch") {
|
|
376
|
-
setTouch(false);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}),
|
|
384
|
+
...slotProps,
|
|
380
385
|
children: enhancedTriggerElement
|
|
381
386
|
}
|
|
382
387
|
),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Slot } from "../../slot/dist/index.js";
|
|
2
2
|
import { ModalFooter, ModalContent, ModalHeader, Modal } from "../../modal/dist/index.js";
|
|
3
3
|
import { useFloatingParentNodeId, FloatingTree, useFloatingNodeId, FloatingNode, FloatingFocusManager, FloatingPortal, offset, flip, shift, size, useFloating, autoUpdate, useHover, safePolygon, useClick, useFocus, useDismiss, useRole, useInteractions } from "@floating-ui/react";
|
|
4
|
-
import { memo, forwardRef, useId, useRef, useEffect,
|
|
4
|
+
import { memo, forwardRef, useMemo, useId, useRef, useEffect, useCallback, createContext, useContext, useState } from "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { useEventCallback } from "usehooks-ts";
|
|
7
7
|
import { findChildByType } from "../../../shared/utils/assertion.js";
|
|
@@ -37,11 +37,14 @@ var PopoverTrigger = memo(
|
|
|
37
37
|
forwardRef((props, forwardedRef) => {
|
|
38
38
|
const { children } = props;
|
|
39
39
|
const { getReferenceProps, refs } = usePopoverContext();
|
|
40
|
+
const slotProps = useMemo(() => {
|
|
41
|
+
return getReferenceProps();
|
|
42
|
+
}, [getReferenceProps]);
|
|
40
43
|
return /* @__PURE__ */ jsx(
|
|
41
44
|
Slot,
|
|
42
45
|
{
|
|
43
46
|
ref: mergeRefs(refs.setReference, forwardedRef),
|
|
44
|
-
...
|
|
47
|
+
...slotProps,
|
|
45
48
|
children
|
|
46
49
|
}
|
|
47
50
|
);
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Slot } from "../../../slot/dist/index.js";
|
|
3
|
-
import { memo, forwardRef } from "react";
|
|
3
|
+
import { memo, forwardRef, useMemo } from "react";
|
|
4
4
|
import { usePopoverContext } from "../popover-context.js";
|
|
5
5
|
import { mergeRefs } from "../../../../shared/utils/merge-refs/merge-refs.js";
|
|
6
6
|
const PopoverTrigger = memo(
|
|
7
7
|
forwardRef((props, forwardedRef) => {
|
|
8
8
|
const { children } = props;
|
|
9
9
|
const { getReferenceProps, refs } = usePopoverContext();
|
|
10
|
+
const slotProps = useMemo(() => {
|
|
11
|
+
return getReferenceProps();
|
|
12
|
+
}, [getReferenceProps]);
|
|
10
13
|
return /* @__PURE__ */ jsx(
|
|
11
14
|
Slot,
|
|
12
15
|
{
|
|
13
16
|
ref: mergeRefs(refs.setReference, forwardedRef),
|
|
14
|
-
...
|
|
17
|
+
...slotProps,
|
|
15
18
|
children
|
|
16
19
|
}
|
|
17
20
|
);
|
|
@@ -373,6 +373,38 @@ var SelectComponent = memo(function SelectComponent2(props) {
|
|
|
373
373
|
size: sizeProp
|
|
374
374
|
});
|
|
375
375
|
}, [triggerElement, isControlledOpen, sizeProp]);
|
|
376
|
+
const handleTouchStart = useEventCallback(() => {
|
|
377
|
+
setTouch(true);
|
|
378
|
+
});
|
|
379
|
+
const handleMouseDown = useEventCallback(() => {
|
|
380
|
+
refs.isMouseDownFromTrigger.current = true;
|
|
381
|
+
});
|
|
382
|
+
const handlePointerMove = useEventCallback(({ pointerType }) => {
|
|
383
|
+
if (pointerType !== "touch") {
|
|
384
|
+
setTouch(false);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
const slotProps = useMemo(() => {
|
|
388
|
+
return {
|
|
389
|
+
"aria-haspopup": "listbox",
|
|
390
|
+
"aria-expanded": isControlledOpen,
|
|
391
|
+
"aria-controls": menuId,
|
|
392
|
+
...getReferenceProps({
|
|
393
|
+
disabled,
|
|
394
|
+
onTouchStart: handleTouchStart,
|
|
395
|
+
onMouseDown: handleMouseDown,
|
|
396
|
+
onPointerMove: handlePointerMove
|
|
397
|
+
})
|
|
398
|
+
};
|
|
399
|
+
}, [
|
|
400
|
+
isControlledOpen,
|
|
401
|
+
menuId,
|
|
402
|
+
getReferenceProps,
|
|
403
|
+
disabled,
|
|
404
|
+
handleTouchStart,
|
|
405
|
+
handleMouseDown,
|
|
406
|
+
handlePointerMove
|
|
407
|
+
]);
|
|
376
408
|
if (!triggerElement || !contentElement) {
|
|
377
409
|
console.error("Select requires both Select.Trigger and Select.Content components as children");
|
|
378
410
|
return null;
|
|
@@ -382,23 +414,7 @@ var SelectComponent = memo(function SelectComponent2(props) {
|
|
|
382
414
|
Slot,
|
|
383
415
|
{
|
|
384
416
|
ref: floating.refs.setReference,
|
|
385
|
-
|
|
386
|
-
"aria-expanded": isControlledOpen,
|
|
387
|
-
"aria-controls": menuId,
|
|
388
|
-
...getReferenceProps({
|
|
389
|
-
disabled,
|
|
390
|
-
onTouchStart() {
|
|
391
|
-
setTouch(true);
|
|
392
|
-
},
|
|
393
|
-
onMouseDown() {
|
|
394
|
-
refs.isMouseDownFromTrigger.current = true;
|
|
395
|
-
},
|
|
396
|
-
onPointerMove({ pointerType }) {
|
|
397
|
-
if (pointerType !== "touch") {
|
|
398
|
-
setTouch(false);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}),
|
|
417
|
+
...slotProps,
|
|
402
418
|
children: enhancedTriggerElement
|
|
403
419
|
}
|
|
404
420
|
),
|
|
@@ -373,6 +373,38 @@ const SelectComponent = memo(function SelectComponent2(props) {
|
|
|
373
373
|
size: sizeProp
|
|
374
374
|
});
|
|
375
375
|
}, [triggerElement, isControlledOpen, sizeProp]);
|
|
376
|
+
const handleTouchStart = useEventCallback(() => {
|
|
377
|
+
setTouch(true);
|
|
378
|
+
});
|
|
379
|
+
const handleMouseDown = useEventCallback(() => {
|
|
380
|
+
refs.isMouseDownFromTrigger.current = true;
|
|
381
|
+
});
|
|
382
|
+
const handlePointerMove = useEventCallback(({ pointerType }) => {
|
|
383
|
+
if (pointerType !== "touch") {
|
|
384
|
+
setTouch(false);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
const slotProps = useMemo(() => {
|
|
388
|
+
return {
|
|
389
|
+
"aria-haspopup": "listbox",
|
|
390
|
+
"aria-expanded": isControlledOpen,
|
|
391
|
+
"aria-controls": menuId,
|
|
392
|
+
...getReferenceProps({
|
|
393
|
+
disabled,
|
|
394
|
+
onTouchStart: handleTouchStart,
|
|
395
|
+
onMouseDown: handleMouseDown,
|
|
396
|
+
onPointerMove: handlePointerMove
|
|
397
|
+
})
|
|
398
|
+
};
|
|
399
|
+
}, [
|
|
400
|
+
isControlledOpen,
|
|
401
|
+
menuId,
|
|
402
|
+
getReferenceProps,
|
|
403
|
+
disabled,
|
|
404
|
+
handleTouchStart,
|
|
405
|
+
handleMouseDown,
|
|
406
|
+
handlePointerMove
|
|
407
|
+
]);
|
|
376
408
|
if (!triggerElement || !contentElement) {
|
|
377
409
|
console.error("Select requires both Select.Trigger and Select.Content components as children");
|
|
378
410
|
return null;
|
|
@@ -382,23 +414,7 @@ const SelectComponent = memo(function SelectComponent2(props) {
|
|
|
382
414
|
Slot,
|
|
383
415
|
{
|
|
384
416
|
ref: floating.refs.setReference,
|
|
385
|
-
|
|
386
|
-
"aria-expanded": isControlledOpen,
|
|
387
|
-
"aria-controls": menuId,
|
|
388
|
-
...getReferenceProps({
|
|
389
|
-
disabled,
|
|
390
|
-
onTouchStart() {
|
|
391
|
-
setTouch(true);
|
|
392
|
-
},
|
|
393
|
-
onMouseDown() {
|
|
394
|
-
refs.isMouseDownFromTrigger.current = true;
|
|
395
|
-
},
|
|
396
|
-
onPointerMove({ pointerType }) {
|
|
397
|
-
if (pointerType !== "touch") {
|
|
398
|
-
setTouch(false);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}),
|
|
417
|
+
...slotProps,
|
|
402
418
|
children: enhancedTriggerElement
|
|
403
419
|
}
|
|
404
420
|
),
|
|
@@ -1,25 +1,21 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
2
3
|
interface SlotProps extends React.HTMLAttributes<HTMLElement> {
|
|
3
4
|
children?: React.ReactNode;
|
|
4
5
|
}
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
+
* Slot component - Lightweight implementation
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* 2. 简化 props 合并逻辑
|
|
11
|
-
* 3. 避免不必要的深度遍历
|
|
12
|
-
* 4. 更好的类型安全
|
|
9
|
+
* Based on @radix-ui/react-slot design, used for asChild pattern prop forwarding
|
|
10
|
+
* Performance optimization should be done at the consumer level (e.g., useMemo to cache props)
|
|
13
11
|
*/
|
|
14
12
|
declare const Slot: React.ForwardRefExoticComponent<SlotProps & React.RefAttributes<HTMLElement>>;
|
|
15
13
|
/**
|
|
16
|
-
* Hook
|
|
17
|
-
* 用于需要更细粒度控制的场景
|
|
14
|
+
* Hook version of Slot logic
|
|
18
15
|
*/
|
|
19
16
|
declare function useSlot(children: React.ReactNode, slotProps: Record<string, unknown>, forwardedRef?: React.Ref<unknown>): string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined;
|
|
20
17
|
/**
|
|
21
|
-
*
|
|
22
|
-
* 用于替代 `const Component = asChild ? Slot : "button"` 模式
|
|
18
|
+
* asChild 模式 Hook
|
|
23
19
|
*/
|
|
24
20
|
declare function useAsChild<T extends React.ElementType = "button">(asChild: boolean | undefined, defaultElement: T): T | typeof Slot;
|
|
25
21
|
|
|
@@ -1,68 +1,57 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { forwardRef } from "react";
|
|
2
3
|
import { jsx, Fragment } from "react/jsx-runtime";
|
|
3
4
|
var Slot = forwardRef(
|
|
4
5
|
({ children, ...slotProps }, forwardedRef) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return children;
|
|
8
|
-
}
|
|
9
|
-
const childRef = children.ref;
|
|
6
|
+
if (React.isValidElement(children)) {
|
|
7
|
+
const childrenRef = getElementRef(children);
|
|
10
8
|
const mergedProps = mergeProps(slotProps, children.props);
|
|
11
|
-
return
|
|
9
|
+
return React.cloneElement(children, {
|
|
12
10
|
...mergedProps,
|
|
13
|
-
ref: forwardedRef ? composeRefs(forwardedRef,
|
|
11
|
+
ref: forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef
|
|
14
12
|
});
|
|
15
|
-
}
|
|
16
|
-
return /* @__PURE__ */ jsx(Fragment, { children
|
|
13
|
+
}
|
|
14
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
17
15
|
}
|
|
18
16
|
);
|
|
19
17
|
Slot.displayName = "Slot";
|
|
20
18
|
var SlotClone = forwardRef(
|
|
21
19
|
({ children, ...slotProps }, forwardedRef) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return children;
|
|
25
|
-
}
|
|
26
|
-
const childRef = children.ref;
|
|
20
|
+
if (React.isValidElement(children)) {
|
|
21
|
+
const childrenRef = getElementRef(children);
|
|
27
22
|
const mergedProps = mergeProps(slotProps, children.props);
|
|
28
|
-
return
|
|
23
|
+
return React.cloneElement(children, {
|
|
29
24
|
...mergedProps,
|
|
30
|
-
ref: forwardedRef ? composeRefs(forwardedRef,
|
|
25
|
+
ref: forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef
|
|
31
26
|
});
|
|
32
|
-
}
|
|
33
|
-
return /* @__PURE__ */ jsx(Fragment, { children
|
|
27
|
+
}
|
|
28
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
34
29
|
}
|
|
35
30
|
);
|
|
36
31
|
SlotClone.displayName = "SlotClone";
|
|
37
32
|
function mergeProps(slotProps, childProps) {
|
|
38
33
|
const overrideProps = { ...childProps };
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
overrideProps.style = { ...slotProps.style, ...childProps.style };
|
|
46
|
-
} else if (slotProps.style) {
|
|
47
|
-
overrideProps.style = slotProps.style;
|
|
48
|
-
}
|
|
49
|
-
for (const propName in slotProps) {
|
|
50
|
-
if (propName.startsWith("on") && typeof slotProps[propName] === "function") {
|
|
51
|
-
const slotHandler = slotProps[propName];
|
|
52
|
-
const childHandler = childProps[propName];
|
|
53
|
-
if (childHandler && typeof childHandler === "function") {
|
|
34
|
+
for (const propName in childProps) {
|
|
35
|
+
const slotPropValue = slotProps[propName];
|
|
36
|
+
const childPropValue = childProps[propName];
|
|
37
|
+
const isHandler = /^on[A-Z]/.test(propName);
|
|
38
|
+
if (isHandler) {
|
|
39
|
+
if (slotPropValue && childPropValue) {
|
|
54
40
|
overrideProps[propName] = (...args) => {
|
|
55
|
-
|
|
56
|
-
|
|
41
|
+
const result = childPropValue(...args);
|
|
42
|
+
slotPropValue(...args);
|
|
43
|
+
return result;
|
|
57
44
|
};
|
|
58
|
-
} else {
|
|
59
|
-
overrideProps[propName] =
|
|
45
|
+
} else if (slotPropValue) {
|
|
46
|
+
overrideProps[propName] = slotPropValue;
|
|
60
47
|
}
|
|
61
|
-
} else if (propName
|
|
62
|
-
overrideProps[propName] =
|
|
48
|
+
} else if (propName === "style") {
|
|
49
|
+
overrideProps[propName] = { ...slotPropValue, ...childPropValue };
|
|
50
|
+
} else if (propName === "className") {
|
|
51
|
+
overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
|
|
63
52
|
}
|
|
64
53
|
}
|
|
65
|
-
return overrideProps;
|
|
54
|
+
return { ...slotProps, ...overrideProps };
|
|
66
55
|
}
|
|
67
56
|
function composeRefs(...refs) {
|
|
68
57
|
return (node) => {
|
|
@@ -70,12 +59,25 @@ function composeRefs(...refs) {
|
|
|
70
59
|
if (typeof ref === "function") {
|
|
71
60
|
ref(node);
|
|
72
61
|
} else if (ref != null) {
|
|
73
|
-
|
|
74
|
-
mutableRef.current = node;
|
|
62
|
+
ref.current = node;
|
|
75
63
|
}
|
|
76
64
|
});
|
|
77
65
|
};
|
|
78
66
|
}
|
|
67
|
+
function getElementRef(element) {
|
|
68
|
+
var _a, _b;
|
|
69
|
+
let getter = (_a = Object.getOwnPropertyDescriptor(element.props, "ref")) == null ? void 0 : _a.get;
|
|
70
|
+
let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
|
|
71
|
+
if (mayWarn) {
|
|
72
|
+
return element.ref;
|
|
73
|
+
}
|
|
74
|
+
getter = (_b = Object.getOwnPropertyDescriptor(element, "ref")) == null ? void 0 : _b.get;
|
|
75
|
+
mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
|
|
76
|
+
if (mayWarn) {
|
|
77
|
+
return element.props.ref;
|
|
78
|
+
}
|
|
79
|
+
return element.props.ref || element.ref;
|
|
80
|
+
}
|
|
79
81
|
export {
|
|
80
82
|
Slot
|
|
81
83
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
export interface SlotProps extends React.HTMLAttributes<HTMLElement> {
|
|
3
3
|
children?: React.ReactNode;
|
|
4
4
|
}
|
|
@@ -6,28 +6,22 @@ interface SlotCloneProps {
|
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Slot component - Lightweight implementation
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* 2. 简化 props 合并逻辑
|
|
14
|
-
* 3. 避免不必要的深度遍历
|
|
15
|
-
* 4. 更好的类型安全
|
|
11
|
+
* Based on @radix-ui/react-slot design, used for asChild pattern prop forwarding
|
|
12
|
+
* Performance optimization should be done at the consumer level (e.g., useMemo to cache props)
|
|
16
13
|
*/
|
|
17
14
|
export declare const Slot: React.ForwardRefExoticComponent<SlotProps & React.RefAttributes<HTMLElement>>;
|
|
18
15
|
/**
|
|
19
|
-
* SlotClone 组件
|
|
20
|
-
* 当需要处理嵌套结构时使用
|
|
16
|
+
* SlotClone 组件
|
|
21
17
|
*/
|
|
22
18
|
export declare const SlotClone: React.ForwardRefExoticComponent<SlotCloneProps & React.RefAttributes<HTMLElement>>;
|
|
23
19
|
/**
|
|
24
|
-
* Hook
|
|
25
|
-
* 用于需要更细粒度控制的场景
|
|
20
|
+
* Hook version of Slot logic
|
|
26
21
|
*/
|
|
27
22
|
export declare function useSlot(children: React.ReactNode, slotProps: Record<string, unknown>, forwardedRef?: React.Ref<unknown>): string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined;
|
|
28
23
|
/**
|
|
29
|
-
*
|
|
30
|
-
* 用于替代 `const Component = asChild ? Slot : "button"` 模式
|
|
24
|
+
* asChild 模式 Hook
|
|
31
25
|
*/
|
|
32
26
|
export declare function useAsChild<T extends React.ElementType = "button">(asChild: boolean | undefined, defaultElement: T): T | typeof Slot;
|
|
33
27
|
export {};
|
|
@@ -1,68 +1,57 @@
|
|
|
1
1
|
import { jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { forwardRef, useMemo } from "react";
|
|
3
4
|
const Slot = forwardRef(
|
|
4
5
|
({ children, ...slotProps }, forwardedRef) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return children;
|
|
8
|
-
}
|
|
9
|
-
const childRef = children.ref;
|
|
6
|
+
if (React.isValidElement(children)) {
|
|
7
|
+
const childrenRef = getElementRef(children);
|
|
10
8
|
const mergedProps = mergeProps(slotProps, children.props);
|
|
11
|
-
return
|
|
9
|
+
return React.cloneElement(children, {
|
|
12
10
|
...mergedProps,
|
|
13
|
-
ref: forwardedRef ? composeRefs(forwardedRef,
|
|
11
|
+
ref: forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef
|
|
14
12
|
});
|
|
15
|
-
}
|
|
16
|
-
return /* @__PURE__ */ jsx(Fragment, { children
|
|
13
|
+
}
|
|
14
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
17
15
|
}
|
|
18
16
|
);
|
|
19
17
|
Slot.displayName = "Slot";
|
|
20
18
|
const SlotClone = forwardRef(
|
|
21
19
|
({ children, ...slotProps }, forwardedRef) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return children;
|
|
25
|
-
}
|
|
26
|
-
const childRef = children.ref;
|
|
20
|
+
if (React.isValidElement(children)) {
|
|
21
|
+
const childrenRef = getElementRef(children);
|
|
27
22
|
const mergedProps = mergeProps(slotProps, children.props);
|
|
28
|
-
return
|
|
23
|
+
return React.cloneElement(children, {
|
|
29
24
|
...mergedProps,
|
|
30
|
-
ref: forwardedRef ? composeRefs(forwardedRef,
|
|
25
|
+
ref: forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef
|
|
31
26
|
});
|
|
32
|
-
}
|
|
33
|
-
return /* @__PURE__ */ jsx(Fragment, { children
|
|
27
|
+
}
|
|
28
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
34
29
|
}
|
|
35
30
|
);
|
|
36
31
|
SlotClone.displayName = "SlotClone";
|
|
37
32
|
function mergeProps(slotProps, childProps) {
|
|
38
33
|
const overrideProps = { ...childProps };
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
overrideProps.style = { ...slotProps.style, ...childProps.style };
|
|
46
|
-
} else if (slotProps.style) {
|
|
47
|
-
overrideProps.style = slotProps.style;
|
|
48
|
-
}
|
|
49
|
-
for (const propName in slotProps) {
|
|
50
|
-
if (propName.startsWith("on") && typeof slotProps[propName] === "function") {
|
|
51
|
-
const slotHandler = slotProps[propName];
|
|
52
|
-
const childHandler = childProps[propName];
|
|
53
|
-
if (childHandler && typeof childHandler === "function") {
|
|
34
|
+
for (const propName in childProps) {
|
|
35
|
+
const slotPropValue = slotProps[propName];
|
|
36
|
+
const childPropValue = childProps[propName];
|
|
37
|
+
const isHandler = /^on[A-Z]/.test(propName);
|
|
38
|
+
if (isHandler) {
|
|
39
|
+
if (slotPropValue && childPropValue) {
|
|
54
40
|
overrideProps[propName] = (...args) => {
|
|
55
|
-
|
|
56
|
-
|
|
41
|
+
const result = childPropValue(...args);
|
|
42
|
+
slotPropValue(...args);
|
|
43
|
+
return result;
|
|
57
44
|
};
|
|
58
|
-
} else {
|
|
59
|
-
overrideProps[propName] =
|
|
45
|
+
} else if (slotPropValue) {
|
|
46
|
+
overrideProps[propName] = slotPropValue;
|
|
60
47
|
}
|
|
61
|
-
} else if (propName
|
|
62
|
-
overrideProps[propName] =
|
|
48
|
+
} else if (propName === "style") {
|
|
49
|
+
overrideProps[propName] = { ...slotPropValue, ...childPropValue };
|
|
50
|
+
} else if (propName === "className") {
|
|
51
|
+
overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
|
|
63
52
|
}
|
|
64
53
|
}
|
|
65
|
-
return overrideProps;
|
|
54
|
+
return { ...slotProps, ...overrideProps };
|
|
66
55
|
}
|
|
67
56
|
function composeRefs(...refs) {
|
|
68
57
|
return (node) => {
|
|
@@ -70,22 +59,35 @@ function composeRefs(...refs) {
|
|
|
70
59
|
if (typeof ref === "function") {
|
|
71
60
|
ref(node);
|
|
72
61
|
} else if (ref != null) {
|
|
73
|
-
|
|
74
|
-
mutableRef.current = node;
|
|
62
|
+
ref.current = node;
|
|
75
63
|
}
|
|
76
64
|
});
|
|
77
65
|
};
|
|
78
66
|
}
|
|
67
|
+
function getElementRef(element) {
|
|
68
|
+
var _a, _b;
|
|
69
|
+
let getter = (_a = Object.getOwnPropertyDescriptor(element.props, "ref")) == null ? void 0 : _a.get;
|
|
70
|
+
let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
|
|
71
|
+
if (mayWarn) {
|
|
72
|
+
return element.ref;
|
|
73
|
+
}
|
|
74
|
+
getter = (_b = Object.getOwnPropertyDescriptor(element, "ref")) == null ? void 0 : _b.get;
|
|
75
|
+
mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
|
|
76
|
+
if (mayWarn) {
|
|
77
|
+
return element.props.ref;
|
|
78
|
+
}
|
|
79
|
+
return element.props.ref || element.ref;
|
|
80
|
+
}
|
|
79
81
|
function useSlot(children, slotProps, forwardedRef) {
|
|
80
82
|
return useMemo(() => {
|
|
81
|
-
if (!
|
|
83
|
+
if (!React.isValidElement(children)) {
|
|
82
84
|
return children;
|
|
83
85
|
}
|
|
84
|
-
const
|
|
86
|
+
const childrenRef = getElementRef(children);
|
|
85
87
|
const mergedProps = mergeProps(slotProps, children.props);
|
|
86
|
-
return
|
|
88
|
+
return React.cloneElement(children, {
|
|
87
89
|
...mergedProps,
|
|
88
|
-
ref: forwardedRef ? composeRefs(forwardedRef,
|
|
90
|
+
ref: forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef
|
|
89
91
|
});
|
|
90
92
|
}, [children, slotProps, forwardedRef]);
|
|
91
93
|
}
|
|
@@ -184,12 +184,17 @@ var TooltipTrigger = forwardRef(
|
|
|
184
184
|
function TooltipTrigger2({ children, ...props }, propRef) {
|
|
185
185
|
const state = useTooltipState();
|
|
186
186
|
const ref = useMergeRefs([state.refs.setReference, propRef]);
|
|
187
|
+
const slotProps = useMemo(() => {
|
|
188
|
+
return {
|
|
189
|
+
...state.disabled && { disabled: true },
|
|
190
|
+
...state.getReferenceProps(props)
|
|
191
|
+
};
|
|
192
|
+
}, [state.disabled, state.getReferenceProps, props]);
|
|
187
193
|
return /* @__PURE__ */ jsx(
|
|
188
194
|
Slot,
|
|
189
195
|
{
|
|
190
196
|
ref,
|
|
191
|
-
...
|
|
192
|
-
...state.getReferenceProps(props),
|
|
197
|
+
...slotProps,
|
|
193
198
|
children
|
|
194
199
|
}
|
|
195
200
|
);
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Slot } from "../../../slot/dist/index.js";
|
|
3
3
|
import { useMergeRefs } from "@floating-ui/react";
|
|
4
|
-
import { forwardRef } from "react";
|
|
4
|
+
import { forwardRef, useMemo } from "react";
|
|
5
5
|
import { useTooltipState } from "../context/tooltip-context.js";
|
|
6
6
|
const TooltipTrigger = forwardRef(
|
|
7
7
|
function TooltipTrigger2({ children, ...props }, propRef) {
|
|
8
8
|
const state = useTooltipState();
|
|
9
9
|
const ref = useMergeRefs([state.refs.setReference, propRef]);
|
|
10
|
+
const slotProps = useMemo(() => {
|
|
11
|
+
return {
|
|
12
|
+
...state.disabled && { disabled: true },
|
|
13
|
+
...state.getReferenceProps(props)
|
|
14
|
+
};
|
|
15
|
+
}, [state.disabled, state.getReferenceProps, props]);
|
|
10
16
|
return /* @__PURE__ */ jsx(
|
|
11
17
|
Slot,
|
|
12
18
|
{
|
|
13
19
|
ref,
|
|
14
|
-
...
|
|
15
|
-
...state.getReferenceProps(props),
|
|
20
|
+
...slotProps,
|
|
16
21
|
children
|
|
17
22
|
}
|
|
18
23
|
);
|
package/package.json
CHANGED