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
10 changes: 5 additions & 5 deletions apps/vr-tests-react-components/src/stories/Field.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ import {
TextareaField,
} from '@fluentui/react-field';
import { SparkleFilled } from '@fluentui/react-icons';
import { FieldComponent, FieldPropsWithOptionalComponentProps } from '@fluentui/react-field/src/Field';
import { FieldControl, FieldPropsWithOptionalComponentProps } from '@fluentui/react-field/src/Field';

type FieldComponentProps = Pick<
FieldPropsWithOptionalComponentProps<FieldComponent>,
type FieldControlProps = Pick<
FieldPropsWithOptionalComponentProps<FieldControl>,
'orientation' | 'required' | 'label' | 'validationState' | 'validationMessage' | 'validationMessageIcon' | 'hint'
>;

/**
* Common VR tests for all field components. Pass the given Field component (or a wrapper around it).
*/
const storiesOfField = (name: string, Field: React.VoidFunctionComponent<FieldComponentProps>) =>
const storiesOfField = (name: string, Field: React.VoidFunctionComponent<FieldControlProps>) =>
storiesOf(name, module)
.addDecorator(story => <Screener steps={new Steps().snapshot('default').end()}>{story()}</Screener>)
.addDecorator(story => (
Expand Down Expand Up @@ -65,7 +65,7 @@ const storiesOfField = (name: string, Field: React.VoidFunctionComponent<FieldCo
*/
const storiesOfFieldWithSize = (
name: string,
Field: React.VoidFunctionComponent<FieldComponentProps & { size?: 'small' | 'medium' | 'large' }>,
Field: React.VoidFunctionComponent<FieldControlProps & { size?: 'small' | 'medium' | 'large' }>,
) =>
storiesOfField(name, Field)
.addStory('size:small', () => <Field label="Example field" size="small" />)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "chore: Clean up Field tests and story imports in preparation of moving to individual packages",
"packageName": "@fluentui/react-field",
"email": "[email protected]",
"dependentChangeType": "patch"
}
36 changes: 18 additions & 18 deletions packages/react-components/react-field/etc/react-field.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { Textarea } from '@fluentui/react-textarea';
export const CheckboxField: ForwardRefComponent<CheckboxFieldProps>;

// @public (undocumented)
export const checkboxFieldClassNames: SlotClassNames<FieldSlots<FieldComponent>>;
export const checkboxFieldClassNames: SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export type CheckboxFieldProps = Omit<FieldProps<typeof Checkbox>, 'label'> & {
Expand All @@ -43,27 +43,27 @@ export type CheckboxFieldProps = Omit<FieldProps<typeof Checkbox>, 'label'> & {
export const ComboboxField: ForwardRefComponent<ComboboxFieldProps>;

// @public (undocumented)
export const comboboxFieldClassNames: SlotClassNames<FieldSlots<FieldComponent>>;
export const comboboxFieldClassNames: SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export type ComboboxFieldProps = FieldProps<typeof Combobox>;

// @public
export type FieldConfig<T extends FieldComponent> = {
export type FieldConfig<T extends FieldControl> = {
component: T;
classNames: SlotClassNames<FieldSlots<T>>;
labelConnection?: 'htmlFor' | 'aria-labelledby';
ariaInvalidOnError?: boolean;
};

// @public
export type FieldProps<T extends FieldComponent> = ComponentProps<Partial<FieldSlots<T>>, 'control'> & {
export type FieldProps<T extends FieldControl> = ComponentProps<Partial<FieldSlots<T>>, 'control'> & {
orientation?: 'vertical' | 'horizontal';
validationState?: 'error' | 'warning' | 'success';
};

// @public
export type FieldSlots<T extends FieldComponent> = {
export type FieldSlots<T extends FieldControl> = {
root: NonNullable<Slot<'div'>>;
control: SlotComponent<T>;
label?: Slot<typeof Label>;
Expand All @@ -73,18 +73,18 @@ export type FieldSlots<T extends FieldComponent> = {
};

// @public
export type FieldState<T extends FieldComponent> = ComponentState<Required<FieldSlots<T>>> & Pick<FieldProps<T>, 'orientation' | 'validationState'> & {
export type FieldState<T extends FieldControl> = ComponentState<Required<FieldSlots<T>>> & Pick<FieldProps<T>, 'orientation' | 'validationState'> & {
classNames: SlotClassNames<FieldSlots<T>>;
};

// @public (undocumented)
export const getFieldClassNames: (name: string) => SlotClassNames<FieldSlots<FieldComponent>>;
export const getFieldClassNames: (name: string) => SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export const InputField: ForwardRefComponent<InputFieldProps>;

// @public (undocumented)
export const inputFieldClassNames: SlotClassNames<FieldSlots<FieldComponent>>;
export const inputFieldClassNames: SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export type InputFieldProps = FieldProps<typeof Input>;
Expand All @@ -93,7 +93,7 @@ export type InputFieldProps = FieldProps<typeof Input>;
export const ProgressField: ForwardRefComponent<ProgressFieldProps>;

// @public (undocumented)
export const progressFieldClassNames: SlotClassNames<FieldSlots<FieldComponent>>;
export const progressFieldClassNames: SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export type ProgressFieldProps = FieldProps<typeof Progress>;
Expand All @@ -102,19 +102,19 @@ export type ProgressFieldProps = FieldProps<typeof Progress>;
export const RadioGroupField: ForwardRefComponent<RadioGroupFieldProps>;

// @public (undocumented)
export const radioGroupFieldClassNames: SlotClassNames<FieldSlots<FieldComponent>>;
export const radioGroupFieldClassNames: SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export type RadioGroupFieldProps = FieldProps<typeof RadioGroup>;

// @public
export const renderField_unstable: <T extends FieldComponent>(state: FieldState<T>) => JSX.Element;
export const renderField_unstable: <T extends FieldControl>(state: FieldState<T>) => JSX.Element;

// @public (undocumented)
export const SelectField: ForwardRefComponent<SelectFieldProps>;

// @public (undocumented)
export const selectFieldClassNames: SlotClassNames<FieldSlots<FieldComponent>>;
export const selectFieldClassNames: SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export type SelectFieldProps = FieldProps<typeof Select>;
Expand All @@ -123,7 +123,7 @@ export type SelectFieldProps = FieldProps<typeof Select>;
export const SliderField: ForwardRefComponent<SliderFieldProps>;

// @public (undocumented)
export const sliderFieldClassNames: SlotClassNames<FieldSlots<FieldComponent>>;
export const sliderFieldClassNames: SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export type SliderFieldProps = FieldProps<typeof Slider>;
Expand All @@ -132,7 +132,7 @@ export type SliderFieldProps = FieldProps<typeof Slider>;
export const SpinButtonField: ForwardRefComponent<SpinButtonFieldProps>;

// @public (undocumented)
export const spinButtonFieldClassNames: SlotClassNames<FieldSlots<FieldComponent>>;
export const spinButtonFieldClassNames: SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export type SpinButtonFieldProps = FieldProps<typeof SpinButton>;
Expand All @@ -141,7 +141,7 @@ export type SpinButtonFieldProps = FieldProps<typeof SpinButton>;
export const SwitchField: ForwardRefComponent<SwitchFieldProps>;

// @public (undocumented)
export const switchFieldClassNames: SlotClassNames<FieldSlots<FieldComponent>>;
export const switchFieldClassNames: SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export type SwitchFieldProps = Omit<FieldProps<typeof Switch>, 'labelPosition'>;
Expand All @@ -150,16 +150,16 @@ export type SwitchFieldProps = Omit<FieldProps<typeof Switch>, 'labelPosition'>;
export const TextareaField: ForwardRefComponent<TextareaFieldProps>;

// @public (undocumented)
export const textareaFieldClassNames: SlotClassNames<FieldSlots<FieldComponent>>;
export const textareaFieldClassNames: SlotClassNames<FieldSlots<FieldControl>>;

// @public (undocumented)
export type TextareaFieldProps = FieldProps<typeof Textarea>;

// @public
export const useField_unstable: <T extends FieldComponent>(props: FieldPropsWithOptionalComponentProps<T>, ref: React_2.Ref<HTMLElement>, params: FieldConfig<T>) => FieldState<T>;
export const useField_unstable: <T extends FieldControl>(props: FieldPropsWithOptionalComponentProps<T>, ref: React_2.Ref<HTMLElement>, params: FieldConfig<T>) => FieldState<T>;

// @public
export const useFieldStyles_unstable: <T extends FieldComponent>(state: FieldState<T>) => void;
export const useFieldStyles_unstable: <T extends FieldControl>(state: FieldState<T>) => void;

// (No @packageDocumentation comment for this package)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,6 @@ export function isConformant<TProps = {}>(
const defaultOptions: Partial<IsConformantOptions<TProps>> = {
componentPath: require.main?.filename.replace('.test', ''),
extraTests: griffelTests as TestObject<TProps>,

// Field-specific defaults
primarySlot: 'control' as keyof TProps,
testOptions: testInfo.testOptions?.['has-static-classnames']
? undefined
: {
'has-static-classnames': [
{
props: {
label: 'label text',
validationState: 'error',
validationMessage: 'validation message text',
hint: 'hint text',
},
},
],
},
};

baseIsConformant(defaultOptions, testInfo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ describe('CheckboxField', () => {
isConformant({
Component: CheckboxField,
displayName: 'CheckboxField',
primarySlot: 'control',
testOptions: {
'has-static-classnames': [
{
Expand All @@ -20,6 +21,7 @@ describe('CheckboxField', () => {
},
],
},
disabledTests: ['exported-top-level'], // TODO re-enable once component is exported without _unstable
});

// Most functionality is tested by Field.test.tsx, and Checkbox's tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ describe('ComboboxField', () => {
isConformant({
Component: ComboboxField,
displayName: 'ComboboxField',
primarySlot: 'control',
testOptions: {
'has-static-classnames': [
{
props: {
label: 'label text',
validationState: 'error',
validationMessage: 'validation message text',
hint: 'hint text',
},
},
],
},
disabledTests: ['exported-top-level'], // TODO re-enable once component is exported without _unstable
});

// Most functionality is tested by Field.test.tsx, and Combobox's tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { SlotComponent } from './SlotComponent.types';
* Note: the use of VoidFunctionComponent means that component is not *required* to have a children prop,
* but it is still allowed to have a children prop.
*/
export type FieldComponent = React.VoidFunctionComponent<
export type FieldControl = React.VoidFunctionComponent<
Pick<
React.HTMLAttributes<HTMLElement>,
'id' | 'className' | 'style' | 'aria-labelledby' | 'aria-describedby' | 'aria-invalid' | 'aria-errormessage'
Expand All @@ -19,7 +19,7 @@ export type FieldComponent = React.VoidFunctionComponent<
/**
* Slots added by Field
*/
export type FieldSlots<T extends FieldComponent> = {
export type FieldSlots<T extends FieldControl> = {
root: NonNullable<Slot<'div'>>;

/**
Expand Down Expand Up @@ -54,7 +54,7 @@ export type FieldSlots<T extends FieldComponent> = {
/**
* Field Props
*/
export type FieldProps<T extends FieldComponent> = ComponentProps<Partial<FieldSlots<T>>, 'control'> & {
export type FieldProps<T extends FieldControl> = ComponentProps<Partial<FieldSlots<T>>, 'control'> & {
/**
* The orientation of the label relative to the field component.
* This only affects the label, and not the validationMessage or hint (which always appear below the field component).
Expand All @@ -79,7 +79,7 @@ export type FieldProps<T extends FieldComponent> = ComponentProps<Partial<FieldS
* This allows Field to forward the required and size props to the label if the underlying component supports them,
* but doesn't add them to the public API of fields that don't support them.
*/
export type FieldPropsWithOptionalComponentProps<T extends FieldComponent> = FieldProps<T> & {
export type FieldPropsWithOptionalComponentProps<T extends FieldControl> = FieldProps<T> & {
/**
* Whether the field label should be marked as required.
*/
Expand All @@ -96,7 +96,7 @@ export type FieldPropsWithOptionalComponentProps<T extends FieldComponent> = Fie
/**
* Configuration parameters for a Field class, passed to useField_unstable
*/
export type FieldConfig<T extends FieldComponent> = {
export type FieldConfig<T extends FieldControl> = {
/**
* The underlying input component that this field is wrapping.
*/
Expand Down Expand Up @@ -129,7 +129,7 @@ export type FieldConfig<T extends FieldComponent> = {
/**
* State used in rendering Field
*/
export type FieldState<T extends FieldComponent> = ComponentState<Required<FieldSlots<T>>> &
export type FieldState<T extends FieldControl> = ComponentState<Required<FieldSlots<T>>> &
Pick<FieldProps<T>, 'orientation' | 'validationState'> & {
classNames: SlotClassNames<FieldSlots<T>>;
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as React from 'react';
import { getSlots } from '@fluentui/react-utilities';
import type { FieldComponent, FieldSlots, FieldState } from './Field.types';
import type { FieldControl, FieldSlots, FieldState } from './Field.types';

/**
* Render the final JSX of Field
*/
export const renderField_unstable = <T extends FieldComponent>(state: FieldState<T>) => {
const { slots, slotProps } = getSlots<FieldSlots<FieldComponent>>(state as FieldState<FieldComponent>);
export const renderField_unstable = <T extends FieldControl>(state: FieldState<T>) => {
const { slots, slotProps } = getSlots<FieldSlots<FieldControl>>(state as FieldState<FieldControl>);

return (
<slots.root {...slotProps.root}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { CheckmarkCircle12Filled, ErrorCircle12Filled, Warning12Filled } from '@
import { Label } from '@fluentui/react-label';
import { getNativeElementProps, resolveShorthand, useId } from '@fluentui/react-utilities';
import type {
FieldComponent,
FieldConfig,
FieldControl,
FieldProps,
FieldPropsWithOptionalComponentProps,
FieldState,
Expand All @@ -19,7 +19,7 @@ const validationMessageIcons = {
/**
* Partition the props used by the Field itself, from the props that are passed to the underlying field component.
*/
export const getPartitionedFieldProps = <Props extends FieldProps<FieldComponent>>(props: Props) => {
export const getPartitionedFieldProps = <Props extends FieldProps<FieldControl>>(props: Props) => {
const {
className,
control,
Expand Down Expand Up @@ -60,7 +60,7 @@ export const getPartitionedFieldProps = <Props extends FieldProps<FieldComponent
* @param ref - Ref to the control slot (primary slot)
* @param params - Configuration parameters for this Field
*/
export const useField_unstable = <T extends FieldComponent>(
export const useField_unstable = <T extends FieldControl>(
props: FieldPropsWithOptionalComponentProps<T>,
ref: React.Ref<HTMLElement>,
params: FieldConfig<T>,
Expand Down Expand Up @@ -134,7 +134,7 @@ export const useField_unstable = <T extends FieldComponent>(
}
}

const state: FieldState<FieldComponent> = {
const state: FieldState<FieldControl> = {
orientation,
validationState,
classNames: params.classNames,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { makeStyles, mergeClasses } from '@griffel/react';
import type { FieldComponent, FieldProps, FieldSlots, FieldState } from './Field.types';
import type { FieldControl, FieldProps, FieldSlots, FieldState } from './Field.types';
import type { SlotClassNames } from '@fluentui/react-utilities';
import { tokens, typographyStyles } from '@fluentui/react-theme';

export const getFieldClassNames = (name: string): SlotClassNames<FieldSlots<FieldComponent>> => ({
export const getFieldClassNames = (name: string): SlotClassNames<FieldSlots<FieldControl>> => ({
root: `fui-${name}`,
control: `fui-${name}__control`,
label: `fui-${name}__label`,
Expand Down Expand Up @@ -81,9 +81,9 @@ const useValidationMessageIconStyles = makeStyles({
/**
* Apply styling to the Field slots based on the state
*/
export const useFieldStyles_unstable = <T extends FieldComponent>(state: FieldState<T>) => {
export const useFieldStyles_unstable = <T extends FieldControl>(state: FieldState<T>) => {
const classNames = state.classNames;
const validationState: FieldProps<FieldComponent>['validationState'] = state.validationState;
const validationState: FieldProps<FieldControl>['validationState'] = state.validationState;
const horizontal = state.orientation === 'horizontal';

const rootStyles = useRootStyles();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ describe('InputField', () => {
isConformant({
Component: InputField,
displayName: 'InputField',
primarySlot: 'control',
testOptions: {
'has-static-classnames': [
{
props: {
label: 'label text',
validationState: 'error',
validationMessage: 'validation message text',
hint: 'hint text',
},
},
],
},
disabledTests: ['exported-top-level'], // TODO re-enable once component is exported without _unstable
});

// Most functionality is tested by Field.test.tsx, and Input's tests
Expand Down
Loading