Skip to content
Draft
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": "patch",
"comment": "chore: improve Slot signature to be more presentable in Storybook",
"packageName": "@fluentui/react-utilities",
"email": "bernardo.sunderhus@gmail.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,7 @@ export { SelectionMode_2 as SelectionMode }
export function setVirtualParent(child: Node, parent?: Node): void;

// @public
export type Slot<Type extends keyof JSX.IntrinsicElements | React_2.ComponentType | React_2.VoidFunctionComponent | UnknownSlotProps, AlternateAs extends keyof JSX.IntrinsicElements = never> = IsSingleton<Extract<Type, string>> extends true ? WithSlotShorthandValue<Type extends keyof JSX.IntrinsicElements ? {
as?: Type;
} & WithSlotRenderFunction<IntrinsicElementProps<Type>> : Type extends React_2.ComponentType<infer Props> ? WithSlotRenderFunction<Props> : Type> | {
[As in AlternateAs]: {
as: As;
} & WithSlotRenderFunction<IntrinsicElementProps<As>>;
}[AlternateAs] | null : 'Error: First parameter to Slot must not be not a union of types. See documentation of Slot type.';
export type Slot<Type extends keyof JSX.IntrinsicElements | React_2.ComponentType | React_2.VoidFunctionComponent | UnknownSlotProps, AlternateAs extends keyof JSX.IntrinsicElements = never> = SlotProps<Type, AlternateAs> | SlotShorthandValueFromType<Type> | null;

declare namespace slot {
export {
Expand Down
51 changes: 36 additions & 15 deletions packages/react-components/react-utilities/src/compose/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,25 @@ export type UnknownSlotProps = Pick<React.HTMLAttributes<HTMLElement>, 'children
/**
* Helper type for {@link Slot}. Adds shorthand types that are assignable to the slot's `children`.
*/
type WithSlotShorthandValue<Props extends { children?: unknown }> =
| Props
| Extract<SlotShorthandValue, Props['children']>;
type SlotShorthandValueFromType<Type extends keyof JSX.IntrinsicElements | React.ComponentType | UnknownSlotProps> =
IsSingleton<Extract<Type, string>> extends true
? Extract<
SlotShorthandValue,
Type extends EmptyIntrinsicElements
? never
: Type extends keyof JSX.IntrinsicElements
? React.ReactNode
: Type extends React.ComponentType<infer Props>
? 'children' extends keyof Props
? Props['children']
: never
: Type extends UnknownSlotProps
? 'children' extends keyof Type
? Type['children']
: never
: never
>
: 'Error: Type of SlotShorthandValueFromType must not be an union of types. See documentation of Slot type.';

/**
* Helper type for {@link Slot}. Takes the props we want to support for a slot and adds the ability for `children`
Expand Down Expand Up @@ -100,20 +116,25 @@ type IntrinsicElementProps<Type extends keyof JSX.IntrinsicElements> = Type exte
export type Slot<
Type extends keyof JSX.IntrinsicElements | React.ComponentType | React.VoidFunctionComponent | UnknownSlotProps,
AlternateAs extends keyof JSX.IntrinsicElements = never,
> = SlotProps<Type, AlternateAs> | SlotShorthandValueFromType<Type> | null;

/**
* @internal
*/
type SlotProps<
Type extends keyof JSX.IntrinsicElements | React.ComponentType | React.VoidFunctionComponent | UnknownSlotProps,
AlternateAs extends keyof JSX.IntrinsicElements = never,
> = IsSingleton<Extract<Type, string>> extends true
?
| WithSlotShorthandValue<
Type extends keyof JSX.IntrinsicElements // Intrinsic elements like `div`
? { as?: Type } & WithSlotRenderFunction<IntrinsicElementProps<Type>>
: Type extends React.ComponentType<infer Props> // Component types like `typeof Button`
? WithSlotRenderFunction<Props>
: Type // Props types like `ButtonProps`
>
| {
[As in AlternateAs]: { as: As } & WithSlotRenderFunction<IntrinsicElementProps<As>>;
}[AlternateAs]
| null
: 'Error: First parameter to Slot must not be not a union of types. See documentation of Slot type.';
| (Type extends keyof JSX.IntrinsicElements // Intrinsic elements like `div`
? { as?: Type } & WithSlotRenderFunction<IntrinsicElementProps<Type>>
: Type extends React.ComponentType<infer Props> // Component types like `typeof Button`
? WithSlotRenderFunction<Props>
: Type)
| (AlternateAs extends unknown
? { as: AlternateAs } & WithSlotRenderFunction<IntrinsicElementProps<AlternateAs>>
: never)
: 'Error: First parameter to SlotProps must not be a union of types. See documentation of Slot type.';

/**
* Evaluates to true if the given type contains exactly one string, or false if it is a union of strings.
Expand Down