GithubHelp home page GithubHelp logo

t-hugs / focus-rings Goto Github PK

View Code? Open in Web Editor NEW

This project forked from discord/focus-rings

0.0 1.0 0.0 168 KB

A centralized system for displaying and stylizing focus indicators anywhere on a webpage.

License: MIT License

TypeScript 98.47% CSS 1.53%

focus-rings's Introduction

Focus Rings

A centralized system for displaying and stylizing focus indicators anywhere on a webpage.

a gif showing focus rings in action

Motivation

When working on creating a complete keyboard navigation experience for Discord, we ran into a number of problems with rendering clean and consistent focus rings and were unable to find any suitable native alternatives. After a lot of trial and error, we landed on this system as a way to meet all of our needs. You can read more about the process we went through in this blog post.

Installation

This package is published under react-focus-rings and can be installed with any npm-compatible package manager.

Usage

This library is composed of two components: FocusRing and FocusRingScope.

FocusRingScope

FocusRingScope is responsible for providing a frame of reference for calculating the position of any FocusRing instances it contains. The containerRef prop takes a React.Ref that references the DOM element that should be used for these position calculations. You'll want to include a FocusRingScope instance at the top level of your application. If a component creates a new scroll container, or is absoultely positioned within the viewport, you should add a new FocusRingScope.

function ScopeExample() {
  const containerRef = React.useRef<HTMLDivElement>(null);
  return (
    <div ref={containerRef} id="main">
      <FocusRingScope containerRef={containerRef}>
       {/* ... */}
      </FocusRingScope>
    </div>
  )
}

Keep in mind that the element provided to containerRef must be styled with position: relative or else the alignment calculations will be incorrect. If you find that FocusRing isn't being rendered at all or its positioning is wrong, verify that you have a FocusRingScope in the correct places and that the containerRef element has the position: relative style.

FocusRing

The FocusRing is the main show. You can wrap any focusable element with a FocusRing and it will add the required focus/blur listeners and magically render the focus ring when the element receives focus. We recommend integrating this at the design primitive level, in custom components like Button or Link, so you get the focus ring behavior across your application with minimal effort.

function Button(props: ButtonProps) {
  return (
    <FocusRing>
      <button {...props} />
    </FocusRing>
  );
}

Props

FocusRing has a few props you can use to get the right behavior and alignment. If using TypeScript the type is exported as FocusRingProps

import {FocusRingProps} from 'react-focus-rings'
  • within - acts like :focus-within and will render the focus ring if any descendant is focused
  • enabled - controls whether the FocusRing is being rendered
  • focused - controls the focused state
  • offset - lets you adjust the alignment of the focus ring, relative to the focused element. Can be a number or Offset object
  • focusTarget - lets you choose a different element to act as the focus target for the ring. Must be used with ringTarget.
  • ringTarget - lets you choose a different element to render the ring around. Must be used with focusTarget.
  • focusWithinClassName - lets you apply a CSS class to the focused element when a descendant is focused. Like :focus-within.

Default Styling

The focus ring also relies on some default CSS styles in order to render properly. To make this work in your project, be sure to import the styles separately somwhere within your app with import "focus-rings/src/styles.css";.

Example

A complete, minimal example might look like this:

import * as React from "react";
import ReactDOM from "react-dom";

import { FocusRing, FocusRingScope } from "react-focus-rings";
import "focus-rings/src/styles.css";

function App() {
  const containerRef = React.useRef<HTMLDivElement>(null);
  return (
    <div className="app-container" ref={containerRef}>
      <FocusRingScope containerRef={containerRef}>
        <div className="content">
          <p>Here's a paragraph with some text.</p>
          <FocusRing offset={-2}>
            <button onClick={console.log}>Click Me</button>
          </FocusRing>
          <p>Here's another paragraph with more text.</p>
        </div>
      </FocusRingScope>
    </div>
  );
}

ReactDOM.render(<App />, document.body);

You can find a more complete example in the examples directory of this repository. You can find a hosted version of the example application here.

focus-rings's People

Contributors

aweary avatar faultyserver avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.