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
@@ -0,0 +1,7 @@
{
"type": "none",
"comment": "feat: replace ToolbarRadio implementation by usage of toggle button as radio",
"packageName": "@fluentui/react-toolbar",
"email": "[email protected]",
"dependentChangeType": "none"
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,12 @@ import type { ComponentState } from '@fluentui/react-utilities';
import { DividerSlots } from '@fluentui/react-divider';
import { DividerState } from '@fluentui/react-divider';
import type { ForwardRefComponent } from '@fluentui/react-utilities';
import { RadioGroupProps } from '@fluentui/react-radio';
import { RadioGroupState } from '@fluentui/react-radio';
import { RadioProps } from '@fluentui/react-radio';
import { RadioState } from '@fluentui/react-radio';
import * as React_2 from 'react';
import type { Slot } from '@fluentui/react-utilities';
import { SlotClassNames } from '@fluentui/react-utilities';
import { ToggleButtonProps } from '@fluentui/react-button';
import { ToggleButtonState } from '@fluentui/react-button';

// @public (undocumented)
export type RadioGroupContextValue = Pick<RadioGroupProps, 'name' | 'value' | 'defaultValue' | 'disabled' | 'layout' | 'required'>;

// @public (undocumented)
export type RadioGroupContextValues = {
radioGroup: RadioGroupContextValue;
};

// @public
export const renderToolbar_unstable: (state: ToolbarState, contextValues: ToolbarContextValues) => JSX.Element;

Expand All @@ -55,6 +43,7 @@ export const toolbarClassNames: SlotClassNames<ToolbarSlots>;
// @public (undocumented)
export type ToolbarContextValue = Pick<ToolbarState, 'size' | 'vertical' | 'checkedValues'> & {
handleToggleButton?: ToggableHandler;
handleRadio?: ToggableHandler;
};

// @public (undocumented)
Expand Down Expand Up @@ -83,26 +72,17 @@ export type ToolbarProps = ComponentProps<ToolbarSlots> & {
};

// @public
export const ToolbarRadio: ForwardRefComponent<ToolbarRadioProps>;

// @public
export const ToolbarRadioGroup: ForwardRefComponent<ToolbarRadioGroupProps>;

// @public
export type ToolbarRadioGroupProps = RadioGroupProps;
export const ToolbarRadioButton: ForwardRefComponent<ToolbarRadioButtonProps>;

// @public
export type ToolbarRadioGroupState = RadioGroupState;

// @public
export type ToolbarRadioProps = RadioProps & {
size?: 'small' | 'medium';
export type ToolbarRadioButtonProps = ComponentProps<ButtonSlots> & Partial<Pick<ToggleButtonProps, 'disabled' | 'disabledFocusable' | 'size'>> & {
appearance?: 'primary' | 'subtle';
name: string;
value: string;
};

// @public
export type ToolbarRadioState = RadioState & {
size?: 'small' | 'medium';
};
export type ToolbarRadioButtonState = ComponentState<Partial<ButtonSlots>> & ToggleButtonState & Required<Pick<ToggleButtonProps, 'checked'>> & Pick<ToolbarRadioButtonProps, 'name' | 'value'>;

// @public (undocumented)
export type ToolbarSlots = {
Expand All @@ -112,6 +92,7 @@ export type ToolbarSlots = {
// @public
export type ToolbarState = ComponentState<ToolbarSlots> & Required<Pick<ToolbarProps, 'size' | 'checkedValues' | 'vertical'>> & Pick<ToolbarProps, 'defaultCheckedValues' | 'onCheckedValueChange'> & {
handleToggleButton: ToggableHandler;
handleRadio: ToggableHandler;
};

// @public
Expand Down
1 change: 1 addition & 0 deletions packages/react-components/react-toolbar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@fluentui/react-theme": "^9.1.1",
"@fluentui/react-utilities": "^9.1.2",
"@fluentui/react-context-selector": "^9.0.5",
"@fluentui/react-hooks": "^8.6.12",
"@fluentui/react-radio": "^9.0.9",
"@fluentui/react-tabster": "^9.2.0",
"@griffel/react": "^1.4.1",
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/ToolbarRadioButton/index';

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,27 @@ export type ToolbarState = ComponentState<ToolbarSlots> &
* Toggles the state of a ToggleButton item
*/
handleToggleButton: ToggableHandler;
/*
* Toggles the state of a ToggleButton item
*/
handleRadio: ToggableHandler;
};

export type ToolbarContextValue = Pick<ToolbarState, 'size' | 'vertical' | 'checkedValues'> & {
handleToggleButton?: ToggableHandler;
handleRadio?: ToggableHandler;
};

export type ToolbarContextValues = {
toolbar: ToolbarContextValue;
};

export type UninitializedToolbarState = Omit<ToolbarState, 'checkedValues' | 'handleToggleButton'> &
export type UninitializedToolbarState = Omit<ToolbarState, 'checkedValues' | 'handleToggleButton' | 'handleRadio'> &
Partial<Pick<ToolbarState, 'checkedValues'>>;

export type ToggableHandler = (
e: React.MouseEvent | React.KeyboardEvent,
name?: string,
value?: string,
name: string,
value: string,
checked?: boolean,
) => void;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const ToolbarContext = createContext<ToolbarContextValue | undefined>(und
const toolbarContextDefaultValue: ToolbarContextValue = {
size: 'medium' as 'medium',
handleToggleButton: () => null,
handleRadio: () => null,
vertical: false,
checkedValues: {},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const useToolbar_unstable = (props: ToolbarProps, ref: React.Ref<HTMLElem
const { onCheckedValueChange } = initialState;

const handleToggleButton: ToggableHandler = useEventCallback(
(e: React.MouseEvent | React.KeyboardEvent, name?: string, value?: string, checked?: boolean) => {
(e: React.MouseEvent | React.KeyboardEvent, name: string, value: string, checked?: boolean) => {
if (name && value) {
const checkedItems = checkedValues?.[name] || [];
const newCheckedItems = [...checkedItems];
Expand All @@ -64,9 +64,22 @@ export const useToolbar_unstable = (props: ToolbarProps, ref: React.Ref<HTMLElem
},
);

const handleRadio: ToggableHandler = useEventCallback(
(e: React.MouseEvent | React.KeyboardEvent, name: string, value: string, checked?: boolean) => {
if (name && value) {
onCheckedValueChange?.(e, {
name,
checkedItems: checkedValues?.[name],
});
setCheckedValues(s => ({ ...s, [name]: [value] }));
}
},
);

return {
...initialState,
handleToggleButton,
handleRadio,
checkedValues: checkedValues ?? {},
};
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { ToolbarContextValue, ToolbarContextValues, ToolbarState } from './Toolbar.types';

export function useToolbarContextValues_unstable(state: ToolbarState): ToolbarContextValues {
const { size, handleToggleButton, vertical, checkedValues } = state;
const { size, handleToggleButton, vertical, checkedValues, handleRadio } = state;
// This context is created with "@fluentui/react-context-selector", these is no sense to memoize it
const toolbar: ToolbarContextValue = {
size,
vertical,
handleToggleButton,
handleRadio,
checkedValues,
};

Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from 'react';
import { render } from '@testing-library/react';
import { ToolbarRadioButton } from './ToolbarRadioButton';
import { isConformant } from '../../common/isConformant';
import { ToggleButtonProps } from '@fluentui/react-button';

describe('ToolbarRadioButton', () => {
isConformant({
Component: ToolbarRadioButton as React.FunctionComponent<ToggleButtonProps>,
displayName: 'ToolbarRadioButton',
disabledTests: ['component-has-static-classnames-object'],
});

// TODO add more tests here, and create visual regression tests in /apps/vr-tests

it('renders a default state', () => {
const result = render(
<ToolbarRadioButton name="name" value="value">
Default ToolbarRadio
</ToolbarRadioButton>,
);
expect(result.container).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as React from 'react';
import type { ToolbarRadioButtonProps } from './ToolbarRadioButton.types';
import type { ForwardRefComponent } from '@fluentui/react-utilities';
import { renderToggleButton_unstable } from '@fluentui/react-button';
import { useToolbarRadioButton_unstable } from './useToolbarRadioButton';
import { useToolbarRadioButtonStyles_unstable } from './useToolbarRadioButtonStyles';

/**
* ToolbarRadioButton component
*/
export const ToolbarRadioButton: ForwardRefComponent<ToolbarRadioButtonProps> = React.forwardRef((props, ref) => {
const state = useToolbarRadioButton_unstable(props, ref);

useToolbarRadioButtonStyles_unstable(state);
return renderToggleButton_unstable(state);
}) as ForwardRefComponent<ToolbarRadioButtonProps>;

ToolbarRadioButton.displayName = 'ToolbarRadioButton';
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { ComponentProps, ComponentState } from '@fluentui/react-utilities';
import { ToggleButtonProps, ButtonSlots, ToggleButtonState } from '@fluentui/react-button';

/**
* ToolbarRadioButton Props
*/
export type ToolbarRadioButtonProps = ComponentProps<ButtonSlots> &
Partial<Pick<ToggleButtonProps, 'disabled' | 'disabledFocusable' | 'size'>> & {
appearance?: 'primary' | 'subtle';
name: string;
value: string;
};

/**
* State used in rendering ToolbarRadioButton
*/
export type ToolbarRadioButtonState = ComponentState<Partial<ButtonSlots>> &
ToggleButtonState &
Required<Pick<ToggleButtonProps, 'checked'>> &
Pick<ToolbarRadioButtonProps, 'name' | 'value'>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ToolbarRadioButton renders a default state 1`] = `
<div>
<button
aria-pressed="false"
class="fui-Button fui-ToggleButton"
name="name"
type="button"
value="value"
>
Default ToolbarRadio
</button>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './ToolbarRadioButton';
export * from './ToolbarRadioButton.types';
Loading