Skip to content

Commit

Permalink
feat(rac): Register variants for Aria Combobox, Select
Browse files Browse the repository at this point in the history
Change-Id: Ia5a96d1898c945a66b7538cd9ed62e3930759428
GitOrigin-RevId: 8d720aefcda23a0de4a71ae1d425467cf597c3d4
  • Loading branch information
sarahsga authored and actions-user committed Nov 8, 2024
1 parent ec99dd6 commit 03a26b9
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
26 changes: 25 additions & 1 deletion plasmicpkgs/react-aria/src/registerComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,27 @@ import {
registerComponentHelper,
useAutoOpen,
} from "./utils";
import { pickAriaComponentVariants, WithVariants } from "./variant-utils";

const COMBOBOX_NAME = makeComponentName("combobox");

export interface BaseComboboxControlContextData {
itemIds: string[];
}

const COMBOBOX_VARIANTS = ["disabled" as const];

const { variants: COMBOBOX_VARIANTS_DATA } =
pickAriaComponentVariants(COMBOBOX_VARIANTS);

export interface BaseComboboxProps
extends ComboBoxProps<{}>,
WithVariants<typeof COMBOBOX_VARIANTS>,
HasControlContextData<BaseComboboxControlContextData> {
placeholder?: string;
children?: React.ReactNode;
isOpen?: boolean;
className?: string;
}

/*
Expand All @@ -61,6 +69,9 @@ export function BaseComboBox(props: BaseComboboxProps) {
const {
children,
setControlContextData,
plasmicUpdateVariant,
className,
isDisabled,
isOpen: _isOpen, // uncontrolled if not selected in canvas/edit mode
...rest
} = props;
Expand All @@ -75,8 +86,20 @@ export function BaseComboBox(props: BaseComboboxProps) {
});
}, []);

// NOTE: Aria <Combobox> does not support render props, neither does it provide an onDisabledChange event, so we have to manually update the disabled state.
useEffect(() => {
plasmicUpdateVariant?.({
disabled: isDisabled,
});
}, [isDisabled, plasmicUpdateVariant]);

return (
<ComboBox {...rest}>
<ComboBox
isDisabled={isDisabled}
// Not calling plasmicUpdateVariant within className callback (which has access to render props) because it would then run on every render
className={className}
{...rest}
>
<PlasmicPopoverContext.Provider value={{}}>
<PlasmicListBoxContext.Provider
value={{
Expand All @@ -99,6 +122,7 @@ export function registerComboBox(loader?: Registerable) {
displayName: "Aria ComboBox",
importPath: "@plasmicpkgs/react-aria/skinny/registerComboBox",
importName: "BaseComboBox",
variants: COMBOBOX_VARIANTS_DATA,
props: {
...getCommonProps<BaseComboboxProps>("ComboBox", [
"name",
Expand Down
20 changes: 19 additions & 1 deletion plasmicpkgs/react-aria/src/registerSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
registerComponentHelper,
useAutoOpen,
} from "./utils";
import { pickAriaComponentVariants, WithVariants } from "./variant-utils";

// It cannot be used as a hook like useAutoOpen() within the BaseSelect component
// because it needs access to SelectStateContext, which is only created in the BaseSelect component's render function.
Expand Down Expand Up @@ -53,10 +54,17 @@ export interface BaseSelectControlContextData {
itemIds: string[];
}

const SELECT_VARIANTS = ["disabled" as const];

const { variants: SELECT_VARIANTS_DATA } =
pickAriaComponentVariants(SELECT_VARIANTS);

export interface BaseSelectProps
extends SelectProps<{}>, // NOTE: We don't need generic type here since we don't use items prop (that needs it). We just need to make the type checker happy
WithVariants<typeof SELECT_VARIANTS>,
HasControlContextData<BaseSelectControlContextData> {
children?: React.ReactNode;
className?: string;
}

export function BaseSelect(props: BaseSelectProps) {
Expand All @@ -72,10 +80,11 @@ export function BaseSelect(props: BaseSelectProps) {
disabledKeys,
name,
setControlContextData,
plasmicUpdateVariant,
"aria-label": ariaLabel,
} = props;

let idManager = useMemo(() => new ListBoxItemIdManager(), []);
const idManager = useMemo(() => new ListBoxItemIdManager(), []);

useEffect(() => {
idManager.subscribe((ids: string[]) => {
Expand All @@ -85,13 +94,21 @@ export function BaseSelect(props: BaseSelectProps) {
});
}, []);

// NOTE: Aria <Select> does not support render props, neither does it provide an onDisabledChange event, so we have to manually update the disabled state.
useEffect(() => {
plasmicUpdateVariant?.({
disabled: isDisabled,
});
}, [isDisabled, plasmicUpdateVariant]);

return (
<Select
placeholder={placeholder}
selectedKey={selectedKey}
onSelectionChange={onSelectionChange}
onOpenChange={onOpenChange}
isDisabled={isDisabled}
// Not calling plasmicUpdateVariant within className callback (which has access to render props) because it would then run on every render
className={className}
style={style}
name={name}
Expand Down Expand Up @@ -144,6 +161,7 @@ export function registerSelect(loader?: Registerable) {
displayName: "Aria Select",
importPath: "@plasmicpkgs/react-aria/skinny/registerSelect",
importName: "BaseSelect",
variants: SELECT_VARIANTS_DATA,
props: {
...getCommonProps<BaseSelectProps>("Select", [
"name",
Expand Down

0 comments on commit 03a26b9

Please sign in to comment.