reshaped 3.8.0-canary.5 → 3.8.0-canary.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/CHANGELOG.md +24 -0
- package/dist/bundle.css +1 -1
- package/dist/bundle.js +11 -11
- package/dist/components/Autocomplete/Autocomplete.js +2 -2
- package/dist/components/Autocomplete/Autocomplete.types.d.ts +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js +4 -4
- package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +2 -2
- package/dist/components/Flyout/Flyout.module.css +1 -1
- package/dist/components/Flyout/Flyout.types.d.ts +7 -7
- package/dist/components/Flyout/FlyoutContent.js +1 -1
- package/dist/components/Flyout/FlyoutControlled.js +4 -2
- package/dist/components/Flyout/tests/Flyout.stories.d.ts +8 -0
- package/dist/components/Flyout/tests/Flyout.stories.js +81 -33
- package/dist/components/Flyout/useFlyout.d.ts +1 -7
- package/dist/components/Flyout/useFlyout.js +5 -1
- package/dist/components/Flyout/utilities/calculatePosition.d.ts +3 -2
- package/dist/components/Flyout/utilities/calculatePosition.js +47 -22
- package/dist/components/Flyout/utilities/flyout.js +4 -2
- package/dist/components/Flyout/utilities/getPositionFallbacks.js +3 -3
- package/dist/components/Flyout/utilities/isFullyVisible.d.ts +0 -2
- package/dist/components/Flyout/utilities/isFullyVisible.js +5 -7
- package/dist/components/Hidden/Hidden.js +2 -1
- package/dist/components/Icon/Icon.js +2 -2
- package/dist/components/Icon/Icon.types.d.ts +1 -1
- package/dist/components/Icon/tests/Icon.stories.js +6 -1
- package/dist/components/MenuItem/MenuItem.module.css +1 -1
- package/dist/components/Popover/Popover.js +2 -2
- package/dist/components/Popover/Popover.module.css +1 -1
- package/dist/components/Popover/Popover.types.d.ts +3 -1
- package/dist/components/Reshaped/Reshaped.css +1 -1
- package/dist/components/Resizable/Resizable.js +4 -3
- package/dist/components/Select/Select.d.ts +8 -1
- package/dist/components/Select/Select.js +22 -48
- package/dist/components/Select/Select.module.css +1 -1
- package/dist/components/Select/Select.types.d.ts +56 -38
- package/dist/components/Select/SelectCustom.d.ts +3 -0
- package/dist/components/Select/SelectCustom.js +11 -0
- package/dist/components/Select/SelectCustomControlled.d.ts +4 -0
- package/dist/components/Select/SelectCustomControlled.js +88 -0
- package/dist/components/Select/SelectCustomUncontrolled.d.ts +4 -0
- package/dist/components/Select/SelectCustomUncontrolled.js +15 -0
- package/dist/components/Select/SelectEndContent.d.ts +3 -0
- package/dist/components/Select/SelectEndContent.js +12 -0
- package/dist/components/Select/SelectNative.d.ts +4 -0
- package/dist/components/Select/SelectNative.js +29 -0
- package/dist/components/Select/SelectOption.d.ts +4 -0
- package/dist/components/Select/SelectOption.js +15 -0
- package/dist/components/Select/SelectOptionGroup.d.ts +4 -0
- package/dist/components/Select/SelectOptionGroup.js +11 -0
- package/dist/components/Select/SelectRoot.d.ts +4 -0
- package/dist/components/Select/SelectRoot.js +21 -0
- package/dist/components/Select/SelectStartContent.d.ts +3 -0
- package/dist/components/Select/SelectStartContent.js +20 -0
- package/dist/components/Select/SelectTrigger.d.ts +4 -0
- package/dist/components/Select/SelectTrigger.js +16 -0
- package/dist/components/Select/tests/Select.stories.d.ts +35 -10
- package/dist/components/Select/tests/Select.stories.js +447 -175
- package/dist/components/Stepper/Stepper.js +2 -2
- package/dist/components/Stepper/Stepper.types.d.ts +2 -0
- package/dist/components/Stepper/tests/Stepper.stories.d.ts +1 -0
- package/dist/components/Stepper/tests/Stepper.stories.js +23 -0
- package/dist/components/Table/Table.js +6 -3
- package/dist/components/Timeline/Timeline.js +3 -2
- package/dist/components/Timeline/tests/Timeline.stories.js +0 -3
- package/dist/components/View/View.js +6 -4
- package/dist/utilities/props.d.ts +3 -0
- package/dist/utilities/props.js +19 -0
- package/package.json +1 -1
- package/dist/components/Select/tests/Select.test.stories.d.ts +0 -27
- package/dist/components/Select/tests/Select.test.stories.js +0 -132
@@ -11,7 +11,7 @@ import useElementId from "../../hooks/useElementId.js";
|
|
11
11
|
import useIsomorphicLayoutEffect from "../../hooks/useIsomorphicLayoutEffect.js";
|
12
12
|
const AutocompleteContext = React.createContext({});
|
13
13
|
const Autocomplete = (props) => {
|
14
|
-
const { children, onChange, onInput, onItemSelect, name, containerRef, instanceRef, onBackspace, onEnter, active, onOpen, onClose, ...textFieldProps } = props;
|
14
|
+
const { children, onChange, onInput, onItemSelect, name, containerRef, instanceRef, onBackspace, onEnter, active, onOpen, onClose, fallbackAdjustLayout, fallbackMinWidth, fallbackMinHeight, ...textFieldProps } = props;
|
15
15
|
const [highlightedId, setHighlightedId] = React.useState();
|
16
16
|
const onBackspaceRef = useHandlerRef(onBackspace);
|
17
17
|
const contentRef = React.useRef(null);
|
@@ -120,7 +120,7 @@ const Autocomplete = (props) => {
|
|
120
120
|
highlightedId,
|
121
121
|
setHighlightedId,
|
122
122
|
}), [highlightedId, handleItemClick]);
|
123
|
-
return (_jsx(AutocompleteContext.Provider, { value: contextValue, children: _jsxs(DropdownMenu, { position: "bottom", width: "trigger", triggerType: "focus", trapFocusMode: false, active: isDropdownActive, onClose: handleClose, onOpen: handleOpen, containerRef: containerRef, disableHideAnimation: true, instanceRef: instanceRef, children: [_jsx(DropdownMenu.Trigger, { children: ({ ref, ...attributes }) => (_jsx(TextField, { ...textFieldProps, name: name, onChange: handleChange, focused: isDropdownActive, attributes: {
|
123
|
+
return (_jsx(AutocompleteContext.Provider, { value: contextValue, children: _jsxs(DropdownMenu, { position: "bottom", width: "trigger", triggerType: "focus", trapFocusMode: false, active: isDropdownActive, onClose: handleClose, onOpen: handleOpen, containerRef: containerRef, fallbackAdjustLayout: fallbackAdjustLayout, fallbackMinWidth: fallbackMinWidth, fallbackMinHeight: fallbackMinHeight, disableHideAnimation: true, instanceRef: instanceRef, children: [_jsx(DropdownMenu.Trigger, { children: ({ ref, ...attributes }) => (_jsx(TextField, { ...textFieldProps, name: name, onChange: handleChange, focused: isDropdownActive, attributes: {
|
124
124
|
...textFieldProps.attributes,
|
125
125
|
// Ignoring the type check since TS can't infer the correct html element type
|
126
126
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
@@ -7,7 +7,7 @@ type SelectArgs = {
|
|
7
7
|
/** Additional data that will be passed to the onItemSelect callback */
|
8
8
|
data?: unknown;
|
9
9
|
};
|
10
|
-
export type Props = TextFieldProps & Pick<DropdownMenuProps, "containerRef" | "instanceRef" | "active" | "onOpen" | "onClose"> & {
|
10
|
+
export type Props = TextFieldProps & Pick<DropdownMenuProps, "containerRef" | "instanceRef" | "active" | "onOpen" | "onClose" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight"> & {
|
11
11
|
/** Callback for when value changes from user input */
|
12
12
|
onInput?: TextFieldProps["onChange"];
|
13
13
|
/** Callback for when an item is selected in the dropdown */
|
@@ -14,8 +14,8 @@ import s from "./DropdownMenu.module.css";
|
|
14
14
|
const DropdownMenuSubContext = React.createContext(null);
|
15
15
|
const DropdownMenuSubTriggerContext = React.createContext(false);
|
16
16
|
const DropdownMenu = (props) => {
|
17
|
-
const { children, position = "bottom-start", triggerType = "click", trapFocusMode = "action-menu", ...popoverProps } = props;
|
18
|
-
return (_jsx(Popover, { ...popoverProps, position: position, padding: 0, trapFocusMode: trapFocusMode, triggerType: triggerType, children: children }));
|
17
|
+
const { children, position = "bottom-start", triggerType = "click", trapFocusMode = "action-menu", borderRadius = "small", ...popoverProps } = props;
|
18
|
+
return (_jsx(Popover, { ...popoverProps, position: position, padding: 0, trapFocusMode: trapFocusMode, triggerType: triggerType, borderRadius: borderRadius, disableHideAnimation: true, children: children }));
|
19
19
|
};
|
20
20
|
const DropdownMenuContent = (props) => {
|
21
21
|
const { children, attributes, className } = props;
|
@@ -62,9 +62,9 @@ const DropdownMenuItem = (props) => {
|
|
62
62
|
return (_jsx(MenuItem, { ...props, roundedCorners: true, className: [s.item, props.className], attributes: { role: "menuitem", ...props.attributes }, onClick: handleClick }));
|
63
63
|
};
|
64
64
|
const DropdownMenuSubMenu = (props) => {
|
65
|
-
const { children } = props;
|
65
|
+
const { children, position = "end-top", contentGap = 0.5, ...dropdownMenuProps } = props;
|
66
66
|
const dropdownMenuRef = React.useRef(null);
|
67
|
-
return (_jsx(DropdownMenuSubContext.Provider, { value: dropdownMenuRef, children: _jsx(DropdownMenu, { triggerType: "hover", position:
|
67
|
+
return (_jsx(DropdownMenuSubContext.Provider, { value: dropdownMenuRef, children: _jsx(DropdownMenu, { ...dropdownMenuProps, triggerType: "hover", position: position, contentGap: contentGap, instanceRef: dropdownMenuRef, children: children }) }));
|
68
68
|
};
|
69
69
|
const DropdownMenuSubTriggerItem = (props) => {
|
70
70
|
const { children, attributes, ...menuItemProps } = props;
|
@@ -3,7 +3,7 @@ import type { PopoverProps, PopoverInstance } from "../Popover";
|
|
3
3
|
import type { MenuItemProps } from "../MenuItem";
|
4
4
|
import type { FlyoutContentProps } from "../Flyout";
|
5
5
|
export type Instance = PopoverInstance;
|
6
|
-
export type Props = Pick<PopoverProps, "children" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "triggerType" | "contentGap" | "contentShift" | "onOpen" | "onClose" | "active" | "defaultActive" | "width" | "disableHideAnimation" | "disableCloseOnOutsideClick" | "instanceRef" | "containerRef" | "originCoordinates"> & {
|
6
|
+
export type Props = Pick<PopoverProps, "children" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "triggerType" | "contentGap" | "contentShift" | "onOpen" | "onClose" | "active" | "defaultActive" | "width" | "disableHideAnimation" | "disableCloseOnOutsideClick" | "instanceRef" | "containerRef" | "originCoordinates" | "borderRadius" | "elevation" | "initialFocusRef"> & {
|
7
7
|
/** Change component trap focus keyboard behavior and shortcuts */
|
8
8
|
trapFocusMode?: Extract<PopoverProps["trapFocusMode"], "action-menu" | "selection-menu"> | false;
|
9
9
|
};
|
@@ -16,5 +16,5 @@ export type SectionProps = {
|
|
16
16
|
export type SubMenuProps = {
|
17
17
|
/** Node for inserting children */
|
18
18
|
children: React.ReactNode;
|
19
|
-
}
|
19
|
+
} & Pick<PopoverProps, "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "contentGap" | "contentShift" | "width" | "containerRef">;
|
20
20
|
export type SubTriggerProps = Omit<MenuItemProps, "endSlot" | "roundedCorners">;
|
@@ -1 +1 @@
|
|
1
|
-
.content{--rs-flyout-gap:0;--rs-flyout-origin-x:50%;--rs-flyout-origin-y:50%;isolation:isolate;pointer-events:none;position:absolute}.content.--hover{pointer-events:all}.content.--hover-disabled,.content.--hover-disabled .inner{pointer-events:none}.inner{opacity:0;outline:none;pointer-events:all;transform:scale(.
|
1
|
+
.content{--rs-flyout-gap:0;--rs-flyout-origin-x:50%;--rs-flyout-origin-y:50%;isolation:isolate;pointer-events:none;position:absolute}.content.--hover{pointer-events:all}.content.--hover-disabled,.content.--hover-disabled .inner{pointer-events:none}.inner{backface-visibility:hidden;height:100%;max-height:100%;max-width:100%;opacity:0;outline:none;overflow:auto;pointer-events:all;transform:scale(.92) translateY(0);transform-origin:var(--rs-flyout-origin-x) var(--rs-flyout-origin-y);transition:1ms var(--rs-easing-accelerate)}[data-rs-keyboard] .inner:focus{box-shadow:var(--rs-focus-shadow)}.content.--width-trigger .inner{transform:scale(1) translateY(var(--rs-unit-x2))}.content.--position-top,.content.--position-top-end,.content.--position-top-start{--rs-flyout-origin-y:100%;padding-bottom:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-bottom,.content.--position-bottom-end,.content.--position-bottom-start{--rs-flyout-origin-y:0%;padding-top:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-bottom-start,.content.--position-top-start{--rs-flyout-origin-x:0%}.content.--position-bottom-end,.content.--position-top-end{--rs-flyout-origin-x:100%}.content.--position-start,.content.--position-start-bottom,.content.--position-start-top{--rs-flyout-origin-x:100%;padding-right:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-end,.content.--position-end-bottom,.content.--position-end-top{--rs-flyout-origin-x:0%;padding-left:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-end-top,.content.--position-start-top{--rs-flyout-origin-y:0%}.content.--position-end-bottom,.content.--position-start-bottom{--rs-flyout-origin-y:100%}.content.--visible .inner{opacity:1;transform:scale(1) translateY(0)}.content.--animated .inner{transition-duration:var(--rs-duration-rapid);transition-property:opacity,transform}.content.--animated.--visible .inner{transition-duration:var(--rs-duration-fast);transition-timing-function:var(--rs-easing-decelerate)}
|
@@ -15,17 +15,13 @@ export type CloseReason = "escape-key" | "outside-click"
|
|
15
15
|
| "item-selection" | "close-button";
|
16
16
|
export type Position = `${YSide}` | `${YSide}-${XSide}` | `${XSide}` | `${XSide}-${YSide}`;
|
17
17
|
export type Width = "trigger" | string;
|
18
|
-
export type Options = {
|
19
|
-
width?: Width;
|
18
|
+
export type Options = Pick<BaseProps, "width" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "contentGap" | "contentShift"> & {
|
20
19
|
position: Position;
|
20
|
+
fallbackPositions?: Position[];
|
21
21
|
container?: HTMLElement | null;
|
22
22
|
rtl: boolean;
|
23
|
-
fallbackPositions?: Position[];
|
24
|
-
fallbackAdjustLayout?: boolean;
|
25
23
|
lastUsedPosition: Position;
|
26
24
|
onPositionChoose: (position: Position) => void;
|
27
|
-
contentGap?: number;
|
28
|
-
contentShift?: number;
|
29
25
|
};
|
30
26
|
export type Styles = React.CSSProperties;
|
31
27
|
export type State = {
|
@@ -102,6 +98,10 @@ type BaseProps = {
|
|
102
98
|
fallbackPositions?: Position[] | false;
|
103
99
|
/** Adjust the content size and shift its position to fit into the container when none of the fallback positions work */
|
104
100
|
fallbackAdjustLayout?: boolean;
|
101
|
+
/** Minimum width for the content when fallbackAdjustLayout is true */
|
102
|
+
fallbackMinWidth?: string;
|
103
|
+
/** Minimum height for the content when fallbackAdjustLayout is true */
|
104
|
+
fallbackMinHeight?: string;
|
105
105
|
/** Change component trap focus keyboard behavior and shortcuts */
|
106
106
|
trapFocusMode?: TrapMode | false;
|
107
107
|
/** Disable the flyout content interactivity */
|
@@ -187,7 +187,7 @@ export type ContextProps = {
|
|
187
187
|
handleContentMouseDown: () => void;
|
188
188
|
handleContentMouseUp: () => void;
|
189
189
|
isSubmenu: boolean;
|
190
|
-
} & Pick<Props, "triggerType" | "contentClassName" | "contentAttributes" | "
|
190
|
+
} & Pick<Props, "triggerType" | "contentClassName" | "contentAttributes" | "contentGap" | "trapFocusMode" | "containerRef" | "disableContentHover" | "autoFocus">;
|
191
191
|
export type TriggerContextProps = {
|
192
192
|
elRef?: ContextProps["triggerElRef"];
|
193
193
|
};
|
@@ -11,7 +11,7 @@ import { useFlyoutContext, ContentProvider } from "./Flyout.context.js";
|
|
11
11
|
import s from "./Flyout.module.css";
|
12
12
|
const FlyoutContent = (props) => {
|
13
13
|
const { children, className, attributes } = props;
|
14
|
-
const { flyout, id, flyoutElRef, triggerElRef, handleClose, handleTransitionEnd, handleTransitionStart, triggerType, handleMouseEnter, handleMouseLeave, handleContentMouseDown, handleContentMouseUp,
|
14
|
+
const { flyout, id, flyoutElRef, triggerElRef, handleClose, handleTransitionEnd, handleTransitionStart, triggerType, handleMouseEnter, handleMouseLeave, handleContentMouseDown, handleContentMouseUp, contentClassName, contentAttributes, contentGap, trapFocusMode, disableContentHover, autoFocus, width, containerRef: passedContainerRef, isSubmenu, } = useFlyoutContext();
|
15
15
|
const { styles, status, position } = flyout;
|
16
16
|
const [mounted, setMounted] = React.useState(false);
|
17
17
|
const closestFixedContainer = React.useMemo(() => {
|
@@ -15,7 +15,7 @@ import cooldown from "./utilities/cooldown.js";
|
|
15
15
|
import { Provider, useFlyoutTriggerContext, useFlyoutContext, useFlyoutContentContext, } from "./Flyout.context.js";
|
16
16
|
import useHandlerRef from "../../hooks/useHandlerRef.js";
|
17
17
|
const FlyoutControlled = (props) => {
|
18
|
-
const { triggerType = "click", groupTimeouts, onOpen, onClose, children, disabled, forcePosition, fallbackAdjustLayout, trapFocusMode = "dialog", width, disableHideAnimation, disableContentHover, disableCloseOnOutsideClick, autoFocus = true, originCoordinates, contentGap = 2, contentShift, contentClassName, contentAttributes, position: passedPosition, active: passedActive, id: passedId, instanceRef, containerRef, initialFocusRef, } = props;
|
18
|
+
const { triggerType = "click", groupTimeouts, onOpen, onClose, children, disabled, forcePosition, fallbackAdjustLayout, fallbackMinWidth, fallbackMinHeight, trapFocusMode = "dialog", width, disableHideAnimation, disableContentHover, disableCloseOnOutsideClick, autoFocus = true, originCoordinates, contentGap = 2, contentShift, contentClassName, contentAttributes, position: passedPosition, active: passedActive, id: passedId, instanceRef, containerRef, initialFocusRef, } = props;
|
19
19
|
const fallbackPositions = props.fallbackPositions === false || forcePosition ? [] : props.fallbackPositions;
|
20
20
|
const onOpenRef = useHandlerRef(onOpen);
|
21
21
|
const onCloseRef = useHandlerRef(onClose);
|
@@ -63,6 +63,8 @@ const FlyoutControlled = (props) => {
|
|
63
63
|
container: containerRef?.current,
|
64
64
|
fallbackPositions,
|
65
65
|
fallbackAdjustLayout,
|
66
|
+
fallbackMinWidth,
|
67
|
+
fallbackMinHeight,
|
66
68
|
contentGap,
|
67
69
|
contentShift,
|
68
70
|
});
|
@@ -322,9 +324,9 @@ const FlyoutControlled = (props) => {
|
|
322
324
|
handleContentMouseUp,
|
323
325
|
triggerType,
|
324
326
|
trapFocusMode,
|
325
|
-
contentGap,
|
326
327
|
contentClassName,
|
327
328
|
contentAttributes,
|
329
|
+
contentGap,
|
328
330
|
containerRef,
|
329
331
|
disableContentHover,
|
330
332
|
autoFocus,
|
@@ -33,6 +33,14 @@ export declare const fallbackAdjustLayout: {
|
|
33
33
|
name: string;
|
34
34
|
render: () => React.JSX.Element;
|
35
35
|
};
|
36
|
+
export declare const fallbackAdjustLayoutShift: {
|
37
|
+
name: string;
|
38
|
+
render: () => React.JSX.Element;
|
39
|
+
};
|
40
|
+
export declare const fallbackAdjustLayoutSize: {
|
41
|
+
name: string;
|
42
|
+
render: () => React.JSX.Element;
|
43
|
+
};
|
36
44
|
export declare const originCoordinates: {
|
37
45
|
name: string;
|
38
46
|
render: () => React.JSX.Element;
|
@@ -17,7 +17,7 @@ const Content = (props) => (<div style={{
|
|
17
17
|
background: "var(--rs-color-background-elevation-overlay)",
|
18
18
|
padding: "var(--rs-unit-x4)",
|
19
19
|
height: props.height === false ? undefined : props.height || 150,
|
20
|
-
|
20
|
+
width: props.width === false ? undefined : props.width || 160,
|
21
21
|
borderRadius: "var(--rs-radius-medium)",
|
22
22
|
border: "1px solid var(--rs-color-border-neutral-faded)",
|
23
23
|
boxSizing: "border-box",
|
@@ -30,10 +30,18 @@ const Demo = (props) => {
|
|
30
30
|
<Flyout.Trigger>
|
31
31
|
{(attributes) => <Button attributes={attributes}>{text || position}</Button>}
|
32
32
|
</Flyout.Trigger>
|
33
|
-
<Flyout.Content
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
<Flyout.Content attributes={{
|
34
|
+
style: {
|
35
|
+
background: "var(--rs-color-background-elevation-overlay)",
|
36
|
+
padding: "var(--rs-unit-x4)",
|
37
|
+
height: contentHeight === false ? undefined : contentHeight || 150,
|
38
|
+
width: contentWidth === false ? undefined : contentWidth || 160,
|
39
|
+
borderRadius: "var(--rs-radius-medium)",
|
40
|
+
border: "1px solid var(--rs-color-border-neutral-faded)",
|
41
|
+
boxSizing: "border-box",
|
42
|
+
},
|
43
|
+
}}>
|
44
|
+
{children || "Content"}
|
37
45
|
</Flyout.Content>
|
38
46
|
</Flyout>);
|
39
47
|
};
|
@@ -222,42 +230,58 @@ export const positionFallbacks = {
|
|
222
230
|
</Example>);
|
223
231
|
},
|
224
232
|
};
|
225
|
-
const FallbackAdjustLayoutControls = ({ containerRef, }) =>
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
233
|
+
const FallbackAdjustLayoutControls = ({ containerRef, large, }) => {
|
234
|
+
const contentHeight = large ? "2000px" : "200px";
|
235
|
+
const contentWidth = large ? "2000px" : "300px";
|
236
|
+
return (<>
|
237
|
+
{/* Left side */}
|
238
|
+
<View position="absolute" insetStart={4} insetTop={10} gap={2}>
|
239
|
+
<Demo contentHeight={contentHeight} position="end" fallbackAdjustLayout fallbackPositions={false} containerRef={containerRef}/>
|
240
|
+
<Demo contentHeight={contentHeight} position="end-bottom" fallbackPositions={false} fallbackAdjustLayout containerRef={containerRef}/>
|
241
|
+
</View>
|
231
242
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
243
|
+
<View position="absolute" insetStart={4} insetTop={80} gap={2}>
|
244
|
+
<Demo position="top" fallbackPositions={false} fallbackAdjustLayout contentWidth={contentWidth} containerRef={containerRef}/>
|
245
|
+
<Demo position="top-end" fallbackPositions={false} fallbackAdjustLayout contentWidth={contentWidth} containerRef={containerRef}/>
|
246
|
+
<Demo position="bottom-end" fallbackPositions={false} fallbackAdjustLayout contentWidth={contentWidth} containerRef={containerRef}/>
|
247
|
+
<Demo position="bottom" fallbackPositions={false} fallbackAdjustLayout contentWidth={contentWidth} containerRef={containerRef}/>
|
248
|
+
</View>
|
236
249
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
250
|
+
<View position="absolute" insetBottom={4} insetStart={4} gap={2}>
|
251
|
+
<Demo contentHeight={contentHeight} position="end-top" fallbackPositions={false} fallbackAdjustLayout containerRef={containerRef}/>
|
252
|
+
<Demo contentHeight={contentHeight} position="end" fallbackPositions={false} fallbackAdjustLayout containerRef={containerRef}/>
|
253
|
+
</View>
|
241
254
|
|
242
|
-
|
255
|
+
{/* Right side */}
|
243
256
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
257
|
+
<View position="absolute" insetTop={10} insetEnd={4} gap={2}>
|
258
|
+
<Demo contentHeight={contentHeight} position="start" fallbackPositions={false} fallbackAdjustLayout containerRef={containerRef}/>
|
259
|
+
<Demo contentHeight={contentHeight} position="start-bottom" fallbackPositions={false} fallbackAdjustLayout containerRef={containerRef}/>
|
260
|
+
</View>
|
248
261
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
262
|
+
<View position="absolute" insetEnd={4} insetTop={80} gap={2}>
|
263
|
+
<Demo position="top-start" fallbackPositions={false} fallbackAdjustLayout contentWidth={contentWidth} containerRef={containerRef}/>
|
264
|
+
<Demo position="top" fallbackPositions={false} fallbackAdjustLayout contentWidth={contentWidth} containerRef={containerRef}/>
|
265
|
+
<Demo position="bottom-start" fallbackPositions={false} fallbackAdjustLayout contentWidth={contentWidth} containerRef={containerRef}/>
|
266
|
+
<Demo position="bottom" fallbackPositions={false} fallbackAdjustLayout contentWidth={contentWidth} containerRef={containerRef}/>
|
267
|
+
</View>
|
253
268
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
269
|
+
<View position="absolute" insetBottom={4} insetEnd={4} gap={2}>
|
270
|
+
<Demo contentHeight={contentHeight} position="start-top" fallbackPositions={false} fallbackAdjustLayout containerRef={containerRef}/>
|
271
|
+
<Demo contentHeight={contentHeight} position="start" fallbackPositions={false} fallbackAdjustLayout containerRef={containerRef}/>
|
272
|
+
</View>
|
273
|
+
</>);
|
274
|
+
};
|
259
275
|
export const fallbackAdjustLayout = {
|
260
276
|
name: "fallbackAdjustLayout",
|
277
|
+
render: () => {
|
278
|
+
return (<Demo contentHeight={false} position="bottom-start" width="200px" fallbackAdjustLayout defaultActive>
|
279
|
+
<div style={{ height: "600px" }}>Content</div>
|
280
|
+
</Demo>);
|
281
|
+
},
|
282
|
+
};
|
283
|
+
export const fallbackAdjustLayoutShift = {
|
284
|
+
name: "fallbackAdjustLayout, shift",
|
261
285
|
render: () => {
|
262
286
|
const containerRef = React.useRef(null);
|
263
287
|
return (<View gap={10}>
|
@@ -280,6 +304,30 @@ export const fallbackAdjustLayout = {
|
|
280
304
|
</View>);
|
281
305
|
},
|
282
306
|
};
|
307
|
+
export const fallbackAdjustLayoutSize = {
|
308
|
+
name: "fallbackAdjustLayout, size",
|
309
|
+
render: () => {
|
310
|
+
const containerRef = React.useRef(null);
|
311
|
+
return (<View gap={10}>
|
312
|
+
<View height="95vh" width="100%" align="center" justify="center">
|
313
|
+
<View backgroundColor="neutral-faded" borderRadius="medium" height="1000px" width="600px" padding={4} paddingBlock={15} overflow="auto">
|
314
|
+
<FallbackAdjustLayoutControls large/>
|
315
|
+
<View height="150%" width="150%" attributes={{ style: { pointerEvents: "none" } }}/>
|
316
|
+
</View>
|
317
|
+
</View>
|
318
|
+
|
319
|
+
<View height="95vh" width="100%" align="center" justify="center">
|
320
|
+
<View backgroundColor="neutral-faded" borderRadius="medium" height="1000px" width="600px" attributes={{ ref: containerRef }} padding={4} paddingBlock={15} overflow="auto">
|
321
|
+
<FallbackAdjustLayoutControls containerRef={containerRef} large/>
|
322
|
+
<View height="150%" width="150%" attributes={{ style: { pointerEvents: "none" } }}/>
|
323
|
+
</View>
|
324
|
+
</View>
|
325
|
+
|
326
|
+
<FallbackAdjustLayoutControls large/>
|
327
|
+
<div style={{ height: "100vh", width: "250%" }}/>
|
328
|
+
</View>);
|
329
|
+
},
|
330
|
+
};
|
283
331
|
export const originCoordinates = {
|
284
332
|
name: "originCoordinates",
|
285
333
|
render: () => {
|
@@ -1,14 +1,8 @@
|
|
1
1
|
import React from "react";
|
2
2
|
import type * as G from "../../types/global";
|
3
3
|
import type * as T from "./Flyout.types";
|
4
|
-
type UseFlyout = (args: {
|
5
|
-
width?: T.Width;
|
6
|
-
position?: T.Position;
|
7
|
-
defaultActive?: boolean;
|
4
|
+
type UseFlyout = (args: Pick<T.Props, "width" | "position" | "defaultActive" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "contentGap" | "contentShift"> & {
|
8
5
|
fallbackPositions?: T.Position[];
|
9
|
-
fallbackAdjustLayout?: boolean;
|
10
|
-
contentGap?: number;
|
11
|
-
contentShift?: number;
|
12
6
|
container?: HTMLElement | null;
|
13
7
|
triggerElRef: React.RefObject<HTMLElement | null>;
|
14
8
|
flyoutElRef: React.RefObject<HTMLElement | null>;
|
@@ -38,7 +38,7 @@ const flyoutReducer = (state, action) => {
|
|
38
38
|
};
|
39
39
|
const useFlyout = (args) => {
|
40
40
|
const { triggerElRef, flyoutElRef, triggerBounds, contentGap, contentShift, ...options } = args;
|
41
|
-
const { position: defaultPosition = "bottom", fallbackPositions, width, container,
|
41
|
+
const { position: defaultPosition = "bottom", fallbackPositions, fallbackAdjustLayout, fallbackMinWidth, fallbackMinHeight, width, container, } = options;
|
42
42
|
const lastUsedPositionRef = React.useRef(defaultPosition);
|
43
43
|
// Memo the array internally to avoid new arrays triggering useCallback
|
44
44
|
const cachedFallbackPositions = React.useMemo(() => fallbackPositions,
|
@@ -77,6 +77,8 @@ const useFlyout = (args) => {
|
|
77
77
|
position: changePositon ? defaultPosition : lastUsedPositionRef.current,
|
78
78
|
fallbackPositions: changePositon ? cachedFallbackPositions : [],
|
79
79
|
fallbackAdjustLayout,
|
80
|
+
fallbackMinWidth,
|
81
|
+
fallbackMinHeight,
|
80
82
|
lastUsedPosition: lastUsedPositionRef.current,
|
81
83
|
onPositionChoose: handlePosition,
|
82
84
|
rtl: isRTL,
|
@@ -103,6 +105,8 @@ const useFlyout = (args) => {
|
|
103
105
|
contentGap,
|
104
106
|
contentShift,
|
105
107
|
handlePosition,
|
108
|
+
fallbackMinWidth,
|
109
|
+
fallbackMinHeight,
|
106
110
|
]);
|
107
111
|
React.useEffect(() => {
|
108
112
|
if (state.status === "rendered")
|
@@ -10,15 +10,16 @@ declare const calculatePosition: (args: {
|
|
10
10
|
};
|
11
11
|
passedContainer?: HTMLElement | null;
|
12
12
|
containerBounds: DOMRect;
|
13
|
-
} & Pick<T.Options, "position" | "rtl" | "width" | "contentGap" | "contentShift" | "fallbackAdjustLayout">) => {
|
13
|
+
} & Pick<T.Options, "position" | "rtl" | "width" | "contentGap" | "contentShift" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight">) => {
|
14
14
|
position: T.Position;
|
15
15
|
styles: {
|
16
|
-
width: string | number | undefined;
|
17
16
|
left: number | undefined;
|
18
17
|
right: number | undefined;
|
19
18
|
top: number | undefined;
|
20
19
|
bottom: number | undefined;
|
21
20
|
transform: string;
|
21
|
+
height: number | undefined;
|
22
|
+
width: string | number | undefined;
|
22
23
|
};
|
23
24
|
boundaries: {
|
24
25
|
left: number;
|
@@ -4,12 +4,14 @@ const SCREEN_OFFSET = 8;
|
|
4
4
|
* Calculate styles for the current position
|
5
5
|
*/
|
6
6
|
const calculatePosition = (args) => {
|
7
|
-
const { triggerBounds, flyoutBounds, containerBounds, position: passedPosition, rtl, width, contentGap = 0, contentShift = 0, passedContainer, fallbackAdjustLayout, } = args;
|
8
|
-
const isFullWidth =
|
7
|
+
const { triggerBounds, flyoutBounds, containerBounds, position: passedPosition, rtl, width: passedWidth, contentGap = 0, contentShift = 0, passedContainer, fallbackAdjustLayout, fallbackMinWidth, fallbackMinHeight, } = args;
|
8
|
+
const isFullWidth = passedWidth === "full" || passedWidth === "100%";
|
9
9
|
let left = 0;
|
10
10
|
let top = 0;
|
11
11
|
let bottom = null;
|
12
12
|
let right = null;
|
13
|
+
let height = undefined;
|
14
|
+
let width = undefined;
|
13
15
|
let position = passedPosition;
|
14
16
|
if (rtl)
|
15
17
|
position = getRTLPosition(position);
|
@@ -96,57 +98,80 @@ const calculatePosition = (args) => {
|
|
96
98
|
break;
|
97
99
|
}
|
98
100
|
if (fallbackAdjustLayout) {
|
99
|
-
const
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
const getOverflow = () => {
|
102
|
+
return {
|
103
|
+
top: -top + scrollY + SCREEN_OFFSET,
|
104
|
+
bottom: top + flyoutHeight + SCREEN_OFFSET - scrollY - renderContainerHeight,
|
105
|
+
left: -left + scrollX + SCREEN_OFFSET,
|
106
|
+
right: left + flyoutWidth + SCREEN_OFFSET - scrollX - renderContainerWidth,
|
107
|
+
};
|
108
|
+
};
|
109
|
+
const overflow = getOverflow();
|
103
110
|
if (isHorizontalPosition) {
|
104
|
-
if (
|
111
|
+
if (overflow.top > 0) {
|
105
112
|
top = SCREEN_OFFSET + scrollY;
|
106
113
|
if (bottom !== null)
|
107
|
-
bottom = bottom -
|
114
|
+
bottom = bottom - overflow.top;
|
108
115
|
}
|
109
|
-
else if (
|
110
|
-
|
111
|
-
top = top - bottomOverflowSize;
|
116
|
+
else if (overflow.bottom > 0) {
|
117
|
+
top = top - overflow.bottom;
|
112
118
|
}
|
113
119
|
}
|
114
120
|
else {
|
115
|
-
if (
|
121
|
+
if (overflow.left > 0) {
|
116
122
|
left = SCREEN_OFFSET + scrollX;
|
117
123
|
if (right !== null)
|
118
|
-
right = right -
|
124
|
+
right = right - overflow.left;
|
119
125
|
}
|
120
|
-
else if (
|
121
|
-
left = left -
|
126
|
+
else if (overflow.right > 0) {
|
127
|
+
left = left - overflow.right;
|
122
128
|
}
|
123
129
|
}
|
130
|
+
const updatedOverflow = getOverflow();
|
131
|
+
if (updatedOverflow.top > 0) {
|
132
|
+
height = Math.max(fallbackMinHeight ? parseInt(fallbackMinHeight) : 0, flyoutHeight - updatedOverflow.top);
|
133
|
+
top = top + (flyoutHeight - height);
|
134
|
+
}
|
135
|
+
else if (updatedOverflow.bottom > 0) {
|
136
|
+
height = Math.max(fallbackMinHeight ? parseInt(fallbackMinHeight) : 0, flyoutHeight - updatedOverflow.bottom);
|
137
|
+
if (bottom !== null)
|
138
|
+
bottom = bottom + (flyoutHeight - height);
|
139
|
+
}
|
140
|
+
if (updatedOverflow.left > 0) {
|
141
|
+
width = Math.max(fallbackMinWidth ? parseInt(fallbackMinWidth) : 0, flyoutWidth - updatedOverflow.left);
|
142
|
+
left = left + (flyoutWidth - width);
|
143
|
+
}
|
144
|
+
else if (updatedOverflow.right > 0) {
|
145
|
+
width = Math.max(fallbackMinWidth ? parseInt(fallbackMinWidth) : 0, flyoutWidth - updatedOverflow.right);
|
146
|
+
if (right !== null)
|
147
|
+
right = right + (flyoutWidth - width);
|
148
|
+
}
|
124
149
|
}
|
125
|
-
let widthStyle;
|
126
150
|
if (isFullWidth) {
|
127
151
|
left = SCREEN_OFFSET;
|
128
|
-
|
152
|
+
width = window.innerWidth - SCREEN_OFFSET * 2;
|
129
153
|
}
|
130
|
-
else if (
|
131
|
-
|
154
|
+
else if (passedWidth === "trigger") {
|
155
|
+
width = triggerBounds.width;
|
132
156
|
}
|
133
157
|
const translateX = right !== null ? -right : left;
|
134
158
|
const translateY = bottom !== null ? -bottom : top;
|
135
159
|
return {
|
136
160
|
position,
|
137
161
|
styles: {
|
138
|
-
width: widthStyle ?? width,
|
139
162
|
left: right === null ? 0 : undefined,
|
140
163
|
right: right === null ? undefined : 0,
|
141
164
|
top: bottom === null ? 0 : undefined,
|
142
165
|
bottom: bottom === null ? undefined : 0,
|
143
166
|
transform: `translate(${translateX}px, ${translateY}px)`,
|
167
|
+
height,
|
168
|
+
width: width ?? passedWidth,
|
144
169
|
},
|
145
170
|
boundaries: {
|
146
171
|
left,
|
147
172
|
top,
|
148
|
-
height: Math.ceil(flyoutHeight),
|
149
|
-
width:
|
173
|
+
height: height ?? Math.ceil(flyoutHeight),
|
174
|
+
width: width ?? Math.ceil(flyoutWidth),
|
150
175
|
},
|
151
176
|
};
|
152
177
|
};
|
@@ -7,7 +7,7 @@ import { resetStyles } from "../Flyout.constants.js";
|
|
7
7
|
* Set position of the target element to fit on the screen
|
8
8
|
*/
|
9
9
|
const flyout = (args) => {
|
10
|
-
const { triggerEl, flyoutEl, triggerBounds: passedTriggerBounds, contentShift = 0, contentGap = 0, position, fallbackPositions, fallbackAdjustLayout, width, container: passedContainer, lastUsedPosition, onPositionChoose, rtl, } = args;
|
10
|
+
const { triggerEl, flyoutEl, triggerBounds: passedTriggerBounds, contentShift = 0, contentGap = 0, position, fallbackPositions, fallbackAdjustLayout, fallbackMinWidth, fallbackMinHeight, width, container: passedContainer, lastUsedPosition, onPositionChoose, rtl, } = args;
|
11
11
|
const targetClone = flyoutEl.cloneNode(true);
|
12
12
|
const baseUnit = getComputedStyle(flyoutEl).getPropertyValue("--rs-unit-x1");
|
13
13
|
const unitModifier = baseUnit ? parseInt(baseUnit) : 4;
|
@@ -55,6 +55,8 @@ const flyout = (args) => {
|
|
55
55
|
passedContainer: passedContainer ||
|
56
56
|
(closestFixedContainer !== document.body ? closestFixedContainer : undefined),
|
57
57
|
fallbackAdjustLayout,
|
58
|
+
fallbackMinWidth,
|
59
|
+
fallbackMinHeight,
|
58
60
|
});
|
59
61
|
};
|
60
62
|
const testVisibility = (calculated) => {
|
@@ -62,7 +64,6 @@ const flyout = (args) => {
|
|
62
64
|
flyoutBounds: calculated.boundaries,
|
63
65
|
visualContainerBounds,
|
64
66
|
renderContainerBounds,
|
65
|
-
container,
|
66
67
|
});
|
67
68
|
};
|
68
69
|
let calculated = null;
|
@@ -70,6 +71,7 @@ const flyout = (args) => {
|
|
70
71
|
testOrder.some((currentPosition) => {
|
71
72
|
const tested = applyPosition(currentPosition);
|
72
73
|
const visible = testVisibility(tested);
|
74
|
+
console.log(currentPosition, tested, visible ? "yes" : "no");
|
73
75
|
if (visible)
|
74
76
|
calculated = tested;
|
75
77
|
return visible;
|
@@ -14,7 +14,7 @@ const fallbackOrder = {
|
|
14
14
|
};
|
15
15
|
// Get an order of positions to try to fit flyout on the screen based on its starting position
|
16
16
|
const getPositionFallbacks = (position, availableFallbacks) => {
|
17
|
-
const result = [position];
|
17
|
+
const result = new Set([position]);
|
18
18
|
const chunks = position.split("-");
|
19
19
|
const [firstChunk] = chunks;
|
20
20
|
const passedPositionOrder = positions[firstChunk];
|
@@ -31,9 +31,9 @@ const getPositionFallbacks = (position, availableFallbacks) => {
|
|
31
31
|
const position = fallbackOrder[index];
|
32
32
|
if (availableFallbacks?.indexOf(position) === -1)
|
33
33
|
return;
|
34
|
-
result.
|
34
|
+
result.add(position);
|
35
35
|
});
|
36
36
|
});
|
37
|
-
return result;
|
37
|
+
return Array.from(result);
|
38
38
|
};
|
39
39
|
export default getPositionFallbacks;
|
@@ -8,7 +8,5 @@ declare const isFullyVisible: (args: {
|
|
8
8
|
visualContainerBounds: DOMRect;
|
9
9
|
/** Bounds of the container where flyout content is rendered */
|
10
10
|
renderContainerBounds: DOMRect;
|
11
|
-
/** Container where the flyout content is rendered */
|
12
|
-
container: HTMLElement;
|
13
11
|
}) => boolean;
|
14
12
|
export default isFullyVisible;
|
@@ -2,20 +2,18 @@
|
|
2
2
|
* Check if element visually fits within its render container
|
3
3
|
*/
|
4
4
|
const isFullyVisible = (args) => {
|
5
|
-
const { flyoutBounds, visualContainerBounds, renderContainerBounds
|
6
|
-
|
7
|
-
const scrollY = container === document.body ? window.scrollY : container.scrollTop;
|
8
|
-
if (renderContainerBounds.left + flyoutBounds.left - scrollX < visualContainerBounds.left) {
|
5
|
+
const { flyoutBounds, visualContainerBounds, renderContainerBounds } = args;
|
6
|
+
if (renderContainerBounds.left + flyoutBounds.left < visualContainerBounds.left) {
|
9
7
|
return false;
|
10
8
|
}
|
11
|
-
if (renderContainerBounds.top + flyoutBounds.top
|
9
|
+
if (renderContainerBounds.top + flyoutBounds.top < visualContainerBounds.top) {
|
12
10
|
return false;
|
13
11
|
}
|
14
|
-
if (renderContainerBounds.left + flyoutBounds.left + flyoutBounds.width
|
12
|
+
if (renderContainerBounds.left + flyoutBounds.left + flyoutBounds.width >
|
15
13
|
visualContainerBounds.right) {
|
16
14
|
return false;
|
17
15
|
}
|
18
|
-
if (renderContainerBounds.top + flyoutBounds.top + flyoutBounds.height
|
16
|
+
if (renderContainerBounds.top + flyoutBounds.top + flyoutBounds.height >
|
19
17
|
visualContainerBounds.bottom) {
|
20
18
|
return false;
|
21
19
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { classNames, responsiveClassNames } from "../../utilities/props.js";
|
2
|
+
import { classNames, responsiveClassNames, setComponentChildId } from "../../utilities/props.js";
|
3
3
|
import s from "./Hidden.module.css";
|
4
4
|
const Hidden = (props) => {
|
5
5
|
const { as: TagName = "div", children, visibility, hide } = props;
|
@@ -7,4 +7,5 @@ const Hidden = (props) => {
|
|
7
7
|
return _jsx(TagName, { className: rootClassNames, children: children });
|
8
8
|
};
|
9
9
|
Hidden.displayName = "Hidden";
|
10
|
+
setComponentChildId(Hidden, "Hidden");
|
10
11
|
export default Hidden;
|