refactor: refactor breadcrumb component

This commit is contained in:
jinhojang6 2023-02-16 01:10:18 +09:00
parent 9c97071103
commit 4cb6e5a541
No known key found for this signature in database
GPG Key ID: 0E7AA62CB0D9E6F3
8 changed files with 67 additions and 104 deletions

View File

@ -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',

View File

@ -11,13 +11,6 @@ export default {
value: ['small', 'medium', 'large'],
},
},
maxItems: {
control: {
type: 'number',
min: 2,
max: 6,
},
},
},
} as Meta

View File

@ -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 {

View File

@ -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>

View File

@ -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`,

View File

@ -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;
}

View File

@ -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>

View File

@ -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'