├── .nvmrc ├── .yarnclean ├── packages ├── alert │ ├── types │ │ └── index.d.ts │ ├── package.json │ └── README.md ├── alert-dialog │ ├── types │ │ └── index.d.ts │ ├── package.json │ └── examples │ │ ├── basic.example.js │ │ └── basic-ts.example.tsx ├── menu-button │ ├── examples │ │ ├── pete-older.png │ │ ├── pete-younger.png │ │ ├── animate.css │ │ ├── basic.example.js │ │ ├── basic.example.tsx │ │ ├── no-portal.example.js │ │ ├── animated.example.js │ │ ├── basic-strict-mode.example.js │ │ ├── with-tooltip.example.js │ │ ├── with-render-props.example.js │ │ ├── render-prop.example.js │ │ ├── custom-wrapper.example.js │ │ ├── custom-wrapper.example.tsx │ │ ├── with-other-tabbables.example.js │ │ ├── with-disabled-items.example.js │ │ ├── with-usemenubuttoncontext-hook.example.tsx │ │ └── long-text.example.js │ ├── package.json │ └── README.md ├── accordion │ ├── styles.css │ ├── README.md │ └── package.json ├── tooltip │ ├── styles.css │ ├── package.json │ ├── examples │ │ ├── basic.example.js │ │ ├── basic.example.tsx │ │ ├── with-as-prop.example.js │ │ ├── with-dialog.example.js │ │ └── with-dialog.example.tsx │ └── README.md ├── disclosure │ ├── README.md │ ├── examples │ │ ├── basic.example.js │ │ ├── basic-ts.example.tsx │ │ ├── controlled.example.js │ │ └── controlled-ts.example.tsx │ └── package.json ├── visually-hidden │ ├── examples │ │ ├── basic.example.tsx │ │ ├── basic.example.js │ │ └── with-as-prop.example.tsx │ ├── package.json │ ├── README.md │ └── __tests__ │ │ └── visually-hidden.test.tsx ├── window-size │ ├── examples │ │ ├── basic.example.js │ │ ├── basic.example.tsx │ │ └── hook.example.js │ ├── README.md │ └── package.json ├── slider │ ├── examples │ │ ├── contained-handle.example.js │ │ ├── examples.css │ │ ├── basic.example.tsx │ │ ├── vertical.example.js │ │ ├── vertical.example.tsx │ │ ├── basic.example.js │ │ ├── with-steps.example.js │ │ ├── with-steps.example.tsx │ │ └── controlled-audio-progress.example.js │ ├── package.json │ └── README.md ├── utils │ ├── README.md │ ├── __tests__ │ │ └── utils.test.tsx │ └── package.json ├── machine │ ├── README.md │ └── package.json ├── checkbox │ ├── README.md │ ├── src │ │ └── index.tsx │ ├── examples │ │ ├── hook.example.tsx │ │ ├── custom-pseudo.example.js │ │ └── basic-mixed.example.js │ ├── styles.css │ └── package.json ├── skip-nav │ ├── styles.css │ ├── package.json │ ├── examples │ │ ├── basic.example.js │ │ └── with-custom-id.example.js │ └── README.md ├── dialog │ ├── styles.css │ ├── examples │ │ ├── autofocus-ts.example.tsx │ │ ├── basic-ts.example.tsx │ │ ├── no-tabbables.example.js │ │ ├── dismiss.example.js │ │ ├── basic.example.js │ │ ├── long-content.example.js │ │ ├── with-tooltip.example.js │ │ ├── dropdown.example.js │ │ ├── with-dialog-overlay.example.js │ │ ├── nested.example.js │ │ ├── destroy-trigger.example.js │ │ ├── aria-hides-content.example.js │ │ └── autofocus.example.js │ ├── package.json │ └── README.md ├── portal │ ├── README.md │ ├── package.json │ └── examples │ │ ├── basic.example.js │ │ └── basic.example.tsx ├── component-component │ ├── examples │ │ └── state.example.js │ ├── package.json │ └── README.md ├── combobox │ ├── styles.css │ ├── package.json │ ├── examples │ │ ├── utils.ts │ │ ├── with-button.example.js │ │ └── basic.example.js │ └── README.md ├── auto-id │ ├── package.json │ ├── README.md │ └── __tests__ │ │ └── auto-id.test.tsx ├── descendants │ └── package.json ├── rect │ ├── package.json │ ├── examples │ │ ├── basic-use-rect.example.js │ │ ├── basic.example.js │ │ ├── basic.example.tsx │ │ ├── change-observed-ref.example.tsx │ │ └── pin-use-rect.example.js │ └── README.md ├── tabs │ ├── styles.css │ ├── examples │ │ ├── basic.example.js │ │ ├── manual-activation.example.js │ │ ├── basic.example.tsx │ │ ├── rtl-direction.example.tsx │ │ ├── disabled.example.js │ │ ├── basic-strict-mode.example.js │ │ ├── vertical-rtl.example.tsx │ │ ├── vertical.example.js │ │ ├── rtl-html.example.tsx │ │ ├── with-render-props.example.js │ │ ├── with-arbitrary-elements.example.tsx │ │ ├── controlled.example.js │ │ └── controlled.example.tsx │ ├── package.json │ └── README.md ├── popover │ ├── README.md │ ├── package.json │ └── examples │ │ ├── basic.example.js │ │ ├── basic.example.tsx │ │ ├── hidden.example.js │ │ └── hidden.example.tsx └── listbox │ ├── package.json │ ├── examples │ ├── common.tsx │ ├── basic.example.js │ ├── basic-strict-mode.example.tsx │ └── controlled.example.tsx │ └── README.md ├── .prettierignore ├── website-deploy-key.enc ├── .codesandbox ├── ci.json └── templates │ └── reach-ui │ ├── src │ ├── examples │ │ ├── menu-button │ │ │ ├── index.js │ │ │ └── basic.js │ │ └── index.js │ ├── reach-styles.js │ ├── CurrentState.js │ ├── index.js │ └── styles.css │ └── package.json ├── website ├── src │ ├── images │ │ └── reach-icon.png │ ├── components │ │ ├── Pipe.js │ │ ├── Note.js │ │ ├── SVG.js │ │ ├── Note.module.scss │ │ ├── AsPropWarning.js │ │ ├── TOC.js │ │ ├── MatchMedia.js │ │ ├── SEO.js │ │ └── createMediaListener.js │ ├── pages │ │ ├── 404.js │ │ ├── funding.mdx │ │ ├── index.mdx │ │ └── auto-id.mdx │ └── styles │ │ └── root.scss ├── postcss.config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── gatsby-browser.js └── static │ └── router │ └── static │ └── js │ ├── 9.e7cbaa3d.chunk.js │ ├── 8.ce712278.chunk.js │ ├── 0.94cd3f75.chunk.js │ ├── vendor.f4d1301c.js │ ├── 26.f55ae2ec.chunk.js │ └── 27.0815c9fd.chunk.js ├── .storybook ├── manager.js ├── styles.css ├── preview.js └── main.js ├── .github ├── ISSUE_TEMPLATE │ ├── Documentation.md │ ├── Question.md │ ├── Feature_request.md │ └── Bug_report.md ├── FUNDING.yml ├── stale.yml └── PULL_REQUEST_TEMPLATE.md ├── types ├── rollup-plugin-babel │ └── index.d.ts ├── jest.d.ts ├── @babel │ └── index.d.ts ├── index.d.ts └── @reach │ └── index.d.ts ├── lerna.json ├── scripts ├── constants.ts ├── build-all.ts ├── deploy-website.sh ├── build-package.ts ├── config │ └── jest.ts ├── types.ts └── test.ts ├── .gitignore ├── test ├── types.ts └── setupTests.ts ├── LICENSE └── .travis.yml /.nvmrc: -------------------------------------------------------------------------------- 1 | 14 2 | -------------------------------------------------------------------------------- /.yarnclean: -------------------------------------------------------------------------------- 1 | @types/react-native 2 | -------------------------------------------------------------------------------- /packages/alert/types/index.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | -------------------------------------------------------------------------------- /packages/alert-dialog/types/index.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.yml 2 | node_modules 3 | packages/*/dist 4 | website/static 5 | -------------------------------------------------------------------------------- /website-deploy-key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/reach-ui/develop/website-deploy-key.enc -------------------------------------------------------------------------------- /.codesandbox/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildCommand": "build", 3 | "sandboxes": ["/.codesandbox/templates/reach-ui"] 4 | } 5 | -------------------------------------------------------------------------------- /website/src/images/reach-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/reach-ui/develop/website/src/images/reach-icon.png -------------------------------------------------------------------------------- /.codesandbox/templates/reach-ui/src/examples/menu-button/index.js: -------------------------------------------------------------------------------- 1 | import Basic from "./basic"; 2 | 3 | export { Basic }; 4 | -------------------------------------------------------------------------------- /website/src/components/Pipe.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export function Pipe() { 4 | return <>|; 5 | } 6 | -------------------------------------------------------------------------------- /.storybook/manager.js: -------------------------------------------------------------------------------- 1 | import { addons } from "@storybook/addons"; 2 | 3 | addons.setConfig({ 4 | enableShortcuts: false, 5 | }); 6 | -------------------------------------------------------------------------------- /packages/menu-button/examples/pete-older.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/reach-ui/develop/packages/menu-button/examples/pete-older.png -------------------------------------------------------------------------------- /packages/menu-button/examples/pete-younger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/reach-ui/develop/packages/menu-button/examples/pete-younger.png -------------------------------------------------------------------------------- /website/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = () => ({ 2 | plugins: [ 3 | require(`postcss-preset-env`)({ 4 | stage: 2 5 | }) 6 | ] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/accordion/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --reach-accordion: 1; 3 | } 4 | 5 | [data-reach-accordion-button][disabled] { 6 | cursor: not-allowed; 7 | } 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41B Documentation" 3 | about: Suggestions for Reach UI documentation 4 | --- 5 | 6 | ## 📖 Documentation 7 | -------------------------------------------------------------------------------- /types/rollup-plugin-babel/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module "rollup-plugin-babel" { 2 | export function custom(arg: any): any; 3 | let def: { custom: typeof custom }; 4 | export default def; 5 | } 6 | -------------------------------------------------------------------------------- /types/jest.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace jest { 2 | interface Matchers { 3 | toHaveNoViolations(): CustomMatcherResult; 4 | toHaveNoAxeViolations(): Promise; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /website/gatsby-node.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's Node APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/node-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.12.1", 3 | "registry": "https://registry.npmjs.org/", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "npmClient": "yarn", 8 | "useWorkspaces": true 9 | } 10 | -------------------------------------------------------------------------------- /website/gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/ssr-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | -------------------------------------------------------------------------------- /types/@babel/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module "@babel/core" { 2 | // @see line 226 of https://unpkg.com/@babel/core@7.4.4/lib/index.js 3 | export const DEFAULT_EXTENSIONS: string[]; 4 | export function createConfigItem(boop: any[], options: any): void; 5 | } 6 | -------------------------------------------------------------------------------- /website/src/components/Note.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import cx from "clsx"; 3 | import styles from "./Note.module.scss"; 4 | 5 | export function Note(props) { 6 | return
; 7 | } 8 | -------------------------------------------------------------------------------- /.codesandbox/templates/reach-ui/src/reach-styles.js: -------------------------------------------------------------------------------- 1 | import "@reach/combobox/styles.css"; 2 | import "@reach/dialog/styles.css"; 3 | import "@reach/menu-button/styles.css"; 4 | import "@reach/skip-nav/styles.css"; 5 | import "@reach/tabs/styles.css"; 6 | import "@reach/tooltip/styles.css"; 7 | -------------------------------------------------------------------------------- /website/src/components/SVG.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | function SVG({ children, title, ...props }) { 4 | return ( 5 | 6 | {title && {title}} 7 | {children} 8 | 9 | ); 10 | } 11 | 12 | export default SVG; 13 | -------------------------------------------------------------------------------- /website/src/pages/404.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Layout from "../components/Layout"; 3 | 4 | const NotFoundPage = () => ( 5 | 6 |

NOT FOUND

7 |

You just hit a route that doesn't exist... the sadness.

8 |
9 | ); 10 | 11 | export default NotFoundPage; 12 | -------------------------------------------------------------------------------- /website/src/components/Note.module.scss: -------------------------------------------------------------------------------- 1 | @import "../styles/root.scss"; 2 | 3 | .Note { 4 | background: $color-primary-xlight; 5 | display: block; 6 | padding: 2rem; 7 | margin: 1rem 1rem 2.5rem; 8 | 9 | :first-child { 10 | margin-top: 0; 11 | } 12 | 13 | :last-child { 14 | margin-bottom: 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.storybook/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, 4 | Ubuntu, Cantarell, Helvetica Neue, sans-serif; 5 | } 6 | 7 | :focus:not(:focus-visible) { 8 | outline: none; 9 | } 10 | 11 | * { 12 | box-sizing: border-box; 13 | } 14 | 15 | #root { 16 | margin: 0.5rem; 17 | } 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "❓Question" 3 | about: "For usage questions, please use Stack Overflow or Reactiflux!" 4 | --- 5 | 6 | ## ❓Question 7 | 8 | Were are working on getting a dedicated channel on [Reactiflux](https://www.reactiflux.com/), but you can still post questions there under one of the `need-help` or `libraries` channels in the mean time. 9 | -------------------------------------------------------------------------------- /packages/menu-button/examples/animate.css: -------------------------------------------------------------------------------- 1 | @keyframes slide-down { 2 | 0% { 3 | opacity: 0; 4 | transform: translateY(-10px); 5 | } 6 | 100% { 7 | opacity: 1; 8 | transform: translateY(0); 9 | } 10 | } 11 | 12 | .slide-down[data-reach-menu-list], 13 | .slide-down[data-reach-menu-items] { 14 | border-radius: 5px; 15 | animation: slide-down 0.2s ease; 16 | } 17 | -------------------------------------------------------------------------------- /packages/tooltip/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --reach-tooltip: 1; 3 | } 4 | 5 | [data-reach-tooltip] { 6 | z-index: 1; 7 | pointer-events: none; 8 | position: absolute; 9 | padding: 0.25em 0.5em; 10 | box-shadow: 2px 2px 10px hsla(0, 0%, 0%, 0.1); 11 | white-space: nowrap; 12 | font-size: 85%; 13 | background: #f0f0f0; 14 | color: #444; 15 | border: solid 1px #ccc; 16 | } 17 | -------------------------------------------------------------------------------- /packages/accordion/README.md: -------------------------------------------------------------------------------- 1 | # @reach/accordion 2 | 3 | [![Stable release](https://img.shields.io/npm/v/@reach/accordion.svg)](https://npm.im/@reach/accordion) ![MIT license](https://badgen.now.sh/badge/license/MIT) 4 | 5 | [Docs](https://reach.tech/accordion) | [Source](https://github.com/reach/reach-ui/tree/main/packages/accordion) | [WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.2/#accordion) 6 | -------------------------------------------------------------------------------- /packages/disclosure/README.md: -------------------------------------------------------------------------------- 1 | # @reach/disclosure 2 | 3 | [![Stable release](https://img.shields.io/npm/v/@reach/disclosure.svg)](https://npm.im/@reach/disclosure) ![MIT license](https://badgen.now.sh/badge/license/MIT) 4 | 5 | [Docs](https://reach.tech/disclosure) | [Source](https://github.com/reach/reach-ui/tree/main/packages/disclosure) | [WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.2/#disclosure) 6 | -------------------------------------------------------------------------------- /packages/visually-hidden/examples/basic.example.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import VisuallyHidden from "@reach/visually-hidden"; 3 | 4 | let name = "As a div (TS)"; 5 | 6 | function Example() { 7 | return Hidden Message; 8 | } 9 | 10 | Example.story = { name }; 11 | export const Comp = Example; 12 | export default { title: "VisuallyHidden" }; 13 | -------------------------------------------------------------------------------- /packages/window-size/examples/basic.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import WindowSize from "@reach/window-size"; 3 | 4 | let name = "Basic"; 5 | 6 | function Example() { 7 | return ( 8 | 9 | {(sizes) =>
Window size: {JSON.stringify(sizes, null, 2)}
} 10 |
11 | ); 12 | } 13 | 14 | Example.story = { name }; 15 | export const Comp = Example; 16 | export default { title: "WindowSize" }; 17 | -------------------------------------------------------------------------------- /packages/slider/examples/contained-handle.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Slider, SLIDER_HANDLE_ALIGN_CONTAIN } from "@reach/slider"; 3 | import "@reach/slider/styles.css"; 4 | 5 | let name = "Contained Handle"; 6 | 7 | function Example() { 8 | return ; 9 | } 10 | 11 | Example.story = { name }; 12 | export const Comp = Example; 13 | export default { title: "Slider" }; 14 | -------------------------------------------------------------------------------- /packages/window-size/examples/basic.example.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import WindowSize from "@reach/window-size"; 3 | 4 | let name = "Basic (TS)"; 5 | 6 | function Example() { 7 | return ( 8 | 9 | {(sizes) =>
Window size: {JSON.stringify(sizes, null, 2)}
} 10 |
11 | ); 12 | } 13 | 14 | Example.story = { name }; 15 | export const Comp = Example; 16 | export default { title: "WindowSize" }; 17 | -------------------------------------------------------------------------------- /packages/window-size/examples/hook.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { useWindowSize } from "@reach/window-size"; 3 | 4 | let name = "Basic"; 5 | 6 | function Example() { 7 | const sizes = useWindowSize(); 8 | return ( 9 |
Window size (but with a hook): {JSON.stringify(sizes, null, 2)}
10 | ); 11 | } 12 | 13 | Example.story = { name }; 14 | export const Comp = Example; 15 | export default { title: "useWindowSize" }; 16 | -------------------------------------------------------------------------------- /.codesandbox/templates/reach-ui/src/CurrentState.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export const CurrentState = (props) => ( 4 |
5 |

Current State

6 |
12 |       props = {JSON.stringify(props, null, 2)}
13 |     
14 |
15 | ); 16 | 17 | export default CurrentState; 18 | -------------------------------------------------------------------------------- /scripts/constants.ts: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | 3 | export const projectRoot = path.resolve(__dirname, "../"); 4 | 5 | export const paths = { 6 | projectRoot, 7 | packages: path.join(projectRoot, "packages"), 8 | testsSetup: path.join(projectRoot, "test/setupTests.ts"), 9 | projectCache: path.join(projectRoot, ".cache"), 10 | progressEstimatorCache: path.join( 11 | projectRoot, 12 | "node_modules/.cache/progress-estimator" 13 | ), 14 | }; 15 | -------------------------------------------------------------------------------- /packages/utils/README.md: -------------------------------------------------------------------------------- 1 | # @reach/utils 2 | 3 | [![Stable release](https://img.shields.io/npm/v/@reach/utils.svg)](https://npm.im/@reach/utils) ![MIT license](https://badgen.now.sh/badge/license/MIT) 4 | 5 | Shared utilities for various `@reach` packages. 6 | 7 | **Important:** This package is intended for internal use by the Reach UI library. You should not use it directly in your production projects, as the APIs can and will change often without regard to sem-ver. You have been warned! 8 | -------------------------------------------------------------------------------- /packages/machine/README.md: -------------------------------------------------------------------------------- 1 | # @reach/machine 2 | 3 | [![Stable release](https://img.shields.io/npm/v/@reach/machine.svg)](https://npm.im/@reach/machine) ![MIT license](https://badgen.now.sh/badge/license/MIT) 4 | 5 | State machine utilities for the Reach UI library. 6 | 7 | **Important:** This package is intended for internal use by the Reach UI library. You should not use it directly in your production projects, as the APIs can and will change often without regard to sem-ver. You have been warned! 8 | -------------------------------------------------------------------------------- /packages/checkbox/README.md: -------------------------------------------------------------------------------- 1 | # @reach/checkbox 2 | 3 | [![Stable release](https://img.shields.io/npm/v/@reach/checkbox.svg)](https://npm.im/@reach/checkbox) ![MIT license](https://badgen.now.sh/badge/license/MIT) 4 | 5 | [Docs](https://reach.tech/checkbox) | [Source](https://github.com/reach/reach-ui/tree/main/packages/checkbox) | [WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.2/#checkbox) 6 | 7 | React components to build accessible custom checkboxes with support for indeterminate (mixed) state. 8 | -------------------------------------------------------------------------------- /packages/skip-nav/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --reach-skip-nav: 1; 3 | } 4 | 5 | [data-reach-skip-nav-link] { 6 | border: 0; 7 | clip: rect(0 0 0 0); 8 | height: 1px; 9 | width: 1px; 10 | margin: -1px; 11 | padding: 0; 12 | overflow: hidden; 13 | position: absolute; 14 | } 15 | 16 | [data-reach-skip-nav-link]:focus { 17 | padding: 1rem; 18 | position: fixed; 19 | top: 10px; 20 | left: 10px; 21 | background: white; 22 | z-index: 1; 23 | width: auto; 24 | height: auto; 25 | clip: auto; 26 | } 27 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare const __DEV__: boolean; 2 | 3 | declare module "jest-axe" { 4 | import { run, RunOptions, AxeResults } from "axe-core"; 5 | export function axe( 6 | html: any, 7 | additionalOptions?: T 8 | ): Promise; 9 | export function configureAxe( 10 | defaultOptions?: T 11 | ): (html: any, additionalOptions: RunOptions) => Promise; 12 | export const toHaveNoViolations: jest.ExpectExtendMap; 13 | } 14 | -------------------------------------------------------------------------------- /packages/slider/examples/examples.css: -------------------------------------------------------------------------------- 1 | [data-reach-slider-marker] > span { 2 | position: absolute; 3 | font-size: 12px; 4 | } 5 | 6 | [data-reach-slider-marker][data-orientation="horizontal"] > span { 7 | top: calc(100% + 5px); 8 | left: 50%; 9 | text-align: center; 10 | transform: translateX(-50%); 11 | } 12 | 13 | [data-reach-slider-marker][data-orientation="vertical"] > span { 14 | left: calc(100% + 5px); 15 | top: 50%; 16 | text-align: right; 17 | transform: translateY(-50%); 18 | white-space: nowrap; 19 | } 20 | -------------------------------------------------------------------------------- /packages/checkbox/src/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to @reach/checkbox! 3 | * 4 | * Accessible components to build custom, tri-state checkboxes in React. 5 | * 6 | * This package provides two top-level components: 7 | * - MixedCheckbox 8 | * - CustomCheckbox 9 | * 10 | * @see Docs https://reach.tech/checkbox 11 | * @see Source https://github.com/reach/reach-ui/tree/main/packages/checkbox 12 | * @see WAI-ARIA https://www.w3.org/TR/wai-aria-practices-1.2/#checkbox 13 | */ 14 | 15 | export * from "./custom"; 16 | export * from "./mixed"; 17 | -------------------------------------------------------------------------------- /packages/dialog/styles.css: -------------------------------------------------------------------------------- 1 | /* This code is subject to LICENSE in root of this repository */ 2 | 3 | /* Used to detect in JavaScript if apps have loaded styles or not. */ 4 | :root { 5 | --reach-dialog: 1; 6 | } 7 | 8 | [data-reach-dialog-overlay] { 9 | background: hsla(0, 0%, 0%, 0.33); 10 | position: fixed; 11 | top: 0; 12 | right: 0; 13 | bottom: 0; 14 | left: 0; 15 | overflow: auto; 16 | } 17 | 18 | [data-reach-dialog-content] { 19 | width: 50vw; 20 | margin: 10vh auto; 21 | background: white; 22 | padding: 2rem; 23 | outline: none; 24 | } 25 | -------------------------------------------------------------------------------- /packages/utils/__tests__/utils.test.tsx: -------------------------------------------------------------------------------- 1 | import { checkStyles } from "@reach/utils"; 2 | 3 | describe("@reach/utils", () => { 4 | let warn = console.warn; 5 | afterEach(() => (console.warn = warn)); 6 | 7 | describe("checkStyles", () => { 8 | let consoleOutput: string[] = []; 9 | let mockedWarn = (output: any) => consoleOutput.push(output); 10 | beforeEach(() => (console.warn = mockedWarn)); 11 | it("should not issue warnings while testing", () => { 12 | checkStyles("accordion"); 13 | expect(consoleOutput).toEqual([]); 14 | }); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | /NOTES.md 9 | 10 | # runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | 17 | # generated doc files 18 | /doc.json 19 | 20 | # bundled files 21 | /packages/*/dist 22 | /packages/*/errors 23 | 24 | # editor specific 25 | .vscode 26 | .editorconfig 27 | 28 | # website 29 | /website-deploy-key 30 | /website-deploy-key.pub 31 | /website/public/ 32 | 33 | # other 34 | node_modules 35 | .cache 36 | .env 37 | package-lock.json 38 | .pnp/ 39 | .pnp.js 40 | .yarn-integrity 41 | /errors 42 | -------------------------------------------------------------------------------- /packages/slider/examples/basic.example.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Slider, SliderMarker } from "@reach/slider"; 3 | import "@reach/slider/styles.css"; 4 | import "./examples.css"; 5 | 6 | let name = "Basic (TS)"; 7 | 8 | function Example() { 9 | return ( 10 | 11 | 12 | 10 13 | 14 | 15 | 90 16 | 17 | 18 | ); 19 | } 20 | 21 | Example.story = { name }; 22 | export const Comp = Example; 23 | export default { title: "Slider" }; 24 | -------------------------------------------------------------------------------- /packages/visually-hidden/examples/basic.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import VisuallyHidden from "@reach/visually-hidden"; 3 | 4 | let name = "Basic"; 5 | 6 | function Example() { 7 | return ( 8 | 14 | ); 15 | } 16 | 17 | Example.story = { name }; 18 | export const Comp = Example; 19 | export default { title: "VisuallyHidden" }; 20 | -------------------------------------------------------------------------------- /packages/visually-hidden/examples/with-as-prop.example.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import VisuallyHidden from "@reach/visually-hidden"; 3 | 4 | let name = "Basic (TS)"; 5 | 6 | function Example() { 7 | return ( 8 | 14 | ); 15 | } 16 | 17 | Example.story = { name }; 18 | export const Comp = Example; 19 | export default { title: "VisuallyHidden" }; 20 | -------------------------------------------------------------------------------- /website/src/components/AsPropWarning.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Note } from "./Note"; 3 | 4 | export function AsPropWarning() { 5 | return ( 6 | 7 |

8 | NOTE: Many semantic elements, such as{" "} 9 | button elements, have meaning to assistive devices and 10 | browsers that provide context for the user and, in many cases, provide 11 | or restrict interactive behaviors. Use caution when overriding our 12 | defaults and make sure that the element you choose to render provides 13 | the same experience for all users. 14 |

15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /website/src/styles/root.scss: -------------------------------------------------------------------------------- 1 | $ff-sans: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, 2 | Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 3 | $ff-mono: "SFMono-Regular", Consolas, "Roboto Mono", "Droid Sans Mono", 4 | "Liberation Mono", Menlo, Courier, monospace; 5 | $color-error: #bf4a3f; 6 | $color-primary: #1159a6; 7 | $color-primary-bright: #007bff; 8 | $color-primary-light: #3f94bf; 9 | $color-primary-xlight: #c7e4f2; 10 | $color-body: #222; 11 | $color-body-background: #fafafa; 12 | $color-focus-outline: #1eaedb; 13 | $color-input-background: #fff; 14 | $color-input-border: #d1d1d1; 15 | $color-rule-border: #e1e1e1; 16 | $color-table-cell-border: #eee; 17 | -------------------------------------------------------------------------------- /test/types.ts: -------------------------------------------------------------------------------- 1 | import { 2 | queries, 3 | RenderOptions as TLRenderOptions, 4 | RenderResult as TLRenderResult, 5 | } from "@testing-library/react"; 6 | import { axe } from "jest-axe"; 7 | import { ThenArg } from "@reach/utils"; 8 | 9 | export type EventElement = Document | Element | Window; 10 | 11 | export type RenderOptions = Omit & { 12 | strict?: boolean; 13 | }; 14 | 15 | export type RenderResult< 16 | P extends React.HTMLAttributes, 17 | T extends HTMLElement 18 | > = TLRenderResult & { 19 | setProps(props: P): RenderResult; 20 | forceUpdate(): RenderResult; 21 | }; 22 | 23 | export type AxeResults = ThenArg>; 24 | -------------------------------------------------------------------------------- /packages/slider/examples/vertical.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { 3 | Slider, 4 | SliderMarker, 5 | SLIDER_ORIENTATION_VERTICAL, 6 | } from "@reach/slider"; 7 | import "@reach/slider/styles.css"; 8 | import "./examples.css"; 9 | 10 | let name = "Vertical"; 11 | 12 | function Example() { 13 | return ( 14 | 15 | 16 | 10 17 | 18 | 19 | 90 20 | 21 | 22 | ); 23 | } 24 | 25 | Example.story = { name }; 26 | export const Comp = Example; 27 | export default { title: "Slider" }; 28 | -------------------------------------------------------------------------------- /.codesandbox/templates/reach-ui/src/examples/index.js: -------------------------------------------------------------------------------- 1 | import * as MenuButton from "./menu-button"; 2 | 3 | // TODO: Add examples for all components for easy testing. 4 | // TODO: Unify examples between Storybook and Codesandbox if practical. 5 | 6 | // Usage: 7 | // import Reach from './examples 8 | // 9 | 10 | let Example = { 11 | Alert: {}, 12 | AlertDialog: {}, 13 | AutoID: {}, 14 | Combobox: {}, 15 | ComponentComponent: {}, 16 | Dialog: {}, 17 | MenuButton, 18 | Popover: {}, 19 | Portal: {}, 20 | Rect: {}, 21 | SkipNav: {}, 22 | Slider: {}, 23 | Tabs: {}, 24 | Tooltip: {}, 25 | VisuallyHidden: {}, 26 | WindowSize: {} 27 | }; 28 | 29 | export default Example; 30 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: reach-ui 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /packages/slider/examples/vertical.example.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { 3 | Slider, 4 | SliderMarker, 5 | SLIDER_ORIENTATION_VERTICAL, 6 | } from "@reach/slider"; 7 | import "@reach/slider/styles.css"; 8 | import "./examples.css"; 9 | 10 | let name = "Vertical (TS)"; 11 | 12 | function Example() { 13 | return ( 14 | 15 | 16 | 10 17 | 18 | 19 | 90 20 | 21 | 22 | ); 23 | } 24 | 25 | Example.story = { name }; 26 | export const Comp = Example; 27 | export default { title: "Slider" }; 28 | -------------------------------------------------------------------------------- /website/gatsby-browser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @reach/router (and by association, Gatsby) adds a role of `group` to the 3 | * focus wrapper element. We're going to remove that default behavior in the 4 | * router, as it results in some wacky reading of all content as a huge string 5 | * in VoiceOver + NVDA which is less than desirable. 6 | * This is a workaround for now. 7 | */ 8 | exports.onInitialClientRender = () => { 9 | let rootEl = document.getElementById("gatsby-focus-wrapper"); 10 | if (rootEl) { 11 | rootEl.removeAttribute("role"); 12 | // rootEl.removeAttribute("tabindex"); 13 | // rootEl.removeAttribute("style"); 14 | requestAnimationFrame(() => { 15 | document.body.focus(); 16 | }); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 180 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 14 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - "Status: In Progress" 8 | - "Status: Investigation" 9 | - "Type: Bug" 10 | - "Type: Request for Comment" 11 | - "Type: Regression" 12 | - "Resolution: Won't Fix" 13 | # Label to use when marking an issue as stale 14 | staleLabel: "Resolution: Stale" 15 | # Comment to post when marking an issue as stale. Set to `false` to disable 16 | markComment: false 17 | # Comment to post when closing a stale issue. Set to `false` to disable 18 | closeComment: false 19 | -------------------------------------------------------------------------------- /.codesandbox/templates/reach-ui/src/index.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import * as ReactDOM from "react-dom"; 3 | import CurrentState from "./CurrentState"; 4 | 5 | import "./styles.css"; 6 | import "./reach-styles"; 7 | 8 | function App() { 9 | return ( 10 |
11 |

Reach UI Template

12 |
{/* Add your code here. */}
13 |
14 | 21 |
22 | ); 23 | } 24 | 25 | const rootElement = document.getElementById("root"); 26 | ReactDOM.render(, rootElement); 27 | -------------------------------------------------------------------------------- /website/static/router/static/js/9.e7cbaa3d.chunk.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[9],{"./src/markdown/tutorial/01-intro.md":function(t,o,n){"use strict";n.r(o),n.d(o,"title",function(){return r});var e=n("./node_modules/react/index.js"),a=n.n(e);const r="Tutorial Introduction";o.default=function(){return a.a.createElement("div",{className:"markdown",dangerouslySetInnerHTML:{__html:"

Tutorial Introduction

\n

You can follow along with this tutorial with code sandbox right above this text.

\n

When you navigate from step to step, the sandbox will reload with code that’s ready for the next step. You can also open the sandbox in a new window and even download it to run locally. Big thanks to Code Sandbox for such a great tool :D

\n"}})}}}]); -------------------------------------------------------------------------------- /packages/window-size/README.md: -------------------------------------------------------------------------------- 1 | # @reach/window-size 2 | 3 | [![Stable release](https://img.shields.io/npm/v/@reach/window-size.svg)](https://npm.im/@reach/window-size) ![MIT license](https://badgen.now.sh/badge/license/MIT) 4 | 5 | [Docs](https://reach.tech/window-size) | [Source](https://github.com/reach/reach-ui/tree/main/packages/window-size) 6 | 7 | Measure the current window dimensions. 8 | 9 | ```jsx 10 | import WindowSize, { useWindowSize } from "@reach/window-size"; 11 | 12 | function Example() { 13 | const { width, height } = useWindowSize(); 14 | return ( 15 |
16 |

17 | Looks like a pretty{" "} 18 | {width <= 400 ? "small" : width >= 1000 ? "large" : "normal"} screen! 19 |

20 |
21 | ); 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /packages/slider/examples/basic.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Slider, SliderMarker } from "@reach/slider"; 3 | import "@reach/slider/styles.css"; 4 | import "./examples.css"; 5 | 6 | let name = "Basic"; 7 | 8 | function Example() { 9 | return ( 10 |
11 | 12 | 13 | 10 14 | 15 | 16 | 90 17 | 18 | 19 |
20 |
21 |
22 | 23 |
24 | ); 25 | } 26 | 27 | Example.story = { name }; 28 | export const Comp = Example; 29 | export default { title: "Slider" }; 30 | -------------------------------------------------------------------------------- /packages/disclosure/examples/basic.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { 3 | Disclosure, 4 | DisclosureButton, 5 | DisclosurePanel, 6 | } from "@reach/disclosure"; 7 | 8 | let name = "Basic"; 9 | 10 | function Example() { 11 | return ( 12 | 13 | I have a secret 14 | 15 | Ante rhoncus facilisis iaculis nostra faucibus vehicula ac consectetur 16 | pretium, lacus nunc consequat id viverra facilisi ligula eleifend, 17 | congue gravida malesuada proin scelerisque luctus est convallis. 18 | 19 | 20 | ); 21 | } 22 | 23 | Example.story = { name }; 24 | export const Comp = Example; 25 | export default { title: "Disclosure" }; 26 | -------------------------------------------------------------------------------- /packages/portal/README.md: -------------------------------------------------------------------------------- 1 | # @reach/portal 2 | 3 | [![Stable release](https://img.shields.io/npm/v/@reach/portal.svg)](https://npm.im/@reach/portal) ![MIT license](https://badgen.now.sh/badge/license/MIT) 4 | 5 | [Docs](https://reach.tech/portal) | [Source](https://github.com/reach/reach-ui/tree/main/packages/portal) 6 | 7 | Creates and appends a DOM node to the end of `document.body` and renders a React tree into it. Useful for rendering a natural React element hierarchy with a different DOM hierarchy to prevent parent styles from clipping or hiding content (for popovers, dropdowns, and modals). 8 | 9 | ```jsx 10 | import Portal from "@reach/portal"; 11 | 12 | function Example() { 13 | return ( 14 | 15 |
Stuff goes here
16 |
17 | ); 18 | } 19 | ``` 20 | -------------------------------------------------------------------------------- /scripts/build-all.ts: -------------------------------------------------------------------------------- 1 | import { loadPackages, iter } from "lerna-script"; 2 | import { buildPackage } from "./build"; 3 | import { 4 | cleanDistDirectories, 5 | getPackageDirectoryMap, 6 | timeFromStart, 7 | log, 8 | } from "./utils"; 9 | 10 | (async function () { 11 | let packages = await loadPackages(); 12 | let packageMap = await getPackageDirectoryMap(packages); 13 | let start = Date.now(); 14 | 15 | await cleanDistDirectories(); 16 | await iter.batched(packages)(async (pkg) => { 17 | let packagePath = packageMap[pkg.name]; 18 | if (!packagePath) { 19 | return; 20 | } 21 | log.rainbow.bold(`Building ${pkg.name}`); 22 | return await buildPackage(pkg.name, packagePath); 23 | }); 24 | 25 | log.bold(`Finished build in ${timeFromStart(start)}`); 26 | })(); 27 | -------------------------------------------------------------------------------- /packages/disclosure/examples/basic-ts.example.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { 3 | Disclosure, 4 | DisclosureButton, 5 | DisclosurePanel, 6 | } from "@reach/disclosure"; 7 | 8 | let name = "Basic (TS)"; 9 | 10 | function Example() { 11 | return ( 12 | 13 | I have a secret 14 | 15 | Ante rhoncus facilisis iaculis nostra faucibus vehicula ac consectetur 16 | pretium, lacus nunc consequat id viverra facilisi ligula eleifend, 17 | congue gravida malesuada proin scelerisque luctus est convallis. 18 | 19 | 20 | ); 21 | } 22 | 23 | Example.story = { name }; 24 | export const Comp = Example; 25 | export default { title: "Disclosure" }; 26 | -------------------------------------------------------------------------------- /website/static/router/static/js/8.ce712278.chunk.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[8],{"./src/markdown/tutorial/02-installation.md":function(n,a,t){"use strict";t.r(a),t.d(a,"title",function(){return s});var o=t("./node_modules/react/index.js"),e=t.n(o);const s="Tutorial - Installation";a.default=function(){return e.a.createElement("div",{className:"markdown",dangerouslySetInnerHTML:{__html:'

Tutorial - Installation

\n

If you’re following along with code sandbox for this tutorial, Reach Router is already installed.

\n

In your own apps you can install it with npm or yarn.

\n
npm install @reach/router\n# or\nyarn add @reach/router\n
\n'}})}}}]); -------------------------------------------------------------------------------- /scripts/deploy-website.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | root_dir="$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)")" 6 | tmp_dir="/tmp/reach.tech" 7 | 8 | # Clone reacttraining.com repo into the tmp dir 9 | rm -rf $tmp_dir 10 | git clone --depth 2 --branch master "git@github.com:reach/reach.tech.git" $tmp_dir 11 | 12 | # Build the website into the public dir 13 | rm -rf "$tmp_dir/public" 14 | cd "$root_dir/website" 15 | yarn 16 | yarn build 17 | mv public "$tmp_dir/public" 18 | 19 | # Commit all changes 20 | cd $tmp_dir 21 | git add -A 22 | git commit \ 23 | --allow-empty \ 24 | --author "Travis CI " \ 25 | -m "Update reach-ui website 26 | 27 | https://travis-ci.com/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" 28 | 29 | # Deploy 30 | git push origin master 31 | -------------------------------------------------------------------------------- /website/static/router/static/js/0.94cd3f75.chunk.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[0],{"./src/markdown/tutorial/10-next-steps.md":function(e,t,n){"use strict";n.r(t),n.d(t,"title",function(){return s});var o=n("./node_modules/react/index.js"),a=n.n(o);const s="Tutorial - Next Steps";t.default=function(){return a.a.createElement("div",{className:"markdown",dangerouslySetInnerHTML:{__html:"

Tutorial - Next Steps

\n

Congratulations! You now know everything you need to know to get started with Reach Router. Above this text is a the full application we just built.

\n

So what’s next? Go build something, of course. Then come back here to browse the examples, read the guides, and give the API references a skim. Shouldn’t take more than 30 minutes to read it all.

\n

Let us know how it goes!

\n"}})}}}]); -------------------------------------------------------------------------------- /packages/component-component/examples/state.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Component from "@reach/component-component"; 3 | 4 | let name = "Basic State"; 5 | 6 | function Example() { 7 | return ( 8 | 9 | {({ setState, state }) => ( 10 |
17 | 20 |
21 | )} 22 |
23 | ); 24 | } 25 | 26 | Example.story = { name }; 27 | export const Comp = Example; 28 | export default { title: "ComponentComponent" }; 29 | -------------------------------------------------------------------------------- /.codesandbox/templates/reach-ui/src/examples/menu-button/basic.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { action } from "@storybook/addon-actions"; 3 | import { Menu, MenuList, MenuButton, MenuItem } from "@reach/menu-button"; 4 | import "@reach/menu-button/styles.css"; 5 | 6 | export default function Basic() { 7 | return ( 8 | 9 | 10 | Actions 11 | 12 | 13 | Download 14 | Create a Copy 15 | Mark as Draft 16 | Delete 17 | 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /.storybook/preview.js: -------------------------------------------------------------------------------- 1 | import { configure } from "@storybook/react"; 2 | import "./styles.css"; 3 | 4 | configure(() => { 5 | const req = require.context( 6 | "../packages", 7 | true, 8 | /^((?!node_modules).)*\.example\.(js|ts|tsx)$/ 9 | ); 10 | 11 | let allExports = {}; 12 | for (let pathToExample of req.keys()) { 13 | let { Comp, default: defaultExport } = req(pathToExample); 14 | 15 | if (!Comp || !defaultExport) { 16 | continue; 17 | } 18 | 19 | let { name } = Comp.story; 20 | let { title } = defaultExport; 21 | 22 | allExports[title] = { 23 | ...(allExports[title] || {}), 24 | default: { title }, 25 | [name]: Comp, 26 | }; 27 | } 28 | 29 | return Object.keys(allExports).reduce((prev, cur) => { 30 | return [...prev, allExports[cur]]; 31 | }, []); 32 | }, module); 33 | -------------------------------------------------------------------------------- /packages/combobox/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --reach-combobox: 1; 3 | } 4 | 5 | [data-reach-combobox-popover] { 6 | border: solid 1px hsla(0, 0%, 0%, 0.25); 7 | background: hsla(0, 100%, 100%, 0.99); 8 | font-size: 85%; 9 | } 10 | 11 | [data-reach-combobox-list] { 12 | list-style: none; 13 | margin: 0; 14 | padding: 0; 15 | user-select: none; 16 | } 17 | 18 | [data-reach-combobox-option] { 19 | cursor: pointer; 20 | margin: 0; 21 | padding: 0.25rem 0.5rem; 22 | } 23 | 24 | [data-reach-combobox-option][aria-selected="true"] { 25 | background: hsl(211, 10%, 95%); 26 | } 27 | 28 | [data-reach-combobox-option]:hover { 29 | background: hsl(211, 10%, 92%); 30 | } 31 | 32 | [data-reach-combobox-option][aria-selected="true"]:hover { 33 | background: hsl(211, 10%, 90%); 34 | } 35 | 36 | [data-suggested-value] { 37 | font-weight: bold; 38 | } 39 | -------------------------------------------------------------------------------- /packages/component-component/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/component-component", 3 | "version": "0.12.0", 4 | "description": "Declarative React Component Definitions", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/component-component" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "dependencies": { 16 | "prop-types": "^15.7.2" 17 | }, 18 | "peerDependencies": { 19 | "react": "^16.4.0", 20 | "react-dom": "^16.4.0" 21 | }, 22 | "main": "dist/index.js", 23 | "module": "dist/component-component.esm.js", 24 | "files": [ 25 | "README.md", 26 | "dist" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /packages/portal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/portal", 3 | "version": "0.12.1", 4 | "description": "Declarative portals for React", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/portal" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "peerDependencies": { 16 | "react": "^16.8.0", 17 | "react-dom": "^16.8.0" 18 | }, 19 | "main": "dist/index.js", 20 | "module": "dist/portal.esm.js", 21 | "typings": "dist/index.d.ts", 22 | "files": [ 23 | "README.md", 24 | "dist" 25 | ], 26 | "dependencies": { 27 | "@reach/utils": "0.12.1", 28 | "tslib": "^2.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/dialog/examples/autofocus-ts.example.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Dialog } from "@reach/dialog"; 3 | import "@reach/dialog/styles.css"; 4 | 5 | let name = "Autofocus (TS)"; 6 | 7 | function Example() { 8 | const [showDialog, setShowDialog] = React.useState(false); 9 | const button = React.useRef(null); 10 | return ( 11 |
12 | 13 | 18 | 19 | 20 | 21 |
22 | ); 23 | } 24 | 25 | Example.story = { name }; 26 | export const Comp = Example; 27 | export default { title: "Dialog" }; 28 | -------------------------------------------------------------------------------- /packages/dialog/examples/basic-ts.example.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Dialog } from "@reach/dialog"; 3 | import "@reach/dialog/styles.css"; 4 | 5 | let name = "Basic (TS)"; 6 | 7 | function Example() { 8 | const [showDialog, setShowDialog] = React.useState(false); 9 | return ( 10 |
11 | 12 | 13 | 14 |

This is killer!

15 | 16 |
17 | 18 | 19 |
20 |
21 | ); 22 | } 23 | 24 | Example.story = { name }; 25 | export const Comp = Example; 26 | export default { title: "Dialog" }; 27 | -------------------------------------------------------------------------------- /packages/slider/examples/with-steps.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Slider, SliderMarker } from "@reach/slider"; 3 | import "@reach/slider/styles.css"; 4 | import "./examples.css"; 5 | 6 | let name = "With Steps"; 7 | 8 | function Example() { 9 | const step = 20; 10 | const min = 0; 11 | const max = 120; 12 | const range = max - min; 13 | const steps = Array.from(Array(range / step + 1).keys()); 14 | 15 | return ( 16 | 17 | {steps.map((key) => { 18 | const value = key * step; 19 | return ( 20 | 21 | {value} 22 | 23 | ); 24 | })} 25 | 26 | ); 27 | } 28 | 29 | Example.story = { name }; 30 | export const Comp = Example; 31 | export default { title: "Slider" }; 32 | -------------------------------------------------------------------------------- /website/src/pages/funding.mdx: -------------------------------------------------------------------------------- 1 | import SEO from "../components/SEO"; 2 | 3 | 7 | 8 | # Funding 9 | 10 | Development is primarily funded by [React Training](https://reacttraining.com) workshops, private training and online courses. 11 | 12 | If you are interested in supporting the continued development of Reach UI, please consider: 13 | 14 | - [Donating to the Open Collective](https://opencollective.com/reach-ui) 15 | - [Subscribing to online courses](https://reacttraining.com/courses/) 16 | - [Attending a workshop](https://reacttraining.com/workshops/) 17 | - [Getting private training](https://reacttraining.com/training/) 18 | - Emailing [hello@reacttraining.com](mailto:hello@reacttraining.com) for direct corporate sponsorship 19 | 20 | Thank you! 21 | -------------------------------------------------------------------------------- /packages/checkbox/examples/hook.example.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { useMixedCheckbox } from "@reach/checkbox"; 3 | import "@reach/checkbox/styles.css"; 4 | 5 | let name = "With useMixedCheckbox hook"; 6 | 7 | function Example() { 8 | const [checked, setChecked] = React.useState(true); 9 | let inputRef = React.useRef(null); 10 | let [inputProps] = useMixedCheckbox(inputRef, { 11 | checked, 12 | onChange: (event) => setChecked(event.target.checked), 13 | }); 14 | return ( 15 |
16 | 20 | 21 |
22 | ); 23 | } 24 | 25 | Example.story = { name }; 26 | export const Comp = Example; 27 | export default { title: "Checkbox" }; 28 | -------------------------------------------------------------------------------- /packages/slider/examples/with-steps.example.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Slider, SliderMarker } from "@reach/slider"; 3 | import "@reach/slider/styles.css"; 4 | import "./examples.css"; 5 | 6 | let name = "With Steps (TS)"; 7 | 8 | function Example() { 9 | const step = 20; 10 | const min = 0; 11 | const max = 120; 12 | const range = max - min; 13 | const steps = Array.from(Array(range / step + 1).keys()); 14 | 15 | return ( 16 | 17 | {steps.map((key) => { 18 | const value = key * step; 19 | return ( 20 | 21 | {value} 22 | 23 | ); 24 | })} 25 | 26 | ); 27 | } 28 | 29 | Example.story = { name }; 30 | export const Comp = Example; 31 | export default { title: "Slider" }; 32 | -------------------------------------------------------------------------------- /packages/auto-id/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/auto-id", 3 | "version": "0.12.1", 4 | "description": "Autogenerate IDs to facilitate WAI-ARIA and server rendering.", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/auto-id" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "peerDependencies": { 16 | "react": "^16.8.0", 17 | "react-dom": "^16.8.0" 18 | }, 19 | "main": "dist/index.js", 20 | "module": "dist/auto-id.esm.js", 21 | "typings": "dist/index.d.ts", 22 | "files": [ 23 | "README.md", 24 | "dist" 25 | ], 26 | "dependencies": { 27 | "@reach/utils": "0.12.1", 28 | "tslib": "^2.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/utils", 3 | "version": "0.12.1", 4 | "description": "Internal, shared utilities for Reach UI.", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/utils" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "peerDependencies": { 16 | "react": "^16.8.0", 17 | "react-dom": "^16.8.0" 18 | }, 19 | "main": "dist/index.js", 20 | "module": "dist/utils.esm.js", 21 | "typings": "dist/index.d.ts", 22 | "files": [ 23 | "README.md", 24 | "dist" 25 | ], 26 | "dependencies": { 27 | "@types/warning": "^3.0.0", 28 | "tslib": "^2.0.0", 29 | "warning": "^4.0.3" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/visually-hidden/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/visually-hidden", 3 | "version": "0.12.0", 4 | "description": "Render text that is announced to screen readers but visually hidden.", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/visually-hidden" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "peerDependencies": { 16 | "react": "^16.8.0", 17 | "react-dom": "^16.8.0" 18 | }, 19 | "main": "dist/index.js", 20 | "module": "dist/visually-hidden.esm.js", 21 | "typings": "dist/index.d.ts", 22 | "files": [ 23 | "README.md", 24 | "dist" 25 | ], 26 | "dependencies": { 27 | "tslib": "^2.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/checkbox/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --reach-checkbox: 1; 3 | } 4 | 5 | [data-reach-custom-checkbox-container] { 6 | display: inline-block; 7 | position: relative; 8 | margin-right: 0.75ex; 9 | cursor: default; 10 | width: 0.875rem; 11 | height: 0.875rem; 12 | } 13 | 14 | [data-reach-custom-checkbox-container]:focus-within, 15 | [data-reach-custom-checkbox-container][data-focus] { 16 | box-shadow: 0 0 4px 1px Highlight; 17 | outline: -webkit-focus-ring-color auto 4px; 18 | } 19 | 20 | [data-reach-custom-checkbox-input] { 21 | position: absolute !important; 22 | top: 0 !important; 23 | left: 0 !important; 24 | margin: 0 !important; 25 | padding: 0 !important; 26 | width: 100% !important; 27 | height: 100% !important; 28 | opacity: 0 !important; 29 | z-index: 1 !important; 30 | cursor: inherit; 31 | box-shadow: none !important; 32 | outline: none !important; 33 | } 34 | -------------------------------------------------------------------------------- /packages/auto-id/README.md: -------------------------------------------------------------------------------- 1 | # @reach/auto-id 2 | 3 | [![Stable release](https://img.shields.io/npm/v/@reach/auto-id.svg)](https://npm.im/@reach/auto-id) ![MIT license](https://badgen.now.sh/badge/license/MIT) 4 | 5 | [Docs](https://reach.tech/auto-id) | [Source](https://github.com/reach/reach-ui/tree/main/packages/auto-id) 6 | 7 | Autogenerate IDs to facilitate WAI-ARIA and server rendering. 8 | 9 | A string can be supplied as an argument to be `useId` in lieu of the auto-generated ID. This is handy for accepting user-provided prop IDs that need to be deterministic. 10 | 11 | ```jsx 12 | import { useId } from "@reach/auto-id"; 13 | 14 | function FormField(props) { 15 | const id = useId(props.id); 16 | return ( 17 | 18 | 19 | 20 | 21 | ); 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /packages/dialog/examples/no-tabbables.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { action } from "@storybook/addon-actions"; 3 | import { Dialog } from "@reach/dialog"; 4 | import "@reach/dialog/styles.css"; 5 | 6 | let name = "No Tabbables"; 7 | 8 | function Example() { 9 | const [showDialog, setShowDialog] = React.useState(false); 10 | return ( 11 |
12 | 13 | setShowDialog(false)} 17 | onFocus={action("Focused!")} 18 | > 19 |

There are no tabbables here

20 |

Tab should focus the element itself

21 |
22 |
23 | ); 24 | } 25 | 26 | Example.story = { name }; 27 | export const Comp = Example; 28 | export default { title: "Dialog" }; 29 | -------------------------------------------------------------------------------- /packages/machine/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/machine", 3 | "version": "0.12.1", 4 | "description": "State machine utilities for the Reach UI library.", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/machine" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "dependencies": { 16 | "@reach/utils": "0.12.1", 17 | "@xstate/fsm": "1.4.0", 18 | "tslib": "^2.0.0" 19 | }, 20 | "peerDependencies": { 21 | "react": "^16.8.0", 22 | "react-dom": "^16.8.0" 23 | }, 24 | "main": "dist/index.js", 25 | "module": "dist/machine.esm.js", 26 | "typings": "dist/index.d.ts", 27 | "files": [ 28 | "README.md", 29 | "dist" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/window-size/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/window-size", 3 | "version": "0.12.1", 4 | "description": "Measure the window size in React", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/window-size" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "dependencies": { 16 | "@reach/utils": "0.12.1", 17 | "prop-types": "^15.7.2", 18 | "tslib": "^2.0.0" 19 | }, 20 | "peerDependencies": { 21 | "react": "^16.8.0", 22 | "react-dom": "^16.8.0" 23 | }, 24 | "main": "dist/index.js", 25 | "module": "dist/window-size.esm.js", 26 | "typings": "dist/index.d.ts", 27 | "files": [ 28 | "README.md", 29 | "dist" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/disclosure/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/disclosure", 3 | "version": "0.12.1", 4 | "description": "Accessible React disclosure component", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/disclosure" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "dependencies": { 16 | "@reach/auto-id": "0.12.1", 17 | "@reach/utils": "0.12.1", 18 | "tslib": "^2.0.0" 19 | }, 20 | "peerDependencies": { 21 | "react": "^16.8.0", 22 | "react-dom": "^16.8.0" 23 | }, 24 | "main": "dist/index.js", 25 | "module": "dist/disclosure.esm.js", 26 | "typings": "dist/index.d.ts", 27 | "files": [ 28 | "README.md", 29 | "dist" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/skip-nav/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/skip-nav", 3 | "version": "0.12.1", 4 | "description": "Skip navigation links for screen reader and keyboard users.", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/skip-nav" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "dependencies": { 16 | "@reach/utils": "0.12.1", 17 | "tslib": "^2.0.0" 18 | }, 19 | "peerDependencies": { 20 | "react": "^16.8.0", 21 | "react-dom": "^16.8.0" 22 | }, 23 | "main": "dist/index.js", 24 | "module": "dist/skip-nav.esm.js", 25 | "typings": "dist/index.d.ts", 26 | "files": [ 27 | "README.md", 28 | "dist", 29 | "styles.css" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /packages/descendants/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/descendants", 3 | "version": "0.12.1", 4 | "description": "A descendant index solution for better accessibility support in compound components", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/descendants" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "dependencies": { 16 | "@reach/utils": "0.12.1", 17 | "tslib": "^2.0.0" 18 | }, 19 | "peerDependencies": { 20 | "react": "^16.8.0", 21 | "react-dom": "^16.8.0" 22 | }, 23 | "main": "dist/index.js", 24 | "module": "dist/descendants.esm.js", 25 | "typings": "dist/index.d.ts", 26 | "files": [ 27 | "README.md", 28 | "dist" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /packages/dialog/examples/dismiss.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Dialog } from "@reach/dialog"; 3 | import "@reach/dialog/styles.css"; 4 | 5 | let name = "Dismiss"; 6 | 7 | function Example() { 8 | const [showDialog, setShowDialog] = React.useState(false); 9 | return ( 10 |
11 | 12 | setShowDialog(false)} 16 | > 17 | 18 |

This is killer!

19 | 20 |
21 | 22 | 23 |
24 |
25 | ); 26 | } 27 | 28 | Example.story = { name }; 29 | export const Comp = Example; 30 | export default { title: "Dialog" }; 31 | -------------------------------------------------------------------------------- /packages/rect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/rect", 3 | "version": "0.12.1", 4 | "description": "Measure React elements position in the DOM", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/rect" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "dependencies": { 16 | "@reach/observe-rect": "1.2.0", 17 | "@reach/utils": "0.12.1", 18 | "prop-types": "^15.7.2", 19 | "tslib": "^2.0.0" 20 | }, 21 | "peerDependencies": { 22 | "react": "^16.8.0", 23 | "react-dom": "^16.8.0" 24 | }, 25 | "main": "dist/index.js", 26 | "module": "dist/rect.esm.js", 27 | "typings": "dist/index.d.ts", 28 | "files": [ 29 | "README.md", 30 | "dist" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /packages/alert/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reach/alert", 3 | "version": "0.12.1", 4 | "description": "Screen-reader-friendly alert messages.", 5 | "author": "React Training ", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/reach/reach-ui.git", 10 | "directory": "packages/alert" 11 | }, 12 | "scripts": { 13 | "build": "ts-node --transpile-only ../../scripts/build-package $npm_package_name" 14 | }, 15 | "dependencies": { 16 | "@reach/utils": "0.12.1", 17 | "@reach/visually-hidden": "0.12.0", 18 | "prop-types": "^15.7.2", 19 | "tslib": "^2.0.0" 20 | }, 21 | "peerDependencies": { 22 | "react": "^16.8.0", 23 | "react-dom": "^16.8.0" 24 | }, 25 | "main": "dist/index.js", 26 | "module": "dist/alert.esm.js", 27 | "typings": "dist/index.d.ts", 28 | "files": [ 29 | "README.md", 30 | "dist" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /packages/menu-button/examples/basic.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Menu, MenuList, MenuButton, MenuItem } from "@reach/menu-button"; 3 | import { action } from "@storybook/addon-actions"; 4 | import "@reach/menu-button/styles.css"; 5 | 6 | let name = "Basic"; 7 | 8 | function Example() { 9 | return ( 10 | 11 | 12 | Actions 13 | 14 | 15 | Download 16 | Create a Copy 17 | Mark as Draft 18 | Delete 19 | 20 | 21 | ); 22 | } 23 | 24 | Example.story = { name }; 25 | export const Comp = Example; 26 | export default { title: "MenuButton" }; 27 | -------------------------------------------------------------------------------- /packages/tabs/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --reach-tabs: 1; 3 | } 4 | 5 | [data-reach-tabs][data-orientation="vertical"] { 6 | display: flex; 7 | } 8 | 9 | [data-reach-tab-list] { 10 | display: flex; 11 | background: hsla(0, 0%, 0%, 0.05); 12 | } 13 | 14 | [data-reach-tab-list][aria-orientation="vertical"] { 15 | flex-direction: column; 16 | } 17 | 18 | [data-reach-tab] { 19 | display: inline-block; 20 | border: none; 21 | padding: 0.25em 0.5em; 22 | margin: 0; 23 | border-bottom: 1px solid transparent; 24 | background: none; 25 | color: inherit; 26 | font: inherit; 27 | cursor: pointer; 28 | -webkit-appearance: none; 29 | -moz-appearance: none; 30 | } 31 | 32 | [data-reach-tab]:active { 33 | background: hsla(0, 0%, 0%, 0.05); 34 | } 35 | 36 | [data-reach-tab]:disabled { 37 | opacity: 0.25; 38 | cursor: default; 39 | } 40 | 41 | [data-reach-tab][data-selected] { 42 | border-bottom-color: currentColor; 43 | } 44 | -------------------------------------------------------------------------------- /.codesandbox/templates/reach-ui/src/styles.css: -------------------------------------------------------------------------------- 1 | html { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | *, 8 | *:before, 9 | *:after { 10 | box-sizing: inherit; 11 | } 12 | 13 | html, 14 | body { 15 | margin: 0; 16 | padding: 0; 17 | font-family: -apple-system, BlinkMacSystemFont, sans-serif; 18 | line-height: 1.5; 19 | color: #242424; 20 | text-rendering: optimizeLegibility; 21 | } 22 | 23 | .App { 24 | padding: 1rem; 25 | } 26 | 27 | .CurrentState { 28 | margin: 1rem 0; 29 | } 30 | 31 | .CurrentState h3 { 32 | margin: 0; 33 | padding: 0; 34 | } 35 | 36 | .CurrentState pre { 37 | background: #f6f8fa; 38 | border: 1px solid #e2e2e2; 39 | font-size: 0.75rem; 40 | padding: 0.5rem; 41 | } 42 | 43 | pre, 44 | code { 45 | font-family: "Menlo", monospace; 46 | } 47 | 48 | hr { 49 | padding: 0; 50 | margin: 1rem 0; 51 | border: 0; 52 | height: 1px; 53 | background: #8c8c8c; 54 | } 55 | -------------------------------------------------------------------------------- /packages/rect/examples/basic-use-rect.example.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { useRect } from "@reach/rect"; 3 | 4 | let name = "Basic (useRect)"; 5 | 6 | function Example() { 7 | const ref = React.useRef(); 8 | const rect = useRect(ref, { observe: true }); 9 | return ( 10 |
11 |
{JSON.stringify(rect, null, 2)}
12 |