-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(in-page-navigation): add new component package (#2827)
* feat(in-page-nav): add new package * chore: website description updates * chore(in-page-nav): add styling * chore(in-page-nav): add context * chore(in-page-nav): add fullWidth story * chore(in-page-nav): add changeset, update deps * chore(in-page-nav): run install * chore(in-page-nav): add tests * docs: in-page-navigation * docs: remove extra section * chore: add customization story * chore(in-page-nav): rename docs page * chore(in-page-nav): take out comments * docs: add in page nav vs tabs section * chore(in-page-nav): add deps, refactor styling * chore(in-page-nav): refactor, add global types * chore(in-page-nav): add unique label to stories * chore(in-page-nav): remove story comparisons * chore(in-page-nav): fix underline bug * chore: update overflow * fix: overflow issue * chore(in-page-nav): add padding * fix: overflow issue * chore: update site VRT Co-authored-by: Nora Krantz <[email protected]> Co-authored-by: TheSisb <[email protected]> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
- Loading branch information
1 parent
9c85685
commit 8290a1e
Showing
25 changed files
with
748 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
'@twilio-paste/in-page-navigation': major | ||
'@twilio-paste/core': minor | ||
--- | ||
|
||
[In Page Navigation] add a package for the navigation component In Page Navigation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
139 changes: 139 additions & 0 deletions
139
packages/paste-core/components/in-page-navigation/__tests__/index.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import * as React from 'react'; | ||
import {render} from '@testing-library/react'; | ||
import {CustomizationProvider} from '@twilio-paste/customization'; | ||
|
||
import {InPageNavigation, InPageNavigationItem} from '../src'; | ||
|
||
describe('InPageNavigation', () => { | ||
it('should render a nav with correct aria-label', () => { | ||
const {getByRole} = render( | ||
<InPageNavigation aria-label="my-nav"> | ||
<InPageNavigationItem href="#">page 1</InPageNavigationItem> | ||
<InPageNavigationItem href="#">page 2</InPageNavigationItem> | ||
</InPageNavigation> | ||
); | ||
|
||
expect(getByRole('navigation')).toHaveAttribute('aria-label', 'my-nav'); | ||
}); | ||
|
||
it('should render a list with list items and links', () => { | ||
const {getAllByRole} = render( | ||
<InPageNavigation aria-label="my-nav"> | ||
<InPageNavigationItem href="#">page 1</InPageNavigationItem> | ||
<InPageNavigationItem href="#">page 2</InPageNavigationItem> | ||
</InPageNavigation> | ||
); | ||
|
||
expect(getAllByRole('list')).toHaveLength(1); | ||
expect(getAllByRole('listitem')).toHaveLength(2); | ||
expect(getAllByRole('link')).toHaveLength(2); | ||
}); | ||
|
||
it('should use the currentPage prop to apply aria-current', () => { | ||
const {getByText} = render( | ||
<InPageNavigation aria-label="my-nav"> | ||
<InPageNavigationItem href="#">page 1</InPageNavigationItem> | ||
<InPageNavigationItem currentPage href="#"> | ||
page 2 | ||
</InPageNavigationItem> | ||
</InPageNavigation> | ||
); | ||
|
||
expect(getByText('page 2')).toHaveAttribute('aria-current', 'page'); | ||
}); | ||
|
||
it('should pass props given to InPageNavigationItem onto its <a> child', () => { | ||
const {getByText} = render( | ||
<InPageNavigation aria-label="my-nav"> | ||
<InPageNavigationItem data-test-id="page-1" href="#"> | ||
page 1 | ||
</InPageNavigationItem> | ||
<InPageNavigationItem currentPage href="#"> | ||
page 2 | ||
</InPageNavigationItem> | ||
</InPageNavigation> | ||
); | ||
|
||
expect(getByText('page 1')).toHaveAttribute('data-test-id', 'page-1'); | ||
}); | ||
}); | ||
|
||
describe('Customization', () => { | ||
it('should set a default element name', () => { | ||
const {getByRole} = render( | ||
<InPageNavigation aria-label="my-nav"> | ||
<InPageNavigationItem href="#">page 1</InPageNavigationItem> | ||
</InPageNavigation> | ||
); | ||
|
||
expect(getByRole('navigation')).toHaveAttribute('data-paste-element', 'IN_PAGE_NAVIGATION'); | ||
expect(getByRole('list')).toHaveAttribute('data-paste-element', 'IN_PAGE_NAVIGATION_ITEMS'); | ||
expect(getByRole('listitem')).toHaveAttribute('data-paste-element', 'IN_PAGE_NAVIGATION_ITEM'); | ||
expect(getByRole('link')).toHaveAttribute('data-paste-element', 'IN_PAGE_NAVIGATION_ITEM_ANCHOR'); | ||
}); | ||
|
||
it('should set a custom element name when provided', () => { | ||
const {getByRole} = render( | ||
<InPageNavigation element="MY_IN_PAGE_NAVIGATION" aria-label="my-nav"> | ||
<InPageNavigationItem element="MY_IN_PAGE_NAVIGATION_ITEM" href="#"> | ||
page 1 | ||
</InPageNavigationItem> | ||
</InPageNavigation> | ||
); | ||
|
||
expect(getByRole('navigation')).toHaveAttribute('data-paste-element', 'MY_IN_PAGE_NAVIGATION'); | ||
expect(getByRole('list')).toHaveAttribute('data-paste-element', 'MY_IN_PAGE_NAVIGATION_ITEMS'); | ||
expect(getByRole('listitem')).toHaveAttribute('data-paste-element', 'MY_IN_PAGE_NAVIGATION_ITEM'); | ||
expect(getByRole('link')).toHaveAttribute('data-paste-element', 'MY_IN_PAGE_NAVIGATION_ITEM_ANCHOR'); | ||
}); | ||
|
||
it('should add custom styles to default element names', () => { | ||
const {getByRole} = render( | ||
<CustomizationProvider | ||
baseTheme="default" | ||
theme={TestTheme} | ||
elements={{ | ||
IN_PAGE_NAVIGATION: {fontWeight: 'fontWeightLight'}, | ||
IN_PAGE_NAVIGATION_ITEMS: {padding: 'space40'}, | ||
IN_PAGE_NAVIGATION_ITEM: {margin: 'space40'}, | ||
IN_PAGE_NAVIGATION_ITEM_ANCHOR: {fontSize: 'fontSize40'}, | ||
}} | ||
> | ||
<InPageNavigation aria-label="my-nav"> | ||
<InPageNavigationItem href="#">page 1</InPageNavigationItem> | ||
</InPageNavigation> | ||
</CustomizationProvider> | ||
); | ||
|
||
expect(getByRole('navigation')).toHaveStyleRule('font-weight', '400'); | ||
expect(getByRole('list')).toHaveStyleRule('padding', '0.75rem'); | ||
expect(getByRole('listitem')).toHaveStyleRule('margin', '0.75rem'); | ||
expect(getByRole('link')).toHaveStyleRule('font-size', '1rem'); | ||
}); | ||
|
||
it('should add custom styles to custom element names', () => { | ||
const {getByRole} = render( | ||
<CustomizationProvider | ||
baseTheme="default" | ||
theme={TestTheme} | ||
elements={{ | ||
MY_IN_PAGE_NAVIGATION: {fontWeight: 'fontWeightLight'}, | ||
MY_IN_PAGE_NAVIGATION_ITEMS: {padding: 'space40'}, | ||
MY_IN_PAGE_NAVIGATION_ITEM: {margin: 'space40'}, | ||
MY_IN_PAGE_NAVIGATION_ITEM_ANCHOR: {fontSize: 'fontSize40'}, | ||
}} | ||
> | ||
<InPageNavigation element="MY_IN_PAGE_NAVIGATION" aria-label="my-nav"> | ||
<InPageNavigationItem element="MY_IN_PAGE_NAVIGATION_ITEM" href="#"> | ||
page 1 | ||
</InPageNavigationItem> | ||
</InPageNavigation> | ||
</CustomizationProvider> | ||
); | ||
|
||
expect(getByRole('navigation')).toHaveStyleRule('font-weight', '400'); | ||
expect(getByRole('list')).toHaveStyleRule('padding', '0.75rem'); | ||
expect(getByRole('listitem')).toHaveStyleRule('margin', '0.75rem'); | ||
expect(getByRole('link')).toHaveStyleRule('font-size', '1rem'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
const {build} = require('../../../../tools/build/esbuild'); | ||
|
||
build(require('./package.json')); |
60 changes: 60 additions & 0 deletions
60
packages/paste-core/components/in-page-navigation/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
{ | ||
"name": "@twilio-paste/in-page-navigation", | ||
"version": "0.0.0", | ||
"category": "navigation", | ||
"status": "production", | ||
"description": "An In Page Navigation is a group of styled links that lets users navigate between related pages.", | ||
"author": "Twilio Inc.", | ||
"license": "MIT", | ||
"main:dev": "src/index.tsx", | ||
"main": "dist/index.js", | ||
"module": "dist/index.es.js", | ||
"types": "dist/index.d.ts", | ||
"sideEffects": false, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"files": [ | ||
"dist" | ||
], | ||
"scripts": { | ||
"build": "yarn clean && NODE_ENV=production node build.js && tsc", | ||
"build:js": "NODE_ENV=development node build.js", | ||
"build:props": "typedoc --tsconfig ./tsconfig.json --json ./dist/prop-types.json", | ||
"clean": "rm -rf ./dist", | ||
"tsc": "tsc" | ||
}, | ||
"peerDependencies": { | ||
"@twilio-paste/anchor": "^9.0.1", | ||
"@twilio-paste/animation-library": "^0.3.2", | ||
"@twilio-paste/box": "^7.0.0", | ||
"@twilio-paste/customization": "^5.0.0", | ||
"@twilio-paste/design-tokens": "^8.0.0", | ||
"@twilio-paste/icons": "^9.4.0", | ||
"@twilio-paste/style-props": "^6.0.0", | ||
"@twilio-paste/styling-library": "^1.0.0", | ||
"@twilio-paste/theme": "^8.0.0", | ||
"@twilio-paste/types": "^3.1.1", | ||
"@twilio-paste/uid-library": "^0.2.6", | ||
"prop-types": "^15.7.2", | ||
"react": "^16.8.6 || ^17.0.2", | ||
"react-dom": "^16.8.6 || ^17.0.2" | ||
}, | ||
"devDependencies": { | ||
"@twilio-paste/anchor": "^9.0.1", | ||
"@twilio-paste/animation-library": "^0.3.2", | ||
"@twilio-paste/box": "^7.0.0", | ||
"@twilio-paste/customization": "^5.0.0", | ||
"@twilio-paste/design-tokens": "^8.0.0", | ||
"@twilio-paste/icons": "^9.4.0", | ||
"@twilio-paste/style-props": "^6.0.0", | ||
"@twilio-paste/styling-library": "^1.0.0", | ||
"@twilio-paste/theme": "^8.0.0", | ||
"@twilio-paste/types": "^3.1.1", | ||
"@twilio-paste/uid-library": "^0.2.6", | ||
"prop-types": "^15.7.2", | ||
"react": "^17.0.2", | ||
"react-dom": "^17.0.2", | ||
"typescript": "^4.6.4" | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
packages/paste-core/components/in-page-navigation/src/InPageNavigation.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import * as React from 'react'; | ||
import * as PropTypes from 'prop-types'; | ||
import {Box, safelySpreadBoxProps} from '@twilio-paste/box'; | ||
import type {BoxProps} from '@twilio-paste/box'; | ||
|
||
import type {Variants} from './types'; | ||
import {InPageNavigationContext} from './InPageNavigationContext'; | ||
|
||
export interface InPageNavigationProps extends Omit<React.ComponentPropsWithRef<'div'>, 'children'> { | ||
children?: React.ReactNode; | ||
element?: BoxProps['element']; | ||
'aria-label': string; | ||
variant?: Variants; | ||
} | ||
|
||
const InPageNavigation = React.forwardRef<HTMLDivElement, InPageNavigationProps>( | ||
({element = 'IN_PAGE_NAVIGATION', variant = 'default', children, ...props}, ref) => { | ||
return ( | ||
<InPageNavigationContext.Provider value={{variant}}> | ||
<Box {...safelySpreadBoxProps(props)} as="nav" ref={ref} element={element}> | ||
<Box | ||
as="ul" | ||
listStyleType="none" | ||
element={`${element}_ITEMS`} | ||
display="flex" | ||
justifyContent={variant === 'fullWidth' ? 'space-evenly' : 'flex-start'} | ||
borderBottomWidth="borderWidth10" | ||
borderBottomColor="colorBorderWeak" | ||
borderBottomStyle="solid" | ||
margin="space0" | ||
marginBottom="space60" | ||
paddingLeft="space0" | ||
paddingRight={variant === 'default' ? 'space70' : 'space0'} | ||
columnGap={variant === 'default' ? 'space70' : 'space0'} | ||
> | ||
{children} | ||
</Box> | ||
</Box> | ||
</InPageNavigationContext.Provider> | ||
); | ||
} | ||
); | ||
|
||
InPageNavigation.displayName = 'InPageNavigation'; | ||
|
||
InPageNavigation.propTypes = { | ||
children: PropTypes.node, | ||
element: PropTypes.string, | ||
'aria-label': PropTypes.string.isRequired, | ||
variant: PropTypes.oneOf(['fullWidth', 'default']), | ||
}; | ||
|
||
export {InPageNavigation}; |
13 changes: 13 additions & 0 deletions
13
packages/paste-core/components/in-page-navigation/src/InPageNavigationContext.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import * as React from 'react'; | ||
|
||
import type {Variants} from './types'; | ||
|
||
interface InPageNavigationContextValue { | ||
variant?: Variants; | ||
} | ||
|
||
const InPageNavigationContext = React.createContext<InPageNavigationContextValue>({ | ||
variant: 'default', | ||
}); | ||
|
||
export {InPageNavigationContext}; |
Oops, something went wrong.