reshaped 3.9.0-canary.2 → 3.9.0-canary.3
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/bundle.css +1 -1
- package/dist/bundle.js +2 -31
- package/dist/components/Autocomplete/Autocomplete.js +2 -2
- package/dist/components/Autocomplete/Autocomplete.types.d.ts +1 -1
- package/dist/components/Calendar/Calendar.types.d.ts +15 -4
- package/dist/components/Calendar/CalendarControlled.js +43 -8
- package/dist/components/Calendar/CalendarControls.js +9 -9
- package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +1 -1
- package/dist/components/Flyout/Flyout.module.css +1 -1
- package/dist/components/Flyout/Flyout.types.d.ts +3 -1
- package/dist/components/Flyout/FlyoutContent.js +2 -1
- package/dist/components/Flyout/FlyoutControlled.js +3 -2
- package/dist/components/Popover/Popover.module.css +1 -1
- package/dist/components/Popover/Popover.types.d.ts +1 -1
- package/package.json +1 -1
|
@@ -11,7 +11,7 @@ import useIsomorphicLayoutEffect from "../../hooks/useIsomorphicLayoutEffect.js"
|
|
|
11
11
|
import s from "./Autocomplete.module.css";
|
|
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, fallbackAdjustLayout, fallbackMinWidth, fallbackMinHeight, ...textFieldProps } = props;
|
|
14
|
+
const { children, onChange, onInput, onItemSelect, name, containerRef, instanceRef, onBackspace, onEnter, active, onOpen, onClose, fallbackAdjustLayout, fallbackMinWidth, fallbackMinHeight, contentMaxHeight, ...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, 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: {
|
|
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, contentMaxHeight: contentMaxHeight, 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" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight"> & {
|
|
10
|
+
export type Props = TextFieldProps & Pick<DropdownMenuProps, "containerRef" | "instanceRef" | "active" | "onOpen" | "onClose" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "contentMaxHeight"> & {
|
|
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 */
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
export type SelectionMode = "date" | "month";
|
|
2
2
|
export type BaseProps = {
|
|
3
|
-
/** Default month to display
|
|
3
|
+
/** Default month to display. Used in uncontrolled mode to provide the initial month and then updated by the component internally
|
|
4
4
|
* @default Date.now()
|
|
5
5
|
*/
|
|
6
6
|
defaultMonth?: Date;
|
|
7
|
+
/** Month to display. Used in controlled mode and should be updated using the `onMonthChange` callback */
|
|
8
|
+
month?: Date;
|
|
9
|
+
/** Callback when the month changes */
|
|
10
|
+
onMonthChange?: (args: {
|
|
11
|
+
date: Date;
|
|
12
|
+
}) => void;
|
|
7
13
|
/** Minimum date that can be selected */
|
|
8
14
|
min?: Date;
|
|
9
15
|
/** Maximum date that can be selected */
|
|
10
16
|
max?: Date;
|
|
17
|
+
/** Number of months to render at the same time
|
|
18
|
+
* @default 1
|
|
19
|
+
*/
|
|
20
|
+
monthsToRender?: number;
|
|
11
21
|
/** First day of the week
|
|
12
22
|
* @default 1, Monday
|
|
13
23
|
*/
|
|
@@ -129,12 +139,13 @@ export type DateProps = {
|
|
|
129
139
|
} & Pick<MonthProps, "hoveredDate" | "onDateHover" | "onDateHoverEnd" | "onChange" | "range" | "min" | "max" | "selectedDates">;
|
|
130
140
|
export type ControlsProps = {
|
|
131
141
|
selectionMode: SelectionMode;
|
|
142
|
+
monthsToRender: number;
|
|
132
143
|
onMonthTitleClick: () => void;
|
|
133
|
-
monthTitleRef
|
|
144
|
+
monthTitleRef?: React.RefObject<HTMLButtonElement | null>;
|
|
134
145
|
monthDate: Date;
|
|
135
146
|
renderSelectedMonthLabel?: BaseProps["renderSelectedMonthLabel"];
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
hidePrevious?: boolean;
|
|
148
|
+
hideNext?: boolean;
|
|
138
149
|
onNextClick: () => void;
|
|
139
150
|
onPreviousClick: () => void;
|
|
140
151
|
} & Pick<BaseProps, "nextMonthAriaLabel" | "nextYearAriaLabel" | "previousMonthAriaLabel" | "previousYearAriaLabel" | "monthSelectionAriaLabel">;
|
|
@@ -9,9 +9,9 @@ import CalendarMonth from "./CalendarMonth.js";
|
|
|
9
9
|
import CalendarYear from "./CalendarYear.js";
|
|
10
10
|
import useCalendarKeyboardNavigation from "./useCalendarKeyboardNavigation.js";
|
|
11
11
|
const CalendarControlled = (props) => {
|
|
12
|
-
const { value, onChange, defaultMonth, min, max, range, firstWeekDay, selectedDates, renderMonthLabel, renderSelectedMonthLabel, renderWeekDay, previousMonthAriaLabel, previousYearAriaLabel, nextMonthAriaLabel, nextYearAriaLabel, monthSelectionAriaLabel, renderMonthAriaLabel, renderDateAriaLabel, renderDateSlot, } = props;
|
|
12
|
+
const { value, onChange, defaultMonth, month, onMonthChange, min, max, range, firstWeekDay, selectedDates, monthsToRender = 1, renderMonthLabel, renderSelectedMonthLabel, renderWeekDay, previousMonthAriaLabel, previousYearAriaLabel, nextMonthAriaLabel, nextYearAriaLabel, monthSelectionAriaLabel, renderMonthAriaLabel, renderDateAriaLabel, renderDateSlot, } = props;
|
|
13
13
|
const [selectionMode, setSelectionMode] = React.useState("date");
|
|
14
|
-
const [monthDate, setMonthDate] = React.useState(defaultMonth || new Date());
|
|
14
|
+
const [monthDate, setMonthDate] = React.useState(month || defaultMonth || new Date());
|
|
15
15
|
const [hoveredDate, setHoveredDate] = React.useState(null);
|
|
16
16
|
const monthTitleRef = React.useRef(null);
|
|
17
17
|
const prevSelectionModeRef = React.useRef(selectionMode);
|
|
@@ -19,23 +19,38 @@ const CalendarControlled = (props) => {
|
|
|
19
19
|
const selectionRootRef = React.useRef(null);
|
|
20
20
|
const handlePreviousClick = () => {
|
|
21
21
|
if (selectionMode === "month") {
|
|
22
|
-
|
|
22
|
+
const updatedMonth = setYearToPrevious(monthDate);
|
|
23
|
+
onMonthChange?.({ date: updatedMonth });
|
|
24
|
+
if (month === undefined)
|
|
25
|
+
setMonthDate(updatedMonth);
|
|
23
26
|
return;
|
|
24
27
|
}
|
|
25
|
-
|
|
28
|
+
const updatedMonth = setMonthToPrevious(monthDate);
|
|
29
|
+
onMonthChange?.({ date: updatedMonth });
|
|
30
|
+
if (month === undefined)
|
|
31
|
+
setMonthDate(updatedMonth);
|
|
26
32
|
};
|
|
27
33
|
const handleNextClick = () => {
|
|
28
34
|
if (selectionMode === "month") {
|
|
29
|
-
|
|
35
|
+
const updatedMonth = setYearToNext(monthDate);
|
|
36
|
+
onMonthChange?.({ date: updatedMonth });
|
|
37
|
+
if (month === undefined)
|
|
38
|
+
setMonthDate(updatedMonth);
|
|
30
39
|
return;
|
|
31
40
|
}
|
|
32
|
-
|
|
41
|
+
const updatedMonth = setMonthToNext(monthDate);
|
|
42
|
+
onMonthChange?.({ date: updatedMonth });
|
|
43
|
+
if (month === undefined)
|
|
44
|
+
setMonthDate(updatedMonth);
|
|
33
45
|
};
|
|
34
46
|
const handleMonthTitleClick = () => {
|
|
35
47
|
setSelectionMode("month");
|
|
36
48
|
};
|
|
37
49
|
const handleMonthClick = (i) => {
|
|
38
|
-
|
|
50
|
+
const updatedMonth = setMonthTo(monthDate, i);
|
|
51
|
+
onMonthChange?.({ date: updatedMonth });
|
|
52
|
+
if (month === undefined)
|
|
53
|
+
setMonthDate(updatedMonth);
|
|
39
54
|
setSelectionMode("date");
|
|
40
55
|
};
|
|
41
56
|
const handleDateHover = (date) => {
|
|
@@ -53,6 +68,14 @@ const CalendarControlled = (props) => {
|
|
|
53
68
|
}
|
|
54
69
|
prevSelectionModeRef.current = selectionMode;
|
|
55
70
|
}, [selectionMode]);
|
|
71
|
+
/**
|
|
72
|
+
* Handle rendering in controlled mode
|
|
73
|
+
*/
|
|
74
|
+
React.useEffect(() => {
|
|
75
|
+
if (!month)
|
|
76
|
+
return;
|
|
77
|
+
setMonthDate(month);
|
|
78
|
+
}, [month]);
|
|
56
79
|
useCalendarKeyboardNavigation({
|
|
57
80
|
monthDate,
|
|
58
81
|
rootRef: selectionRootRef,
|
|
@@ -63,7 +86,19 @@ const CalendarControlled = (props) => {
|
|
|
63
86
|
min,
|
|
64
87
|
max,
|
|
65
88
|
});
|
|
66
|
-
return (_jsxs(View, { gap: 2, children: [_jsx(
|
|
89
|
+
return (_jsxs(View, { gap: 2, children: [_jsx(View, { direction: "row", gap: 4, children: Array.from({ length: selectionMode === "date" ? monthsToRender : 1 }).map((_, index) => {
|
|
90
|
+
const hidePrevious = bounds.isFirstMonth || (monthsToRender > 0 && index > 0);
|
|
91
|
+
const hideNext = bounds.isLastMonth ||
|
|
92
|
+
(selectionMode === "date" && monthsToRender > 0 && index < monthsToRender - 1);
|
|
93
|
+
const currentMonthDate = new Date(monthDate);
|
|
94
|
+
currentMonthDate.setMonth(currentMonthDate.getMonth() + index);
|
|
95
|
+
return (_jsx(View.Item, { grow: true, children: _jsx(CalendarControls, { renderSelectedMonthLabel: renderSelectedMonthLabel, monthDate: currentMonthDate, selectionMode: selectionMode, hidePrevious: hidePrevious, hideNext: hideNext, monthTitleRef: index === 0 ? monthTitleRef : undefined, onMonthTitleClick: handleMonthTitleClick, onNextClick: handleNextClick, onPreviousClick: handlePreviousClick, previousMonthAriaLabel: previousMonthAriaLabel, previousYearAriaLabel: previousYearAriaLabel, nextMonthAriaLabel: nextMonthAriaLabel, nextYearAriaLabel: nextYearAriaLabel, monthSelectionAriaLabel: monthSelectionAriaLabel, monthsToRender: monthsToRender }) }, index));
|
|
96
|
+
}) }), _jsxs(View, { direction: "row", gap: 4, attributes: { ref: selectionRootRef }, children: [selectionMode === "date" &&
|
|
97
|
+
Array.from({ length: monthsToRender }).map((_, index) => {
|
|
98
|
+
const currentMonthDate = new Date(monthDate);
|
|
99
|
+
currentMonthDate.setMonth(currentMonthDate.getMonth() + index);
|
|
100
|
+
return (_jsx(View.Item, { grow: true, children: _jsx(CalendarMonth, { date: currentMonthDate, value: value, onChange: onChange, min: min, max: max, range: range, firstWeekDay: firstWeekDay, hoveredDate: hoveredDate, selectedDates: selectedDates, onDateHover: handleDateHover, onDateHoverEnd: handleDateHoverEnd, renderWeekDay: renderWeekDay, renderDateAriaLabel: renderDateAriaLabel, renderDateSlot: renderDateSlot }) }, index));
|
|
101
|
+
}), selectionMode === "month" && (_jsx(CalendarYear, { monthDate: monthDate, onMonthClick: handleMonthClick, renderMonthLabel: renderMonthLabel, renderMonthAriaLabel: renderMonthAriaLabel, min: min, max: max }))] })] }));
|
|
67
102
|
};
|
|
68
103
|
CalendarControlled.displayName = "CalendarControlled";
|
|
69
104
|
export default CalendarControlled;
|
|
@@ -10,35 +10,35 @@ import IconChevronRight from "../../icons/ChevronRight.js";
|
|
|
10
10
|
import { onNextFrame } from "../../utilities/animation.js";
|
|
11
11
|
import s from "./Calendar.module.css";
|
|
12
12
|
const CalendarControls = (props) => {
|
|
13
|
-
const { selectionMode, onMonthTitleClick, monthTitleRef, monthDate, renderSelectedMonthLabel,
|
|
13
|
+
const { selectionMode, onMonthTitleClick, monthTitleRef, monthDate, renderSelectedMonthLabel, hidePrevious, hideNext, onNextClick, onPreviousClick, monthSelectionAriaLabel = "Select a month", previousMonthAriaLabel = "Previous month", previousYearAriaLabel = "Previous year", nextMonthAriaLabel = "Next month", nextYearAriaLabel = "Next year", } = props;
|
|
14
14
|
const prevRef = React.useRef(null);
|
|
15
15
|
const nextRef = React.useRef(null);
|
|
16
16
|
React.useEffect(() => {
|
|
17
|
-
if (!
|
|
17
|
+
if (!hidePrevious)
|
|
18
18
|
return;
|
|
19
19
|
if (document.activeElement !== prevRef.current)
|
|
20
20
|
return;
|
|
21
|
-
const targetEl = nextRef.current || monthTitleRef
|
|
21
|
+
const targetEl = nextRef.current || monthTitleRef?.current;
|
|
22
22
|
onNextFrame(() => {
|
|
23
23
|
targetEl?.focus();
|
|
24
24
|
});
|
|
25
|
-
}, [
|
|
25
|
+
}, [hidePrevious, monthTitleRef]);
|
|
26
26
|
React.useEffect(() => {
|
|
27
|
-
if (!
|
|
27
|
+
if (!hideNext)
|
|
28
28
|
return;
|
|
29
29
|
if (document.activeElement !== nextRef.current)
|
|
30
30
|
return;
|
|
31
|
-
const targetEl = prevRef.current || monthTitleRef
|
|
31
|
+
const targetEl = prevRef.current || monthTitleRef?.current;
|
|
32
32
|
onNextFrame(() => {
|
|
33
33
|
targetEl?.focus();
|
|
34
34
|
});
|
|
35
|
-
}, [
|
|
36
|
-
return (_jsxs(View, { direction: "row", gap: 2, align: "center", children: [_jsx(Hidden, { visibility: true, hide:
|
|
35
|
+
}, [hideNext, monthTitleRef]);
|
|
36
|
+
return (_jsxs(View, { direction: "row", gap: 2, align: "center", children: [_jsx(Hidden, { visibility: true, hide: hidePrevious, children: _jsx("div", { className: s.control, children: _jsx(Button, { variant: "ghost", icon: IconChevronLeft, onClick: onPreviousClick, attributes: {
|
|
37
37
|
ref: prevRef,
|
|
38
38
|
"aria-label": selectionMode === "date" ? previousMonthAriaLabel : previousYearAriaLabel,
|
|
39
39
|
} }) }) }), _jsxs(View.Item, { grow: true, children: [selectionMode === "date" && (_jsxs(Button, { fullWidth: true, variant: "ghost", onClick: onMonthTitleClick, attributes: { ref: monthTitleRef }, children: [renderSelectedMonthLabel
|
|
40
40
|
? renderSelectedMonthLabel({ date: monthDate })
|
|
41
|
-
: monthDate.toLocaleDateString("en-US", { month: "long", year: "numeric" }), _jsx(HiddenVisually, { children: monthSelectionAriaLabel })] })), selectionMode === "month" && (_jsx(Text, { align: "center", weight: "medium", children: monthDate.toLocaleDateString("en-US", { year: "numeric" }) }))] }), _jsx(Hidden, { visibility: true, hide:
|
|
41
|
+
: monthDate.toLocaleDateString("en-US", { month: "long", year: "numeric" }), _jsx(HiddenVisually, { children: monthSelectionAriaLabel })] })), selectionMode === "month" && (_jsx(Text, { align: "center", weight: "medium", children: monthDate.toLocaleDateString("en-US", { year: "numeric" }) }))] }), _jsx(Hidden, { visibility: true, hide: hideNext, children: _jsx("div", { className: s.control, children: _jsx(Button, { variant: "ghost", icon: IconChevronRight, onClick: onNextClick, attributes: {
|
|
42
42
|
ref: nextRef,
|
|
43
43
|
"aria-label": selectionMode === "date" ? nextMonthAriaLabel : nextYearAriaLabel,
|
|
44
44
|
} }) }) })] }));
|
|
@@ -3,7 +3,7 @@ import type { MenuItemProps } from "../MenuItem";
|
|
|
3
3
|
import type { PopoverProps, PopoverInstance } from "../Popover";
|
|
4
4
|
import type React from "react";
|
|
5
5
|
export type Instance = PopoverInstance;
|
|
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" | "positionRef" | "originCoordinates" | "borderRadius" | "elevation" | "initialFocusRef"> & {
|
|
6
|
+
export type Props = Pick<PopoverProps, "children" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "triggerType" | "contentGap" | "contentShift" | "contentMaxHeight" | "onOpen" | "onClose" | "active" | "defaultActive" | "width" | "disableHideAnimation" | "disableCloseOnOutsideClick" | "instanceRef" | "containerRef" | "positionRef" | "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
|
};
|
|
@@ -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{backface-visibility:hidden;height:100%;max-height:
|
|
1
|
+
.content{--rs-flyout-gap:0;--rs-flyout-max-h:100%;--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:var(--rs-flyout-max-h);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-shadow-focus)}.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)}
|
|
@@ -132,6 +132,8 @@ type BaseProps = {
|
|
|
132
132
|
contentGap?: number;
|
|
133
133
|
/** Shift the content on the secondary axis, relative to its original position */
|
|
134
134
|
contentShift?: number;
|
|
135
|
+
/** Maximum height for the content */
|
|
136
|
+
contentMaxHeight?: string;
|
|
135
137
|
/** Additional classname for the content element */
|
|
136
138
|
contentClassName?: string;
|
|
137
139
|
/** Additional attributes for the content element */
|
|
@@ -189,7 +191,7 @@ export type ContextProps = {
|
|
|
189
191
|
handleContentMouseDown: () => void;
|
|
190
192
|
handleContentMouseUp: () => void;
|
|
191
193
|
isSubmenu: boolean;
|
|
192
|
-
} & Pick<Props, "triggerType" | "contentClassName" | "contentAttributes" | "contentGap" | "trapFocusMode" | "containerRef" | "disableContentHover" | "autoFocus">;
|
|
194
|
+
} & Pick<Props, "triggerType" | "contentClassName" | "contentAttributes" | "contentGap" | "contentMaxHeight" | "trapFocusMode" | "containerRef" | "disableContentHover" | "autoFocus">;
|
|
193
195
|
export type TriggerContextProps = {
|
|
194
196
|
elRef?: ContextProps["triggerElRef"];
|
|
195
197
|
};
|
|
@@ -11,7 +11,7 @@ import s from "./Flyout.module.css";
|
|
|
11
11
|
import cooldown from "./utilities/cooldown.js";
|
|
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, contentClassName, contentAttributes, contentGap, trapFocusMode, disableContentHover, autoFocus, width, containerRef: passedContainerRef, isSubmenu, } = useFlyoutContext();
|
|
14
|
+
const { flyout, id, flyoutElRef, triggerElRef, handleClose, handleTransitionEnd, handleTransitionStart, triggerType, handleMouseEnter, handleMouseLeave, handleContentMouseDown, handleContentMouseUp, contentClassName, contentAttributes, contentGap, contentMaxHeight, 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(() => {
|
|
@@ -97,6 +97,7 @@ const FlyoutContent = (props) => {
|
|
|
97
97
|
const content = (_jsx(ContentProvider, { value: { elRef: flyoutElRef }, children: _jsx("div", { className: rootClassNames, style: {
|
|
98
98
|
...styles,
|
|
99
99
|
"--rs-flyout-gap": contentGap,
|
|
100
|
+
"--rs-flyout-max-h": contentMaxHeight,
|
|
100
101
|
}, ref: flyoutElRef, onTransitionEnd: handleTransitionEnd, onMouseEnter: triggerType === "hover" ? handleMouseEnter : undefined, onMouseLeave: triggerType === "hover" ? handleMouseLeave : undefined, onMouseDown: handleContentMouseDown, onTouchStart: handleContentMouseDown, onMouseUp: handleContentMouseUp, onTouchEnd: handleContentMouseUp, children: _jsx("div", { role: role, ...attributes, id: id, tabIndex: !autoFocus ? -1 : undefined, "aria-modal": role === "dialog" ? true : undefined, style: { ...attributes?.style, ...contentAttributes?.style }, className: innerClassNames, children: children }) }) }));
|
|
101
102
|
return _jsx(Portal, { targetRef: containerRef, children: content });
|
|
102
103
|
};
|
|
@@ -15,7 +15,7 @@ import { Provider, useFlyoutTriggerContext, useFlyoutContext, useFlyoutContentCo
|
|
|
15
15
|
import useFlyout from "./useFlyout.js";
|
|
16
16
|
import cooldown from "./utilities/cooldown.js";
|
|
17
17
|
const FlyoutControlled = (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, positionRef, } = 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, contentMaxHeight, contentClassName, contentAttributes, position: passedPosition, active: passedActive, id: passedId, instanceRef, containerRef, initialFocusRef, positionRef, } = props;
|
|
19
19
|
const fallbackPositions = props.fallbackPositions === false || forcePosition ? [] : props.fallbackPositions;
|
|
20
20
|
const onOpenRef = useHandlerRef(onOpen);
|
|
21
21
|
const onCloseRef = useHandlerRef(onClose);
|
|
@@ -305,7 +305,7 @@ const FlyoutControlled = (props) => {
|
|
|
305
305
|
shouldReturnFocusRef.current = false;
|
|
306
306
|
handleClose({ reason: "outside-click" });
|
|
307
307
|
}, {
|
|
308
|
-
disabled:
|
|
308
|
+
disabled: !isRendered || disableCloseOnOutsideClick,
|
|
309
309
|
});
|
|
310
310
|
return (_jsx(Provider, { value: {
|
|
311
311
|
id,
|
|
@@ -331,6 +331,7 @@ const FlyoutControlled = (props) => {
|
|
|
331
331
|
contentClassName,
|
|
332
332
|
contentAttributes,
|
|
333
333
|
contentGap,
|
|
334
|
+
contentMaxHeight,
|
|
334
335
|
containerRef,
|
|
335
336
|
disableContentHover,
|
|
336
337
|
autoFocus,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.content{max-width:360px}.content--variant-elevated{background:var(--rs-color-background-elevation-overlay);border-radius:var(--rs-radius-medium);box-shadow:
|
|
1
|
+
.content{--rs-border-w:1px;border:var(--rs-border-w) solid var(--rs-color-border-neutral-faded);max-width:360px}.content--variant-elevated{background:var(--rs-color-background-elevation-overlay);border-radius:var(--rs-radius-medium);box-shadow:var(--rs-shadow-overlay);color:var(--rs-color-foreground-neutral);min-width:220px}.content--variant-elevated.content--elevation-raised{box-shadow:var(--rs-shadow-raised)}.content--radius-small{border-radius:var(--rs-radius-small)}.content.content--has-width{max-width:none;min-width:0}@media (--rs-viewport-s ){.content{max-width:none}}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { FlyoutProps, FlyoutInstance } from "../Flyout";
|
|
2
2
|
import type React from "react";
|
|
3
3
|
export type Instance = FlyoutInstance;
|
|
4
|
-
export type Props = Pick<FlyoutProps, "id" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "onOpen" | "onClose" | "width" | "trapFocusMode" | "active" | "defaultActive" | "contentGap" | "contentShift" | "instanceRef" | "triggerType" | "disableHideAnimation" | "disableContentHover" | "disableCloseOnOutsideClick" | "autoFocus" | "containerRef" | "positionRef" | "initialFocusRef" | "originCoordinates"> & {
|
|
4
|
+
export type Props = Pick<FlyoutProps, "id" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "onOpen" | "onClose" | "width" | "trapFocusMode" | "active" | "defaultActive" | "contentGap" | "contentShift" | "contentMaxHeight" | "instanceRef" | "triggerType" | "disableHideAnimation" | "disableContentHover" | "disableCloseOnOutsideClick" | "autoFocus" | "containerRef" | "positionRef" | "initialFocusRef" | "originCoordinates"> & {
|
|
5
5
|
/** Node for inserting children */
|
|
6
6
|
children?: React.ReactNode;
|
|
7
7
|
/** Content element padding, unit token multiplier */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reshaped",
|
|
3
3
|
"description": "Professionally crafted design system in React & Figma for building products of any scale and complexity",
|
|
4
|
-
"version": "3.9.0-canary.
|
|
4
|
+
"version": "3.9.0-canary.3",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"email": "hello@reshaped.so",
|
|
7
7
|
"homepage": "https://reshaped.so",
|