Skip to content

Commit 3f91517

Browse files
reidbarberLFDanLu
andauthored
RAC Select: propagate placeholder to Button label (#4512)
Co-authored-by: Daniel Lu <[email protected]>
1 parent a5129de commit 3f91517

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

packages/react-aria-components/src/Select.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ export interface SelectProps<T extends object> extends Omit<AriaSelectProps<T>,
2727

2828
interface SelectValueContext {
2929
state: SelectState<unknown>,
30-
valueProps: HTMLAttributes<HTMLElement>
30+
valueProps: HTMLAttributes<HTMLElement>,
31+
placeholder?: string
3132
}
3233

3334
export const SelectContext = createContext<ContextValue<SelectProps<any>, HTMLDivElement>>(null);
@@ -81,9 +82,9 @@ function Select<T extends object>(props: SelectProps<T>, ref: ForwardedRef<HTMLD
8182
return (
8283
<Provider
8384
values={[
84-
[InternalSelectContext, {state, valueProps}],
85+
[InternalSelectContext, {state, valueProps, placeholder: props.placeholder}],
8586
[LabelContext, {...labelProps, ref: labelRef, elementType: 'span'}],
86-
[ButtonContext, {...triggerProps, ref: buttonRef, isPressed: state.isOpen}],
87+
[ButtonContext, {...triggerProps, ref: buttonRef, isPressed: state.isOpen, children: state.selectedItem?.textValue ?? props.placeholder}],
8788
[PopoverContext, {
8889
state,
8990
triggerRef: buttonRef,
@@ -131,7 +132,7 @@ export interface SelectValueRenderProps<T> {
131132
export interface SelectValueProps<T extends object> extends Omit<HTMLAttributes<HTMLElement>, keyof RenderProps<unknown>>, RenderProps<SelectValueRenderProps<T>> {}
132133

133134
function SelectValue<T extends object>(props: SelectValueProps<T>, ref: ForwardedRef<HTMLSpanElement>) {
134-
let {state, valueProps} = useContext(InternalSelectContext)!;
135+
let {state, valueProps, placeholder} = useContext(InternalSelectContext)!;
135136
let rendered = state.selectedItem?.rendered;
136137
if (typeof rendered === 'function') {
137138
// If the selected item has a function as a child, we need to call it to render to JSX.
@@ -151,7 +152,7 @@ function SelectValue<T extends object>(props: SelectValueProps<T>, ref: Forwarde
151152
let renderProps = useRenderProps({
152153
...props,
153154
// TODO: localize this.
154-
defaultChildren: rendered || 'Select an item',
155+
defaultChildren: rendered || placeholder || 'Select an item',
155156
defaultClassName: 'react-aria-SelectValue',
156157
values: {
157158
selectedItem: state.selectedItem?.value as T ?? null,

packages/react-aria-components/test/Select.test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ describe('Select', () => {
139139
expect(button).toHaveTextContent('1 - Cat');
140140
});
141141

142+
it('supports placeholder', () => {
143+
let {getByRole} = render(<TestSelect placeholder="Select an animal" />);
144+
let button = getByRole('button');
145+
expect(button).toHaveTextContent('Select an animal');
146+
});
147+
142148
// FIXME: not sure why this test hangs
143149
it.skip('should support render props', () => {
144150
let {getByRole} = render(

0 commit comments

Comments
 (0)