Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
{
"mcp": {
"servers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
},
"typescript.tsdk": "node_modules/typescript/lib",
"editor.formatOnSave": true,
"[javascript]": {
Expand All @@ -17,10 +25,7 @@
"source.fixAll.stylelint": "explicit"
}
},
"stylelint.validate": [
"css",
"postcss"
],
"stylelint.validate": ["css", "postcss"],
"json.schemas": [
{
"fileMatch": ["*.docs.json"],
Expand Down
2 changes: 1 addition & 1 deletion examples/nextjs/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import './.next/types/routes.d.ts'
import "./.next/dev/types/routes.d.ts";

Check failure on line 3 in examples/nextjs/next-env.d.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `"./.next/dev/types/routes.d.ts";` with `'./.next/dev/types/routes.d.ts'`

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
42 changes: 42 additions & 0 deletions examples/nextjs/src/app/underlinenav/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use client'

import React from 'react'
import {UnderlineNav} from '@primer/react'

export default function UnderlineNavPage() {
const [selectedIndex, setSelectedIndex] = React.useState<number | null>(1)

const items: {navigation: string; counter?: number | string; href?: string}[] = [
{navigation: 'Code', href: '#code'},
{navigation: 'Issues', counter: '12K', href: '#issues'},
{navigation: 'Pull Requests', counter: 13, href: '#pull-requests'},
{navigation: 'Discussions', counter: 5, href: '#discussions'},
{navigation: 'Actions', counter: 4, href: '#actions'},
{navigation: 'Projects', counter: 9, href: '#projects'},
{navigation: 'Insights', counter: '0', href: '#insights'},
{navigation: 'Settings', counter: 10, href: '#settings'},
{navigation: 'Security', href: '#security'},
]

return (
<div style={{margin: '0 auto', padding: '16px'}}>
<h1 style={{marginBottom: '16px'}}>UnderlineNav - Overflow on Narrow Screen</h1>
<UnderlineNav aria-label="Repository">
{items.map((item, index) => (
<UnderlineNav.Item
key={item.navigation}
aria-current={index === selectedIndex ? 'page' : undefined}
onSelect={event => {
event.preventDefault()
setSelectedIndex(index)
}}
counter={item.counter}
href={item.href}
>
{item.navigation}
</UnderlineNav.Item>
))}
</UnderlineNav>
</div>
)
}
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
],
"scripts": {
"build": "./script/build",
"build:components": "npx rollup -c",
"clean": "rimraf dist generated",
"start": "concurrently npm:start:*",
"start:storybook": "STORYBOOK=true storybook dev -p 6006",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
/* stylelint-disable-next-line primer/box-shadow */
box-shadow: inset 0 -1px var(--borderColor-muted);

/* Hide overflow during SSR to prevent horizontal scrollbar before JS hydration calculates which items fit */
overflow: hidden;

&[data-ssr-hidden='false'] {
overflow: visible;
}

&[data-variant='flush'] {
/* stylelint-disable-next-line primer/spacing */
padding-inline: unset;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Used for UnderlineNav and UnderlinePanels components

import React from 'react'
import React, {useState} from 'react'
import {type ForwardedRef, forwardRef, type FC, type PropsWithChildren, type ElementType} from 'react'
import {isElement} from 'react-is'
import type {IconProps} from '@primer/octicons-react'
import CounterLabel from '../../CounterLabel'
import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../../utils/polymorphic'
import useIsomorphicLayoutEffect from '../../utils/useIsomorphicLayoutEffect'

import classes from './UnderlineTabbedInterface.module.css'
import {clsx} from 'clsx'
Expand All @@ -22,10 +23,19 @@ type UnderlineWrapperProps<As extends React.ElementType> = {

export const UnderlineWrapper = forwardRef((props, ref) => {
const {children, className, as: Component = 'div', ...rest} = props
// Track hydration state: true on server and initial client render, false after hydration
const [isSSR, setIsSSR] = useState(true)

useIsomorphicLayoutEffect(() => {
// After hydration, allow overflow to be visible
setIsSSR(false)
}, [])

return (
<Component
className={clsx(classes.UnderlineWrapper, className)}
ref={ref as ForwardedRef<HTMLDivElement>}
data-ssr-hidden={isSSR ? 'true' : 'false'}
{...rest}
>
{children}
Expand Down
Loading