Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react-card - Migrate Card to new prop merging / root as a slot #20111

Merged
merged 6 commits into from
Oct 6, 2021
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": "Migrate Card to new prop merging",
"packageName": "@fluentui/react-card",
"email": "[email protected]",
"dependentChangeType": "patch"
}
101 changes: 44 additions & 57 deletions packages/react-card/etc/react-card.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,99 +4,86 @@

```ts

import type { ComponentPropsCompat } from '@fluentui/react-utilities';
import type { ComponentStateCompat } from '@fluentui/react-utilities';
import type { ComponentProps } from '@fluentui/react-utilities';
import type { ComponentState } from '@fluentui/react-utilities';
import type { ForwardRefComponent } from '@fluentui/react-utilities';
import type { IntrinsicShorthandProps } from '@fluentui/react-utilities';
import * as React_2 from 'react';
import type { ShorthandPropsCompat } from '@fluentui/react-utilities';

// @public
export const Card: ForwardRefComponent<CardProps>;

// @public
export type CardDefaultedProps = never;
// @public (undocumented)
export type CardCommons = {};

// @public
export const CardFooter: ForwardRefComponent<CardFooterProps>;

// @public
export type CardFooterDefaultedProps = never;

// @public
export interface CardFooterProps extends ComponentPropsCompat, React_2.HTMLAttributes<HTMLElement> {
action?: ShorthandPropsCompat<React_2.HTMLAttributes<HTMLElement>>;
}
export type CardFooterProps = ComponentProps<CardFooterSlots>;

// @public
export type CardFooterShorthandProps = 'action';
export const cardFooterShorthandProps: Array<keyof CardFooterSlots>;

// @public
export const cardFooterShorthandProps: CardFooterShorthandProps[];
// @public (undocumented)
export type CardFooterSlots = {
root: IntrinsicShorthandProps<'div'>;
action?: IntrinsicShorthandProps<'div'>;
};

// @public
export interface CardFooterState extends ComponentStateCompat<CardFooterProps, CardFooterShorthandProps, CardFooterDefaultedProps> {
ref: React_2.Ref<HTMLElement>;
}
export type CardFooterState = ComponentState<CardFooterSlots>;

// @public
export const CardHeader: ForwardRefComponent<CardHeaderProps>;

// @public
export type CardHeaderDefaultedProps = never;

// @public
export interface CardHeaderProps extends ComponentPropsCompat, React_2.HTMLAttributes<HTMLElement> {
action?: ShorthandPropsCompat<React_2.HTMLAttributes<HTMLElement>>;
content?: ShorthandPropsCompat<React_2.HTMLAttributes<HTMLElement>>;
description: ShorthandPropsCompat<React_2.HTMLAttributes<HTMLElement>>;
header: ShorthandPropsCompat<React_2.HTMLAttributes<HTMLElement>>;
image: ShorthandPropsCompat<React_2.ImgHTMLAttributes<HTMLImageElement>>;
}
export type CardHeaderProps = ComponentProps<CardHeaderSlots>;

// @public
export type CardHeaderShorthandProps = 'image' | 'content' | 'header' | 'description' | 'action';
// @public (undocumented)
export const cardHeaderShorthandProps: Array<keyof CardHeaderSlots>;

// @public
export const cardHeaderShorthandPropsCompat: CardHeaderShorthandProps[];
// @public (undocumented)
export type CardHeaderSlots = {
root: IntrinsicShorthandProps<'div'>;
image: IntrinsicShorthandProps<'div'>;
content?: IntrinsicShorthandProps<'div'>;
header: IntrinsicShorthandProps<'span'>;
description: IntrinsicShorthandProps<'span'>;
action?: IntrinsicShorthandProps<'div'>;
};

// @public
export interface CardHeaderState extends ComponentStateCompat<CardHeaderProps, CardHeaderShorthandProps> {
ref: React_2.Ref<HTMLElement>;
}
export type CardHeaderState = ComponentState<CardHeaderSlots>;

// @public
export const CardPreview: ForwardRefComponent<CardPreviewProps>;

// @public
export type CardPreviewDefaultedProps = never;

// @public
export interface CardPreviewProps extends ComponentPropsCompat, React_2.HTMLAttributes<HTMLElement> {
logo?: ShorthandPropsCompat<React_2.ImgHTMLAttributes<HTMLImageElement>>;
}
export type CardPreviewProps = ComponentProps<CardPreviewSlots>;

// @public
export type CardPreviewShorthandProps = 'logo';
export const cardPreviewShorthandProps: Array<keyof CardPreviewSlots>;

// @public
export const cardPreviewShorthandPropsCompat: CardPreviewShorthandProps[];
// @public (undocumented)
export type CardPreviewSlots = {
root: IntrinsicShorthandProps<'div'>;
logo?: IntrinsicShorthandProps<'div'>;
};

// @public
export interface CardPreviewState extends ComponentStateCompat<CardPreviewProps, CardPreviewShorthandProps, CardPreviewDefaultedProps> {
ref: React_2.Ref<HTMLElement>;
}
export type CardPreviewState = ComponentState<CardPreviewSlots>;

// @public
export interface CardProps extends ComponentPropsCompat, React_2.HTMLAttributes<HTMLElement> {
}
export type CardProps = ComponentProps<CardSlots> & Partial<CardCommons>;

// @public
export type CardShorthandProps = never;
// @public (undocumented)
export type CardSlots = {
root: IntrinsicShorthandProps<'div'>;
};

// @public
export interface CardState extends CardProps, ComponentStateCompat<CardProps, CardShorthandProps, CardDefaultedProps> {
ref: React_2.Ref<HTMLElement>;
}
export type CardState = ComponentState<CardSlots> & CardCommons;

// @public
export const renderCard: (state: CardState) => JSX.Element;
Expand All @@ -111,22 +98,22 @@ export const renderCardHeader: (state: CardHeaderState) => JSX.Element;
export const renderCardPreview: (state: CardPreviewState) => JSX.Element;

// @public
export const useCard: (props: CardProps, ref: React_2.Ref<HTMLElement>, defaultProps?: CardProps | undefined) => CardState;
export const useCard: (props: CardProps, ref: React_2.Ref<HTMLElement>) => CardState;

// @public
export const useCardFooter: (props: CardFooterProps, ref: React_2.Ref<HTMLElement>, defaultProps?: CardFooterProps | undefined) => CardFooterState;
export const useCardFooter: (props: CardFooterProps, ref: React_2.Ref<HTMLElement>) => CardFooterState;

// @public
export const useCardFooterStyles: (state: CardFooterState) => CardFooterState;

// @public
export const useCardHeader: (props: CardHeaderProps, ref: React_2.Ref<HTMLElement>, defaultProps?: CardHeaderProps | undefined) => CardHeaderState;
export const useCardHeader: (props: CardHeaderProps, ref: React_2.Ref<HTMLElement>) => CardHeaderState;

// @public
export const useCardHeaderStyles: (state: CardHeaderState) => CardHeaderState;

// @public
export const useCardPreview: (props: CardPreviewProps, ref: React_2.Ref<HTMLElement>, defaultProps?: CardPreviewProps | undefined) => CardPreviewState;
export const useCardPreview: (props: CardPreviewProps, ref: React_2.Ref<HTMLElement>) => CardPreviewState;

// @public
export const useCardPreviewStyles: (state: CardPreviewState) => CardPreviewState;
Expand Down
30 changes: 10 additions & 20 deletions packages/react-card/src/components/Card/Card.types.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,23 @@
import * as React from 'react';
import type { ComponentPropsCompat, ComponentStateCompat } from '@fluentui/react-utilities';
import type { ComponentProps, ComponentState, IntrinsicShorthandProps } from '@fluentui/react-utilities';

/**
* Card Props
*/
export interface CardProps extends ComponentPropsCompat, React.HTMLAttributes<HTMLElement> {
export type CardSlots = {
root: IntrinsicShorthandProps<'div'>;
};

export type CardCommons = {
/*
* TODO Add props and slots here
* Any slot property should be listed in the cardShorthandProps array below
* Any property that has a default value should be listed in CardDefaultedProps as e.g. 'size' | 'icon'
*/
}
};

/**
* Names of the shorthand properties in CardProps
*/
export type CardShorthandProps = never; // TODO add shorthand property names

/**
* Names of CardProps that have a default value in useCard
* Card Props
*/
export type CardDefaultedProps = never; // TODO add names of properties with default values
export type CardProps = ComponentProps<CardSlots> & Partial<CardCommons>;

/**
* State used in rendering Card
*/
export interface CardState extends CardProps, ComponentStateCompat<CardProps, CardShorthandProps, CardDefaultedProps> {
/**
* Ref to the root element
*/
ref: React.Ref<HTMLElement>;
}
export type CardState = ComponentState<CardSlots> & CardCommons;
8 changes: 4 additions & 4 deletions packages/react-card/src/components/Card/renderCard.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as React from 'react';
import { getSlotsCompat } from '@fluentui/react-utilities';
import type { CardState } from './Card.types';
import { getSlots } from '@fluentui/react-utilities';
import type { CardSlots, CardState } from './Card.types';

/**
* Render the final JSX of Card
*/
export const renderCard = (state: CardState) => {
const { slots, slotProps } = getSlotsCompat(state);
const { slots, slotProps } = getSlots<CardSlots>(state);

return <slots.root {...slotProps.root}>{state.children}</slots.root>;
return <slots.root {...slotProps.root} />;
};
22 changes: 9 additions & 13 deletions packages/react-card/src/components/Card/useCard.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import * as React from 'react';
import { makeMergeProps } from '@fluentui/react-utilities';
import { getNativeElementProps } from '@fluentui/react-utilities';
import type { CardProps, CardState } from './Card.types';

const mergeProps = makeMergeProps<CardState>();

/**
* Create the state required to render Card.
*
Expand All @@ -12,17 +10,15 @@ const mergeProps = makeMergeProps<CardState>();
*
* @param props - props from this instance of Card
* @param ref - reference to root HTMLElement of Card
* @param defaultProps - (optional) default prop values provided by the implementing type
*/
export const useCard = (props: CardProps, ref: React.Ref<HTMLElement>, defaultProps?: CardProps): CardState => {
const state = mergeProps(
{
export const useCard = (props: CardProps, ref: React.Ref<HTMLElement>): CardState => {
return {
components: { root: 'div' },

root: getNativeElementProps(props.as || 'div', {
ref,
role: 'group',
},
defaultProps,
props,
);

return state;
...props,
}),
};
};
18 changes: 9 additions & 9 deletions packages/react-card/src/components/Card/useCardStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ const useStyles = makeStyles({
*/
export const useCardStyles = (state: CardState): CardState => {
const styles = useStyles();
state.className = mergeClasses(
state.root.className = mergeClasses(
styles.root,
(state.onClick ||
state.onMouseUp ||
state.onMouseDown ||
state.onPointerUp ||
state.onPointerDown ||
state.onTouchStart ||
state.onTouchEnd) &&
(state.root.onClick ||
state.root.onMouseUp ||
state.root.onMouseDown ||
state.root.onPointerUp ||
state.root.onPointerDown ||
state.root.onTouchStart ||
state.root.onTouchEnd) &&
styles.interactive,
state.className,
state.root.className,
);

return state;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,16 @@
import * as React from 'react';
import type { ComponentPropsCompat, ComponentStateCompat, ShorthandPropsCompat } from '@fluentui/react-utilities';
import type { ComponentProps, ComponentState, IntrinsicShorthandProps } from '@fluentui/react-utilities';

/**
* CardFooter Props
*/
export interface CardFooterProps extends ComponentPropsCompat, React.HTMLAttributes<HTMLElement> {
/**
* Actions slot
*/
action?: ShorthandPropsCompat<React.HTMLAttributes<HTMLElement>>;
}

/**
* Names of the shorthand properties in CardFooterProps
*/
export type CardFooterShorthandProps = 'action'; // TODO add shorthand property names
export type CardFooterSlots = {
root: IntrinsicShorthandProps<'div'>;
action?: IntrinsicShorthandProps<'div'>;
};

/**
* Names of CardFooterProps that have a default value in useCardFooter
* CardFooter props
*/
export type CardFooterDefaultedProps = never;
export type CardFooterProps = ComponentProps<CardFooterSlots>;

/**
* State used in rendering CardFooter
*/
export interface CardFooterState
extends ComponentStateCompat<CardFooterProps, CardFooterShorthandProps, CardFooterDefaultedProps> {
/**
* Ref to the root element
*/
ref: React.Ref<HTMLElement>;
}
export type CardFooterState = ComponentState<CardFooterSlots>;
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ exports[`CardFooter renders a default state 1`] = `
class=""
>
Default CardFooter
<span
<div
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intended change, action slot can contain any kind of elements so it should not be a span

class=""
>
Action slot
</span>
</div>
</div>
</div>
`;
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import * as React from 'react';
import { getSlotsCompat } from '@fluentui/react-utilities';
import { getSlots } from '@fluentui/react-utilities';
import { cardFooterShorthandProps } from './useCardFooter';
import type { CardFooterState } from './CardFooter.types';
import type { CardFooterSlots, CardFooterState } from './CardFooter.types';

/**
* Render the final JSX of CardFooter
*/
export const renderCardFooter = (state: CardFooterState) => {
const { slots, slotProps } = getSlotsCompat(state, cardFooterShorthandProps);
const { slots, slotProps } = getSlots<CardFooterSlots>(state, cardFooterShorthandProps);

return (
<slots.root {...slotProps.root}>
{state.children}
{slotProps.root.children}
<slots.action {...slotProps.action} />
</slots.root>
);
Expand Down
Loading