Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ export interface ClipboardCopyProps extends Omit<React.HTMLProps<HTMLDivElement>
textAriaLabel?: string;
/** Aria-label to use on the ClipboardCopyToggle. */
toggleAriaLabel?: string;
/** ID to use on the TextInput. */
inputId?: string;
/** Name attribute to use on the TextInput. */
inputName?: string;
/** Flag to show if the input is read only. */
isReadOnly?: boolean;
/** Flag to determine if clipboard copy is in the expanded state initially */
Expand Down Expand Up @@ -91,6 +95,10 @@ export interface ClipboardCopyProps extends Omit<React.HTMLProps<HTMLDivElement>
onCopy?: (event: React.ClipboardEvent<HTMLDivElement>, text?: React.ReactNode) => void;
/** A function that is triggered on changing the text. */
onChange?: (event: React.FormEvent, text?: string) => void;
/** Callback function when text input is focused */
onInputFocus?: (event?: any) => void;
/** Callback function when text input is blurred (focus leaves) */
onInputBlur?: (event?: any) => void;
/** The text which is copied. */
children: string | string[];
/** Additional actions for inline clipboard copy. Should be wrapped with ClipboardCopyAction. */
Expand Down Expand Up @@ -177,6 +185,8 @@ class ClipboardCopy extends Component<ClipboardCopyProps, ClipboardCopyState> {
/* eslint-disable @typescript-eslint/no-unused-vars */
isExpanded,
onChange, // Don't pass to <div>
onInputFocus, // Don't pass to <div>
onInputBlur, // Don't pass to <div>
/* eslint-enable @typescript-eslint/no-unused-vars */
isReadOnly,
isCode,
Expand All @@ -189,6 +199,8 @@ class ClipboardCopy extends Component<ClipboardCopyProps, ClipboardCopyState> {
clickTip,
textAriaLabel,
toggleAriaLabel,
inputId,
inputName,
variant,
position,
className,
Expand Down Expand Up @@ -295,8 +307,11 @@ class ClipboardCopy extends Component<ClipboardCopyProps, ClipboardCopyState> {
readOnlyVariant={isReadOnly || this.state.expanded ? 'default' : undefined}
onChange={this.updateText}
value={this.state.expanded ? this.state.textWhenExpanded : copyableText}
id={`text-input-${id}`}
id={inputId ?? `text-input-${id}`}
name={inputName}
aria-label={textAriaLabel}
onFocus={onInputFocus}
onBlur={onInputBlur}
{...(isCode && { dir: 'ltr' })}
/>
<ClipboardCopyButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,18 @@ test('Passes textAriaLabel to TextInput', () => {
expect(screen.getByRole('textbox')).toHaveAccessibleName('text label');
});

test('Passes inputId to TextInput', () => {
render(<ClipboardCopy inputId="custom-input-id">{children}</ClipboardCopy>);

expect(screen.getByRole('textbox')).toHaveAttribute('id', 'custom-input-id');
});

test('Passes inputName to TextInput', () => {
render(<ClipboardCopy inputName="custom-input-name">{children}</ClipboardCopy>);

expect(screen.getByRole('textbox')).toHaveAttribute('name', 'custom-input-name');
});

test('Calls onChange when ClipboardCopy textinput is typed in', async () => {
const onChangeMock = jest.fn();
const user = userEvent.setup();
Expand Down Expand Up @@ -338,6 +350,66 @@ test('Does not call onChange when ClipboardCopy textinput is not typed in', asyn
expect(onChangeMock).not.toHaveBeenCalled();
});

test('Calls onFocus when ClipboardCopy textinput is focused', async () => {
const onFocusMock = jest.fn();
const user = userEvent.setup();

render(<ClipboardCopy onInputFocus={onFocusMock}>{children}</ClipboardCopy>);

await user.click(screen.getByRole('textbox'));

expect(onFocusMock).toHaveBeenCalledTimes(1);
});

test('Does not call onFocus when ClipboardCopy textinput is not focused', async () => {
const onFocusMock = jest.fn();
const user = userEvent.setup();

render(
<>
<ClipboardCopy onInputFocus={onFocusMock}>{children}</ClipboardCopy>
<input aria-label="native input" />
</>
);

await user.click(screen.getByRole('textbox', { name: 'native input' }));

expect(onFocusMock).not.toHaveBeenCalled();
});

test('Calls onBlur when ClipboardCopy textinput loses focus', async () => {
const onBlurMock = jest.fn();
const user = userEvent.setup();

render(
<>
<ClipboardCopy onInputBlur={onBlurMock}>{children}</ClipboardCopy>
<input aria-label="native input" />
</>
);

await user.click(screen.getByRole('textbox', { name: 'Copyable input' }));
await user.click(screen.getByRole('textbox', { name: 'native input' }));

expect(onBlurMock).toHaveBeenCalledTimes(1);
});

test('Does not call onBlur when ClipboardCopy textinput does not lose focus', async () => {
const onBlurMock = jest.fn();
const user = userEvent.setup();

render(
<>
<ClipboardCopy onInputBlur={onBlurMock}>{children}</ClipboardCopy>
<input aria-label="native input" />
</>
);

await user.click(screen.getByRole('textbox', { name: 'native input' }));

expect(onBlurMock).not.toHaveBeenCalled();
});

test('Calls onCopy when ClipboardCopyButton is clicked', async () => {
const onCopyMock = jest.fn();
const user = userEvent.setup();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ exports[`Matches snapshot 1`] = `
<input
aria-invalid="false"
aria-label="Copyable input"
data-ouia-component-id="OUIA-Generated-TextInputBase-36"
data-ouia-component-id="OUIA-Generated-TextInputBase-42"
data-ouia-component-type="PF6/TextInput"
data-ouia-safe="true"
id="text-input-generated-id"
Expand Down
Loading