headlessui-float icon indicating copy to clipboard operation
headlessui-float copied to clipboard

Accept `className` as part of FloatProps

Open JesusTheHun opened this issue 2 years ago • 1 comments

Is your feature request related to a problem? Please describe.

I'm using a combobox that uses all space available. Right now Float renders a blank div by default, meaning that its width will be width of its content. I want the width of the Float div to take all the space available.

So right now I have to create a dumb component and pass it to Float:

const FullWidthDiv: React.FC = ({children}) => <div className='w-full'>{children}</div>;
<Float as={FullWidthDiv} />

It feel like unnecessary work and accepting/passing className to the div would be more intuitive. Maybe disable (or trigger a warning) that if as is provided because the element itself may not accept className as a prop.

JesusTheHun avatar Aug 04 '22 12:08 JesusTheHun

Hi @JesusTheHun

Can you please provide minimal examples (using like github repo, codesandbox, stackblitz..., and suggest can use the Vite & React scaffolding: https://vite.new/react) with the ComboBox component? because I don't know your intention 😅.

ycs77 avatar Aug 05 '22 16:08 ycs77

Stackblitz : https://stackblitz.com/edit/github-k6mhmk?file=src/components/ExampleComboboxWithAs.tsx

Check the DummyDiv at the end of the file. I have to create a dummy div just to add some classes. It would be nice to just pass them to the Float component :

<Float className={'w-full'}> ... </Float>

// Instead of

const MyCustomDiv = ({ children }) => <div className={'w-full'}>{children}</div>;
<Float as={MyCustomDiv}> ... </Float>

JesusTheHun avatar Aug 08 '22 16:08 JesusTheHun

I think you're going to make a fullscreen Modal?

If that's the case, Headless UI Float is not suitable for such a thing. This package is a wrapper for Floating UI, the purpose is to create floating elements.

If you want to create a fullscreen Modal, it is recommended to use the Dialog / Modal component of Headless UI or other Modal packages.

ycs77 avatar Aug 08 '22 18:08 ycs77

No I'm not. I just want my option list to be the same width as my button. So I need to tell the float to take all the space available.

JesusTheHun avatar Aug 08 '22 18:08 JesusTheHun

You can use this to set the list to be the width same as the button.

First, you have to wrap the <Float> with a <div> containing the relative and the width class, set the as={Fragment} prop of <Float>, final set the options list and button width to full (w-full).

import { Fragment } from 'react'

<Listbox>
  <div className="relative w-[260px]">
    <Float placement="bottom" offset={4} as={Fragment}>
      <Listbox.Button className="w-full ...">
        ...
      </Listbox.Button>

      <Listbox.Options className="w-full ...">
        ...
      </Listbox.Options>
    </Float>
  </div>
</Listbox>

If you want to set the width as button self width, you can use the inline-block for the wrapper:

<Listbox>
  <div className="relative inline-block">
    <Float>...</Float>
  </div>
</Listbox>

Or wrap a flexbox out fo the <Listbox>:

<div className="flex items-center">
  <Listbox>
    <div className="relative">
      <Float>...</Float>
    </div>
  </Listbox>
</div>

Reference from Headless UI Listbox example: https://headlessui.com/react/listbox

ycs77 avatar Aug 09 '22 03:08 ycs77

Your example could work, if we didn't circle back to #16 . Using Fragment the position is messed up, in my case the position ignores the shift.

JesusTheHun avatar Aug 09 '22 09:08 JesusTheHun