mirror of
https://github.com/zhigang1992/react.git
synced 2026-02-01 17:18:41 +08:00
refactor(breadcrumbs): auto assign separator to crumbs item
docs(breadcrumbs): update docs
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Breadcrumbs should redefined all separators 1`] = `
|
||||
"<nav class=\\"\\"><span class=\\"breadcrums-item\\">test-1</span><div class=\\"separator \\">*<style>
|
||||
"<nav class=\\"\\"><span class=\\"breadcrums-item \\">test-1</span><div class=\\"separator \\">*<style>
|
||||
.separator {
|
||||
display: inline-flex;
|
||||
margin: 0 8px;
|
||||
@@ -9,93 +9,77 @@ exports[`Breadcrumbs should redefined all separators 1`] = `
|
||||
pointer-events: none;
|
||||
align-items: center;
|
||||
}
|
||||
</style></div><span class=\\"breadcrums-item\\">test-2</span><div class=\\"separator \\">*<style>
|
||||
.separator {
|
||||
display: inline-flex;
|
||||
margin: 0 8px;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
</style></div><span class=\\"breadcrums-item \\">test-2</span><style>
|
||||
nav {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: inherit;
|
||||
color: #888;
|
||||
font-size: 1rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style></div><style>
|
||||
nav {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: inherit;
|
||||
color: #888;
|
||||
font-size: 1rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
nav :global(.link:hover) {
|
||||
color: rgba(0, 112, 243, 0.85);
|
||||
}
|
||||
nav :global(.link:hover) {
|
||||
color: rgba(0, 112, 243, 0.85);
|
||||
}
|
||||
|
||||
nav > :global(span:last-of-type) {
|
||||
color: #444;
|
||||
}
|
||||
nav > :global(span:last-of-type) {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
nav > :global(.separator:last-child) {
|
||||
display: none;
|
||||
}
|
||||
nav > :global(.separator:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
nav :global(svg) {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin: 0 4px;
|
||||
}
|
||||
nav :global(svg) {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
nav :global(.breadcrums-item) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style></nav>"
|
||||
nav :global(.breadcrums-item) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style></nav>"
|
||||
`;
|
||||
|
||||
exports[`Breadcrumbs should render correctly 1`] = `
|
||||
"<nav class=\\"\\"><span class=\\"breadcrums-item\\">test-1</span><div class=\\"separator \\">/<style>
|
||||
.separator {
|
||||
display: inline-flex;
|
||||
margin: 0 8px;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
"<nav class=\\"\\"><span class=\\"breadcrums-item \\">test-1</span><style>
|
||||
nav {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: inherit;
|
||||
color: #888;
|
||||
font-size: 1rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style></div><style>
|
||||
nav {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: inherit;
|
||||
color: #888;
|
||||
font-size: 1rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
nav :global(.link:hover) {
|
||||
color: rgba(0, 112, 243, 0.85);
|
||||
}
|
||||
nav :global(.link:hover) {
|
||||
color: rgba(0, 112, 243, 0.85);
|
||||
}
|
||||
|
||||
nav > :global(span:last-of-type) {
|
||||
color: #444;
|
||||
}
|
||||
nav > :global(span:last-of-type) {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
nav > :global(.separator:last-child) {
|
||||
display: none;
|
||||
}
|
||||
nav > :global(.separator:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
nav :global(svg) {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin: 0 4px;
|
||||
}
|
||||
nav :global(svg) {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
nav :global(.breadcrums-item) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style></nav>"
|
||||
nav :global(.breadcrums-item) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style></nav>"
|
||||
`;
|
||||
|
||||
@@ -28,10 +28,8 @@ describe('Breadcrumbs', () => {
|
||||
it('the specified separator should be redefined', () => {
|
||||
const wrapper = mount(
|
||||
<Breadcrumbs separator="*">
|
||||
<Breadcrumbs.Item>
|
||||
test-1
|
||||
<Breadcrumbs.Separator>%</Breadcrumbs.Separator>
|
||||
</Breadcrumbs.Item>
|
||||
<Breadcrumbs.Item>test-1</Breadcrumbs.Item>
|
||||
<Breadcrumbs.Separator>%</Breadcrumbs.Separator>
|
||||
<Breadcrumbs.Item>test-2</Breadcrumbs.Item>
|
||||
</Breadcrumbs>,
|
||||
)
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
export interface BreadcrumbsConfig {
|
||||
separator?: string
|
||||
}
|
||||
|
||||
const defaultContext = {}
|
||||
|
||||
export const BreadcrumbsContext = React.createContext<BreadcrumbsConfig>(defaultContext)
|
||||
|
||||
export const useBreadcrumbsContext = (): BreadcrumbsConfig =>
|
||||
React.useContext<BreadcrumbsConfig>(BreadcrumbsContext)
|
||||
@@ -4,7 +4,6 @@ import React, { useMemo } from 'react'
|
||||
import withDefaults from '../utils/with-defaults'
|
||||
import { pickChild } from '../utils/collections'
|
||||
import BreadcrumbsSeparator from './breadcrumbs-separator'
|
||||
import { useBreadcrumbsContext } from './breadcrumbs-context'
|
||||
|
||||
interface Props {
|
||||
href?: string
|
||||
@@ -30,41 +29,29 @@ const BreadcrumbsItem = React.forwardRef<
|
||||
{ href, nextLink, onClick, children, className, ...props },
|
||||
ref: React.Ref<HTMLAnchorElement>,
|
||||
) => {
|
||||
const { separator } = useBreadcrumbsContext()
|
||||
const isLink = useMemo(() => href !== undefined || nextLink, [href, nextLink])
|
||||
const [withoutSepChildren, sepChildren] = pickChild(children, BreadcrumbsSeparator)
|
||||
const composeSeparator = useMemo(() => {
|
||||
if (React.Children.count(sepChildren) > 0) return sepChildren
|
||||
return <BreadcrumbsSeparator>{separator}</BreadcrumbsSeparator>
|
||||
}, [separator])
|
||||
|
||||
const [withoutSepChildren] = pickChild(children, BreadcrumbsSeparator)
|
||||
const clickHandler = (event: React.MouseEvent) => {
|
||||
onClick && onClick(event)
|
||||
}
|
||||
|
||||
if (!isLink) {
|
||||
return (
|
||||
<>
|
||||
<span className="breadcrums-item" onClick={clickHandler}>
|
||||
{withoutSepChildren}
|
||||
</span>
|
||||
{composeSeparator}
|
||||
</>
|
||||
<span className={`breadcrums-item ${className}`} onClick={clickHandler}>
|
||||
{withoutSepChildren}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Link
|
||||
className={`breadcrums-item ${className}`}
|
||||
href={href}
|
||||
onClick={clickHandler}
|
||||
ref={ref}
|
||||
{...props}>
|
||||
{withoutSepChildren}
|
||||
</Link>
|
||||
{composeSeparator}
|
||||
</>
|
||||
<Link
|
||||
className={`breadcrums-item ${className}`}
|
||||
href={href}
|
||||
onClick={clickHandler}
|
||||
ref={ref}
|
||||
{...props}>
|
||||
{withoutSepChildren}
|
||||
</Link>
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react'
|
||||
// import useTheme from '../styles/use-theme'
|
||||
import withDefaults from '../utils/with-defaults'
|
||||
|
||||
interface Props {
|
||||
@@ -17,8 +16,6 @@ const BreadcrumbsSeparator: React.FC<React.PropsWithChildren<BreadcrumbsProps>>
|
||||
children,
|
||||
className,
|
||||
}) => {
|
||||
// const theme = useTheme()
|
||||
|
||||
return (
|
||||
<div className={`separator ${className}`}>
|
||||
{children}
|
||||
|
||||
@@ -3,8 +3,7 @@ import useTheme from '../styles/use-theme'
|
||||
import BreadcrumbsItem from './breadcrumbs-item'
|
||||
import BreadcrumbsSeparator from './breadcrumbs-separator'
|
||||
import { addColorAlpha } from '../utils/color'
|
||||
import { BreadcrumbsContext } from './breadcrumbs-context'
|
||||
import { NormalSizes } from 'components/utils/prop-types'
|
||||
import { NormalSizes } from '../utils/prop-types'
|
||||
|
||||
interface Props {
|
||||
size: NormalSizes
|
||||
@@ -38,55 +37,67 @@ const Breadcrumbs: React.FC<React.PropsWithChildren<BreadcrumbsProps>> = ({
|
||||
className,
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const initialValue = useMemo(
|
||||
() => ({
|
||||
separator,
|
||||
}),
|
||||
[separator],
|
||||
)
|
||||
const fontSize = useMemo(() => getSize(size), [size])
|
||||
const hoverColor = useMemo(() => {
|
||||
return addColorAlpha(theme.palette.link, 0.85)
|
||||
}, [theme.palette.link])
|
||||
|
||||
const childrenArray = React.Children.toArray(children)
|
||||
const withSeparatorChildren = childrenArray.map((item, index) => {
|
||||
if (!React.isValidElement(item)) return item
|
||||
const last = childrenArray[index - 1]
|
||||
const lastIsSeparator = React.isValidElement(last) && last.type === BreadcrumbsSeparator
|
||||
const currentIsSeparator = item.type === BreadcrumbsSeparator
|
||||
if (!lastIsSeparator && !currentIsSeparator && index > 0) {
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
<BreadcrumbsSeparator>{separator}</BreadcrumbsSeparator>
|
||||
{item}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
return item
|
||||
})
|
||||
|
||||
return (
|
||||
<BreadcrumbsContext.Provider value={initialValue}>
|
||||
<nav className={className}>
|
||||
{children}
|
||||
<style jsx>{`
|
||||
nav {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: inherit;
|
||||
color: ${theme.palette.accents_4};
|
||||
font-size: ${fontSize};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
<nav className={className}>
|
||||
{withSeparatorChildren}
|
||||
<style jsx>{`
|
||||
nav {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: inherit;
|
||||
color: ${theme.palette.accents_4};
|
||||
font-size: ${fontSize};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
nav :global(.link:hover) {
|
||||
color: ${addColorAlpha(theme.palette.link, 0.85)};
|
||||
}
|
||||
nav :global(.link:hover) {
|
||||
color: ${hoverColor};
|
||||
}
|
||||
|
||||
nav > :global(span:last-of-type) {
|
||||
color: ${theme.palette.accents_6};
|
||||
}
|
||||
nav > :global(span:last-of-type) {
|
||||
color: ${theme.palette.accents_6};
|
||||
}
|
||||
|
||||
nav > :global(.separator:last-child) {
|
||||
display: none;
|
||||
}
|
||||
nav > :global(.separator:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
nav :global(svg) {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin: 0 4px;
|
||||
}
|
||||
nav :global(svg) {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
nav :global(.breadcrums-item) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
`}</style>
|
||||
</nav>
|
||||
</BreadcrumbsContext.Provider>
|
||||
nav :global(.breadcrums-item) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
`}</style>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -64,10 +64,8 @@ Show where users are in the application.
|
||||
</Breadcrumbs>
|
||||
<Spacer y={.5} />
|
||||
<Breadcrumbs separator=">">
|
||||
<Breadcrumbs.Item>
|
||||
Home
|
||||
<Breadcrumbs.Separator>:</Breadcrumbs.Separator>
|
||||
</Breadcrumbs.Item>
|
||||
<Breadcrumbs.Item>Home</Breadcrumbs.Item>
|
||||
<Breadcrumbs.Separator>:</Breadcrumbs.Separator>
|
||||
<Breadcrumbs.Item href="">Components</Breadcrumbs.Item>
|
||||
<Breadcrumbs.Item href="">Basic</Breadcrumbs.Item>
|
||||
<Breadcrumbs.Item>Button</Breadcrumbs.Item>
|
||||
|
||||
@@ -64,10 +64,8 @@ export const meta = {
|
||||
</Breadcrumbs>
|
||||
<Spacer y={.5} />
|
||||
<Breadcrumbs separator=">">
|
||||
<Breadcrumbs.Item>
|
||||
Home
|
||||
<Breadcrumbs.Separator>:</Breadcrumbs.Separator>
|
||||
</Breadcrumbs.Item>
|
||||
<Breadcrumbs.Item>Home</Breadcrumbs.Item>
|
||||
<Breadcrumbs.Separator>:</Breadcrumbs.Separator>
|
||||
<Breadcrumbs.Item href="">Components</Breadcrumbs.Item>
|
||||
<Breadcrumbs.Item href="">Basic</Breadcrumbs.Item>
|
||||
<Breadcrumbs.Item >Button</Breadcrumbs.Item>
|
||||
|
||||
Reference in New Issue
Block a user