Skip to content

Commit

Permalink
[v3] avoid focus-visible style being cut off by overflow-hidden (#3160)
Browse files Browse the repository at this point in the history
aa
  • Loading branch information
dimaMachina authored Aug 31, 2024
1 parent db3b48d commit f662237
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 23 deletions.
6 changes: 6 additions & 0 deletions .changeset/short-icons-impress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'nextra-theme-docs': patch
'nextra': patch
---

avoid focus-visible style being cut off by overflow-hidden
2 changes: 1 addition & 1 deletion examples/swr-site/pages/en/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Callout, Tabs } from 'nextra/components'
{/* wrapped with {} to mark it as javascript so mdx will not put it under a p tag */}
{<h1 className="text-center font-extrabold md:text-5xl mt-8">SWR</h1>}

<Tabs items={['JavaScript', 'C++', {label:'C', disabled: true}, 'Python']} defaultIndex={1}>
<Tabs items={['JavaScript', 'C++', {label:'C', disabled: true}, 'Python', 'TypeScript', 'GraphQL', 'Rust', 'C#', 'Go', 'HTML', 'CSS', 'plaintext', 'bash']} defaultIndex={1}>
<Tabs.Tab>
```js filename="hi.js"
import { useState, useEffect } from 'react';
Expand Down
4 changes: 2 additions & 2 deletions packages/nextra-theme-docs/src/components/collapse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function Collapse({
} else {
container.style.height = `${inner.clientHeight}px`
}

container.style.overflow = isOpen ? '' : 'hidden'
if (isOpen) {
animationRef.current = window.setTimeout(() => {
// should be style property in kebab-case, not css class name
Expand All @@ -62,7 +62,7 @@ export function Collapse({
return (
<div
ref={containerRef}
className="_transform-gpu _overflow-hidden _transition-all _ease-in-out motion-reduce:_transition-none"
className="_transform-gpu _transition-all _ease-in-out motion-reduce:_transition-none"
style={initialOpen.current || horizontal ? undefined : { height: 0 }}
>
<div
Expand Down
5 changes: 3 additions & 2 deletions packages/nextra-theme-docs/src/components/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ export function Sidebar({
>
<div
className={cn(
'_overflow-y-auto _overflow-x-hidden',
'_overflow-y-auto',
'_p-4 _grow md:_h-[calc(100vh-var(--nextra-navbar-height)-var(--nextra-menu-height))]',
showSidebar ? 'nextra-scrollbar' : 'no-scrollbar'
)}
Expand Down Expand Up @@ -444,7 +444,8 @@ export function Sidebar({
<div
className={cn(
'nextra-sidebar-footer _sticky _bottom-0',
'_flex _items-center _gap-2 _mx-4 _py-4',
'_flex _items-center _gap-2 _py-4',
'_mx-3 _px-1', // to hide focused sidebar links
showSidebar
? hasI18n && '_justify-end'
: '_py-4 _flex-wrap _justify-center'
Expand Down
19 changes: 10 additions & 9 deletions packages/nextra-theme-docs/src/components/toc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ export function TOC({ toc, filePath }: TOCProps): ReactElement {
block: 'center',
inline: 'center',
scrollMode: 'always',
boundary: tocRef.current
boundary: tocRef.current!.parentElement
})
}
}, [activeSlug])

return (
<div
className={cn(
'nextra-scrollbar _sticky _top-16 _overflow-y-auto _pr-4 _pt-6 _text-sm [hyphens:auto]',
'nextra-scrollbar _sticky _top-16 _overflow-y-auto _px-4 _pt-6 _text-sm [hyphens:auto]',
'_max-h-[calc(100vh-var(--nextra-navbar-height)-env(safe-area-inset-bottom))] ltr:_-mr-4 rtl:_-ml-4'
)}
>
Expand All @@ -74,16 +74,16 @@ export function TOC({ toc, filePath }: TOCProps): ReactElement {
className={cn(
{
2: '_font-semibold',
3: 'ltr:_pl-4 rtl:_pr-4',
4: 'ltr:_pl-8 rtl:_pr-8',
5: 'ltr:_pl-12 rtl:_pr-12',
6: 'ltr:_pl-16 rtl:_pr-16'
3: 'ltr:_ml-4 rtl:_mr-4',
4: 'ltr:_ml-8 rtl:_mr-8',
5: 'ltr:_ml-12 rtl:_mr-12',
6: 'ltr:_ml-16 rtl:_mr-16'
}[depth],
'_inline-block _transition-colors _subpixel-antialiased',
'_block _transition-colors _subpixel-antialiased',
activeAnchor[id]?.isActive
? '_text-primary-600 contrast-more:!_text-primary-600'
: '_text-gray-500 hover:_text-gray-900 dark:_text-gray-400 dark:hover:_text-gray-300',
'contrast-more:_text-gray-900 contrast-more:_underline contrast-more:dark:_text-gray-50 _w-full _break-words'
'contrast-more:_text-gray-900 contrast-more:_underline contrast-more:dark:_text-gray-50 _break-words'
)}
>
{removeLinks(value)}
Expand All @@ -98,7 +98,8 @@ export function TOC({ toc, filePath }: TOCProps): ReactElement {
<div
className={cn(
hasHeadings && 'nextra-toc-footer _mt-8 _pt-8',
'_sticky _bottom-0 _flex _flex-col _items-start _gap-2 _pb-8'
'_sticky _bottom-0 _flex _flex-col _items-start _gap-2 _pb-8',
'_-mx-1 _px-1' // to hide focused toc links
)}
>
{themeConfig.feedback.content ? (
Expand Down
5 changes: 1 addition & 4 deletions packages/nextra-theme-docs/src/mdx-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -369,10 +369,7 @@ const DEFAULT_COMPONENTS: MDXComponents = {
<nav className={classes.toc} aria-label="table of contents" />
)
) : (
<nav
className={cn(classes.toc, '_px-4')}
aria-label="table of contents"
>
<nav className={classes.toc} aria-label="table of contents">
{renderComponent(themeConfig.toc.component, {
toc: themeConfig.toc.float ? toc : [],
filePath: config.filePath
Expand Down
14 changes: 9 additions & 5 deletions packages/nextra/src/client/components/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import cn from 'clsx'
import type { ComponentProps, ReactElement, ReactNode } from 'react'
import { useCallback, useEffect, useState } from 'react'

type TabItem = string | ReactNode
type TabItem = string | ReactElement

type TabObjectItem = {
label: TabItem
Expand Down Expand Up @@ -80,8 +80,11 @@ function Tabs_({
defaultIndex={defaultIndex}
onChange={handleChange}
>
<div className="nextra-scrollbar _overflow-x-auto _overflow-y-hidden _overscroll-x-contain">
<HeadlessTab.List className="_mt-4 _flex _w-max _min-w-full _border-b _border-gray-200 _pb-px dark:_border-neutral-800">
<div
className={cn('nextra-scrollbar _overflow-x-auto')}
tabIndex={-1} // disables focus in Firefox
>
<HeadlessTab.List className="_mt-4 _flex _w-max _min-w-full _gap-2 _border-b _border-gray-200 _pb-px dark:_border-neutral-800">
{items.map((item, index) => {
const disabled = isTabObjectItem(item) && item.disabled
return (
Expand All @@ -90,7 +93,8 @@ function Tabs_({
disabled={disabled}
className={({ selected }) =>
cn(
'_mr-2 _rounded-t _p-2 _font-medium _leading-5 _transition-colors',
'_ring-inset',
'_rounded-t _p-2 _font-medium _leading-5 _transition-colors',
'_-mb-0.5 _select-none _border-b-2',
selected
? '_border-primary-500 _text-primary-600'
Expand Down Expand Up @@ -118,7 +122,7 @@ function Tab({
...props
}: Omit<ComponentProps<typeof HeadlessTab.Panel>, 'static'>): ReactElement {
return (
<HeadlessTab.Panel {...props} unmount={unmount} className="_rounded _pt-6">
<HeadlessTab.Panel {...props} unmount={unmount} className="_rounded _mt-6">
{children}
</HeadlessTab.Panel>
)
Expand Down

0 comments on commit f662237

Please sign in to comment.