Skip to content
Closed
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 @@ -6,16 +6,37 @@

/// <reference types="react" />

import { ButtonProps } from '@fluentui/react-button';
import { ButtonSlots } from '@fluentui/react-button';
import { ButtonState } from '@fluentui/react-button';
import type { ComponentProps } from '@fluentui/react-utilities';
import type { ComponentState } from '@fluentui/react-utilities';
import type { ForwardRefComponent } from '@fluentui/react-utilities';
import { Link } from '@fluentui/react-link';
import * as React_2 from 'react';
import type { Slot } from '@fluentui/react-utilities';
import type { SlotClassNames } from '@fluentui/react-utilities';

// @public
export const Breadcrumb: ForwardRefComponent<BreadcrumbProps>;

// @public
export const BreadcrumbButton: ForwardRefComponent<BreadcrumbButtonProps>;

// @public (undocumented)
export const breadcrumbButtonClassNames: SlotClassNames<BreadcrumbButtonSlots>;

// @public
export type BreadcrumbButtonProps = ComponentProps<BreadcrumbButtonSlots> & Pick<BreadcrumbProps, 'appearance' | 'size'> & Pick<ButtonProps, 'disabled' | 'iconPosition'> & {
selected?: boolean;
};

// @public (undocumented)
export type BreadcrumbButtonSlots = ButtonSlots;

// @public
export type BreadcrumbButtonState = ComponentState<BreadcrumbButtonSlots> & Omit<ButtonState, keyof ButtonSlots | 'components'> & Required<Pick<BreadcrumbButtonProps, 'selected'>>;

// @public (undocumented)
export const breadcrumbClassNames: SlotClassNames<BreadcrumbSlots>;

Expand Down Expand Up @@ -43,18 +64,44 @@ export const BreadcrumbItem: ForwardRefComponent<BreadcrumbItemProps>;
export const breadcrumbItemClassNames: SlotClassNames<BreadcrumbItemSlots>;

// @public
export type BreadcrumbItemProps = ComponentProps<BreadcrumbItemSlots> & {};
export type BreadcrumbItemProps = ComponentProps<BreadcrumbItemSlots> & Pick<BreadcrumbProps, 'size'> & {
iconPosition?: 'before' | 'after';
};

// @public (undocumented)
export type BreadcrumbItemSlots = {
root: Slot<'li'>;
icon?: Slot<'span'>;
};

// @public
export type BreadcrumbItemState = ComponentState<BreadcrumbItemSlots>;
export type BreadcrumbItemState = ComponentState<BreadcrumbItemSlots> & Required<Pick<BreadcrumbItemProps, 'size'>> & {};

// @public
export const BreadcrumbLink: ForwardRefComponent<BreadcrumbLinkProps>;

// @public (undocumented)
export const breadcrumbLinkClassNames: SlotClassNames<BreadcrumbLinkSlots>;

// @public
export type BreadcrumbLinkProps = ComponentProps<BreadcrumbLinkSlots> & {
iconPosition?: 'before' | 'after';
};

// @public (undocumented)
export type BreadcrumbLinkSlots = {
root: Slot<typeof Link>;
icon?: Slot<'span'>;
};

// @public
export type BreadcrumbLinkState = ComponentState<BreadcrumbLinkSlots> & Required<Pick<BreadcrumbLinkProps, 'iconPosition' | 'disabled'>> & {
iconOnly: boolean;
};

// @public
export type BreadcrumbProps = ComponentProps<BreadcrumbSlots> & {
appearance?: 'transparent' | 'subtle';
size?: 'small' | 'medium' | 'large';
dividerType?: 'chevron' | 'slash';
};
Expand All @@ -66,20 +113,35 @@ export type BreadcrumbSlots = {
};

// @public
export type BreadcrumbState = ComponentState<BreadcrumbSlots> & Required<Pick<BreadcrumbProps, 'size' | 'dividerType'>>;
export type BreadcrumbState = ComponentState<BreadcrumbSlots> & Required<Pick<BreadcrumbProps, 'size' | 'dividerType' | 'appearance'>>;

// @public
export const partitionBreadcrumbItems: <T>(options: PartitionBreadcrumbItemsOptions<T>) => PartitionBreadcrumbItems<T>;

// @public
export const renderBreadcrumb_unstable: (state: BreadcrumbState, contextValues: BreadcrumbContextValues) => JSX.Element;

// @public
export const renderBreadcrumbButton_unstable: (state: BreadcrumbButtonState) => JSX.Element;

// @public
export const renderBreadcrumbDivider_unstable: (state: BreadcrumbDividerState) => JSX.Element;

// @public
export const renderBreadcrumbItem_unstable: (state: BreadcrumbItemState) => JSX.Element;

// @public
export const renderBreadcrumbLink_unstable: (state: BreadcrumbLinkState) => JSX.Element;

// @public
export const useBreadcrumb_unstable: (props: BreadcrumbProps, ref: React_2.Ref<HTMLElement>) => BreadcrumbState;

// @public
export const useBreadcrumbButton_unstable: (props: BreadcrumbButtonProps, ref: React_2.Ref<HTMLButtonElement | HTMLAnchorElement>) => BreadcrumbButtonState;

// @public
export const useBreadcrumbButtonStyles_unstable: (state: BreadcrumbButtonState) => BreadcrumbButtonState;

// @public
export const useBreadcrumbDivider_unstable: (props: BreadcrumbDividerProps, ref: React_2.Ref<HTMLLIElement>) => BreadcrumbDividerState;

Expand All @@ -92,6 +154,12 @@ export const useBreadcrumbItem_unstable: (props: BreadcrumbItemProps, ref: React
// @public
export const useBreadcrumbItemStyles_unstable: (state: BreadcrumbItemState) => BreadcrumbItemState;

// @public
export const useBreadcrumbLink_unstable: (props: BreadcrumbLinkProps, ref: React_2.Ref<HTMLElement>) => BreadcrumbLinkState;

// @public
export const useBreadcrumbLinkStyles_unstable: (state: BreadcrumbLinkState) => BreadcrumbLinkState;

// @public
export const useBreadcrumbStyles_unstable: (state: BreadcrumbState) => BreadcrumbState;

Expand Down
2 changes: 2 additions & 0 deletions packages/react-components/react-breadcrumb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
"@fluentui/scripts-tasks": "*"
},
"dependencies": {
"@fluentui/react-button": "9.3.3",
"@fluentui/react-icons": "^2.0.196",
"@fluentui/react-link": "9.0.29",
"@fluentui/react-shared-contexts": "^9.3.3",
"@fluentui/react-theme": "^9.1.7",
"@fluentui/react-utilities": "^9.7.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/BreadcrumbButton/index';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/BreadcrumbLink/index';
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utili
/**
* Data shared between breadcrumb components
*/
export type BreadcrumbContextValue = Required<Pick<BreadcrumbProps, 'size' | 'dividerType'>>;
export type BreadcrumbContextValue = Required<
Pick<BreadcrumbProps, 'appearance' | 'dividerType' | 'iconPosition' | 'size'>
>;

export type BreadcrumbContextValues = {
breadcrumb: BreadcrumbContextValue;
Expand All @@ -24,17 +26,37 @@ export type BreadcrumbSlots = {
* Breadcrumb Props
*/
export type BreadcrumbProps = ComponentProps<BreadcrumbSlots> & {
/**
* Breadcrumb appearance.
*
* @default 'transparent'
*/
appearance?: 'transparent' | 'subtle';

/**
* Controls type of the divider.
*
* @default 'chevron'
*/
dividerType?: 'chevron' | 'slash';

/**
* Icon position for BreadcrumbButton or BreadcrumbLink.
*
* @default 'before'
*/
iconPosition?: 'before' | 'after';

/**
* Controls size of Breadcrumb items and dividers.
*
* @default 'medium'
*/
size?: 'small' | 'medium' | 'large';

dividerType?: 'chevron' | 'slash';
};

/**
* State used in rendering Breadcrumb
*/
export type BreadcrumbState = ComponentState<BreadcrumbSlots> & Required<Pick<BreadcrumbProps, 'size' | 'dividerType'>>;
export type BreadcrumbState = ComponentState<BreadcrumbSlots> &
Required<Pick<BreadcrumbProps, 'appearance' | 'iconPosition' | 'size' | 'dividerType'>>;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const BreadcrumbContext = React.createContext<BreadcrumbContextValue | undefined
* @internal
*/
export const breadcrumbDefaultValue: BreadcrumbContextValue = {
appearance: 'transparent',
iconPosition: 'before',
size: 'medium',
dividerType: 'chevron',
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ import type { BreadcrumbProps, BreadcrumbState } from './Breadcrumb.types';
* @param ref - reference to root HTMLElement of Breadcrumb
*/
export const useBreadcrumb_unstable = (props: BreadcrumbProps, ref: React.Ref<HTMLElement>): BreadcrumbState => {
const { size = 'medium', dividerType = 'chevron', ...rest } = props;
const {
appearance = 'transparent',
dividerType = 'chevron',
iconPosition = 'before',
size = 'medium',
...rest
} = props;
return {
components: {
root: 'nav',
Expand All @@ -23,7 +29,9 @@ export const useBreadcrumb_unstable = (props: BreadcrumbProps, ref: React.Ref<HT
...rest,
}),
list: resolveShorthand(props.list, { required: true }),
size,
appearance,
dividerType,
iconPosition,
size,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import * as React from 'react';
import type { BreadcrumbContextValues, BreadcrumbState } from './Breadcrumb.types';

export function useBreadcrumbContextValues_unstable(state: BreadcrumbState): BreadcrumbContextValues {
const { size, dividerType } = state;
const { appearance, dividerType, iconPosition, size } = state;

const breadcrumb = React.useMemo(() => {
return { size, dividerType };
}, [size, dividerType]);
return { appearance, dividerType, iconPosition, size };
}, [appearance, dividerType, iconPosition, size]);

return { breadcrumb };
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as React from 'react';
import { render } from '@testing-library/react';
import { BreadcrumbButton } from './BreadcrumbButton';
import { BreadcrumbButtonProps } from './BreadcrumbButton.types';
import { isConformant } from '../../testing/isConformant';
import { breadcrumbButtonClassNames } from './useBreadcrumbButtonStyles';

describe('BreadcrumbButton', () => {
isConformant({
Component: BreadcrumbButton as React.FunctionComponent<BreadcrumbButtonProps>,
displayName: 'BreadcrumbButton',
testOptions: {
'has-static-classnames': [
{
props: {},
expectedClassNames: {
root: breadcrumbButtonClassNames.root,
},
},
],
},
});

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

it('renders a default state', () => {
const result = render(<BreadcrumbButton>Default BreadcrumbButton</BreadcrumbButton>);
expect(result.container).toMatchInlineSnapshot(`
<div>
<button
class="fui-Button fui-BreadcrumbButton"
type="button"
>
Default BreadcrumbButton
</button>
</div>
`);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as React from 'react';
import { useBreadcrumbButton_unstable } from './useBreadcrumbButton';
import { renderBreadcrumbButton_unstable } from './renderBreadcrumbButton';
import { useBreadcrumbButtonStyles_unstable } from './useBreadcrumbButtonStyles';
import type { BreadcrumbButtonProps } from './BreadcrumbButton.types';
import type { ForwardRefComponent } from '@fluentui/react-utilities';

/**
* A button component which is used inside the Breadcrumb.
*/
export const BreadcrumbButton: ForwardRefComponent<BreadcrumbButtonProps> = React.forwardRef((props, ref) => {
const state = useBreadcrumbButton_unstable(props, ref);

useBreadcrumbButtonStyles_unstable(state);
return renderBreadcrumbButton_unstable(state);
});

BreadcrumbButton.displayName = 'BreadcrumbButton';
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { ComponentProps, ComponentState } from '@fluentui/react-utilities';
import { ButtonProps, ButtonSlots, ButtonState } from '@fluentui/react-button';
import { BreadcrumbProps } from '../Breadcrumb/Breadcrumb.types';

export type BreadcrumbButtonSlots = ButtonSlots;

/**
* BreadcrumbButton Props
*/
export type BreadcrumbButtonProps = ComponentProps<BreadcrumbButtonSlots> &
Pick<BreadcrumbProps, 'appearance' | 'iconPosition' | 'size'> &
Pick<ButtonProps, 'disabled'> & {
/**
* Defines current sate of BreadcrumbButton.
*
* @default false
*/
current?: boolean;
};

/**
* State used in rendering BreadcrumbButton
*/
export type BreadcrumbButtonState = ComponentState<BreadcrumbButtonSlots> &
Omit<ButtonState, keyof ButtonSlots | 'components'> &
Required<Pick<BreadcrumbButtonProps, 'current' | 'size'>>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`BreadcrumbButton renders a default state 1`] = `
<div>
<button
class="fui-BreadcrumbButton"
>
Default BreadcrumbButton
</button>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './BreadcrumbButton';
export * from './BreadcrumbButton.types';
export * from './renderBreadcrumbButton';
export * from './useBreadcrumbButton';
export * from './useBreadcrumbButtonStyles';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { BreadcrumbButtonState } from './BreadcrumbButton.types';
import { renderButton_unstable } from '@fluentui/react-button';

/**
* Render the final JSX of BreadcrumbButton
*/
export const renderBreadcrumbButton_unstable = (state: BreadcrumbButtonState) => {
return renderButton_unstable(state);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as React from 'react';
import type { BreadcrumbButtonProps, BreadcrumbButtonState } from './BreadcrumbButton.types';
import { useButton_unstable } from '@fluentui/react-button';
import { useBreadcrumbContext_unstable } from '../Breadcrumb/BreadcrumbContext';

/**
* Create the state required to render BreadcrumbButton.
*
* The returned state can be modified with hooks such as useBreadcrumbButtonStyles_unstable,
* before being passed to renderBreadcrumbButton_unstable.
*
* @param props - props from this instance of BreadcrumbButton
* @param ref - reference to root HTMLElement of BreadcrumbButton
*/
export const useBreadcrumbButton_unstable = (
props: BreadcrumbButtonProps,
ref: React.Ref<HTMLButtonElement | HTMLAnchorElement>,
): BreadcrumbButtonState => {
const { appearance, iconPosition, size } = useBreadcrumbContext_unstable();

const { current = false, ...rest } = props;
return {
...useButton_unstable(
{ ...rest, appearance: props.appearance || appearance, iconPosition: props.iconPosition || iconPosition },
ref,
),
current,
size,
};
};
Loading