Skip to content

Commit

Permalink
feat: add multiple option select to AlphaPicker
Browse files Browse the repository at this point in the history
  • Loading branch information
kyledurand committed Apr 2, 2024
1 parent 8ffddd6 commit 9f94aac
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/wise-teachers-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/polaris': patch
---

Added multi select functionality to AlphaPicker
30 changes: 30 additions & 0 deletions polaris-react/playground/DetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ export function DetailsPage() {
const [vendors, setVendors] = useState([
{value: 'The North Face', children: 'The North Face'},
{value: 'Patagonia', children: 'Patagonia'},
{value: 'Arc’teryx', children: 'Arc’teryx'},
{value: 'Marmot', children: 'Marmot'},
{value: 'Black Diamond', children: 'Black Diamond'},
{value: 'Mountain Hardwear', children: 'Mountain Hardwear'},
{value: 'Columbia', children: 'Columbia'},
{value: 'Canada Goose', children: 'Canada Goose'},
{value: 'Merrell', children: 'Merrell'},
{value: 'Salomon', children: 'Salomon'},
{value: 'Burton', children: 'Burton'},
]);
const skipToContentRef = useRef<HTMLAnchorElement>(null);
const [toastActive, setToastActive] = useState(false);
Expand Down Expand Up @@ -651,6 +660,27 @@ export function DetailsPage() {
value={selected}
/>
<br />
<AlphaPicker
allowMultiple
onSelect={handleSelect}
activator={{
label: 'Vendor',
placeholder: 'None selected',
}}
searchField={{
label: 'Search vendors',
placeholder: 'Search or add new vendor',
autoComplete: 'off',
value: query,
onChange: (value) => setQuery(value),
}}
options={vendors}
addAction={{
value: query,
children: `Add ${query}`,
}}
/>
<br />
<AlphaPicker
onSelect={handleSelect}
activator={{
Expand Down
48 changes: 29 additions & 19 deletions polaris-react/src/components/Picker/Picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function Picker({
...listboxProps
}: PickerProps) {
const activatorRef = React.createRef<HTMLButtonElement>();
const [activeItem, setActiveItem] = useState<string>();
const [activeItems, setActiveItems] = useState<string[]>([]);
const [popoverActive, setPopoverActive] = useState(false);
const [activeOptionId, setActiveOptionId] = useState<string>();
const [textFieldLabelId, setTextFieldLabelId] = useState<string>();
Expand Down Expand Up @@ -164,14 +164,36 @@ export function Picker({
[options],
);

const firstSelectedOption = reactChildrenText(
options.find((option) => option.value === activeItem)?.children,
const handleSelect = useCallback(
(selected: string) => {
setQuery('');
updateText('');
listboxProps.onSelect?.(selected);

if (!allowMultiple) {
handleClose();
setActiveItems([selected]);
return;
}

setActiveItems((selectedOptions) => {
return activeItems.includes(selected)
? selectedOptions.filter((option) => option !== selected)
: [...selectedOptions, selected];
});
},
[updateText, listboxProps, allowMultiple, activeItems, handleClose],
);

const queryMatchesExistingOption = options.some((option) =>
QUERY_REGEX(query).exec(reactChildrenText(option.children)),
const firstSelectedOption = reactChildrenText(
options.find((option) => option.value === activeItems?.[0])?.children,
);

const queryMatchesExistingOption = options.some((option) => {
const matcher = QUERY_REGEX(query);
return reactChildrenText(option.children).match(matcher);
});

return (
<Popover
activator={
Expand Down Expand Up @@ -219,23 +241,11 @@ export function Picker({
value={listboxOptionContextValue}
>
<Box paddingBlock="200">
<Listbox
{...listboxProps}
onSelect={(selected: string) => {
setQuery('');
updateText('');
setActiveItem(selected);
listboxProps.onSelect?.(selected);

if (!allowMultiple) {
handleClose();
}
}}
>
<Listbox {...listboxProps} onSelect={handleSelect}>
{filteredOptions?.map((option) => (
<Listbox.Option
key={option.value}
selected={option.value === activeItem}
selected={activeItems.some((item) => item === option.value)}
{...option}
/>
))}
Expand Down

0 comments on commit 9f94aac

Please sign in to comment.