Skip to content

Commit

Permalink
Select Option width fit parent
Browse files Browse the repository at this point in the history
  • Loading branch information
lerte committed Nov 6, 2024
1 parent 9c0950d commit 0be6da9
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
4 changes: 4 additions & 0 deletions packages/actify/src/components/ListBox/listbox.module.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
.items {
list-style: none;
margin: 0;
padding: 0;
display: block;
padding-block: 8px;
list-style-type: none;
Expand All @@ -9,6 +12,7 @@
--md-menu-container-color,
var(--md-sys-color-surface-container, #f3edf7)
);
width: var(--reference-width);
height: inherit;
max-height: inherit;
overflow: auto;
Expand Down
14 changes: 13 additions & 1 deletion packages/actify/src/components/Popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@ import type { OverlayTriggerState } from 'react-stately'
import React from 'react'

interface PopoverProps extends Omit<AriaPopoverProps, 'popoverRef'> {
referenceWidth?: number
children: React.ReactNode
state: OverlayTriggerState
}

const Popover = ({ children, state, offset = 8, ...props }: PopoverProps) => {
const Popover = ({
children,
state,
offset = 8,
referenceWidth,
...props
}: PopoverProps) => {
const popoverRef = React.useRef(null)
const { popoverProps, underlayProps, arrowProps, placement } = usePopover(
{
Expand All @@ -26,6 +33,11 @@ const Popover = ({ children, state, offset = 8, ...props }: PopoverProps) => {
state
)

popoverProps.style = {
...popoverProps.style,
'--reference-width': referenceWidth + 'px'
} as React.CSSProperties

return (
<Overlay>
<div {...underlayProps} className={styles['underlay']} />
Expand Down
28 changes: 26 additions & 2 deletions packages/actify/src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ interface SelectProps<T> extends AriaSelectOptions<T>, SelectStateOptions<T> {

const Select = <T extends object>(props: SelectProps<T>) => {
const state = useSelectState(props)
const ref = React.useRef(null)
const [referenceWidth, setReferenceWidth] = React.useState<
number | undefined
>(0)
const ref = React.useRef<HTMLButtonElement>(null)

const { triggerProps, valueProps, menuProps } = useSelect(props, state, ref)

Expand All @@ -35,6 +38,22 @@ const Select = <T extends object>(props: SelectProps<T>) => {
Tag = OutlinedField
}

React.useLayoutEffect(() => {
const width = ref?.current?.getBoundingClientRect().width
setReferenceWidth(width)
}, [])

React.useEffect(() => {
const updateWidth = () => {
const width = ref?.current?.getBoundingClientRect().width
setReferenceWidth(width)
}
window.addEventListener('resize', updateWidth)
return () => {
window.removeEventListener('resize', updateWidth)
}
}, [])

return (
<div
style={props.style}
Expand All @@ -56,7 +75,12 @@ const Select = <T extends object>(props: SelectProps<T>) => {
</Tag>

{state.isOpen && (
<Popover state={state} triggerRef={ref} placement="bottom start">
<Popover
state={state}
triggerRef={ref}
placement="bottom start"
referenceWidth={referenceWidth}
>
<ListBox {...menuProps} state={state} />
</Popover>
)}
Expand Down

0 comments on commit 0be6da9

Please sign in to comment.