mirror of https://github.com/acid-info/lsd.git
refactor: refactor breadcrumb component
This commit is contained in:
parent
9c97071103
commit
4cb6e5a541
|
@ -2,15 +2,7 @@ export const breadcrumbClasses = {
|
|||
root: `lsd-breadcrumb`,
|
||||
list: `lsd-breadcrumb-list`,
|
||||
|
||||
trigger: `lsd-breadcrumb-trigger`,
|
||||
triggerLabel: `lsd-breadcrumb-trigger__label`,
|
||||
triggerIcons: `lsd-breadcrumb-trigger-icons`,
|
||||
triggerIcon: `lsd-breadcrumb-trigger-icons__icon`,
|
||||
triggerMenuIcon: `lsd-breadcrumb-trigger-icons__menu-icon`,
|
||||
|
||||
listBox: 'lsd-breadcrumb-list-box',
|
||||
listBoxLarge: 'lsd-breadcrumb-list-box-large',
|
||||
listBoxMedium: 'lsd-breadcrumb-list-box-medium',
|
||||
|
||||
open: 'lsd-breadcrumb--open',
|
||||
disabled: 'lsd-breadcrumb--disabled',
|
||||
|
|
|
@ -11,13 +11,6 @@ export default {
|
|||
value: ['small', 'medium', 'large'],
|
||||
},
|
||||
},
|
||||
maxItems: {
|
||||
control: {
|
||||
type: 'number',
|
||||
min: 2,
|
||||
max: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as Meta
|
||||
|
||||
|
|
|
@ -26,21 +26,12 @@ export const BreadcrumbStyles = css`
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 400px;
|
||||
max-width: 148px;
|
||||
overflow: auto;
|
||||
border: 1px solid rgb(var(--lsd-border-primary));
|
||||
margin-top: 10px;
|
||||
margin-left: 20px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
// Portal cannot be ralatively positioned
|
||||
.${breadcrumbClasses.listBoxLarge} {
|
||||
margin-left: 92px;
|
||||
}
|
||||
|
||||
// Portal cannot be ralatively positioned
|
||||
.${breadcrumbClasses.listBoxMedium} {
|
||||
margin-left: 82px;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.${breadcrumbClasses.listBox} > a {
|
||||
|
|
|
@ -39,8 +39,29 @@ export const Breadcrumb: React.FC<BreadcrumbProps> & {
|
|||
options = [],
|
||||
...props
|
||||
}) => {
|
||||
const ref = useRef<HTMLUListElement>(null)
|
||||
const [open, setOpen] = useState(false)
|
||||
const ellipsisRef = useRef<HTMLLIElement>(null)
|
||||
const [open, setOpen] = useState<boolean>(false)
|
||||
|
||||
maxItems = Math.max(1, Math.min(maxItems || 1, options.length))
|
||||
|
||||
const [root, ...rest] = options
|
||||
const [collapsed, visible] = !ellipsis
|
||||
? [[], rest]
|
||||
: [
|
||||
rest.slice(0, rest.length - maxItems + 1),
|
||||
rest.slice(rest.length - maxItems + 1),
|
||||
]
|
||||
|
||||
const renderItems = (items: BreadcrumbOption[]) =>
|
||||
items.map((item, idx) => (
|
||||
<BreadcrumbItem
|
||||
key={idx}
|
||||
current={idx === visible.length - 1}
|
||||
label={item.value}
|
||||
size={size}
|
||||
link={item.link}
|
||||
/>
|
||||
))
|
||||
|
||||
const onTrigger = () => {
|
||||
!disabled && setOpen((value) => !value)
|
||||
|
@ -61,64 +82,33 @@ export const Breadcrumb: React.FC<BreadcrumbProps> & {
|
|||
open && breadcrumbClasses.open,
|
||||
)}
|
||||
>
|
||||
<ul ref={ref} className={breadcrumbClasses.list}>
|
||||
{!ellipsis || maxItems === options.length
|
||||
? options.map((opt, idx) => (
|
||||
<BreadcrumbItem
|
||||
current={idx === options.length - 1}
|
||||
label={opt.value}
|
||||
size={size}
|
||||
link={opt.link}
|
||||
/>
|
||||
))
|
||||
: options.map((opt, idx) => {
|
||||
if (idx === 1)
|
||||
return (
|
||||
<BreadcrumbItem
|
||||
size={size}
|
||||
label={'...'}
|
||||
onClick={onTrigger}
|
||||
/>
|
||||
)
|
||||
else if (
|
||||
maxItems &&
|
||||
maxItems > 1 &&
|
||||
maxItems < options.length &&
|
||||
idx > 1 &&
|
||||
idx < options.length - maxItems + 1
|
||||
)
|
||||
return null
|
||||
else
|
||||
return (
|
||||
<BreadcrumbItem
|
||||
current={idx === options.length - 1}
|
||||
label={opt.value}
|
||||
size={size}
|
||||
link={opt.link}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
<ul className={breadcrumbClasses.list}>
|
||||
{root && renderItems([root])}
|
||||
{collapsed.length > 0 && (
|
||||
<BreadcrumbItem
|
||||
ellipsisRef={ellipsisRef}
|
||||
size={size}
|
||||
label={'...'}
|
||||
onClick={onTrigger}
|
||||
/>
|
||||
)}
|
||||
{renderItems(visible)}
|
||||
</ul>
|
||||
{ellipsis && maxItems && (
|
||||
{ellipsisRef?.current != null && ellipsis && maxItems && (
|
||||
<Portal id="breadcrumb">
|
||||
<ListBox
|
||||
handleRef={ref}
|
||||
handleRef={ellipsisRef}
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
className={clsx(
|
||||
breadcrumbClasses.listBox,
|
||||
size === 'large'
|
||||
? breadcrumbClasses.listBoxLarge
|
||||
: breadcrumbClasses.listBoxMedium,
|
||||
)}
|
||||
className={clsx(breadcrumbClasses.listBox)}
|
||||
>
|
||||
{options.slice(1, options.length - maxItems + 1).map((opt) => (
|
||||
{collapsed.map((opt) => (
|
||||
<Typography
|
||||
color="primary"
|
||||
component="a"
|
||||
href={opt.link}
|
||||
variant={size === 'large' ? 'label1' : 'label2'}
|
||||
className={breadcrumbItemClasses.listElementLink}
|
||||
className={breadcrumbItemClasses.elementLink}
|
||||
>
|
||||
{opt.value}
|
||||
</Typography>
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
export const breadcrumbItemClasses = {
|
||||
root: `lsd-breadcrumb-item`,
|
||||
label: `lsd-breadcrumb-item__label`,
|
||||
|
||||
listElement: `lsd-breadcrumb-item-list-element`,
|
||||
listElementCurrentPage: `lsd-breadcrumb-item-list-element-current-page`,
|
||||
listElementLink: `lsd-breadcrumb-item-list-element__link`,
|
||||
|
||||
disabled: 'lsd-breadcrumb-item--disabled',
|
||||
selected: 'lsd-breadcrumb-item--selected',
|
||||
element: `lsd-breadcrumb-item-element`,
|
||||
elementCurrentPage: `lsd-breadcrumb-item-element--current-page`,
|
||||
elementLink: `lsd-breadcrumb-item-element-link`,
|
||||
|
||||
small: `lsd-breadcrumb-item--small`,
|
||||
medium: `lsd-breadcrumb-item--medium`,
|
||||
|
|
|
@ -12,22 +12,22 @@ export const BreadcrumbItemStyles = css`
|
|||
content: '/';
|
||||
}
|
||||
|
||||
.${breadcrumbItemClasses.listElement} {
|
||||
.${breadcrumbItemClasses.element} {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.${breadcrumbItemClasses.listElementLink} {
|
||||
.${breadcrumbItemClasses.elementLink} {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.${breadcrumbItemClasses.listElementCurrentPage} {
|
||||
border: 1px solid #000000;
|
||||
.${breadcrumbItemClasses.elementCurrentPage} {
|
||||
border: 1px solid rgb(var(--lsd-border-primary));
|
||||
padding: 4px 12px;
|
||||
}
|
||||
|
||||
.${breadcrumbClasses.root}:not(.${breadcrumbClasses.disabled}) {
|
||||
.${breadcrumbItemClasses.listElementLink} {
|
||||
.${breadcrumbItemClasses.elementLink} {
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: underline;
|
||||
|
@ -35,13 +35,6 @@ export const BreadcrumbItemStyles = css`
|
|||
}
|
||||
}
|
||||
|
||||
.${breadcrumbItemClasses.label} {
|
||||
}
|
||||
|
||||
.${breadcrumbItemClasses.disabled} {
|
||||
opacity: 0.34;
|
||||
}
|
||||
|
||||
.${breadcrumbItemClasses.small} {
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
|
|
@ -10,31 +10,37 @@ export type BreadcrumbItemProps = React.HTMLAttributes<HTMLDivElement> & {
|
|||
current?: boolean
|
||||
disabled?: boolean
|
||||
selected?: boolean
|
||||
ellipsisRef?: React.RefObject<HTMLLIElement>
|
||||
onClick?: () => void
|
||||
}
|
||||
|
||||
export const BreadcrumbItem: React.FC<BreadcrumbItemProps> & {
|
||||
classes: typeof breadcrumbItemClasses
|
||||
} = ({ label, link, size = 'large', current, onClick, selected }) => {
|
||||
} = ({
|
||||
label,
|
||||
link,
|
||||
size = 'large',
|
||||
current,
|
||||
selected,
|
||||
ellipsisRef,
|
||||
onClick,
|
||||
}) => {
|
||||
return (
|
||||
<li
|
||||
className={clsx(breadcrumbItemClasses.listElement)}
|
||||
className={clsx(breadcrumbItemClasses.element)}
|
||||
aria-selected={selected ? 'true' : 'false'}
|
||||
onClick={onClick}
|
||||
ref={ellipsisRef}
|
||||
>
|
||||
<Typography
|
||||
color="primary"
|
||||
component="a"
|
||||
href={link}
|
||||
variant={size === 'large' ? 'label1' : 'label2'}
|
||||
className={
|
||||
current
|
||||
? clsx(
|
||||
breadcrumbItemClasses.listElementLink,
|
||||
breadcrumbItemClasses.listElementCurrentPage,
|
||||
)
|
||||
: breadcrumbItemClasses.listElementLink
|
||||
}
|
||||
className={clsx(
|
||||
breadcrumbItemClasses.elementLink,
|
||||
current && breadcrumbItemClasses.elementCurrentPage,
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
|
|
|
@ -7,3 +7,5 @@ export * from './components/ListBox'
|
|||
export * from './components/TabItem'
|
||||
export * from './components/Tabs'
|
||||
export * from './components/Theme'
|
||||
export * from './components/Breadcrumb'
|
||||
export * from './components/BreadcrumbItem'
|
||||
|
|
Loading…
Reference in New Issue