From 35148a54f35aa69cf9f260e0f5f4fb05bd5c2f34 Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Mon, 17 Apr 2023 02:48:11 +0200 Subject: [PATCH 01/36] feat(react-drawer): create body component --- .../react-drawer/etc/react-drawer.api.md | 27 ++++++ .../react-drawer/package.json | 3 +- .../react-drawer/src/DrawerBody.ts | 1 + .../src/components/Drawer/useDrawer.ts | 55 ++++-------- .../src/components/Drawer/useDrawerStyles.ts | 31 ++++--- .../components/DrawerBody/DrawerBody.test.tsx | 24 ++++++ .../src/components/DrawerBody/DrawerBody.tsx | 18 ++++ .../components/DrawerBody/DrawerBody.types.ts | 15 ++++ .../src/components/DrawerBody/index.ts | 5 ++ .../DrawerBody/renderDrawerBody.tsx | 12 +++ .../components/DrawerBody/useDrawerBody.ts | 25 ++++++ .../DrawerBody/useDrawerBodyStyles.ts | 50 +++++++++++ .../react-drawer/src/index.ts | 8 ++ .../DrawerBody/DrawerBodyBestPractices.md | 5 ++ .../DrawerBody/DrawerBodyDefault.stories.tsx | 85 +++++++++++++++++++ .../DrawerBody/DrawerBodyDescription.md | 0 .../stories/DrawerBody/index.stories.tsx | 18 ++++ .../react-drawer/tsconfig.lib.json | 4 +- 18 files changed, 334 insertions(+), 52 deletions(-) create mode 100644 packages/react-components/react-drawer/src/DrawerBody.ts create mode 100644 packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.test.tsx create mode 100644 packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.tsx create mode 100644 packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.types.ts create mode 100644 packages/react-components/react-drawer/src/components/DrawerBody/index.ts create mode 100644 packages/react-components/react-drawer/src/components/DrawerBody/renderDrawerBody.tsx create mode 100644 packages/react-components/react-drawer/src/components/DrawerBody/useDrawerBody.ts create mode 100644 packages/react-components/react-drawer/src/components/DrawerBody/useDrawerBodyStyles.ts create mode 100644 packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyBestPractices.md create mode 100644 packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDefault.stories.tsx create mode 100644 packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDescription.md create mode 100644 packages/react-components/react-drawer/stories/DrawerBody/index.stories.tsx diff --git a/packages/react-components/react-drawer/etc/react-drawer.api.md b/packages/react-components/react-drawer/etc/react-drawer.api.md index 37b6b074c19914..1f60fa6467cc7b 100644 --- a/packages/react-components/react-drawer/etc/react-drawer.api.md +++ b/packages/react-components/react-drawer/etc/react-drawer.api.md @@ -18,12 +18,30 @@ import type { SlotClassNames } from '@fluentui/react-utilities'; // @public export const Drawer: ForwardRefComponent; +// @public +export const DrawerBody: ForwardRefComponent; + +// @public (undocumented) +export const drawerBodyClassNames: SlotClassNames; + +// @public +export type DrawerBodyProps = ComponentProps & {}; + +// @public (undocumented) +export type DrawerBodySlots = { + root: Slot<'div'>; +}; + +// @public +export type DrawerBodyState = ComponentState; + // @public (undocumented) export const drawerClassNames: SlotClassNames; // @public export const drawerCSSVars: { size: string; + borderRadius: string; }; // @public @@ -49,9 +67,18 @@ export type DrawerState = ComponentState & Required JSX.Element | null; +// @public +export const renderDrawerBody_unstable: (state: DrawerBodyState) => JSX.Element; + // @public export const useDrawer_unstable: (props: DrawerProps, ref: React_2.Ref) => DrawerState; +// @public +export const useDrawerBody_unstable: (props: DrawerBodyProps, ref: React_2.Ref) => DrawerBodyState; + +// @public +export const useDrawerBodyStyles_unstable: (state: DrawerBodyState) => DrawerBodyState; + // @public export const useDrawerStyles_unstable: (state: DrawerState) => DrawerState; diff --git a/packages/react-components/react-drawer/package.json b/packages/react-components/react-drawer/package.json index d41f33f0ecb77b..44efe783c838f6 100644 --- a/packages/react-components/react-drawer/package.json +++ b/packages/react-components/react-drawer/package.json @@ -24,7 +24,8 @@ "type-check": "tsc -b tsconfig.json", "generate-api": "just-scripts generate-api", "storybook": "start-storybook", - "start": "yarn storybook" + "start": "yarn storybook", + "test-ssr": "test-ssr ./stories/**/*.stories.tsx" }, "devDependencies": { "@fluentui/eslint-plugin": "*", diff --git a/packages/react-components/react-drawer/src/DrawerBody.ts b/packages/react-components/react-drawer/src/DrawerBody.ts new file mode 100644 index 00000000000000..7c2ccd83c54666 --- /dev/null +++ b/packages/react-components/react-drawer/src/DrawerBody.ts @@ -0,0 +1 @@ +export * from './components/DrawerBody/index'; diff --git a/packages/react-components/react-drawer/src/components/Drawer/useDrawer.ts b/packages/react-components/react-drawer/src/components/Drawer/useDrawer.ts index 6d17a79d8787fd..9e4d7d4831d13f 100644 --- a/packages/react-components/react-drawer/src/components/Drawer/useDrawer.ts +++ b/packages/react-components/react-drawer/src/components/Drawer/useDrawer.ts @@ -4,36 +4,6 @@ import { DialogProps } from '@fluentui/react-dialog'; import type { DrawerProps, DrawerState } from './Drawer.types'; -/** - * @internal - * Create the state required to render DrawerDialog. - * @param props - props from this instance of Drawer - */ -const useDrawerDialogProps = (props: DrawerProps) => { - const { open, onOpenChange, modal, children, ...otherProps } = props; - - const dialogProps = React.useMemo(() => { - return { - open, - onOpenChange, - modalType: modal ? 'modal' : 'non-modal', - children, - } as DialogProps; - }, [children, modal, onOpenChange, open]); - - const dialogSurfaceProps = React.useMemo(() => { - return { - ...otherProps, - children, - }; - }, [children, otherProps]); - - return { - dialog: dialogProps, - dialogSurface: dialogSurfaceProps, - }; -}; - /** * Create the state required to render Drawer. * @@ -50,8 +20,11 @@ export const useDrawer_unstable = (props: DrawerProps, ref: React.Ref { + return { + open, + onOpenChange, + modalType: modal ? 'modal' : 'non-modal', + children, + } as DialogProps; + }, [children, modal, onOpenChange, open]); + + const dialogSurfaceProps = { + ...otherProps, + children, + }; return { components: { @@ -76,8 +57,8 @@ export const useDrawer_unstable = (props: DrawerProps, ref: React.Ref = { */ export const drawerCSSVars = { size: '--fui-Drawer--size', + borderRadius: '--fui-Drawer--borderRadius', }; /** @@ -19,17 +20,31 @@ export const drawerCSSVars = { */ const useStyles = makeStyles({ root: { - ...shorthands.padding('16px'), - ...shorthands.borderRadius(0), + ...shorthands.borderRadius(`var(${drawerCSSVars.borderRadius})`), ...shorthands.border(0), + ...shorthands.overflow('hidden'), + + [drawerCSSVars.borderRadius]: 0, boxSizing: 'border-box', width: `var(${drawerCSSVars.size})`, maxWidth: 'calc(100vw - 48px)', height: 'auto', + display: 'flex', + flexDirection: 'column', + backgroundColor: tokens.colorNeutralBackground1, + }, + + overlay: { + position: 'fixed', top: 0, bottom: 0, - backgroundColor: tokens.colorNeutralBackground1, + }, + + inline: { + position: 'relative', + alignItems: 'stretch', + justifyContent: 'stretch', }, leftDrawer: { @@ -42,16 +57,6 @@ const useStyles = makeStyles({ left: 'auto', }, - overlay: { - position: 'fixed', - }, - - inline: { - position: 'relative', - alignItems: 'stretch', - justifyContent: 'stretch', - }, - inlineSeparatorLeft: { ...shorthands.borderRight('1px', 'solid', tokens.colorNeutralBackground3), }, diff --git a/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.test.tsx b/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.test.tsx new file mode 100644 index 00000000000000..5b2a912d41d320 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.test.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { DrawerBody } from './DrawerBody'; +import { isConformant } from '../../testing/isConformant'; + +describe('DrawerBody', () => { + isConformant({ + Component: DrawerBody, + displayName: 'DrawerBody', + }); + + it('renders a default state', () => { + const result = render(Default DrawerBody); + expect(result.container).toMatchInlineSnapshot(` +
+
+ Default DrawerBody +
+
+ `); + }); +}); diff --git a/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.tsx b/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.tsx new file mode 100644 index 00000000000000..fb2691171d7c53 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { useDrawerBody_unstable } from './useDrawerBody'; +import { renderDrawerBody_unstable } from './renderDrawerBody'; +import { useDrawerBodyStyles_unstable } from './useDrawerBodyStyles'; +import type { DrawerBodyProps } from './DrawerBody.types'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +/** + * DrawerBody component - TODO: add more docs + */ +export const DrawerBody: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useDrawerBody_unstable(props, ref); + + useDrawerBodyStyles_unstable(state); + return renderDrawerBody_unstable(state); +}); + +DrawerBody.displayName = 'DrawerBody'; diff --git a/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.types.ts b/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.types.ts new file mode 100644 index 00000000000000..6497c736411f28 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.types.ts @@ -0,0 +1,15 @@ +import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; + +export type DrawerBodySlots = { + root: Slot<'div'>; +}; + +/** + * DrawerBody Props + */ +export type DrawerBodyProps = ComponentProps & {}; + +/** + * State used in rendering DrawerBody + */ +export type DrawerBodyState = ComponentState; diff --git a/packages/react-components/react-drawer/src/components/DrawerBody/index.ts b/packages/react-components/react-drawer/src/components/DrawerBody/index.ts new file mode 100644 index 00000000000000..b8273e016d6ed6 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerBody/index.ts @@ -0,0 +1,5 @@ +export * from './DrawerBody'; +export * from './DrawerBody.types'; +export * from './renderDrawerBody'; +export * from './useDrawerBody'; +export * from './useDrawerBodyStyles'; diff --git a/packages/react-components/react-drawer/src/components/DrawerBody/renderDrawerBody.tsx b/packages/react-components/react-drawer/src/components/DrawerBody/renderDrawerBody.tsx new file mode 100644 index 00000000000000..99b84f8c31159a --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerBody/renderDrawerBody.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; +import { getSlots } from '@fluentui/react-utilities'; +import type { DrawerBodyState, DrawerBodySlots } from './DrawerBody.types'; + +/** + * Render the final JSX of DrawerBody + */ +export const renderDrawerBody_unstable = (state: DrawerBodyState) => { + const { slots, slotProps } = getSlots(state); + + return ; +}; diff --git a/packages/react-components/react-drawer/src/components/DrawerBody/useDrawerBody.ts b/packages/react-components/react-drawer/src/components/DrawerBody/useDrawerBody.ts new file mode 100644 index 00000000000000..9ec54bd516fdd5 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerBody/useDrawerBody.ts @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { getNativeElementProps } from '@fluentui/react-utilities'; +import type { DrawerBodyProps, DrawerBodyState } from './DrawerBody.types'; + +/** + * Create the state required to render DrawerBody. + * + * The returned state can be modified with hooks such as useDrawerBodyStyles_unstable, + * before being passed to renderDrawerBody_unstable. + * + * @param props - props from this instance of DrawerBody + * @param ref - reference to root HTMLElement of DrawerBody + */ +export const useDrawerBody_unstable = (props: DrawerBodyProps, ref: React.Ref): DrawerBodyState => { + return { + components: { + root: 'div', + }, + + root: getNativeElementProps('div', { + ref, + ...props, + }), + }; +}; diff --git a/packages/react-components/react-drawer/src/components/DrawerBody/useDrawerBodyStyles.ts b/packages/react-components/react-drawer/src/components/DrawerBody/useDrawerBodyStyles.ts new file mode 100644 index 00000000000000..9c5b84dc3109b9 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerBody/useDrawerBodyStyles.ts @@ -0,0 +1,50 @@ +import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; +import type { DrawerBodySlots, DrawerBodyState } from './DrawerBody.types'; +import type { SlotClassNames } from '@fluentui/react-utilities'; +import { tokens } from '@fluentui/react-theme'; + +export const drawerBodyClassNames: SlotClassNames = { + root: 'fui-DrawerBody', +}; + +/** + * Styles for the root slot + */ +const useStyles = makeStyles({ + root: { + ...shorthands.margin('-1px', 0), + ...shorthands.padding('1px', tokens.spacingHorizontalXXL), + ...shorthands.overflow('auto'), + ...shorthands.flex(1), + + // A "good hack" to display top and bottom borders based on the scroll position + backgroundImage: `linear-gradient(to top, ${tokens.colorNeutralBackground1}, ${tokens.colorNeutralBackground1}), + linear-gradient(to top, ${tokens.colorNeutralBackground1}, ${tokens.colorNeutralBackground1}), + linear-gradient(to top, ${tokens.colorNeutralStroke1}, ${tokens.colorNeutralBackground1}), + linear-gradient(to bottom, ${tokens.colorNeutralStroke1}, ${tokens.colorNeutralBackground1})`, + 'background-position': 'bottom center, top center, bottom center, top center', + backgroundRepeat: 'no-repeat', + backgroundColor: tokens.colorNeutralBackground1, + backgroundSize: '100% 2px, 100% 2px, 100% 1px, 100% 1px', + backgroundAttachment: 'local, local, scroll, scroll', + + ':last-child': { + paddingBottom: `calc(${tokens.spacingHorizontalXXL} + 1px)`, + }, + + ':first-child': { + paddingTop: `calc(${tokens.spacingHorizontalXXL} + 1px)`, + }, + }, +}); + +/** + * Apply styling to the DrawerBody slots based on the state + */ +export const useDrawerBodyStyles_unstable = (state: DrawerBodyState): DrawerBodyState => { + const styles = useStyles(); + + state.root.className = mergeClasses(drawerBodyClassNames.root, styles.root, state.root.className); + + return state; +}; diff --git a/packages/react-components/react-drawer/src/index.ts b/packages/react-components/react-drawer/src/index.ts index 670be1266bb994..d86be8d8c5d5e3 100644 --- a/packages/react-components/react-drawer/src/index.ts +++ b/packages/react-components/react-drawer/src/index.ts @@ -9,3 +9,11 @@ export { } from './Drawer'; export type { DrawerProps, DrawerSlots, DrawerState } from './Drawer'; +export { + DrawerBody, + drawerBodyClassNames, + renderDrawerBody_unstable, + useDrawerBodyStyles_unstable, + useDrawerBody_unstable, +} from './DrawerBody'; +export type { DrawerBodyProps, DrawerBodySlots, DrawerBodyState } from './DrawerBody'; diff --git a/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyBestPractices.md b/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyBestPractices.md new file mode 100644 index 00000000000000..08ff8ddeeb5f86 --- /dev/null +++ b/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyBestPractices.md @@ -0,0 +1,5 @@ +## Best practices + +### Do + +### Don't diff --git a/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDefault.stories.tsx b/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDefault.stories.tsx new file mode 100644 index 00000000000000..0cceeb797f80f6 --- /dev/null +++ b/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDefault.stories.tsx @@ -0,0 +1,85 @@ +import * as React from 'react'; +import { Drawer, DrawerBody, DrawerBodyProps } from '@fluentui/react-drawer'; +import { makeStyles, shorthands, tokens } from '@fluentui/react-components'; + +const useStyles = makeStyles({ + root: { + display: 'flex', + rowGap: '24px', + columnGap: '24px', + }, + + drawer: { + height: '300px', + }, + + container: { + ...shorthands.padding(tokens.spacingHorizontalXXL), + display: 'flex', + justifyContent: 'flex-start', + alignItems: 'center', + }, +}); + +const Header = (props: Partial) => { + const styles = useStyles(); + + return ( +
+ This is a header +
+ ); +}; + +const Footer = (props: Partial) => { + const styles = useStyles(); + + return ( +
+ +
+ ); +}; + +const Body = (props: Partial) => { + return ( + + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Doloribus nam aut amet similique, iure vel voluptates + cum cumque repellendus perferendis maiores officia unde in? Autem neque sequi maiores eum omnis. Lorem ipsum, + dolor sit amet consectetur adipisicing elit. Perspiciatis ipsam explicabo tempora ipsum saepe nam. Eum aliquid + aperiam, laborum labore excepturi nisi odio deserunt facilis error. Mollitia dolor quidem a. Lorem ipsum, dolor + sit amet consectetur adipisicing elit. Eius soluta ea repellendus voluptatum provident ad aut unde accusantium + sed. Officia qui praesentium repudiandae maxime molestias, non mollitia animi laboriosam quis. Lorem, ipsum dolor + sit amet consectetur adipisicing elit. Inventore, architecto eligendi earum dolor voluptas hic minima nihil porro + odio suscipit quaerat accusantium, aperiam, neque beatae ipsa explicabo consequatur cum quam? + + ); +}; + +export const Default = (props: Partial) => { + const styles = useStyles(); + + return ( +
+ + + + + +
+ + + + + +
+ + + +
+ +
+ +
+ ); +}; diff --git a/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDescription.md b/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDescription.md new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/react-components/react-drawer/stories/DrawerBody/index.stories.tsx b/packages/react-components/react-drawer/stories/DrawerBody/index.stories.tsx new file mode 100644 index 00000000000000..296cf279db8c63 --- /dev/null +++ b/packages/react-components/react-drawer/stories/DrawerBody/index.stories.tsx @@ -0,0 +1,18 @@ +import { DrawerBody } from '@fluentui/react-drawer'; + +import descriptionMd from './DrawerBodyDescription.md'; +import bestPracticesMd from './DrawerBodyBestPractices.md'; + +export { Default } from './DrawerBodyDefault.stories'; + +export default { + title: 'Preview Components/DrawerBody', + component: DrawerBody, + parameters: { + docs: { + description: { + component: [descriptionMd, bestPracticesMd].join('\n'), + }, + }, + }, +}; diff --git a/packages/react-components/react-drawer/tsconfig.lib.json b/packages/react-components/react-drawer/tsconfig.lib.json index 6f90cf95c005bd..e17f808c039339 100644 --- a/packages/react-components/react-drawer/tsconfig.lib.json +++ b/packages/react-components/react-drawer/tsconfig.lib.json @@ -16,7 +16,9 @@ "**/*.test.ts", "**/*.test.tsx", "**/*.stories.ts", - "**/*.stories.tsx" + "**/*.stories.tsx", + "**/*.cy.ts", + "**/*.cy.tsx" ], "include": ["./src/**/*.ts", "./src/**/*.tsx"] } From 3c49889ccc350f833aa462ad07c4161a66f8c367 Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Mon, 17 Apr 2023 03:09:55 +0200 Subject: [PATCH 02/36] feat(react-drawer): create header component --- .../react-drawer/src/DrawerHeader.ts | 1 + .../DrawerHeader/DrawerHeader.test.tsx | 24 ++++++++++++++ .../components/DrawerHeader/DrawerHeader.tsx | 18 +++++++++++ .../DrawerHeader/DrawerHeader.types.ts | 15 +++++++++ .../src/components/DrawerHeader/index.ts | 5 +++ .../DrawerHeader/renderDrawerHeader.tsx | 12 +++++++ .../DrawerHeader/useDrawerHeader.ts | 25 +++++++++++++++ .../DrawerHeader/useDrawerHeaderStyles.ts | 31 +++++++++++++++++++ .../react-drawer/src/index.ts | 12 +++++-- .../DrawerHeader/DrawerHeaderBestPractices.md | 5 +++ .../DrawerHeaderDefault.stories.tsx | 4 +++ .../DrawerHeader/DrawerHeaderDescription.md | 0 .../stories/DrawerHeader/index.stories.tsx | 18 +++++++++++ 13 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 packages/react-components/react-drawer/src/DrawerHeader.ts create mode 100644 packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.test.tsx create mode 100644 packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.tsx create mode 100644 packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.types.ts create mode 100644 packages/react-components/react-drawer/src/components/DrawerHeader/index.ts create mode 100644 packages/react-components/react-drawer/src/components/DrawerHeader/renderDrawerHeader.tsx create mode 100644 packages/react-components/react-drawer/src/components/DrawerHeader/useDrawerHeader.ts create mode 100644 packages/react-components/react-drawer/src/components/DrawerHeader/useDrawerHeaderStyles.ts create mode 100644 packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderBestPractices.md create mode 100644 packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderDefault.stories.tsx create mode 100644 packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderDescription.md create mode 100644 packages/react-components/react-drawer/stories/DrawerHeader/index.stories.tsx diff --git a/packages/react-components/react-drawer/src/DrawerHeader.ts b/packages/react-components/react-drawer/src/DrawerHeader.ts new file mode 100644 index 00000000000000..633e9bd67e1ed9 --- /dev/null +++ b/packages/react-components/react-drawer/src/DrawerHeader.ts @@ -0,0 +1 @@ +export * from './components/DrawerHeader/index'; diff --git a/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.test.tsx b/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.test.tsx new file mode 100644 index 00000000000000..922e5ab8ba7df6 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.test.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { DrawerHeader } from './DrawerHeader'; +import { isConformant } from '../../testing/isConformant'; + +describe('DrawerHeader', () => { + isConformant({ + Component: DrawerHeader, + displayName: 'DrawerHeader', + }); + + it('renders a default state', () => { + const result = render(Default DrawerHeader); + expect(result.container).toMatchInlineSnapshot(` +
+
+ Default DrawerHeader +
+
+ `); + }); +}); diff --git a/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.tsx b/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.tsx new file mode 100644 index 00000000000000..691ca24912f308 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { useDrawerHeader_unstable } from './useDrawerHeader'; +import { renderDrawerHeader_unstable } from './renderDrawerHeader'; +import { useDrawerHeaderStyles_unstable } from './useDrawerHeaderStyles'; +import type { DrawerHeaderProps } from './DrawerHeader.types'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +/** + * DrawerHeader component - TODO: add more docs + */ +export const DrawerHeader: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useDrawerHeader_unstable(props, ref); + + useDrawerHeaderStyles_unstable(state); + return renderDrawerHeader_unstable(state); +}); + +DrawerHeader.displayName = 'DrawerHeader'; diff --git a/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.types.ts b/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.types.ts new file mode 100644 index 00000000000000..9c2c0eb318c769 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.types.ts @@ -0,0 +1,15 @@ +import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; + +export type DrawerHeaderSlots = { + root: Slot<'header'>; +}; + +/** + * DrawerHeader Props + */ +export type DrawerHeaderProps = ComponentProps & {}; + +/** + * State used in rendering DrawerHeader + */ +export type DrawerHeaderState = ComponentState; diff --git a/packages/react-components/react-drawer/src/components/DrawerHeader/index.ts b/packages/react-components/react-drawer/src/components/DrawerHeader/index.ts new file mode 100644 index 00000000000000..acb991359954c9 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerHeader/index.ts @@ -0,0 +1,5 @@ +export * from './DrawerHeader'; +export * from './DrawerHeader.types'; +export * from './renderDrawerHeader'; +export * from './useDrawerHeader'; +export * from './useDrawerHeaderStyles'; diff --git a/packages/react-components/react-drawer/src/components/DrawerHeader/renderDrawerHeader.tsx b/packages/react-components/react-drawer/src/components/DrawerHeader/renderDrawerHeader.tsx new file mode 100644 index 00000000000000..abbad67ac71f59 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerHeader/renderDrawerHeader.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; +import { getSlots } from '@fluentui/react-utilities'; +import type { DrawerHeaderState, DrawerHeaderSlots } from './DrawerHeader.types'; + +/** + * Render the final JSX of DrawerHeader + */ +export const renderDrawerHeader_unstable = (state: DrawerHeaderState) => { + const { slots, slotProps } = getSlots(state); + + return ; +}; diff --git a/packages/react-components/react-drawer/src/components/DrawerHeader/useDrawerHeader.ts b/packages/react-components/react-drawer/src/components/DrawerHeader/useDrawerHeader.ts new file mode 100644 index 00000000000000..76eb8a39308422 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerHeader/useDrawerHeader.ts @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { getNativeElementProps } from '@fluentui/react-utilities'; +import type { DrawerHeaderProps, DrawerHeaderState } from './DrawerHeader.types'; + +/** + * Create the state required to render DrawerHeader. + * + * The returned state can be modified with hooks such as useDrawerHeaderStyles_unstable, + * before being passed to renderDrawerHeader_unstable. + * + * @param props - props from this instance of DrawerHeader + * @param ref - reference to root HTMLElement of DrawerHeader + */ +export const useDrawerHeader_unstable = (props: DrawerHeaderProps, ref: React.Ref): DrawerHeaderState => { + return { + components: { + root: 'header', + }, + + root: getNativeElementProps('header', { + ref, + ...props, + }), + }; +}; diff --git a/packages/react-components/react-drawer/src/components/DrawerHeader/useDrawerHeaderStyles.ts b/packages/react-components/react-drawer/src/components/DrawerHeader/useDrawerHeaderStyles.ts new file mode 100644 index 00000000000000..9bbc1ce1b0e180 --- /dev/null +++ b/packages/react-components/react-drawer/src/components/DrawerHeader/useDrawerHeaderStyles.ts @@ -0,0 +1,31 @@ +import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; +import type { DrawerHeaderSlots, DrawerHeaderState } from './DrawerHeader.types'; +import type { SlotClassNames } from '@fluentui/react-utilities'; +import { tokens } from '@fluentui/react-theme'; + +export const drawerHeaderClassNames: SlotClassNames = { + root: 'fui-DrawerHeader', +}; + +/** + * Styles for the root slot + */ +const useStyles = makeStyles({ + root: { + ...shorthands.padding(tokens.spacingVerticalXXL, tokens.spacingHorizontalXXL, tokens.spacingVerticalS), + display: 'flex', + justifyContent: 'flex-start', + alignItems: 'center', + }, +}); + +/** + * Apply styling to the DrawerHeader slots based on the state + */ +export const useDrawerHeaderStyles_unstable = (state: DrawerHeaderState): DrawerHeaderState => { + const styles = useStyles(); + + state.root.className = mergeClasses(drawerHeaderClassNames.root, styles.root, state.root.className); + + return state; +}; diff --git a/packages/react-components/react-drawer/src/index.ts b/packages/react-components/react-drawer/src/index.ts index d86be8d8c5d5e3..0e0fb205fd3533 100644 --- a/packages/react-components/react-drawer/src/index.ts +++ b/packages/react-components/react-drawer/src/index.ts @@ -1,4 +1,3 @@ -// TODO: replace with real exports export { Drawer, drawerCSSVars, @@ -7,8 +6,8 @@ export { useDrawerStyles_unstable, useDrawer_unstable, } from './Drawer'; - export type { DrawerProps, DrawerSlots, DrawerState } from './Drawer'; + export { DrawerBody, drawerBodyClassNames, @@ -17,3 +16,12 @@ export { useDrawerBody_unstable, } from './DrawerBody'; export type { DrawerBodyProps, DrawerBodySlots, DrawerBodyState } from './DrawerBody'; + +export { + DrawerHeader, + drawerHeaderClassNames, + renderDrawerHeader_unstable, + useDrawerHeaderStyles_unstable, + useDrawerHeader_unstable, +} from './DrawerHeader'; +export type { DrawerHeaderProps, DrawerHeaderSlots, DrawerHeaderState } from './DrawerHeader'; diff --git a/packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderBestPractices.md b/packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderBestPractices.md new file mode 100644 index 00000000000000..08ff8ddeeb5f86 --- /dev/null +++ b/packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderBestPractices.md @@ -0,0 +1,5 @@ +## Best practices + +### Do + +### Don't diff --git a/packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderDefault.stories.tsx b/packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderDefault.stories.tsx new file mode 100644 index 00000000000000..44547bc46edae2 --- /dev/null +++ b/packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderDefault.stories.tsx @@ -0,0 +1,4 @@ +import * as React from 'react'; +import { DrawerHeader, DrawerHeaderProps } from '@fluentui/react-drawer'; + +export const Default = (props: Partial) => ; diff --git a/packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderDescription.md b/packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderDescription.md new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/react-components/react-drawer/stories/DrawerHeader/index.stories.tsx b/packages/react-components/react-drawer/stories/DrawerHeader/index.stories.tsx new file mode 100644 index 00000000000000..f7658ce33c769e --- /dev/null +++ b/packages/react-components/react-drawer/stories/DrawerHeader/index.stories.tsx @@ -0,0 +1,18 @@ +import { DrawerHeader } from '@fluentui/react-drawer'; + +import descriptionMd from './DrawerHeaderDescription.md'; +import bestPracticesMd from './DrawerHeaderBestPractices.md'; + +export { Default } from './DrawerHeaderDefault.stories'; + +export default { + title: 'Preview Components/DrawerHeader', + component: DrawerHeader, + parameters: { + docs: { + description: { + component: [descriptionMd, bestPracticesMd].join('\n'), + }, + }, + }, +}; From b2237ea6230b05fd055de6106a11500e1efbd5da Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Mon, 17 Apr 2023 03:14:28 +0200 Subject: [PATCH 03/36] docs: regenerate API --- .../react-drawer/etc/react-drawer.api.md | 26 +++++++++++++++++++ .../DrawerHeader/DrawerHeader.test.tsx | 4 +-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-drawer/etc/react-drawer.api.md b/packages/react-components/react-drawer/etc/react-drawer.api.md index 1f60fa6467cc7b..9e458fb86c56a8 100644 --- a/packages/react-components/react-drawer/etc/react-drawer.api.md +++ b/packages/react-components/react-drawer/etc/react-drawer.api.md @@ -44,6 +44,23 @@ export const drawerCSSVars: { borderRadius: string; }; +// @public +export const DrawerHeader: ForwardRefComponent; + +// @public (undocumented) +export const drawerHeaderClassNames: SlotClassNames; + +// @public +export type DrawerHeaderProps = ComponentProps & {}; + +// @public (undocumented) +export type DrawerHeaderSlots = { + root: Slot<'header'>; +}; + +// @public +export type DrawerHeaderState = ComponentState; + // @public export type DrawerProps = ComponentProps> & { position?: 'left' | 'right'; @@ -70,6 +87,9 @@ export const renderDrawer_unstable: (state: DrawerState) => JSX.Element | null; // @public export const renderDrawerBody_unstable: (state: DrawerBodyState) => JSX.Element; +// @public +export const renderDrawerHeader_unstable: (state: DrawerHeaderState) => JSX.Element; + // @public export const useDrawer_unstable: (props: DrawerProps, ref: React_2.Ref) => DrawerState; @@ -79,6 +99,12 @@ export const useDrawerBody_unstable: (props: DrawerBodyProps, ref: React_2.Ref DrawerBodyState; +// @public +export const useDrawerHeader_unstable: (props: DrawerHeaderProps, ref: React_2.Ref) => DrawerHeaderState; + +// @public +export const useDrawerHeaderStyles_unstable: (state: DrawerHeaderState) => DrawerHeaderState; + // @public export const useDrawerStyles_unstable: (state: DrawerState) => DrawerState; diff --git a/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.test.tsx b/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.test.tsx index 922e5ab8ba7df6..ec373900e090ed 100644 --- a/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.test.tsx +++ b/packages/react-components/react-drawer/src/components/DrawerHeader/DrawerHeader.test.tsx @@ -13,11 +13,11 @@ describe('DrawerHeader', () => { const result = render(Default DrawerHeader); expect(result.container).toMatchInlineSnapshot(`
-
Default DrawerHeader -
+
`); }); From 49e55d3f25d25b97e86a448b65ce98179d112890 Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Tue, 18 Apr 2023 14:22:07 +0200 Subject: [PATCH 04/36] fix: remove .cy files from lib config --- packages/react-components/react-card/tsconfig.lib.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/react-components/react-card/tsconfig.lib.json b/packages/react-components/react-card/tsconfig.lib.json index e17f808c039339..6f90cf95c005bd 100644 --- a/packages/react-components/react-card/tsconfig.lib.json +++ b/packages/react-components/react-card/tsconfig.lib.json @@ -16,9 +16,7 @@ "**/*.test.ts", "**/*.test.tsx", "**/*.stories.ts", - "**/*.stories.tsx", - "**/*.cy.ts", - "**/*.cy.tsx" + "**/*.stories.tsx" ], "include": ["./src/**/*.ts", "./src/**/*.tsx"] } From ca1a06e3ffdf3e88dfba992625c0b1c8062ecccb Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Tue, 18 Apr 2023 14:24:20 +0200 Subject: [PATCH 05/36] fix: remove .cy files from lib config --- packages/react-components/react-card/tsconfig.lib.json | 4 +++- packages/react-components/react-drawer/tsconfig.lib.json | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-components/react-card/tsconfig.lib.json b/packages/react-components/react-card/tsconfig.lib.json index 6f90cf95c005bd..e17f808c039339 100644 --- a/packages/react-components/react-card/tsconfig.lib.json +++ b/packages/react-components/react-card/tsconfig.lib.json @@ -16,7 +16,9 @@ "**/*.test.ts", "**/*.test.tsx", "**/*.stories.ts", - "**/*.stories.tsx" + "**/*.stories.tsx", + "**/*.cy.ts", + "**/*.cy.tsx" ], "include": ["./src/**/*.ts", "./src/**/*.tsx"] } diff --git a/packages/react-components/react-drawer/tsconfig.lib.json b/packages/react-components/react-drawer/tsconfig.lib.json index e17f808c039339..6f90cf95c005bd 100644 --- a/packages/react-components/react-drawer/tsconfig.lib.json +++ b/packages/react-components/react-drawer/tsconfig.lib.json @@ -16,9 +16,7 @@ "**/*.test.ts", "**/*.test.tsx", "**/*.stories.ts", - "**/*.stories.tsx", - "**/*.cy.ts", - "**/*.cy.tsx" + "**/*.stories.tsx" ], "include": ["./src/**/*.ts", "./src/**/*.tsx"] } From aee85b9f44f69608b0a7038ae05bdc9319c757e0 Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Tue, 25 Apr 2023 14:29:19 +0200 Subject: [PATCH 06/36] fix: remove conflict code leftover --- packages/react-components/react-drawer/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-components/react-drawer/package.json b/packages/react-components/react-drawer/package.json index 536dcab7503f71..ca0f37b72fa834 100644 --- a/packages/react-components/react-drawer/package.json +++ b/packages/react-components/react-drawer/package.json @@ -24,8 +24,7 @@ "type-check": "tsc -b tsconfig.json", "generate-api": "just-scripts generate-api", "storybook": "start-storybook", - "start": "yarn storybook", - "test-ssr": "test-ssr ./stories/**/*.stories.tsx" + "start": "yarn storybook" }, "devDependencies": { "@fluentui/eslint-plugin": "*", From b61d019212ee4d10276ca48a0bb515013c72f22b Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Tue, 25 Apr 2023 14:33:17 +0200 Subject: [PATCH 07/36] docs: remove TODO marks --- .../react-drawer/src/components/Drawer/Drawer.tsx | 2 +- .../react-drawer/src/components/DrawerBody/DrawerBody.tsx | 2 +- packages/react-components/react-drawer/src/index.ts | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/react-components/react-drawer/src/components/Drawer/Drawer.tsx b/packages/react-components/react-drawer/src/components/Drawer/Drawer.tsx index 13ded85aa7b97c..8d0e913f7930b0 100644 --- a/packages/react-components/react-drawer/src/components/Drawer/Drawer.tsx +++ b/packages/react-components/react-drawer/src/components/Drawer/Drawer.tsx @@ -6,7 +6,7 @@ import type { DrawerProps } from './Drawer.types'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; /** - * Drawer component - TODO: add more docs + * Drawer contains supplementary content and are used for complex creation, edit, or management experiences. */ export const Drawer: ForwardRefComponent = React.forwardRef((props, ref) => { const state = useDrawer_unstable(props, ref); diff --git a/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.tsx b/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.tsx index fb2691171d7c53..f721fefa5d1f02 100644 --- a/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.tsx +++ b/packages/react-components/react-drawer/src/components/DrawerBody/DrawerBody.tsx @@ -6,7 +6,7 @@ import type { DrawerBodyProps } from './DrawerBody.types'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; /** - * DrawerBody component - TODO: add more docs + * DrawerBody provides with a container for the main content of a Drawer. */ export const DrawerBody: ForwardRefComponent = React.forwardRef((props, ref) => { const state = useDrawerBody_unstable(props, ref); diff --git a/packages/react-components/react-drawer/src/index.ts b/packages/react-components/react-drawer/src/index.ts index d86be8d8c5d5e3..9a1bec39b7594f 100644 --- a/packages/react-components/react-drawer/src/index.ts +++ b/packages/react-components/react-drawer/src/index.ts @@ -1,4 +1,3 @@ -// TODO: replace with real exports export { Drawer, drawerCSSVars, From 0b35c1675b655cf96b9e8fda1c61fdaa275ad72a Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Tue, 25 Apr 2023 14:45:27 +0200 Subject: [PATCH 08/36] docs: add initial stories for header --- .../DrawerBody/DrawerBodyDefault.stories.tsx | 16 +++++++--------- .../DrawerHeader/DrawerHeaderBestPractices.md | 5 ----- .../DrawerHeader/DrawerHeaderDefault.stories.tsx | 7 ++++++- .../stories/DrawerHeader/index.stories.tsx | 3 +-- 4 files changed, 14 insertions(+), 17 deletions(-) delete mode 100644 packages/react-components/react-drawer/stories/DrawerHeader/DrawerHeaderBestPractices.md diff --git a/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDefault.stories.tsx b/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDefault.stories.tsx index 0cceeb797f80f6..98e5456c3e5d12 100644 --- a/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDefault.stories.tsx +++ b/packages/react-components/react-drawer/stories/DrawerBody/DrawerBodyDefault.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Drawer, DrawerBody, DrawerBodyProps } from '@fluentui/react-drawer'; +import { Drawer, DrawerBody, DrawerBodyProps, DrawerHeader } from '@fluentui/react-drawer'; import { makeStyles, shorthands, tokens } from '@fluentui/react-components'; const useStyles = makeStyles({ @@ -13,7 +13,7 @@ const useStyles = makeStyles({ height: '300px', }, - container: { + footer: { ...shorthands.padding(tokens.spacingHorizontalXXL), display: 'flex', justifyContent: 'flex-start', @@ -21,21 +21,19 @@ const useStyles = makeStyles({ }, }); -const Header = (props: Partial) => { - const styles = useStyles(); - +const Header = () => { return ( -
+ This is a header -
+
); }; -const Footer = (props: Partial) => { +const Footer = () => { const styles = useStyles(); return ( -