Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d7462ab
feat: Add FieldContext to pass props to child instead of modifying ch…
behowell Mar 31, 2023
db409be
Change files
behowell Mar 31, 2023
f6c6994
Add component tests
behowell Mar 31, 2023
9605124
Revert field vr tests for now
behowell Mar 31, 2023
eb6b4a9
Merge branch 'master' of https://github.com/microsoft/fluentui into f…
behowell Mar 31, 2023
1175509
Merge branch 'master' of https://github.com/microsoft/fluentui into f…
behowell Mar 31, 2023
a3bc6b2
Merge branch 'field/context' of https://github.com/behowell/fluentui …
behowell Mar 31, 2023
38bab37
Fix tsdoc warnings
behowell Mar 31, 2023
755eb06
Replace supportsSize option with boolean
behowell Mar 31, 2023
3067ea1
Export FieldControlProps and FieldControlPropsOptions
behowell Mar 31, 2023
ba896d6
Add _unstable useFieldContextValues
behowell Mar 31, 2023
628c138
Make FieldContextValues optional in renderField
behowell Mar 31, 2023
a437a37
Merge branch 'master' of https://github.com/microsoft/fluentui into f…
behowell Mar 31, 2023
ded8ebb
Update field size story
behowell Mar 31, 2023
9985f7f
Update RenderFunction story
behowell Mar 31, 2023
081383a
Merge branch 'master' of https://github.com/microsoft/fluentui into f…
behowell Apr 3, 2023
bc19f9d
Remove ProgressBar dependency on useFieldControlProps_unstable
behowell Apr 3, 2023
5d9fd58
Refactor how the label to control connection is managed.
behowell Apr 3, 2023
2f4bcfb
Update tests
behowell Apr 3, 2023
ee60d99
Add `supportsRequired` to useFieldControlProps
behowell Apr 4, 2023
cf76fe5
Merge branch 'master' of https://github.com/microsoft/fluentui into f…
behowell Apr 4, 2023
bad8e7d
Fix wording of render function story
behowell Apr 4, 2023
d3d0ae4
Add tests for required, and fix Dropdown (doesn't support required)
behowell Apr 4, 2023
d121481
Merge branch 'master' of https://github.com/microsoft/fluentui into f…
behowell Apr 4, 2023
3423379
Add a test to Checkbox that it can be labelled by both a field and it…
behowell Apr 4, 2023
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
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Hook up FieldContext for use inside a Field",
"packageName": "@fluentui/react-checkbox",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Hook up FieldContext for use inside a Field",
"packageName": "@fluentui/react-combobox",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Export hooks for FieldContext",
"packageName": "@fluentui/react-components",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "feat: Add FieldContext to pass props to controls inside Field",
"packageName": "@fluentui/react-field",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Hook up FieldContext for use inside a Field",
"packageName": "@fluentui/react-input",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Hook up FieldContext for use inside a Field",
"packageName": "@fluentui/react-progress",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Hook up FieldContext for use inside a Field",
"packageName": "@fluentui/react-radio",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Hook up FieldContext for use inside a Field",
"packageName": "@fluentui/react-select",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Hook up FieldContext for use inside a Field",
"packageName": "@fluentui/react-slider",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Hook up FieldContext for use inside a Field",
"packageName": "@fluentui/react-spinbutton",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Hook up FieldContext for use inside a Field",
"packageName": "@fluentui/react-switch",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Hook up FieldContext for use inside a Field",
"packageName": "@fluentui/react-textarea",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { Field } from '@fluentui/react-field';
import { Checkbox } from './Checkbox';
import { isConformant } from '../../testing/isConformant';
import { resetIdsForTests } from '@fluentui/react-utilities';
Expand Down Expand Up @@ -165,6 +166,38 @@ describe('Checkbox', () => {
expect(input.indeterminate).toEqual(true);
});

it('gets props from a surrounding Field', () => {
const renderedComponent = render(
<Field validationMessage="Test error message" required>
<Checkbox label="Checkbox" />
</Field>,
);

const checkbox = renderedComponent.getByRole('checkbox') as HTMLInputElement;
const message = renderedComponent.getByText('Test error message');

expect(checkbox.getAttribute('aria-describedby')).toEqual(message.id);
expect(checkbox.getAttribute('aria-invalid')).toEqual('true');
expect(checkbox.required).toBe(true);
});

it('is labelled by both the Field and Checkbox labels, if both are present', () => {
const renderedComponent = render(
<Field label="Field label">
<Checkbox label="Checkbox label" />
</Field>,
);

const fieldLabel = renderedComponent.getByText('Field label') as HTMLLabelElement;
const checkboxLabel = renderedComponent.getByText('Checkbox label') as HTMLLabelElement;
const checkbox = renderedComponent.getByRole('checkbox') as HTMLInputElement;

// The checkbox should be labelled by both labels using htmlFor and not aria-labelledby
expect(checkbox.id).toEqual(fieldLabel.htmlFor);
expect(checkbox.id).toEqual(checkboxLabel.htmlFor);
expect(checkbox.getAttribute('aria-labelledby')).toBeNull();
});

describe('Accessibility Tests', () => {
it('renders the input slot (as input)', () => {
const { container } = render(<Checkbox input={{ className: 'test' }} />);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { useFieldControlProps_unstable } from '@fluentui/react-field';
import {
getPartitionedNativeProps,
resolveShorthand,
Expand Down Expand Up @@ -29,6 +30,9 @@ import { useFocusWithin } from '@fluentui/react-tabster';
* @param ref - reference to `<input>` element of Checkbox
*/
export const useCheckbox_unstable = (props: CheckboxProps, ref: React.Ref<HTMLInputElement>): CheckboxState => {
// Merge props from surrounding <Field>, if any
props = useFieldControlProps_unstable(props, { supportsLabelFor: true, supportsRequired: true });

const { disabled = false, required, shape = 'square', size = 'medium', labelPosition = 'after', onChange } = props;

const [checked, setChecked] = useControllableState({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Field } from '@fluentui/react-field';
import { Combobox } from './Combobox';
import { Option } from '../Option/index';
import { isConformant } from '../../testing/isConformant';
Expand Down Expand Up @@ -848,4 +849,25 @@ describe('Combobox', () => {

expect((getByRole('combobox') as HTMLInputElement).value).toEqual('foo');
});

it('gets props from a surrounding Field', () => {
const result = render(
<Field label="Test label" validationMessage="Test error message" required>
<Combobox>
<Option>Red</Option>
<Option>Green</Option>
<Option>Blue</Option>
</Combobox>
</Field>,
);

const combobox = result.getByRole('combobox') as HTMLInputElement;
const label = result.getByText('Test label') as HTMLLabelElement;
const message = result.getByText('Test error message');

expect(combobox.id).toEqual(label.htmlFor);
expect(combobox.getAttribute('aria-describedby')).toEqual(message.id);
expect(combobox.getAttribute('aria-invalid')).toEqual('true');
expect(combobox.required).toBe(true);
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { useFieldControlProps_unstable } from '@fluentui/react-field';
import { ArrowLeft, ArrowRight } from '@fluentui/keyboard-keys';
import { ChevronDownRegular as ChevronDownIcon } from '@fluentui/react-icons';
import {
Expand Down Expand Up @@ -29,6 +30,9 @@ import type { ComboboxProps, ComboboxState } from './Combobox.types';
* @param ref - reference to root HTMLElement of Combobox
*/
export const useCombobox_unstable = (props: ComboboxProps, ref: React.Ref<HTMLInputElement>): ComboboxState => {
// Merge props from surrounding <Field>, if any
props = useFieldControlProps_unstable(props, { supportsLabelFor: true, supportsRequired: true, supportsSize: true });

const baseState = useComboboxBaseState({ ...props, editable: true });
const {
activeOption,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { fireEvent, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Field } from '@fluentui/react-field';
import { Dropdown } from './Dropdown';
import { Option } from '../Option/index';
import { isConformant } from '../../testing/isConformant';
Expand Down Expand Up @@ -652,4 +653,25 @@ describe('Dropdown', () => {

expect(combobox.getAttribute('aria-activedescendant')).toEqual(getByText('Red').id);
});

it('gets props from a surrounding Field', () => {
const result = render(
<Field label="Test label" validationMessage="Test error message" required>
<Dropdown>
<Option>Red</Option>
<Option>Green</Option>
<Option>Blue</Option>
</Dropdown>
</Field>,
);

const combobox = result.getByRole('combobox') as HTMLInputElement;
const label = result.getByText('Test label') as HTMLLabelElement;
const message = result.getByText('Test error message');

expect(combobox.id).toEqual(label.htmlFor);
expect(combobox.getAttribute('aria-describedby')).toEqual(message.id);
expect(combobox.getAttribute('aria-invalid')).toEqual('true');
expect(combobox.getAttribute('aria-required')).toEqual('true');
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { useFieldControlProps_unstable } from '@fluentui/react-field';
import { ChevronDownRegular as ChevronDownIcon } from '@fluentui/react-icons';
import { getPartitionedNativeProps, mergeCallbacks, resolveShorthand, useTimeout } from '@fluentui/react-utilities';
import { getDropdownActionFromKey } from '../../utils/dropdownKeyActions';
Expand All @@ -21,6 +22,9 @@ import { useMergedRefs } from '@fluentui/react-utilities';
* @param ref - reference to root HTMLElement of Dropdown
*/
export const useDropdown_unstable = (props: DropdownProps, ref: React.Ref<HTMLButtonElement>): DropdownState => {
// Merge props from surrounding <Field>, if any
props = useFieldControlProps_unstable(props, { supportsLabelFor: true, supportsSize: true });

const baseState = useComboboxBaseState(props);
const { activeOption, getIndexOfId, getOptionsMatchingText, open, setActiveOption, setFocusVisible, setOpen } =
baseState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import { comboboxFieldClassNames } from '@fluentui/react-combobox';
import { ComboboxFieldProps_unstable as ComboboxFieldProps } from '@fluentui/react-combobox';
import { Field } from '@fluentui/react-field';
import { fieldClassNames } from '@fluentui/react-field';
import { FieldContextProvider } from '@fluentui/react-field';
import { FieldContextValue } from '@fluentui/react-field';
import { FieldContextValues } from '@fluentui/react-field';
import { FieldControlProps } from '@fluentui/react-field';
import { FieldControlPropsOptions } from '@fluentui/react-field';
import { FieldProps } from '@fluentui/react-field';
import { FieldSlots } from '@fluentui/react-field';
import { FieldState } from '@fluentui/react-field';
Expand Down Expand Up @@ -116,6 +121,9 @@ import { TreeState } from '@fluentui/react-tree';
import { useAlert_unstable } from '@fluentui/react-alert';
import { useAlertStyles_unstable } from '@fluentui/react-alert';
import { useField_unstable } from '@fluentui/react-field';
import { useFieldContext_unstable } from '@fluentui/react-field';
import { useFieldContextValues_unstable } from '@fluentui/react-field';
import { useFieldControlProps_unstable } from '@fluentui/react-field';
import { useFieldStyles_unstable } from '@fluentui/react-field';
import { useFlatTree_unstable } from '@fluentui/react-tree';
import { useInfoButton_unstable } from '@fluentui/react-infobutton';
Expand Down Expand Up @@ -181,6 +189,16 @@ export { Field }

export { fieldClassNames }

export { FieldContextProvider }

export { FieldContextValue }

export { FieldContextValues }

export { FieldControlProps }

export { FieldControlPropsOptions }

export { FieldProps }

export { FieldSlots }
Expand Down Expand Up @@ -379,6 +397,12 @@ export { useAlertStyles_unstable }

export { useField_unstable }

export { useFieldContext_unstable }

export { useFieldContextValues_unstable }

export { useFieldControlProps_unstable }

export { useFieldStyles_unstable }

export { useFlatTree_unstable }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,23 @@ export type { TextareaFieldProps_unstable as TextareaFieldProps } from '@fluentu
export {
Field,
fieldClassNames,
FieldContextProvider,
renderField_unstable,
useFieldContext_unstable,
useFieldContextValues_unstable,
useFieldControlProps_unstable,
useFieldStyles_unstable,
useField_unstable,
} from '@fluentui/react-field';
export type { FieldProps, FieldSlots, FieldState } from '@fluentui/react-field';
export type {
FieldContextValue,
FieldContextValues,
FieldControlProps,
FieldControlPropsOptions,
FieldProps,
FieldSlots,
FieldState,
} from '@fluentui/react-field';

export {
Skeleton,
Expand Down
Loading