UNPKG

@equinor/eds-core-react

Version:

The React implementation of the Equinor Design System

138 lines (135 loc) 4.74 kB
import styled from 'styled-components'; import { tokens } from '@equinor/eds-tokens'; import { FocusScope, useFocusManager } from 'react-aria'; import { useRef, useEffect } from 'react'; import { jsx } from 'react/jsx-runtime'; // Disable no-autofocus - it's not the native autofocus attribute, but react-aria's autoFocus prop /* eslint-disable jsx-a11y/no-autofocus */ const Grid = styled.div.withConfig({ displayName: "YearGrid__Grid", componentId: "sc-1l9jho8-0" })(["display:grid;grid-template-columns:repeat(6,1fr);grid-gap:8px;margin:8px;"]); const GridColumn = styled.button.withConfig({ displayName: "YearGrid__GridColumn", componentId: "sc-1l9jho8-1" })(["background-color:transparent;outline:none;border:none;display:flex;justify-content:center;cursor:pointer;padding:8px;font-size:", ";font-family:", ";font-weight:", ";line-height:", ";color:", ";border-radius:999px;", ";&:hover{background-color:#f0f0f0;}&:focus{outline:2px dashed ", ";}"], tokens.typography.navigation.button.fontSize, tokens.typography.navigation.button.fontFamily, tokens.typography.navigation.button.fontWeight, tokens.typography.navigation.button.lineHeight, tokens.colors.text.static_icons__default.rgba, ({ $active }) => $active ? `background-color: ${tokens.colors.interactive.primary__selected_highlight.rgba}` : '', tokens.colors.interactive.primary__resting.rgba); const TOTAL_VISIBLE_YEARS = 36; const RANGE_OFFSET = 30 / 2; const GridFocusManager = ({ year: selectedYear, setFocusedYear, yearPickerPage, setYearPickerPage }) => { const focusManager = useFocusManager(); const prevYear = useRef(); const navByKeyboard = useRef(false); const page = yearPickerPage * TOTAL_VISIBLE_YEARS; const years = Array.from({ length: TOTAL_VISIBLE_YEARS }, (_, i) => i + (selectedYear + page - RANGE_OFFSET)); useEffect(() => { if (prevYear.current === undefined) { prevYear.current = yearPickerPage; return; } if (!navByKeyboard.current) { focusManager.focusFirst(); return; } navByKeyboard.current = false; yearPickerPage > prevYear.current ? focusManager.focusFirst() : focusManager.focusLast(); prevYear.current = yearPickerPage; }, [yearPickerPage, focusManager]); const onKeyDown = year => e => { const target = e.currentTarget; const parent = target.parentElement; const isFirstYear = years.at(0) === year; const isLastYear = years.at(-1) === year; switch (e.key) { case 'ArrowRight': e.preventDefault(); if (isLastYear) { navByKeyboard.current = true; setYearPickerPage(page => page + 1); break; } focusManager.focusNext({ wrap: true }); break; case 'ArrowLeft': e.preventDefault(); if (isFirstYear) { navByKeyboard.current = true; setYearPickerPage(page => page - 1); break; } focusManager.focusPrevious({ wrap: true }); break; case 'ArrowDown': { e.preventDefault(); if (isLastYear) { navByKeyboard.current = true; setYearPickerPage(page => page + 1); break; } const selfIndex = Array.from(parent.children).indexOf(target); const focusElement = Array.from(parent.children).at(selfIndex + 5); focusManager.focusNext({ from: focusElement }); break; } case 'ArrowUp': { e.preventDefault(); if (isFirstYear) { navByKeyboard.current = true; setYearPickerPage(page => page - 1); break; } const selfIndex = Array.from(parent.children).indexOf(target); const focusElement = Array.from(parent.children).at(selfIndex - 5); focusManager.focusPrevious({ from: focusElement }); break; } } }; return years.map(year => /*#__PURE__*/jsx(GridColumn, { $active: selectedYear === year, onKeyDown: onKeyDown(year), onClick: () => setFocusedYear(year), "aria-label": `Set year to ${year}`, tabIndex: 0, children: year }, year)); }; const YearGrid = ({ setFocusedYear, year: selectedYear, yearPickerPage, setYearPickerPage }) => { return /*#__PURE__*/jsx(Grid, { children: /*#__PURE__*/jsx(FocusScope, { contain: true, restoreFocus: true, autoFocus: true, children: /*#__PURE__*/jsx(GridFocusManager, { year: selectedYear, setFocusedYear: setFocusedYear, yearPickerPage: yearPickerPage, setYearPickerPage: setYearPickerPage }) }) }); }; export { YearGrid };