Skip to content

Commit

Permalink
add disabled state, show first option text if react node
Browse files Browse the repository at this point in the history
  • Loading branch information
kyledurand committed Mar 16, 2024
1 parent 7fd7213 commit 4019b65
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 22 deletions.
5 changes: 4 additions & 1 deletion polaris-react/playground/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ export function Playground() {
placeholder: 'Search for a product',
autoComplete: 'off',
}}
activator={{label: 'Product', placeholder: 'Select a product'}}
activator={{
label: 'Product',
placeholder: 'Select a product',
}}
options={options}
onSelect={(selected) => console.log(selected)}
addAction={{value: 'add', children: 'Add product'}}
Expand Down
22 changes: 10 additions & 12 deletions polaris-react/src/components/Picker/Picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ import type {ListboxProps, OptionProps} from '../Listbox';
import {Listbox} from '../Listbox';
import {Icon} from '../Icon';

import {TextField, Activator} from './components';
import {Activator, TextField} from './components';
import type {ActivatorProps} from './components';

export interface PickerProps extends Omit<ListboxProps, 'children'> {
/** Configure the button that activates the Picker */
activator: ActivatorProps;
/** Textfield that allows filtering of options */
searchField?: TextFieldProps;
/** Allows more than one option to be selected */
allowMultiple?: boolean;
/** The options to be listed within the picker */
options?: OptionProps[];
/** Used to add a new picker option that isn't listed */
addAction?: OptionProps;
/** Textfield that allows filtering of options */
searchField?: TextFieldProps;
/** Whether or not more options are available to lazy load when the bottom of the listbox reached. Use the hasMoreResults boolean provided by the GraphQL API of the paginated data. */
willLoadMoreOptions?: boolean;
/** Height to set on the Popover Pane. */
Expand All @@ -49,10 +49,8 @@ export interface PickerProps extends Omit<ListboxProps, 'children'> {
onClose?(): void;
}

const filterRegex = (value: string) => new RegExp(value, 'i');

// regex match string exact upper or lower case
const filterRegexExact = (value: string) => new RegExp(`^${value}$`, 'i');
const FILTER_REGEX = (value: string) => new RegExp(value, 'i');
const QUERY_MATCH = (value: string) => new RegExp(`^${value}$`, 'i');

export function Picker({
activator,
Expand Down Expand Up @@ -182,22 +180,22 @@ export function Picker({
}

const resultOptions = options?.filter((option) =>
filterRegex(value).exec(reactChildrenText(option.children)),
FILTER_REGEX(value).exec(reactChildrenText(option.children)),
);
setFilteredOptions(resultOptions ?? []);
},
[options],
);

const firstSelectedOption = options.find(
(option) => option.value === active,
)?.children;
const firstSelectedOption = reactChildrenText(
options.find((option) => option.value === active)?.children,
);
const firstSelectedLabel = firstSelectedOption
? firstSelectedOption?.toString()
: activator.placeholder;

const queryMatchesExistingOption = options.some((option) =>
filterRegexExact(query).exec(reactChildrenText(option.children)),
QUERY_MATCH(query).exec(reactChildrenText(option.children)),
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@
outline-offset: var(--p-space-025);
}
}

.disabled {
pointer-events: none;
background-color: var(--p-color-bg-surface-disabled);
border-color: var(--p-color-border-disabled);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,40 @@ import {BlockStack} from '../../../BlockStack';
import {Icon} from '../../../Icon';
import {Text} from '../../../Text';
import {UnstyledButton} from '../../../UnstyledButton';
import {classNames} from '../../../../utilities/css';

import styles from './Activator.module.css';

export interface ActivatorProps {
label: string;
label?: string;
placeholder?: string;
disabled?: boolean;
onClick?(): void;
}

export function Activator({placeholder, onClick, label}: ActivatorProps) {
export function Activator({
disabled,
label,
placeholder,
onClick,
}: ActivatorProps) {
return (
<UnstyledButton className={styles.Activator} onClick={onClick}>
<UnstyledButton
className={classNames(styles.Activator, disabled && styles.disabled)}
onClick={onClick}
>
<BlockStack as="span" gap="100">
<Text as="span" variant="bodySm" alignment="start" tone="subdued">
{label}
</Text>
<Text as="span" variant="bodyMd" alignment="start">
{placeholder}
</Text>
{label && (
<Text as="span" variant="bodySm" alignment="start" tone="subdued">
{label}
</Text>
)}

{placeholder && (
<Text as="span" variant="bodyMd" alignment="start">
{placeholder}
</Text>
)}
</BlockStack>
<span>
<Icon tone="subdued" source={SelectIcon} />
Expand Down

0 comments on commit 4019b65

Please sign in to comment.