Commit Graph

8 Commits

Author SHA1 Message Date
Robin Malfait 8c7cbb3b09 Add string shorthand for the anchor prop (#3133)
* allow to define `anchor` as a string. E.g.: `anchor="bottom"`

* use `--anchor-gap`, `--anchor-offset` and `--anchor-padding` variables by default

This way simply adding `anchor="bottom"` to one of the anchorable
components will also use these variables defined on the component.

* update playgrounds to use new string-based `anchor` prop

+ CSS variables

* update changelog
2024-04-25 02:13:25 +02:00
Robin Malfait 6c9e4b2b6f Allow passing a boolean to the anchor prop (#3121) 2024-04-22 23:42:58 +02:00
Robin Malfait b4cda76f91 Remove the anchor.strategy option (#3120)
* remove the `strategy` options, use "absolute" by default

Right now there is no good reason to expose the strategy, because the
default is good performance wise, and using `absolute` is fine because
we are portalled so there is no parent relative container to worry
about.

* update changelog
2024-04-22 17:05:30 +02:00
Robin Malfait 38551c8512 Ensure anchored components are always rendered in a stacking context (#3115)
* provide `floatingStyles` based on incoming `anchor` information

Before this change, we were only providing the `floatingStyles` based on
the `isEnabled` state. However, this relies on information that is only
available in the next render.

Now the styles are provided one render too late. This means, that there
will be a moment where the `ListboxOptions` (in case of a `Listbox`) is
rendered at the end of the page (and expanding the height of the parent)
without positioning it on top of it in a separate layer (due to the
`position: absolute;`)

The reason this was added was to prevent applying styles to the
`ListboxOptions` if it did not require anchoring (aka no `anchor={{…}}`
prop is provided).

Instead of relying on the `isEnabled` value (which is computed based on
information that is only available in the next render), we provide the
styles based on the incoming `anchor` information which is available
immediately.

The cool thing is that Floating UI is already providing a default
`position: absolute; top: 0; left: 0;` style. If we apply this, it's
already stacked instead of rendering at the end of the page.

* update changelog
2024-04-20 01:01:23 +02:00
Robin Malfait 888ea123a4 Use absolute as the default Floating UI strategy (#3097)
* set default anchor strategy to `absolute`

This is done for 2 reasons:

1. The default strategy in Floating UI was already `absolute`
2. It can improve performance drastically when using transitions

The main reason we used `fixed` was to ensure that it wasn't
accidentally positioned to another `relative` element. However, all
components that use this `FloatingProvider` will also use a portal which
puts elements in the `<body>` already so this should be safe.

If it is not safe for your application, then you can still use the
`fixed` strategy.

* update changelog
2024-04-15 17:43:34 +02:00
Robin Malfait ae8c253c21 Fix typos (#3086)
* fix a bunch of typos

* fix typos in `@headlessui/vue`
2024-04-08 23:31:50 +02:00
Robin Malfait 8a9867cd58 Accept optional strategy for the anchor prop (#3034)
* accept `strategy` for the `anchor` prop

* update changelog
2024-03-14 22:16:56 +01:00
Robin Malfait e662f12398 2.0.0 Alpha prep (#2887)
* bump React & React DOM dependencies

* fix typo `TOmitableProps` → `TOmittableProps`

* bump prettier

* run prettier after prettier version bump

* bump TypeScript

* run prettier after TypeScript version bump

* enable `verbatimModuleSyntax`

This ensures all imported types are using the `type` keyword.

* add `type` to type related imports

* add common testing scenarios

Will be used in the new and existing components.

* add script to make Next.js happy

Right now Next.js does barrel file optimization and re-writing imports
to a real path in the `dist` folder. Most of those rewrites don't
actually exist because they have an assumption:

```js
import { FooBar } from '@headlessui/react'
```

is rewritten as:
```js
import { FooBar } from '@headlessui/react/dist/components/foo-bar/foo-bar'
```

This script will make sure these paths exist...

* improve `by` prop, introduce `useByComparator`

This hook has a default implementation when comparing objects. If the
object contains an `id`, then we will compare the objects by their
`id`'s without the user of the library needing to specify `by="id"`.

If the objects don't have an `id` prop, then the default is still to
compare by reference (unless specicified otherwise).

* sync yarn.lock

* rename `Features` to `HiddenFeatures` for `Hidden` component

* rename `Features` to `FocusTrapFeatures` in `FocusTrap` component

* rename `Features` to `RenderFeatures` in `render` util

* add `floating-ui` as a dependency + introduce internal floating related components

* bump Vue dependencies

* ensure scroll bar calculations can't go negative

* improve types in `@headlessui/vue`

* use snapshot tests for `Transition` tests in `@headlessui/vue`

* use snapshot tests for `portal` tests in `@headlessui/vue`

* rename `src/components/transitions/` to `src/components/transition/` (singular)

This is so that we can be consistent with the other components.

* drop custom `toMatchFormattedCss`, prefer snapshot tests instead

* use snapshot tests for `Label` tests in `@headlessui/vue`

* use snapshot tests for `Description` tests in `@headlessui/vue`

* sort exported components in tests for `@headlessui/vue`

* use snapshot tests in `@headlessui/tailwindcss`

* rename `mergeProps` to `mergePropsAdvanced`

This is a more complex version of a soon to be exported `mergeProps`
that we will be using in our components.

* do not expose `aria-labelledby` if it is only referencing itself

* expose boolean state as `kebab-case` instead of `camelCase`

These are the ones being exposed inside `data-headlessui-state="..."`

* expose boolean data attributes

A slot with `{active,focus,hover}` will be exposed as:
```html
<span data-headlessui-state="active focus hover"></span>
```

But also as boolean attributes:
```html
<span data-active data-focus data-hover></span>
```

* improve internal types for `className` in `render` util

* ensure we keep exposed data attributes into account when trying to forward them to the component inside the `Fragment`

* add small typescript type fix

This is internal code, and the public API is not influenced by this
`:any`. It does make TypeScript happy.

* introduce `mergeProps` util to be used in our components

This will help us to merge props, when event handlers are available they
will be merged by wrapping them in a function such that both (or more)
event handlers are called for the same `event`.

* add new internal `Modal` component

* fix: when using `Focus.Previous` with `activeIndex = -1` should start at the end

* prefer `window.scrollY` instead of `window.pageYOffset`

Because `window.pageYOffset` is deprecated.

* add `'use client'` directives on client only components

These components use hooks that won't work in server components and you
will receive an error otherwise.

* drop `import 'client-only'` in favor of the `'use client'` directive

* add React Aria dependencies

* pin beta dependencies

* prettier bump formatting

* improve TypeScript types in tests

* use new Jest matchers instead of deprecated ones

* improve typescript types in Vue

* prefer `useLabelledBy` and `useDescribedBy`

* add internal `DisabledProvider`

* add internal `IdProvider`

* add internal `useDidElementMove` hook

* add internal `useElementSize` hook

* add internal `useIsTouchDevice` hook

* add internal `useActivePress` hook

* use snapshot tests for `Description` tests

* use snapshot tests for `Label` tests

* use snapshot tests for `Portal` tests

* use snapshot tests for `render` tests

* add (private) `Tooltip` component

Currently this one is not ready yet, so its not publicly exposed yet.

* add internal `FormFields` component

This one adds a component to render (hidden) inputs for native form
support. It also ensures that form fields can be hoisted to the end of
the nearest `Field`. If the components are not inside a `Field` they
will be rendered in place.

* add new `Button` component

* add new `Checkbox` component

* add new `DataInteractive` component

* add new `Field` component

* add new `Fieldset` component

* add new `Legend` component

* add new `Input` component

* add new `Select` component

* add new `Textarea` component

* export new components

* WIP

* remove `within: true`

This only makes sense if anything inside the current element receives
focus, which is not the case for `input`, `select`, `textarea` or
`Radio/RadioOption`.

* group focus/hover/active hooks together

* conditionally link anchor panel

* immediately focus the container

* prevent premature disabling of `Listbox`'s floating integration

+ Track whether the button moved or not when disabling such that we can
  disable the transitions earlier.

* improve scroll locking on iOS

* skip hydration tests for now

* skip certain focus trap tests for now

* update CHANGELOG.md

* add missing requires

* drop unused `@ts-expect-error`

* ignore type issues in playgrounds

These playgrounds are mainly test playgrounds. Lower priority for now,
we will get back to them.

* add yarn resolutions to solve swc bug
2023-12-20 19:57:57 +01:00