Skip to content

Commit f1907e3

Browse files
committed
fix: popover height limit
1 parent bed8032 commit f1907e3

File tree

4 files changed

+137
-120
lines changed

4 files changed

+137
-120
lines changed

.changeset/sour-toys-accept.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cube-dev/ui-kit": patch
3+
---
4+
5+
Fix popover height limit for Select and ComboBox.

src/components/fields/ComboBox/ComboBox.tsx

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,22 @@ const InputElement = tasty({
7171
styles: DEFAULT_INPUT_STYLES,
7272
});
7373

74+
const ComboBoxOverlayWrapper = tasty({
75+
qa: 'ComboBoxOverlayWrapper',
76+
styles: {
77+
position: 'absolute',
78+
zIndex: 1000,
79+
},
80+
});
81+
7482
const ComboBoxOverlayElement = tasty({
7583
qa: 'ComboBoxOverlay',
7684
styles: {
7785
display: 'grid',
7886
gridRows: '1sf',
7987
gridColumns: '1sf',
8088
width: '$min-width max-content 50vw',
81-
height: 'initial max-content (50vh - $size)',
89+
height: 'initial max-content (50vh - 5x)',
8290
overflow: 'auto',
8391
background: '#white',
8492
radius: '1cr',
@@ -89,7 +97,6 @@ const ComboBoxOverlayElement = tasty({
8997
'': false,
9098
hidden: true,
9199
},
92-
93100
transition:
94101
'translate $transition ease-out, scale $transition ease-out, theme $transition ease-out',
95102
translate: {
@@ -873,56 +880,54 @@ function ComboBoxOverlay({
873880
const overlayContent = (
874881
<DisplayTransition isShown={isOpen}>
875882
{({ phase, isShown, ref: transitionRef }) => (
876-
<ComboBoxOverlayElement
877-
{...mergeProps(
878-
overlayPositionProps,
879-
overlayBehaviorProps,
880-
compositeFocusProps,
881-
)}
882-
ref={(value) => {
883-
transitionRef(value as HTMLElement | null);
884-
(popoverRef as any).current = value;
885-
}}
886-
data-placement={placementDirection}
887-
data-phase={phase}
888-
mods={{
889-
open: isShown,
890-
hidden: phase === 'unmounted',
891-
}}
892-
styles={overlayStyles}
893-
style={{
894-
'--min-width': comboBoxWidth ? `${comboBoxWidth}px` : undefined,
895-
...overlayPositionProps.style,
896-
}}
883+
<ComboBoxOverlayWrapper
884+
{...mergeProps(overlayPositionProps, overlayBehaviorProps)}
885+
ref={popoverRef}
886+
style={overlayPositionProps.style}
897887
>
898-
<ListBox
899-
ref={listBoxRef}
900-
focusOnHover
901-
disableSelectionToggle
902-
id={`ComboBoxListBox-${comboBoxId}`}
903-
aria-label={
904-
ariaLabel || (typeof label === 'string' ? label : 'Options')
905-
}
906-
selectedKey={effectiveSelectedKey}
907-
selectionMode="single"
908-
isDisabled={isDisabled}
909-
disabledKeys={disabledKeys}
910-
shouldUseVirtualFocus={true}
911-
items={items as any}
912-
filter={filter}
913-
styles={listBoxStyles}
914-
optionStyles={optionStyles}
915-
sectionStyles={sectionStyles}
916-
headingStyles={headingStyles}
917-
stateRef={listStateRef}
888+
<ComboBoxOverlayElement
889+
{...compositeFocusProps}
890+
ref={transitionRef}
891+
data-placement={placementDirection}
892+
data-phase={phase}
918893
mods={{
919-
popover: true,
894+
open: isShown,
895+
hidden: phase === 'unmounted',
896+
}}
897+
styles={overlayStyles}
898+
style={{
899+
'--min-width': comboBoxWidth ? `${comboBoxWidth}px` : undefined,
920900
}}
921-
onSelectionChange={onSelectionChange}
922901
>
923-
{children as any}
924-
</ListBox>
925-
</ComboBoxOverlayElement>
902+
<ListBox
903+
ref={listBoxRef}
904+
focusOnHover
905+
disableSelectionToggle
906+
id={`ComboBoxListBox-${comboBoxId}`}
907+
aria-label={
908+
ariaLabel || (typeof label === 'string' ? label : 'Options')
909+
}
910+
selectedKey={effectiveSelectedKey}
911+
selectionMode="single"
912+
isDisabled={isDisabled}
913+
disabledKeys={disabledKeys}
914+
shouldUseVirtualFocus={true}
915+
items={items as any}
916+
filter={filter}
917+
styles={listBoxStyles}
918+
optionStyles={optionStyles}
919+
sectionStyles={sectionStyles}
920+
headingStyles={headingStyles}
921+
stateRef={listStateRef}
922+
mods={{
923+
popover: true,
924+
}}
925+
onSelectionChange={onSelectionChange}
926+
>
927+
{children as any}
928+
</ListBox>
929+
</ComboBoxOverlayElement>
930+
</ComboBoxOverlayWrapper>
926931
)}
927932
</DisplayTransition>
928933
);

src/components/fields/FilterPicker/FilterPicker.stories.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { userEvent, within } from 'storybook/test';
44
import {
55
CheckIcon,
66
DatabaseIcon,
7-
EditIcon,
87
FilterIcon,
98
PlusIcon,
109
RightIcon,

src/components/fields/Select/Select.tsx

Lines changed: 79 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,20 @@ const OptionItem = tasty(ItemBase, {
121121
},
122122
});
123123

124-
const OverlayElement = tasty({
124+
const SelectOverlayWrapper = tasty({
125+
qa: 'SelectOverlayWrapper',
125126
styles: {
126127
position: 'absolute',
128+
zIndex: 1000,
129+
},
130+
});
131+
132+
const OverlayElement = tasty({
133+
styles: {
127134
width: 'min $overlay-min-width',
128135
display: 'grid',
129136
gridRows: '1sf',
130-
height: 'initial max-content (50vh - $size)',
137+
height: 'initial max-content (50vh - 5x)',
131138
overflow: 'auto',
132139
background: '#white',
133140
radius: '1cr',
@@ -572,83 +579,84 @@ export function ListBoxPopup({
572579
<Portal>
573580
<DisplayTransition isShown={state.isOpen && !isDisabled}>
574581
{({ phase, isShown, ref: transitionRef }) => (
575-
<OverlayElement
582+
<SelectOverlayWrapper
576583
{...overlayProps}
577584
{...parentOverlayProps}
578-
ref={(value) => {
579-
transitionRef(value as HTMLElement | null);
580-
(popoverRef as any).current = value;
581-
}}
582-
data-placement={placementDirection}
583-
data-phase={phase}
584-
mods={{
585-
open: isShown,
586-
}}
587-
styles={overlayStyles}
588-
style={{
589-
'--overlay-min-width': minWidth ? `${minWidth}px` : 'initial',
590-
...parentOverlayProps?.style,
591-
}}
585+
ref={popoverRef}
586+
style={parentOverlayProps?.style}
592587
>
593-
<FocusScope restoreFocus>
594-
<DismissButton onDismiss={() => state.close()} />
595-
{(() => {
596-
const renderedItems: React.ReactNode[] = [];
597-
let isFirstSection = true;
598-
599-
for (const item of state.collection) {
600-
if (item.type === 'section') {
601-
if (!isFirstSection) {
588+
<OverlayElement
589+
ref={transitionRef}
590+
data-placement={placementDirection}
591+
data-phase={phase}
592+
mods={{
593+
open: isShown,
594+
}}
595+
styles={overlayStyles}
596+
style={{
597+
'--overlay-min-width': minWidth ? `${minWidth}px` : 'initial',
598+
}}
599+
>
600+
<FocusScope restoreFocus>
601+
<DismissButton onDismiss={() => state.close()} />
602+
{(() => {
603+
const renderedItems: React.ReactNode[] = [];
604+
let isFirstSection = true;
605+
606+
for (const item of state.collection) {
607+
if (item.type === 'section') {
608+
if (!isFirstSection) {
609+
renderedItems.push(
610+
<ListDivider
611+
key={`divider-${String(item.key)}`}
612+
as="li"
613+
role="separator"
614+
aria-orientation="horizontal"
615+
/>,
616+
);
617+
}
618+
602619
renderedItems.push(
603-
<ListDivider
604-
key={`divider-${String(item.key)}`}
605-
as="li"
606-
role="separator"
607-
aria-orientation="horizontal"
620+
<SelectSection
621+
key={item.key}
622+
item={item}
623+
state={state}
624+
optionStyles={optionStyles}
625+
sectionStyles={undefined}
626+
shouldUseVirtualFocus={shouldUseVirtualFocus}
627+
size={listItemSize}
608628
/>,
609629
);
610-
}
611630

612-
renderedItems.push(
613-
<SelectSection
614-
key={item.key}
615-
item={item}
616-
state={state}
617-
optionStyles={optionStyles}
618-
sectionStyles={undefined}
619-
shouldUseVirtualFocus={shouldUseVirtualFocus}
620-
size={listItemSize}
621-
/>,
622-
);
623-
624-
isFirstSection = false;
625-
} else {
626-
renderedItems.push(
627-
<Option
628-
key={item.key}
629-
item={item}
630-
state={state}
631-
styles={optionStyles}
632-
shouldUseVirtualFocus={shouldUseVirtualFocus}
633-
size={listItemSize}
634-
/>,
635-
);
631+
isFirstSection = false;
632+
} else {
633+
renderedItems.push(
634+
<Option
635+
key={item.key}
636+
item={item}
637+
state={state}
638+
styles={optionStyles}
639+
shouldUseVirtualFocus={shouldUseVirtualFocus}
640+
size={listItemSize}
641+
/>,
642+
);
643+
}
636644
}
637-
}
638-
639-
return (
640-
<ListBoxElement
641-
styles={listBoxStyles}
642-
{...listBoxProps}
643-
ref={listBoxRef}
644-
>
645-
{renderedItems}
646-
</ListBoxElement>
647-
);
648-
})()}
649-
<DismissButton onDismiss={() => state.close()} />
650-
</FocusScope>
651-
</OverlayElement>
645+
646+
return (
647+
<ListBoxElement
648+
styles={listBoxStyles}
649+
{...listBoxProps}
650+
ref={listBoxRef}
651+
>
652+
{renderedItems}
653+
</ListBoxElement>
654+
);
655+
})()}
656+
<DismissButton onDismiss={() => state.close()} />
657+
</FocusScope>
658+
</OverlayElement>
659+
</SelectOverlayWrapper>
652660
)}
653661
</DisplayTransition>
654662
</Portal>

0 commit comments

Comments
 (0)