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": "prerelease",
"comment": "fix: refactor DrawerHeaderTitle slot creation while keeping the same API",
"packageName": "@fluentui/react-drawer",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import type { ComponentState } from '@fluentui/react-utilities';
import { DialogProps } from '@fluentui/react-dialog';
import { DialogSurfaceProps } from '@fluentui/react-dialog';
import { DialogSurfaceSlots } from '@fluentui/react-dialog';
import { DialogTitleSlots } from '@fluentui/react-dialog';
import type { ForwardRefComponent } from '@fluentui/react-utilities';
import { MotionShorthand } from '@fluentui/react-motion-preview';
import { MotionState } from '@fluentui/react-motion-preview';
Expand Down Expand Up @@ -97,15 +96,13 @@ export const DrawerHeaderTitle: ForwardRefComponent<DrawerHeaderTitleProps>;
export const drawerHeaderTitleClassNames: SlotClassNames<DrawerHeaderTitleSlots>;

// @public
export type DrawerHeaderTitleProps = ComponentProps<DrawerHeaderTitleSlots> & {
children: React_2.ReactNode | undefined;
};
export type DrawerHeaderTitleProps = ComponentProps<DrawerHeaderTitleSlots>;

// @public (undocumented)
export type DrawerHeaderTitleSlots = {
root: Slot<'div'>;
heading?: DialogTitleSlots['root'];
action?: DialogTitleSlots['action'];
heading?: Slot<'h2', 'h1' | 'h3' | 'h4' | 'h5' | 'h6' | 'div'>;
action?: Slot<'div'>;
};

// @public
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { DialogTitleSlots } from '@fluentui/react-dialog';
import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';
import * as React from 'react';

export type DrawerHeaderTitleSlots = {
root: Slot<'div'>;
Expand All @@ -9,24 +7,18 @@ export type DrawerHeaderTitleSlots = {
* By default this is a h2, but can be any heading or div.
* If `div` is provided do not forget to also provide proper `role="heading"` and `aria-level` attributes
*/
heading?: DialogTitleSlots['root'];
heading?: Slot<'h2', 'h1' | 'h3' | 'h4' | 'h5' | 'h6' | 'div'>;

/**
* Action slot for the close button
*/
action?: DialogTitleSlots['action'];
action?: Slot<'div'>;
};

/**
* DrawerHeaderTitle Props
*/
export type DrawerHeaderTitleProps = ComponentProps<DrawerHeaderTitleSlots> & {
/**
* Content of the DrawerHeaderTitle
* Children is mandatory because DrawerHeaderTitle is a wrapper component
*/
children: React.ReactNode | undefined;
};
export type DrawerHeaderTitleProps = ComponentProps<DrawerHeaderTitleSlots>;

/**
* State used in rendering DrawerHeaderTitle
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import { getNativeElementProps, slot } from '@fluentui/react-utilities';
import type { DrawerHeaderTitleProps, DrawerHeaderTitleState } from './DrawerHeaderTitle.types';
import { useDialogTitle_unstable } from '@fluentui/react-dialog';

/**
* Create the state required to render DrawerHeaderTitle.
Expand All @@ -16,13 +15,19 @@ export const useDrawerHeaderTitle_unstable = (
props: DrawerHeaderTitleProps,
ref: React.Ref<HTMLDivElement>,
): DrawerHeaderTitleState => {
const { root: heading, action, components: titleComponents } = useDialogTitle_unstable(props, ref);
let heading = slot.resolveShorthand(props.heading);

if (!heading) {
heading = {
children: props.children,
};
}

return {
components: {
root: 'div',
heading: titleComponents.root,
action: titleComponents.action,
heading: 'h2',
action: 'div',
},

root: slot.always(
Expand All @@ -32,17 +37,15 @@ export const useDrawerHeaderTitle_unstable = (
}),
{ elementType: 'div' },
),
heading: slot.optional(props.heading, {
renderByDefault: true,
heading: slot.optional(getNativeElementProps(heading.as ?? 'h2', heading), {
defaultProps: {
...heading,
className: undefined, // remove className from heading
children: props.children,
},
elementType: titleComponents.root,
renderByDefault: true,
elementType: 'h2',
}),
action: slot.optional(props.action, {
defaultProps: action,
elementType: titleComponents.action,
elementType: 'div',
}),
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from 'react';
import { DrawerInline, DrawerHeader, DrawerHeaderTitle } from '@fluentui/react-drawer';
import { Button, makeStyles } from '@fluentui/react-components';
import { Dismiss24Regular } from '@fluentui/react-icons';

const useStyles = makeStyles({
drawer: {
width: '400px',
height: '600px',
},
});

export const WithTitle = () => {
return (
<DrawerInline className={useStyles().drawer} open>
<DrawerHeader>
<DrawerHeaderTitle>Drawer with title</DrawerHeaderTitle>
<DrawerHeaderTitle heading={{ as: 'h1' }}>Drawer with custom tag</DrawerHeaderTitle>
<DrawerHeaderTitle action={<Button appearance="subtle" aria-label="Close" icon={<Dismiss24Regular />} />}>
Drawer with title and action
</DrawerHeaderTitle>
</DrawerHeader>
</DrawerInline>
);
};

WithTitle.parameters = {
docs: {
controls: {
disable: true,
},
description: {
story: [
'`DrawerHeaderTitle` is a component that provides a structured heading for a Drawer and can be used to display a title and an action.',
'Although it works as a standalone component, it is intended to be used within a `DrawerHeader`.',
'The title renders an `h2` element by default but it can be customized using the `heading` prop.',
].join('\n'),
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export { Position } from './DrawerPosition.stories';
export { Size } from './DrawerSize.stories';
export { CustomSize } from './DrawerCustomSize.stories';
export { Separator } from './DrawerSeparator.stories';
export { WithTitle } from './DrawerWithTitle.stories';
export { WithNavigation } from './DrawerWithNavigation.stories';
export { WithScroll } from './DrawerWithScroll.stories';
export { AlwaysOpen } from './DrawerAlwaysOpen.stories';
Expand Down