)}
);
diff --git a/website/package-lock.json b/website/package-lock.json
index 0349f8746e..62aa752bfc 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -12,7 +12,7 @@
"dependencies": {
"@docsearch/css": "^3.1.0",
"@docsearch/react": "^3.1.0",
- "@floating-ui/react": "^0.20.1",
+ "@floating-ui/react": "^0.21.0",
"@mdx-js/loader": "^2.1.1",
"@mdx-js/react": "^2.1.1",
"@next/mdx": "^12.1.5",
@@ -27,6 +27,7 @@
"rehype-pretty-code": "^0.9.4",
"remark-smartypants": "^2.0.0",
"shiki": "^0.12.1",
+ "tailwind-merge": "^1.10.0",
"unist-util-visit": "^2.0.3",
"use-isomorphic-layout-effect": "^1.1.1"
},
@@ -1892,9 +1893,9 @@
}
},
"node_modules/@floating-ui/react": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.20.1.tgz",
- "integrity": "sha512-JHTHJ+/YsIxNFH8uJDFa5OyI6dSUZcle6wAFe0zRTjgWD+rkACfBBoJtx2itTtn7C4a7xAz4jgxdEQcMel194g==",
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.21.0.tgz",
+ "integrity": "sha512-4Zut7tjeDVEKHaR6N3uG4m1dl114UkLuK4SNAeHlAb4pKu5KEkMkI34Y8NmCc4ARfXIu25UGUhYBUzShDhbofA==",
"dependencies": {
"@floating-ui/react-dom": "^1.3.0",
"aria-hidden": "^1.1.3",
@@ -7379,6 +7380,11 @@
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.1.tgz",
"integrity": "sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg=="
},
+ "node_modules/tailwind-merge": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.10.0.tgz",
+ "integrity": "sha512-WFnDXSS4kFTZwjKg5/oZSGzBRU/l+qcbv5NVTzLUQvJ9yovDAP05h0F2+ZFW0Lw9EcgRoc2AfURUdZvnEFrXKg=="
+ },
"node_modules/tailwindcss": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz",
@@ -9437,9 +9443,9 @@
}
},
"@floating-ui/react": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.20.1.tgz",
- "integrity": "sha512-JHTHJ+/YsIxNFH8uJDFa5OyI6dSUZcle6wAFe0zRTjgWD+rkACfBBoJtx2itTtn7C4a7xAz4jgxdEQcMel194g==",
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.21.0.tgz",
+ "integrity": "sha512-4Zut7tjeDVEKHaR6N3uG4m1dl114UkLuK4SNAeHlAb4pKu5KEkMkI34Y8NmCc4ARfXIu25UGUhYBUzShDhbofA==",
"requires": {
"@floating-ui/react-dom": "^1.3.0",
"aria-hidden": "^1.1.3",
@@ -13253,6 +13259,11 @@
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.1.tgz",
"integrity": "sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg=="
},
+ "tailwind-merge": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.10.0.tgz",
+ "integrity": "sha512-WFnDXSS4kFTZwjKg5/oZSGzBRU/l+qcbv5NVTzLUQvJ9yovDAP05h0F2+ZFW0Lw9EcgRoc2AfURUdZvnEFrXKg=="
+ },
"tailwindcss": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz",
diff --git a/website/package.json b/website/package.json
index 7285a08333..aea5a9daeb 100644
--- a/website/package.json
+++ b/website/package.json
@@ -30,7 +30,7 @@
"dependencies": {
"@docsearch/css": "^3.1.0",
"@docsearch/react": "^3.1.0",
- "@floating-ui/react": "^0.20.1",
+ "@floating-ui/react": "^0.21.0",
"@mdx-js/loader": "^2.1.1",
"@mdx-js/react": "^2.1.1",
"@next/mdx": "^12.1.5",
@@ -45,6 +45,7 @@
"rehype-pretty-code": "^0.9.4",
"remark-smartypants": "^2.0.0",
"shiki": "^0.12.1",
+ "tailwind-merge": "^1.10.0",
"unist-util-visit": "^2.0.3",
"use-isomorphic-layout-effect": "^1.1.1"
}
diff --git a/website/pages/docs/FloatingArrow.mdx b/website/pages/docs/FloatingArrow.mdx
index 82da88b8d5..20feae400e 100644
--- a/website/pages/docs/FloatingArrow.mdx
+++ b/website/pages/docs/FloatingArrow.mdx
@@ -196,7 +196,8 @@ The color of the arrow.
default: `"none"{:js}`
-The stroke (border) color of the arrow.
+The stroke (border) color of the arrow. This must match (or be
+less than) the floating element's border width.
```js
diff --git a/website/pages/docs/react.mdx b/website/pages/docs/react.mdx
index 94cd93dafa..3ac70a1b35 100644
--- a/website/pages/docs/react.mdx
+++ b/website/pages/docs/react.mdx
@@ -8,24 +8,17 @@ This allows you to create components such as tooltips, popovers,
dropdown menus, hover cards, modal dialogs, select menus,
comboboxes, and more.
-## Library goals
-
-The goal of this library is to provide **building blocks** to
-create your own floating UI components, handling difficult parts
-like accessibility and positioning for you, but not offering
-pre-built components. In theory, this allows you to build any
-type of component you desire, since you can add your own custom
-logic on top.
-
-If you're looking for flexibility and are comfortable building
-your own components, this library is hopefully what you're
-looking for. If instead, you're looking for something simpler and
-ready-made, you will likely find other libraries better suited
-for your use case. React component libraries that use Floating UI
-behind the scenes for positioning include
-[Radix UI](https://www.radix-ui.com/),
-[Mantine](https://mantine.dev/), [Ariakit](https://ariakit.org/),
-among others.
+## Goals
+
+- **Provide building blocks to create your own floating UI
+ components**: pre-built components aren't exported, rather the
+ primitives necessary to create them.
+- **Accessibility-first mindset**: the building blocks ensure
+ accessible user experiences and work with assistive technology.
+- **Low-level, extremely configurable and flexible**: At the cost
+ of more code to setup, you get high control and flexibility, so
+ you can create "bespoke" and complex floating elements you
+ won't find in most component libraries.
## Install
@@ -43,13 +36,6 @@ and uses this one as a dependency.
npm install @floating-ui/react-dom
```
-This documentation refers to the latest version of the library.
-If you find a feature is missing locally, make sure you have
-upgraded to the latest version:
-
-- [Latest `@floating-ui/react` versions](https://www.npmjs.com/package/@floating-ui/react?activeTab=versions)
-- [Latest `@floating-ui/react-dom` versions](https://www.npmjs.com/package/@floating-ui/react-dom?activeTab=versions)
-
## Usage
There are two main parts to creating floating elements:
diff --git a/website/pages/docs/useClientPoint.mdx b/website/pages/docs/useClientPoint.mdx
new file mode 100644
index 0000000000..763c9b81fe
--- /dev/null
+++ b/website/pages/docs/useClientPoint.mdx
@@ -0,0 +1,135 @@
+# useClientPoint
+
+Positions the floating element at a given client point `(x, y)`,
+usually generated by a mouse event. By default, the client's
+mouse position is automatically tracked.
+
+```js
+import {useClientPoint} from '@floating-ui/react';
+```
+
+## Usage
+
+This hook is an interaction hook that returns event handler
+props.
+
+To use it, pass it the `context{:.const}` object returned from
+`useFloating(){:js}`, and then feed its result into the
+`useInteractions(){:js}` array. The returned prop getters are
+then spread onto the elements for rendering.
+
+```js {9-13} /context/
+function App() {
+ const [isOpen, setIsOpen] = useState(false);
+
+ const {x, y, strategy, refs, context} = useFloating({
+ open: isOpen,
+ onOpenChange: setIsOpen,
+ });
+
+ const clientPoint = useClientPoint(context);
+
+ const {getReferenceProps, getFloatingProps} = useInteractions([
+ clientPoint,
+ ]);
+
+ return (
+ <>
+
+ Reference element
+
+ {isOpen && (
+
+ Floating element
+
+ )}
+ >
+ );
+}
+```
+
+The default behavior is to follow the mouse cursor `clientX` and
+`clientY` coordinates.
+
+## Pointer events
+
+If the floating element is not interactive, disable pointer
+events:
+
+```css
+.floating {
+ pointer-events: none;
+}
+```
+
+This will ensure that the floating element does not block point
+updates.
+
+## Props
+
+```ts
+interface Props {
+ enabled?: boolean;
+ axis?: 'both' | 'x' | 'y';
+ x?: number | null;
+ y?: number | null;
+}
+```
+
+### enabled
+
+default: `true{:js}`
+
+Conditionally enable/disable the hook.
+
+```js
+useClientPoint(context, {
+ enabled: false,
+});
+```
+
+### axis
+
+default: `'both'{:js}`
+
+Whether to restrict the client point to an axis and use the
+reference element (if it exists) as the other axis. This can be
+useful if the floating element is also interactive.
+
+```js
+useClientPoint(context, {
+ axis: 'x',
+});
+```
+
+### x
+
+default: `null{:js}`
+
+An explicitly defined `x` client coordinate.
+
+```js
+useClientPoint(context, {
+ x: 100,
+});
+```
+
+### y
+
+default: `null{:js}`
+
+An explicitly defined `y` client coordinate.
+
+```js
+useClientPoint(context, {
+ y: 100,
+});
+```
diff --git a/website/pages/docs/useDismiss.mdx b/website/pages/docs/useDismiss.mdx
index d10bf3e1b4..b2a0f2b577 100644
--- a/website/pages/docs/useDismiss.mdx
+++ b/website/pages/docs/useDismiss.mdx
@@ -217,7 +217,7 @@ useDismiss(context, {
### bubbles
-default: `true{:js}`
+default: `undefined{:js}`
When dealing with nested floating elements, this determines
whether the dismissal bubbles through the entire
@@ -244,9 +244,8 @@ Any omitted events will use the default value.
```js
useDismiss(context, {
bubbles: {
- escapeKey: false,
- // can be omitted, same as default
- outsidePress: true,
+ escapeKey: true, // false by default
+ outsidePress: false, // true by default
},
});
```
diff --git a/website/pages/docs/useTypeahead.mdx b/website/pages/docs/useTypeahead.mdx
index a237d98fe3..9da5f80373 100644
--- a/website/pages/docs/useTypeahead.mdx
+++ b/website/pages/docs/useTypeahead.mdx
@@ -89,6 +89,7 @@ interface Props {
resetMs?: number;
ignoreKeys?: Array;
selectedIndex?: number | null;
+ onTypingChange?: (isTyping) => void;
}
```
@@ -193,7 +194,7 @@ useTypeahead(context, {
### resetMs
-default: `1000{:js}`
+default: `750{:js}`
Debounce timeout which will reset the transient string as the
user types.
@@ -230,11 +231,16 @@ useTypeahead(context, {
});
```
-## Data
+### onTypingChange
-### typing
+default: no-op
+
+Callback invoked with the typing state as the user types.
-This hook sets `context.dataRef.current.typing = boolean{:js}` to
-determine if the user is currently typing. If a select option
-needs to be selected with `Space`, but the typeahead also allows
-spaces, this can be used to conditionally run the handler.
+```js
+useTypeahead(context, {
+ onTypingChange(isTyping) {
+ // ...
+ },
+});
+```
diff --git a/website/pages/index.js b/website/pages/index.js
index cc1931303e..55ef0cdedd 100644
--- a/website/pages/index.js
+++ b/website/pages/index.js
@@ -1,11 +1,40 @@
import {
+ autoUpdate,
+ flip,
+ FloatingDelayGroup,
+ FloatingFocusManager,
+ FloatingNode,
+ FloatingPortal,
+ FloatingTree,
getOverflowAncestors,
+ offset,
+ safePolygon,
shift,
+ size,
+ useClick,
+ useDismiss,
useFloating,
+ useFloatingNodeId,
+ useFloatingParentNodeId,
+ useFloatingTree,
+ useHover,
+ useInteractions,
+ useListNavigation,
+ useMergeRefs,
+ useRole,
+ useTransitionStyles,
+ useTypeahead,
} from '@floating-ui/react';
+import classNames from 'classnames';
import cn from 'classnames';
import Head from 'next/head';
import Link from 'next/link';
+import {
+ Children,
+ cloneElement,
+ isValidElement,
+ useId,
+} from 'react';
import {
forwardRef,
useCallback,
@@ -13,16 +42,40 @@ import {
useRef,
useState,
} from 'react';
-import {ArrowRight, GitHub} from 'react-feather';
+import {
+ ArrowRight,
+ BarChart,
+ Check,
+ ChevronRight,
+ Edit,
+ GitHub,
+ Heart,
+ Share,
+} from 'react-feather';
import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';
import Logo from '../assets/logo.svg';
import Text from '../assets/text.svg';
import {MINI_SPONSORS, SPONSORS} from '../data';
+import {Button} from '../lib/components/Button';
import {Cards} from '../lib/components/Cards';
import {Chrome} from '../lib/components/Chrome';
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogHeading,
+ DialogTrigger,
+} from '../lib/components/Dialog';
import {Floating} from '../lib/components/Floating';
import {Logos} from '../lib/components/Logos';
+import {
+ Popover,
+ PopoverClose,
+ PopoverContent,
+ PopoverTrigger,
+} from '../lib/components/Popover';
import {
Tooltip,
TooltipContent,
@@ -509,6 +562,831 @@ function Virtual() {
);
}
+function PopoverDemo() {
+ const [isOpen, setIsOpen] = useState(false);
+ const [name, setName] = useState('Balloon name');
+ const [editName, setEditName] = useState(name);
+
+ return (
+
+ A JavaScript library to{' '}
+ position and
+ create{' '}
+ interactions{' '}
+ for{' '}
- floating element
+ floating elements
@@ -613,14 +1490,22 @@ function HomePage() {
flow of content, like this one!
- {' '}
- next to another element while making sure it stays in
- view optimally. This lets you position tooltips,
- popovers, or dropdowns to efficiently float on top of
- the UI!
+
+
+
+
+
+
+
+ Advanced anchor positioning.
+
+
+ Anchor a floating element next to another element
+ while making sure it stays in view by{' '}
+ avoiding collisions. This lets you
+ position tooltips, popovers, or dropdowns optimally.
-
@@ -630,9 +1515,209 @@ function HomePage() {
+
+
+ Interactions for React.
+
+
+ Build your own floating UI components with React.
+ From simple tooltips to select menus, you have full
+ control while ensuring{' '}
+ fully accessible UI experiences.
+
+
+
+
+
+
+
+
+ Tooltips
+
+
+ Floating elements that display information
+ related to an anchor element on hover or focus.
+
+ Floating elements that display an anchored
+ interactive dialog on click.
+
+
+
+
+
+
+
+
+
+
+
+
+ Select Menus
+
+
+ Floating elements that display a list of
+ options to choose from on click.
+
+
+
+
+
+
+
+
+
+
+
+
+ Comboboxes
+
+
+ Floating elements that combine an input and a
+ list of searchable options to choose from.
+
+
+
+
+
+
+
+
+
+
+
+
+ Dropdown Menus
+
+
+ Floating elements that display a list of
+ buttons that perform an action.
+
+
+
+
+
+
+
+
+
+
+
+
+ Dialogs
+
+
+ A floating modal window overlaid on the UI,
+ rendering the content underneath inert.
+
+
+
+
+
+
+
+
+
+
+
+ Use Floating UI with React{' '}
+
+
+
+
-
- Light as a feather.
+
+ Modern, tree-shakeable modules.
This positioning toolkit has a platform-agnostic 0.6
@@ -704,31 +1789,6 @@ function HomePage() {
-
-
- Interactions for React.
-
-
- In addition to positioning, there are also
- interaction primitives to build floating UI
- components with React. This includes event hooks for
- hover, focus or click, modal and non-modal focus
- management, keyboard list navigation, typeahead,
- portals, backdrop overlays, screen reader support,
- and more.
-