Skip to content

Commit

Permalink
fix(Pill): bugs in Pill with Enhanced options (#1316)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: PillButton props toggleDropdown removed
BREAKING CHANGE: Pill uses RadixDropdown under the hood.

---------

Co-authored-by: janseke10 <janneke.vanhulten@home.nl>
  • Loading branch information
eszthoff and janseke10 authored Nov 18, 2024
1 parent 100a129 commit 8e2ed49
Show file tree
Hide file tree
Showing 15 changed files with 657 additions and 593 deletions.
1 change: 0 additions & 1 deletion src/components/Dropdown/Dropdown.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.DropdownContent,
.DropdownSubContent {
max-width: 400px;
border-radius: var(--radius-8, 8px);
border: 1px solid var(--color-border-subtlest, #e6e6e6);
background: var(--color-background-neutral-subtlest-default, #fff);
Expand Down
97 changes: 42 additions & 55 deletions src/components/Pill/Pill.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from 'react';
import { PopupBase } from '../PopupBase';
import { PillButton, PillButtonProps } from './PillButton';
import { PillButtonEnhanced, PillButtonEnhancedProps } from './PillButtonEnhanced';
import { PillDropdown, PillDropdownChildrenParams } from './PillDropdown';
import { DropdownContent, DropdownPortal, DropdownRoot } from '../Dropdown';

export interface ClassicButtonProps extends Omit<PillButtonProps, 'toggleDropdown' | 'children'> {
/** Trigger button variant */
Expand Down Expand Up @@ -57,71 +57,58 @@ export const Pill = <PriorityItemValue extends unknown>({
ref,
content = null,
children,
dropdownRef: dropdownRefFromProps,
dropdownRef,
noPaddingInDropdown = false,
additionalDropdownProps = {},
onClose,
...rest
}: Props<PriorityItemValue>) => {
const buttonRef = React.useMemo(() => ref || React.createRef<HTMLElement>(), [ref]);
const dropdownRef = React.useMemo(
() => dropdownRefFromProps || React.createRef<HTMLElement>(),
[dropdownRefFromProps]
);

const buttonRenderer = ({ setPopupVisibility, isOpen }) => {
const toggleDropdown = () => {
if (isOpen && onClose) {
onClose();
}
setPopupVisibility(!isOpen);
};

return variant === 'classic' ? (
<PillButton
name={name}
content={content}
isOpen={isOpen}
toggleDropdown={toggleDropdown}
onClear={onClear}
{...rest}
/>
) : (
<PillButtonEnhanced
name={name}
content={content}
isOpen={isOpen}
toggleDropdown={toggleDropdown}
onClear={onClear}
{...rest}
/>
);
};
const [isOpen, setIsOpen] = React.useState(false);

const closeDropdown = (setPopupVisibility) => {
const closeDropdown = () => {
onClose?.();
setPopupVisibility(false);
};

const dropdownRenderer = ({ setPopupVisibility }) => (
<PillDropdown
close={() => closeDropdown(setPopupVisibility)}
noPadding={noPaddingInDropdown}
doneLabel={doneLabel}
{...additionalDropdownProps}
>
{children}
</PillDropdown>
);
const handleOpenStateChange = (open) => {
setIsOpen(open);
if (!open) {
onClose?.();
}
};

return (
<PopupBase
anchorRenderer={buttonRenderer}
popupRenderer={dropdownRenderer}
anchorRef={buttonRef}
popupRef={dropdownRef}
onClose={onClose}
/>
<DropdownRoot onOpenChange={handleOpenStateChange} modal={false}>
{variant === 'classic' ? (
<PillButton
name={name}
content={content}
onClear={onClear}
isOpen={isOpen}
{...rest}
/>
) : (
<PillButtonEnhanced
name={name}
content={content}
onClear={onClear}
isOpen={isOpen}
{...rest}
/>
)}
<DropdownPortal>
<DropdownContent asChild>
<PillDropdown
ref={dropdownRef}
close={closeDropdown}
noPadding={noPaddingInDropdown}
doneLabel={doneLabel}
{...additionalDropdownProps}
>
{children}
</PillDropdown>
</DropdownContent>
</DropdownPortal>
</DropdownRoot>
);
};

Expand Down
74 changes: 44 additions & 30 deletions src/components/Pill/PillButton/PillButton.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import * as React from 'react';
import { IoIosArrowDown, IoMdClose } from 'react-icons/io';
import { bem } from '../../../utils';
import { bem, mergeRefs } from '../../../utils';
import { ENTER_KEY } from '../../../constants';
import styles from './PillButton.scss';
import { DropdownTrigger } from '../../Dropdown';

export interface PillButtonBaseProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'content'> {
/** Wether the dropdown is open or closed */
isOpen?: boolean;
/** a function to be called when dropdown should be toggled */
toggleDropdown: () => void;
/** a function to be called to clear the pill/filter content */
onClear: () => void;
/** name describing the pill/filter */
Expand All @@ -35,7 +34,6 @@ export const PillButton = React.forwardRef<HTMLElement, Props>(
{
isOpen = false,
isContentDefault = false,
toggleDropdown,
onClear,
name,
content = null,
Expand All @@ -46,6 +44,7 @@ export const PillButton = React.forwardRef<HTMLElement, Props>(
},
ref
) => {
const mainRef = React.useRef();
const isActive = !!content;
const propsForBem = { isOpen, isActive };

Expand Down Expand Up @@ -99,37 +98,52 @@ export const PillButton = React.forwardRef<HTMLElement, Props>(
}
: undefined;

const handleKeyDownOnPill = (e) => {
if (e.key === ENTER_KEY) {
e.preventDefault();
toggleDropdown();
}
};

return (
<div ref={ref} {...rest} {...block({ ...propsForBem, ...rest })}>
<div ref={mergeRefs([ref, mainRef])} {...rest} {...block({ ...propsForBem, ...rest })}>
<div ref={labelRef} {...elem('label', propsForBem)}>
{isActive && name}
</div>
<div
ref={pillRef}
{...elem('pill', propsForBem)}
style={pillMinWidth ? { minWidth: pillMinWidth } : undefined}
onClick={toggleDropdown}
onKeyDown={handleKeyDownOnPill}
tabIndex="0"
role="button"
>
<span {...elem('pillLabel', propsForBem)}>{content || name}</span>
<button
type="button"
{...elem('button', propsForBem)}
onClick={buttonClick}
onKeyDown={handleKeyDownOnButton}
{isButtonClickable ? (
<div
ref={pillRef}
{...elem('pill', propsForBem)}
style={pillMinWidth ? { minWidth: pillMinWidth } : undefined}
>
{buttonIcon}
</button>
</div>
<DropdownTrigger>
<span tabIndex="0" role="button" {...elem('pillLabel', propsForBem)}>
{content || name}
</span>
</DropdownTrigger>
<button
type="button"
{...elem('button', propsForBem)}
onClick={buttonClick}
onKeyDown={handleKeyDownOnButton}
>
{buttonIcon}
</button>
</div>
) : (
<DropdownTrigger>
<div
ref={pillRef}
{...elem('pill', propsForBem)}
style={pillMinWidth ? { minWidth: pillMinWidth } : undefined}
tabIndex="0"
role="button"
>
<span {...elem('pillLabel', propsForBem)}>{content || name}</span>
<button
type="button"
{...elem('button', propsForBem)}
onClick={buttonClick}
onKeyDown={handleKeyDownOnButton}
>
{buttonIcon}
</button>
</div>
</DropdownTrigger>
)}
</div>
);
}
Expand Down
Loading

0 comments on commit 8e2ed49

Please sign in to comment.