first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+15
View File
@@ -0,0 +1,15 @@
Fluent UI React Foundation
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Note: Usage of the fonts and icons referenced in Fluent UI React is subject to the terms listed at https://aka.ms/fluentui-assets-license
+3
View File
@@ -0,0 +1,3 @@
# @fluentui/foundation-legacy
This library is deprecated. New [Fluent UI React](https://developer.microsoft.com/en-us/fluentui) components are no longer built on top of the patterns and utilities from this package.
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "@fluentui/scripts-api-extractor/api-extractor.common.json"
}
+8
View File
@@ -0,0 +1,8 @@
/** Jest test setup file. */
const { setIconOptions } = require('@fluentui/style-utilities');
// Suppress icon warnings.
setIconOptions({
disableWarnings: true,
});
+359
View File
@@ -0,0 +1,359 @@
import { ISchemeNames } from '@fluentui/style-utilities';
import { IStyle } from '@fluentui/style-utilities';
import { IStyleSetBase } from '@fluentui/style-utilities';
import { ITheme } from '@fluentui/style-utilities';
import type { JSXIntrinsicElement } from '@fluentui/utilities';
import type { JSXIntrinsicElementKeys } from '@fluentui/utilities';
import { styled as legacyStyled } from '@fluentui/utilities';
import * as React_2 from 'react';
/**
* Assembles a higher order component based on the following: styles, theme, view, and state.
* Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param options - component Component options. See IComponentOptions for more detail.
*/
export declare function createComponent<TComponentProps extends ValidProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps extends TComponentProps = TComponentProps, TStatics = {}>(view: IViewComponent<TViewProps>, options?: IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics>): React_2.FunctionComponent<TComponentProps> & TStatics;
/**
* This function creates factories that render ouput depending on the user ISlotProp props passed in.
* @param DefaultComponent - Base component to render when not overridden by user props.
* @param options - Factory options, including defaultProp value for shorthand prop mapping.
* @returns ISlotFactory function used for rendering slots.
*/
export declare function createFactory<TProps extends ValidProps, TShorthandProp extends ValidShorthand = never>(DefaultComponent: React_2.ComponentType<TProps>, options?: IFactoryOptions<TProps>): ISlotFactory<TProps, TShorthandProp>;
/**
* Extracts props type from ISlotProp definition.
*/
export declare type ExtractProps<TUnion> = TUnion extends ISlotProp<infer TProps> ? TProps : never;
/**
* Extracts shorthand type from union of ValidShorthand types.
*/
export declare type ExtractShorthand<TUnion> = TUnion extends boolean ? boolean : TUnion extends number ? number : TUnion extends string ? string : never;
/**
* Simple controlled helper that gives priority to props value and falls back to derived value.
*
* @param props - The props object containing controlled prop values.
* @param propName - The controlled prop name.
* @param derivedValue - Derived value. Returned when controlled value is not present.
*/
export declare function getControlledDerivedProps<TProps, TProp extends keyof TProps>(props: Readonly<TProps>, propName: TProp, derivedValue: TProps[TProp]): TProps[TProp];
/**
* This function generates slots that can be used in JSX given a definition of slots and their corresponding types.
* @param userProps - Props as pass to component.
* @param slots - Slot definition object defining the default slot component for each slot.
* @returns A set of created slots that components can render in JSX.
*/
export declare function getSlots<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots>(userProps: TComponentProps, slots: ISlotDefinition<Required<TComponentSlots>>): ISlots<Required<TComponentSlots>>;
/**
* Component helper that defines options as required for ease of use by component consumers.
*/
export declare type IComponent<TComponentProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TStatics = {}> = Required<IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics>> & {
/**
* Component that generates view output.
*/
view: IViewComponent<TViewProps>;
};
/**
* Component options used by foundation to tie elements together.
*
* * TComponentProps: A styleable props interface for the created component.
* * TTokens: The type for tokens props.
* * TStyleSet: The type for styles properties.
* * TViewProps: The props specific to the view, including processed properties outputted by optional state component.
* If state component is not provided, TComponentProps is the same as TViewProps.
* * TStatics: Static type for statics applied to created component object.
*/
export declare interface IComponentOptions<TComponentProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TStatics = {}> {
/**
* Display name to identify component in React hierarchy. This parameter is required for targeted component styling
* via theming.
*/
displayName?: string;
/**
* List of fields which can be customized.
*/
fields?: string[];
/**
* Styles prop to pass into component.
*/
styles?: IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet>;
/**
* Optional state component that processes TComponentProps into TViewProps.
*/
state?: IStateComponentType<TComponentProps, TViewProps>;
/**
* Optional static object to assign to constructed component.
*/
statics?: TStatics;
/**
* Tokens prop to pass into component.
*/
tokens?: ITokenFunctionOrObject<TViewProps, TTokens>;
/**
* Default prop for which to map primitive values.
*/
factoryOptions?: IFactoryOptions<TComponentProps>;
}
/**
* Helper type defining style sections, one for each component slot.
*/
export declare type IComponentStyles<TSlots> = {
[key in keyof TSlots]?: IStyle;
};
export declare interface IControlledStateOptions<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps> {
defaultPropValue?: TProps[TProp];
defaultPropName?: TDefaultProp;
}
export declare type ICustomizationProps<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = IStyleableComponentProps<TViewProps, TTokens, TStyleSet> & Required<Pick<IStyleableComponentProps<TViewProps, TTokens, TStyleSet>, 'theme'>>;
/**
* Defines user properties that are automatically applied by Slot utilities using slot name.
*/
export declare interface IDefaultSlotProps<TSlots> {
_defaultStyles: IComponentStyles<TSlots>;
}
/**
* Factory options for creating component.
*/
export declare interface IFactoryOptions<TProps> {
/**
* Default prop for which to map primitive values.
*/
defaultProp?: keyof TProps | 'children';
}
/**
* Optional HTML element typing to confine or expand HTML attribute usage for an intrinsic slot.
* Useful for slots that need to allow access to specialized HTML attributes, such as for buttons and inputs.
* Example usage: root?: IHTMLElementSlot\<'button'\>;
*/
export declare type IHTMLElementSlot<TElement extends JSXIntrinsicElementKeys> = ISlotProp<JSXIntrinsicElement<TElement>>;
/**
* Generic slot definition allowing common HTML attributes. Applicable for most intrinsic slots. Please note certain
* elements such as buttons and inputs should make use of IHTMLElementSlot to provide access to specialized attributes
* of those elements.
*/
export declare type IHTMLSlot = ISlotProp<React_2.DetailedHTMLProps<React_2.HTMLAttributes<any>, any>>;
/**
* Props generated by Foundation.
*/
export declare interface IProcessedSlotProps {
className?: string;
}
/**
* Helper interface for accessing user props children.
* @deprecated Use React.PropsWithChildren.
*/
export declare type IPropsWithChildren<TProps> = React_2.PropsWithChildren<TProps>;
/**
* Created Slot structure used for rendering by components.
*/
export declare interface ISlot<TProps> {
(componentProps: React_2.PropsWithChildren<TProps> | undefined | null): ReturnType<React_2.FunctionComponent>;
isSlot?: boolean;
}
/**
* Signature of components that have component factories.
*/
export declare interface ISlotCreator<TProps extends ValidProps, TShorthandProp extends ValidShorthand> {
create?: ISlotFactory<TProps, TShorthandProp>;
}
/**
* An interface for defining slots. Each key in TSlot must point to an ISlottableType.
*/
export declare type ISlotDefinition<TSlots> = {
[slot in keyof TSlots]: React_2.ElementType<ExtractProps<TSlots[slot]>>;
};
/**
* Interface for a slot factory that consumes both component and user slot prop and generates rendered output.
*/
export declare type ISlotFactory<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = (componentProps: TProps & IProcessedSlotProps, userProps: ISlotProp<TProps, TShorthandProp>, slotOptions: ISlotOptions<TProps> | undefined, defaultStyles: IStyle, theme?: ITheme) => ReturnType<React_2.FunctionComponent<TProps>>;
/**
* Defines the slot options object for all slot props:
* 1. ISlotRender function.
* 2. React component with TProps interface.
*/
export declare interface ISlotOptions<TProps> {
component?: React_2.ElementType<TProps>;
render?: ISlotRender<TProps>;
}
/**
* Defines the primary slot prop interface components should use to define their slot props.
*/
export declare type ISlotProp<TProps extends ValidProps, TShorthandProp extends ValidShorthand = never> = TShorthandProp | TProps;
/**
* Content rendering provided by component.
*/
export declare type ISlotRender<TProps> = (props: React_2.PropsWithChildren<TProps>, defaultComponent: React_2.ComponentType<React_2.PropsWithChildren<TProps>>) => ReturnType<React_2.FunctionComponent<React_2.PropsWithChildren<TProps>>>;
/**
* Interface for aggregated slots objects used internally by components. Extract the TProps type passed
* into ISlotProp<TProps> to define the ISlot using TProps.
*/
export declare type ISlots<TSlots> = {
[slot in keyof TSlots]: ISlot<ExtractProps<TSlots[slot]>>;
};
/**
* Slottable version of React.ComponentType.
*/
export declare type ISlottableComponentType<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = React_2.ComponentType<TProps> & ISlotCreator<TProps, TShorthandProp>;
/**
* Automatically defines 'slots' prop based on TSlots props.
*/
export declare type ISlottableProps<TSlots> = TSlots & {
slots?: {
[key in keyof TSlots]+?: ISlotOptions<ExtractProps<TSlots[key]>>;
};
};
/**
* Slottable version of React.ReactType.
*/
export declare type ISlottableReactType<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = React_2.ElementType<TProps> & ISlotCreator<TProps, TShorthandProp>;
/**
* Defines the contract for state components.
*/
export declare type IStateComponentType<TComponentProps, TViewProps> = (props: Readonly<TComponentProps>) => TViewProps;
/**
* Optional props for styleable components. If these props are present, they will automatically be
* used by Foundation when applying theming and styling.
*/
export declare interface IStyleableComponentProps<TViewProps, TTokens, TStyleSet extends IStyleSetBase> {
className?: string;
styles?: IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet>;
theme?: ITheme;
tokens?: ITokenFunctionOrObject<TViewProps, TTokens>;
}
/**
* Function declaration for component styles functions.
*/
export declare type IStylesFunction<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = (props: TViewProps, theme: ITheme, tokens: TTokens) => TStyleSet;
/**
* Composite type for component styles functions and objects.
*/
export declare type IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = IStylesFunction<TViewProps, TTokens, TStyleSet> | TStyleSet;
export declare interface IThemeProviderProps {
scheme?: ISchemeNames;
theme?: ITheme;
}
/**
* Tokens can be defined as an object, function, or an array of objects and functions.
*/
export declare type IToken<TViewProps, TTokens> = ITokenBase<TViewProps, TTokens> | ITokenBaseArray<TViewProps, TTokens>;
/**
* Composite base type that includes all possible resolutions of token functions in an array.
*/
export declare type ITokenBase<TViewProps, TTokens> = ITokenFunctionOrObject<TViewProps, TTokens> | false | null | undefined;
/**
* Composite token base array type allowing for token objects, functions, and function resolutions.
*/
export declare interface ITokenBaseArray<TViewProps, TTokens> extends Array<IToken<TViewProps, TTokens>> {
}
/**
* Function declaration for component token functions.
*/
export declare type ITokenFunction<TViewProps, TTokens> = (props: TViewProps, theme: ITheme) => IToken<TViewProps, TTokens>;
/**
* Composite type for component token functions and objects.
*/
export declare type ITokenFunctionOrObject<TViewProps, TTokens> = ITokenFunction<TViewProps, TTokens> | TTokens;
/**
* Defines the contract for view components.
*/
export declare type IViewComponent<TViewProps> = (props: React_2.PropsWithChildren<TViewProps>) => ReturnType<React_2.FunctionComponent>;
export { legacyStyled }
/**
* Theme provider is a simplified version of Customizer that activates the appropriate theme data
* for a given scheme name.
*
* @param providers - Injected providers for accessing theme data and providing it via a Customizer component.
* @deprecated This is an old ThemeProvider implementation. New code should use the ThemeProvider exported from
* `@fluentui/react` (or `@fluentui/react/lib/Theme`) instead.
*/
export declare const ThemeProvider: React_2.FunctionComponent<React_2.PropsWithChildren<IThemeProviderProps>>;
/**
* Controlled state helper that gives priority to props value. Useful for components that have props with both
* controlled and uncontrolled modes. Any props values will override state, but will not update internal state.
* If prop is defined and then later undefined, state will revert to its previous value.
*
* @param props - The props object containing controlled prop values.
* @param propName - The controlled prop name.
* @param options - Options. defaultPropValue is only used if defaultPropName (or its value) is undefined.
*/
export declare function useControlledState<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps>(props: Readonly<TProps>, propName: TProp, options?: IControlledStateOptions<TProps, TProp, TDefaultProp>): [TProps[TProp] | undefined, React_2.Dispatch<React_2.SetStateAction<TProps[TProp]>>];
/**
* Defines valid prop types.
*/
export declare type ValidProps = object;
/**
* Defines valid shorthand prop types. These should match the defaultProp type provided to createComponent.
*/
export declare type ValidShorthand = string | number | boolean;
/**
* This function is required for any module that uses slots.
*
* This function is a slot resolver that automatically evaluates slot functions to generate React elements.
* A byproduct of this resolver is that it removes slots from the React hierarchy by bypassing React.createElement.
*
* To use this function on a per-file basis, use the jsx directive targeting withSlots.
* This directive must be the FIRST LINE in the file to work correctly.
* Usage of this pragma also requires withSlots import statement.
*
* See React.createElement
*/
export declare function withSlots<P extends {}>(type: ISlot<P> | React_2.FunctionComponent<P> | string, props?: (React_2.Attributes & P) | null, ...children: React_2.ReactNode[]): ReturnType<React_2.FunctionComponent<P>>;
export { }
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+213
View File
@@ -0,0 +1,213 @@
## API Report File for "@fluentui/foundation-legacy"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { ISchemeNames } from '@fluentui/style-utilities';
import { IStyle } from '@fluentui/style-utilities';
import { IStyleSetBase } from '@fluentui/style-utilities';
import { ITheme } from '@fluentui/style-utilities';
import type { JSXIntrinsicElement } from '@fluentui/utilities';
import type { JSXIntrinsicElementKeys } from '@fluentui/utilities';
import { styled as legacyStyled } from '@fluentui/utilities';
import * as React_2 from 'react';
// @public
export function createComponent<TComponentProps extends ValidProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps extends TComponentProps = TComponentProps, TStatics = {}>(view: IViewComponent<TViewProps>, options?: IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics>): React_2.FunctionComponent<TComponentProps> & TStatics;
// @public
export function createFactory<TProps extends ValidProps, TShorthandProp extends ValidShorthand = never>(DefaultComponent: React_2.ComponentType<TProps>, options?: IFactoryOptions<TProps>): ISlotFactory<TProps, TShorthandProp>;
// @public
export type ExtractProps<TUnion> = TUnion extends ISlotProp<infer TProps> ? TProps : never;
// @public
export type ExtractShorthand<TUnion> = TUnion extends boolean ? boolean : TUnion extends number ? number : TUnion extends string ? string : never;
// @public
export function getControlledDerivedProps<TProps, TProp extends keyof TProps>(props: Readonly<TProps>, propName: TProp, derivedValue: TProps[TProp]): TProps[TProp];
// @public
export function getSlots<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots>(userProps: TComponentProps, slots: ISlotDefinition<Required<TComponentSlots>>): ISlots<Required<TComponentSlots>>;
// @public
export type IComponent<TComponentProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TStatics = {}> = Required<IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics>> & {
view: IViewComponent<TViewProps>;
};
// @public
export interface IComponentOptions<TComponentProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TStatics = {}> {
displayName?: string;
factoryOptions?: IFactoryOptions<TComponentProps>;
fields?: string[];
state?: IStateComponentType<TComponentProps, TViewProps>;
statics?: TStatics;
styles?: IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet>;
tokens?: ITokenFunctionOrObject<TViewProps, TTokens>;
}
// @public
export type IComponentStyles<TSlots> = {
[key in keyof TSlots]?: IStyle;
};
// @public (undocumented)
export interface IControlledStateOptions<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps> {
// (undocumented)
defaultPropName?: TDefaultProp;
// (undocumented)
defaultPropValue?: TProps[TProp];
}
// @public (undocumented)
export type ICustomizationProps<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = IStyleableComponentProps<TViewProps, TTokens, TStyleSet> & Required<Pick<IStyleableComponentProps<TViewProps, TTokens, TStyleSet>, 'theme'>>;
// @public
export interface IDefaultSlotProps<TSlots> {
// (undocumented)
_defaultStyles: IComponentStyles<TSlots>;
}
// @public
export interface IFactoryOptions<TProps> {
defaultProp?: keyof TProps | 'children';
}
// @public
export type IHTMLElementSlot<TElement extends JSXIntrinsicElementKeys> = ISlotProp<JSXIntrinsicElement<TElement>>;
// @public
export type IHTMLSlot = ISlotProp<React_2.DetailedHTMLProps<React_2.HTMLAttributes<any>, any>>;
// @public
export interface IProcessedSlotProps {
// (undocumented)
className?: string;
}
// @public @deprecated
export type IPropsWithChildren<TProps> = React_2.PropsWithChildren<TProps>;
// @public
export interface ISlot<TProps> {
// (undocumented)
(componentProps: React_2.PropsWithChildren<TProps> | undefined | null): ReturnType<React_2.FunctionComponent>;
// (undocumented)
isSlot?: boolean;
}
// @public
export interface ISlotCreator<TProps extends ValidProps, TShorthandProp extends ValidShorthand> {
// (undocumented)
create?: ISlotFactory<TProps, TShorthandProp>;
}
// @public
export type ISlotDefinition<TSlots> = {
[slot in keyof TSlots]: React_2.ElementType<ExtractProps<TSlots[slot]>>;
};
// @public
export type ISlotFactory<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = (componentProps: TProps & IProcessedSlotProps, userProps: ISlotProp<TProps, TShorthandProp>, slotOptions: ISlotOptions<TProps> | undefined, defaultStyles: IStyle, theme?: ITheme) => ReturnType<React_2.FunctionComponent<TProps>>;
// @public
export interface ISlotOptions<TProps> {
// (undocumented)
component?: React_2.ElementType<TProps>;
// (undocumented)
render?: ISlotRender<TProps>;
}
// @public
export type ISlotProp<TProps extends ValidProps, TShorthandProp extends ValidShorthand = never> = TShorthandProp | TProps;
// @public
export type ISlotRender<TProps> = (props: React_2.PropsWithChildren<TProps>, defaultComponent: React_2.ComponentType<React_2.PropsWithChildren<TProps>>) => ReturnType<React_2.FunctionComponent<React_2.PropsWithChildren<TProps>>>;
// @public
export type ISlots<TSlots> = {
[slot in keyof TSlots]: ISlot<ExtractProps<TSlots[slot]>>;
};
// @public
export type ISlottableComponentType<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = React_2.ComponentType<TProps> & ISlotCreator<TProps, TShorthandProp>;
// @public
export type ISlottableProps<TSlots> = TSlots & {
slots?: {
[key in keyof TSlots]+?: ISlotOptions<ExtractProps<TSlots[key]>>;
};
};
// @public
export type ISlottableReactType<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = React_2.ElementType<TProps> & ISlotCreator<TProps, TShorthandProp>;
// @public
export type IStateComponentType<TComponentProps, TViewProps> = (props: Readonly<TComponentProps>) => TViewProps;
// @public
export interface IStyleableComponentProps<TViewProps, TTokens, TStyleSet extends IStyleSetBase> {
// (undocumented)
className?: string;
// (undocumented)
styles?: IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet>;
// (undocumented)
theme?: ITheme;
// (undocumented)
tokens?: ITokenFunctionOrObject<TViewProps, TTokens>;
}
// @public
export type IStylesFunction<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = (props: TViewProps, theme: ITheme, tokens: TTokens) => TStyleSet;
// @public
export type IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = IStylesFunction<TViewProps, TTokens, TStyleSet> | TStyleSet;
// @public (undocumented)
export interface IThemeProviderProps {
// (undocumented)
scheme?: ISchemeNames;
// (undocumented)
theme?: ITheme;
}
// @public
export type IToken<TViewProps, TTokens> = ITokenBase<TViewProps, TTokens> | ITokenBaseArray<TViewProps, TTokens>;
// @public
export type ITokenBase<TViewProps, TTokens> = ITokenFunctionOrObject<TViewProps, TTokens> | false | null | undefined;
// @public
export interface ITokenBaseArray<TViewProps, TTokens> extends Array<IToken<TViewProps, TTokens>> {
}
// @public
export type ITokenFunction<TViewProps, TTokens> = (props: TViewProps, theme: ITheme) => IToken<TViewProps, TTokens>;
// @public
export type ITokenFunctionOrObject<TViewProps, TTokens> = ITokenFunction<TViewProps, TTokens> | TTokens;
// @public
export type IViewComponent<TViewProps> = (props: React_2.PropsWithChildren<TViewProps>) => ReturnType<React_2.FunctionComponent>;
export { legacyStyled }
// @public @deprecated
export const ThemeProvider: React_2.FunctionComponent<React_2.PropsWithChildren<IThemeProviderProps>>;
// @public
export function useControlledState<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps>(props: Readonly<TProps>, propName: TProp, options?: IControlledStateOptions<TProps, TProp, TDefaultProp>): [TProps[TProp] | undefined, React_2.Dispatch<React_2.SetStateAction<TProps[TProp]>>];
// @public
export type ValidProps = object;
// @public
export type ValidShorthand = string | number | boolean;
// @public
export function withSlots<P extends {}>(type: ISlot<P> | React_2.FunctionComponent<P> | string, props?: (React_2.Attributes & P) | null, ...children: React_2.ReactNode[]): ReturnType<React_2.FunctionComponent<P>>;
// (No @packageDocumentation comment for this package)
```
+5
View File
@@ -0,0 +1,5 @@
import { preset, task } from '@fluentui/scripts-tasks';
preset();
task('build', 'build:react-with-umd');
+120
View File
@@ -0,0 +1,120 @@
import * as React from 'react';
import { IStyle, IStyleSetBase, ITheme } from '@fluentui/style-utilities';
/**
* Helper interface for accessing user props children.
* @deprecated Use React.PropsWithChildren.
*/
export type IPropsWithChildren<TProps> = React.PropsWithChildren<TProps>;
/**
* Helper type defining style sections, one for each component slot.
*/
export type IComponentStyles<TSlots> = {
[key in keyof TSlots]?: IStyle;
};
/**
* Function declaration for component styles functions.
*/
export type IStylesFunction<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = (props: TViewProps, theme: ITheme, tokens: TTokens) => TStyleSet;
/**
* Composite type for component styles functions and objects.
*/
export type IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = IStylesFunction<TViewProps, TTokens, TStyleSet> | TStyleSet;
/**
* Tokens can be defined as an object, function, or an array of objects and functions.
*/
export type IToken<TViewProps, TTokens> = ITokenBase<TViewProps, TTokens> | ITokenBaseArray<TViewProps, TTokens>;
/**
* Function declaration for component token functions.
*/
export type ITokenFunction<TViewProps, TTokens> = (props: TViewProps, theme: ITheme) => IToken<TViewProps, TTokens>;
/**
* Composite type for component token functions and objects.
*/
export type ITokenFunctionOrObject<TViewProps, TTokens> = ITokenFunction<TViewProps, TTokens> | TTokens;
/**
* Composite base type that includes all possible resolutions of token functions in an array.
*/
export type ITokenBase<TViewProps, TTokens> = ITokenFunctionOrObject<TViewProps, TTokens> | false | null | undefined;
/**
* Composite token base array type allowing for token objects, functions, and function resolutions.
*/
export interface ITokenBaseArray<TViewProps, TTokens> extends Array<IToken<TViewProps, TTokens>> {
}
/**
* Optional props for styleable components. If these props are present, they will automatically be
* used by Foundation when applying theming and styling.
*/
export interface IStyleableComponentProps<TViewProps, TTokens, TStyleSet extends IStyleSetBase> {
className?: string;
styles?: IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet>;
theme?: ITheme;
tokens?: ITokenFunctionOrObject<TViewProps, TTokens>;
}
export type ICustomizationProps<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = IStyleableComponentProps<TViewProps, TTokens, TStyleSet> & Required<Pick<IStyleableComponentProps<TViewProps, TTokens, TStyleSet>, 'theme'>>;
/**
* Defines the contract for state components.
*/
export type IStateComponentType<TComponentProps, TViewProps> = (props: Readonly<TComponentProps>) => TViewProps;
/**
* Defines the contract for view components.
*/
export type IViewComponent<TViewProps> = (props: React.PropsWithChildren<TViewProps>) => ReturnType<React.FunctionComponent>;
/**
* Component options used by foundation to tie elements together.
*
* * TComponentProps: A styleable props interface for the created component.
* * TTokens: The type for tokens props.
* * TStyleSet: The type for styles properties.
* * TViewProps: The props specific to the view, including processed properties outputted by optional state component.
* If state component is not provided, TComponentProps is the same as TViewProps.
* * TStatics: Static type for statics applied to created component object.
*/
export interface IComponentOptions<TComponentProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TStatics = {}> {
/**
* Display name to identify component in React hierarchy. This parameter is required for targeted component styling
* via theming.
*/
displayName?: string;
/**
* List of fields which can be customized.
*/
fields?: string[];
/**
* Styles prop to pass into component.
*/
styles?: IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet>;
/**
* Optional state component that processes TComponentProps into TViewProps.
*/
state?: IStateComponentType<TComponentProps, TViewProps>;
/**
* Optional static object to assign to constructed component.
*/
statics?: TStatics;
/**
* Tokens prop to pass into component.
*/
tokens?: ITokenFunctionOrObject<TViewProps, TTokens>;
/**
* Default prop for which to map primitive values.
*/
factoryOptions?: IFactoryOptions<TComponentProps>;
}
/**
* Component helper that defines options as required for ease of use by component consumers.
*/
export type IComponent<TComponentProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TStatics = {}> = Required<IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics>> & {
/**
* Component that generates view output.
*/
view: IViewComponent<TViewProps>;
};
/**
* Factory options for creating component.
*/
export interface IFactoryOptions<TProps> {
/**
* Default prop for which to map primitive values.
*/
defaultProp?: keyof TProps | 'children';
}
+5
View File
@@ -0,0 +1,5 @@
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
});
//# sourceMappingURL=IComponent.js.map
File diff suppressed because one or more lines are too long
+15
View File
@@ -0,0 +1,15 @@
import * as React from 'react';
import type { JSXIntrinsicElement, JSXIntrinsicElementKeys } from '@fluentui/utilities';
import { ISlotProp } from './ISlots';
/**
* Generic slot definition allowing common HTML attributes. Applicable for most intrinsic slots. Please note certain
* elements such as buttons and inputs should make use of IHTMLElementSlot to provide access to specialized attributes
* of those elements.
*/
export type IHTMLSlot = ISlotProp<React.DetailedHTMLProps<React.HTMLAttributes<any>, any>>;
/**
* Optional HTML element typing to confine or expand HTML attribute usage for an intrinsic slot.
* Useful for slots that need to allow access to specialized HTML attributes, such as for buttons and inputs.
* Example usage: root?: IHTMLElementSlot\<'button'\>;
*/
export type IHTMLElementSlot<TElement extends JSXIntrinsicElementKeys> = ISlotProp<JSXIntrinsicElement<TElement>>;
+5
View File
@@ -0,0 +1,5 @@
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
});
//# sourceMappingURL=IHTMLSlots.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"IHTMLSlots.js","sourceRoot":"../src/","sources":["IHTMLSlots.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport type { JSXIntrinsicElement, JSXIntrinsicElementKeys } from '@fluentui/utilities';\nimport { ISlotProp } from './ISlots';\n\n/**\n * Generic slot definition allowing common HTML attributes. Applicable for most intrinsic slots. Please note certain\n * elements such as buttons and inputs should make use of IHTMLElementSlot to provide access to specialized attributes\n * of those elements.\n */\nexport type IHTMLSlot = ISlotProp<React.DetailedHTMLProps<React.HTMLAttributes<any>, any>>;\n\n/**\n * Optional HTML element typing to confine or expand HTML attribute usage for an intrinsic slot.\n * Useful for slots that need to allow access to specialized HTML attributes, such as for buttons and inputs.\n * Example usage: root?: IHTMLElementSlot\\<'button'\\>;\n */\nexport type IHTMLElementSlot<TElement extends JSXIntrinsicElementKeys> = ISlotProp<JSXIntrinsicElement<TElement>>;\n"]}
+94
View File
@@ -0,0 +1,94 @@
import * as React from 'react';
import { IStyle, ITheme } from '@fluentui/style-utilities';
import { IComponentStyles } from './IComponent';
/**
* Signature of components that have component factories.
*/
export interface ISlotCreator<TProps extends ValidProps, TShorthandProp extends ValidShorthand> {
create?: ISlotFactory<TProps, TShorthandProp>;
}
/**
* Slottable version of React.ComponentType.
*/
export type ISlottableComponentType<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = React.ComponentType<TProps> & ISlotCreator<TProps, TShorthandProp>;
/**
* Slottable version of React.ReactType.
*/
export type ISlottableReactType<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = React.ElementType<TProps> & ISlotCreator<TProps, TShorthandProp>;
/**
* Props generated by Foundation.
*/
export interface IProcessedSlotProps {
className?: string;
}
/**
* An interface for defining slots. Each key in TSlot must point to an ISlottableType.
*/
export type ISlotDefinition<TSlots> = {
[slot in keyof TSlots]: React.ElementType<ExtractProps<TSlots[slot]>>;
};
/**
* Created Slot structure used for rendering by components.
*/
export interface ISlot<TProps> {
(componentProps: React.PropsWithChildren<TProps> | undefined | null): ReturnType<React.FunctionComponent>;
isSlot?: boolean;
}
/**
* Interface for a slot factory that consumes both component and user slot prop and generates rendered output.
*/
export type ISlotFactory<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = (componentProps: TProps & IProcessedSlotProps, userProps: ISlotProp<TProps, TShorthandProp>, slotOptions: ISlotOptions<TProps> | undefined, defaultStyles: IStyle, theme?: ITheme) => ReturnType<React.FunctionComponent<TProps>>;
/**
* Defines valid shorthand prop types. These should match the defaultProp type provided to createComponent.
*/
export type ValidShorthand = string | number | boolean;
/**
* Defines valid prop types.
*/
export type ValidProps = object;
/**
* Extracts props type from ISlotProp definition.
*/
export type ExtractProps<TUnion> = TUnion extends ISlotProp<infer TProps> ? TProps : never;
/**
* Extracts shorthand type from union of ValidShorthand types.
*/
export type ExtractShorthand<TUnion> = TUnion extends boolean ? boolean : TUnion extends number ? number : TUnion extends string ? string : never;
/**
* Interface for aggregated slots objects used internally by components. Extract the TProps type passed
* into ISlotProp<TProps> to define the ISlot using TProps.
*/
export type ISlots<TSlots> = {
[slot in keyof TSlots]: ISlot<ExtractProps<TSlots[slot]>>;
};
/**
* Automatically defines 'slots' prop based on TSlots props.
*/
export type ISlottableProps<TSlots> = TSlots & {
slots?: {
[key in keyof TSlots]+?: ISlotOptions<ExtractProps<TSlots[key]>>;
};
};
/**
* Defines user properties that are automatically applied by Slot utilities using slot name.
*/
export interface IDefaultSlotProps<TSlots> {
_defaultStyles: IComponentStyles<TSlots>;
}
/**
* Defines the primary slot prop interface components should use to define their slot props.
*/
export type ISlotProp<TProps extends ValidProps, TShorthandProp extends ValidShorthand = never> = TShorthandProp | TProps;
/**
* Defines the slot options object for all slot props:
* 1. ISlotRender function.
* 2. React component with TProps interface.
*/
export interface ISlotOptions<TProps> {
component?: React.ElementType<TProps>;
render?: ISlotRender<TProps>;
}
/**
* Content rendering provided by component.
*/
export type ISlotRender<TProps> = (props: React.PropsWithChildren<TProps>, defaultComponent: React.ComponentType<React.PropsWithChildren<TProps>>) => ReturnType<React.FunctionComponent<React.PropsWithChildren<TProps>>>;
+5
View File
@@ -0,0 +1,5 @@
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
});
//# sourceMappingURL=ISlots.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ISlots.js","sourceRoot":"../src/","sources":["ISlots.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { IStyle, ITheme } from '@fluentui/style-utilities';\nimport { IComponentStyles } from './IComponent';\n\n/**\n * Signature of components that have component factories.\n */\nexport interface ISlotCreator<TProps extends ValidProps, TShorthandProp extends ValidShorthand> {\n create?: ISlotFactory<TProps, TShorthandProp>;\n}\n\n/**\n * Slottable version of React.ComponentType.\n */\nexport type ISlottableComponentType<\n TProps extends ValidProps,\n TShorthandProp extends ValidShorthand,\n> = React.ComponentType<TProps> & ISlotCreator<TProps, TShorthandProp>;\n\n/**\n * Slottable version of React.ReactType.\n */\nexport type ISlottableReactType<\n TProps extends ValidProps,\n TShorthandProp extends ValidShorthand,\n> = React.ElementType<TProps> & ISlotCreator<TProps, TShorthandProp>;\n\n/**\n * Props generated by Foundation.\n */\nexport interface IProcessedSlotProps {\n className?: string;\n}\n\n/**\n * An interface for defining slots. Each key in TSlot must point to an ISlottableType.\n */\nexport type ISlotDefinition<TSlots> = { [slot in keyof TSlots]: React.ElementType<ExtractProps<TSlots[slot]>> };\n\n/**\n * Created Slot structure used for rendering by components.\n */\nexport interface ISlot<TProps> {\n (componentProps: React.PropsWithChildren<TProps> | undefined | null): ReturnType<React.FunctionComponent>;\n isSlot?: boolean;\n}\n\n/**\n * Interface for a slot factory that consumes both component and user slot prop and generates rendered output.\n */\nexport type ISlotFactory<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = (\n componentProps: TProps & IProcessedSlotProps,\n userProps: ISlotProp<TProps, TShorthandProp>,\n slotOptions: ISlotOptions<TProps> | undefined,\n defaultStyles: IStyle,\n theme?: ITheme,\n) => ReturnType<React.FunctionComponent<TProps>>;\n\n/**\n * Defines valid shorthand prop types. These should match the defaultProp type provided to createComponent.\n */\nexport type ValidShorthand = string | number | boolean;\n\n/**\n * Defines valid prop types.\n */\n// We can constrain TProps more clearly (notably also exclude Functions) once this TS PR is merged:\n// https://github.com/Microsoft/TypeScript/pull/29317\nexport type ValidProps = object;\n\n/**\n * Extracts props type from ISlotProp definition.\n */\nexport type ExtractProps<TUnion> = TUnion extends ISlotProp<infer TProps> ? TProps : never;\n\n/**\n * Extracts shorthand type from union of ValidShorthand types.\n */\nexport type ExtractShorthand<TUnion> = TUnion extends boolean\n ? boolean\n : TUnion extends number\n ? number\n : TUnion extends string\n ? string\n : never;\n\n/**\n * Interface for aggregated slots objects used internally by components. Extract the TProps type passed\n * into ISlotProp<TProps> to define the ISlot using TProps.\n */\nexport type ISlots<TSlots> = { [slot in keyof TSlots]: ISlot<ExtractProps<TSlots[slot]>> };\n\n/**\n * Automatically defines 'slots' prop based on TSlots props.\n */\nexport type ISlottableProps<TSlots> = TSlots & {\n slots?: { [key in keyof TSlots]+?: ISlotOptions<ExtractProps<TSlots[key]>> };\n};\n\n/**\n * Defines user properties that are automatically applied by Slot utilities using slot name.\n */\nexport interface IDefaultSlotProps<TSlots> {\n _defaultStyles: IComponentStyles<TSlots>;\n}\n\n/**\n * Defines the primary slot prop interface components should use to define their slot props.\n */\n// TODO: Constrain TProps more clearly (notably also exclude Functions) once this TS PR is merged:\n// https://github.com/Microsoft/TypeScript/pull/29317\nexport type ISlotProp<TProps extends ValidProps, TShorthandProp extends ValidShorthand = never> =\n | TShorthandProp\n | TProps;\n\n/**\n * Defines the slot options object for all slot props:\n * 1. ISlotRender function.\n * 2. React component with TProps interface.\n */\n\n// TODO: create mutually exclusive type for component & render, but only if it's a readable error for users.\nexport interface ISlotOptions<TProps> {\n component?: React.ElementType<TProps>;\n render?: ISlotRender<TProps>;\n}\n\n/**\n * Content rendering provided by component.\n */\nexport type ISlotRender<TProps> = (\n props: React.PropsWithChildren<TProps>,\n defaultComponent: React.ComponentType<React.PropsWithChildren<TProps>>,\n) => ReturnType<React.FunctionComponent<React.PropsWithChildren<TProps>>>;\n"]}
+15
View File
@@ -0,0 +1,15 @@
import * as React from 'react';
import { ISchemeNames, ITheme } from '@fluentui/style-utilities';
export interface IThemeProviderProps {
scheme?: ISchemeNames;
theme?: ITheme;
}
/**
* Theme provider is a simplified version of Customizer that activates the appropriate theme data
* for a given scheme name.
*
* @param providers - Injected providers for accessing theme data and providing it via a Customizer component.
* @deprecated This is an old ThemeProvider implementation. New code should use the ThemeProvider exported from
* `@fluentui/react` (or `@fluentui/react/lib/Theme`) instead.
*/
export declare const ThemeProvider: React.FunctionComponent<React.PropsWithChildren<IThemeProviderProps>>;
+26
View File
@@ -0,0 +1,26 @@
define(["require", "exports", "tslib", "react", "@fluentui/style-utilities", "@fluentui/utilities"], function (require, exports, tslib_1, React, style_utilities_1, utilities_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ThemeProvider = void 0;
/**
* Theme provider is a simplified version of Customizer that activates the appropriate theme data
* for a given scheme name.
*
* @param providers - Injected providers for accessing theme data and providing it via a Customizer component.
* @deprecated This is an old ThemeProvider implementation. New code should use the ThemeProvider exported from
* `@fluentui/react` (or `@fluentui/react/lib/Theme`) instead.
*/
var ThemeProvider = function (props) {
var scheme = props.scheme, theme = props.theme, rest = tslib_1.__rest(props, ["scheme", "theme"]);
// TODO: consider merging implementation with theme-proto, which only stores a reference / scheme name to theme
// in context and uses quick global store accessor to trigger change by passing in theme object as child and
// triggering re-render. (perf benefits need verification)
var contextTransform = function (context) {
return (0, style_utilities_1.getThemedContext)(context, scheme, theme);
};
// eslint-disable-next-line react/jsx-no-bind, @typescript-eslint/no-deprecated
return React.createElement(utilities_1.Customizer, tslib_1.__assign({}, rest, { contextTransform: contextTransform }));
};
exports.ThemeProvider = ThemeProvider;
});
//# sourceMappingURL=ThemeProvider.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ThemeProvider.js","sourceRoot":"../src/","sources":["ThemeProvider.tsx"],"names":[],"mappings":";;;;IASA;;;;;;;OAOG;IACI,IAAM,aAAa,GAA0E,UAClG,KAA0B;QAElB,IAAA,MAAM,GAAqB,KAAK,OAA1B,EAAE,KAAK,GAAc,KAAK,MAAnB,EAAK,IAAI,kBAAK,KAAK,EAAlC,mBAA0B,CAAF,CAAW;QAEzC,+GAA+G;QAC/G,8GAA8G;QAC9G,4DAA4D;QAC5D,IAAM,gBAAgB,GAAyC,UAAA,OAAO;YACpE,OAAO,IAAA,kCAAgB,EAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC,CAAC;QAEF,+EAA+E;QAC/E,OAAO,oBAAC,sBAAU,uBAAK,IAAI,IAAE,gBAAgB,EAAE,gBAAgB,IAAI,CAAC;IACtE,CAAC,CAAC;IAdW,QAAA,aAAa,iBAcxB","sourcesContent":["import * as React from 'react';\nimport { getThemedContext, ISchemeNames, ITheme } from '@fluentui/style-utilities';\nimport { Customizer, ICustomizerProps } from '@fluentui/utilities';\n\nexport interface IThemeProviderProps {\n scheme?: ISchemeNames;\n theme?: ITheme;\n}\n\n/**\n * Theme provider is a simplified version of Customizer that activates the appropriate theme data\n * for a given scheme name.\n *\n * @param providers - Injected providers for accessing theme data and providing it via a Customizer component.\n * @deprecated This is an old ThemeProvider implementation. New code should use the ThemeProvider exported from\n * `@fluentui/react` (or `@fluentui/react/lib/Theme`) instead.\n */\nexport const ThemeProvider: React.FunctionComponent<React.PropsWithChildren<IThemeProviderProps>> = (\n props: IThemeProviderProps,\n) => {\n const { scheme, theme, ...rest } = props;\n\n // TODO: consider merging implementation with theme-proto, which only stores a reference / scheme name to theme\n // in context and uses quick global store accessor to trigger change by passing in theme object as child and\n // triggering re-render. (perf benefits need verification)\n const contextTransform: ICustomizerProps['contextTransform'] = context => {\n return getThemedContext(context, scheme, theme);\n };\n\n // eslint-disable-next-line react/jsx-no-bind, @typescript-eslint/no-deprecated\n return <Customizer {...rest} contextTransform={contextTransform} />;\n};\n"]}
+24
View File
@@ -0,0 +1,24 @@
import * as React from 'react';
import { IStyleSetBase } from '@fluentui/style-utilities';
import { IComponentOptions, IViewComponent } from './IComponent';
import { ValidProps } from './ISlots';
/**
* Assembles a higher order component based on the following: styles, theme, view, and state.
* Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param options - component Component options. See IComponentOptions for more detail.
*/
export declare function createComponent<TComponentProps extends ValidProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps extends TComponentProps = TComponentProps, TStatics = {}>(view: IViewComponent<TViewProps>, options?: IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics>): React.FunctionComponent<TComponentProps> & TStatics;
+104
View File
@@ -0,0 +1,104 @@
define(["require", "exports", "tslib", "react", "@fluentui/style-utilities", "@fluentui/utilities", "./slots", "./utilities"], function (require, exports, tslib_1, React, style_utilities_1, utilities_1, slots_1, utilities_2) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createComponent = createComponent;
/**
* Assembles a higher order component based on the following: styles, theme, view, and state.
* Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param options - component Component options. See IComponentOptions for more detail.
*/
function createComponent(view, options) {
if (options === void 0) { options = {}; }
var _a = options.factoryOptions, factoryOptions = _a === void 0 ? {} : _a;
var defaultProp = factoryOptions.defaultProp;
var ResultComponent = function (componentProps) {
var settings = _getCustomizations(options.displayName, React.useContext(utilities_1.CustomizerContext), options.fields);
var stateReducer = options.state;
if (stateReducer) {
// Don't assume state will return all props, so spread useState result over component props.
componentProps = tslib_1.__assign(tslib_1.__assign({}, componentProps), stateReducer(componentProps));
}
var theme = componentProps.theme || settings.theme;
var tokens = _resolveTokens(componentProps, theme, options.tokens, settings.tokens, componentProps.tokens);
var styles = _resolveStyles(componentProps, theme, tokens, options.styles, settings.styles, componentProps.styles);
var viewProps = tslib_1.__assign(tslib_1.__assign({}, componentProps), { styles: styles, tokens: tokens, _defaultStyles: styles, theme: theme });
return view(viewProps);
};
ResultComponent.displayName = options.displayName || view.name;
// If a shorthand prop is defined, create a factory for the component.
// TODO: This shouldn't be a concern of createComponent.. factoryOptions should just be forwarded.
// Need to weigh creating default factories on component creation vs. memoizing them on use in slots.tsx.
if (defaultProp) {
ResultComponent.create = (0, slots_1.createFactory)(ResultComponent, { defaultProp: defaultProp });
}
(0, utilities_2.assign)(ResultComponent, options.statics);
// Later versions of TypeSript should allow us to merge objects in a type safe way and avoid this cast.
return ResultComponent;
}
/**
* Resolve all styles functions with both props and tokens and flatten results along with all styles objects.
*/
function _resolveStyles(props, theme, tokens) {
var allStyles = [];
for (var _i = 3; _i < arguments.length; _i++) {
allStyles[_i - 3] = arguments[_i];
}
return style_utilities_1.concatStyleSets.apply(void 0, allStyles.map(function (styles) {
return typeof styles === 'function' ? styles(props, theme, tokens) : styles;
}));
}
/**
* Resolve all tokens functions with props flatten results along with all tokens objects.
*/
function _resolveTokens(props, theme) {
var allTokens = [];
for (var _i = 2; _i < arguments.length; _i++) {
allTokens[_i - 2] = arguments[_i];
}
var tokens = {};
for (var _a = 0, allTokens_1 = allTokens; _a < allTokens_1.length; _a++) {
var currentTokens = allTokens_1[_a];
if (currentTokens) {
// TODO: why is this cast needed? TS seems to think there is a (TToken | Function) union from somewhere.
currentTokens =
typeof currentTokens === 'function'
? currentTokens(props, theme)
: currentTokens;
if (Array.isArray(currentTokens)) {
currentTokens = _resolveTokens.apply(void 0, tslib_1.__spreadArray([props, theme], currentTokens, false));
}
(0, utilities_2.assign)(tokens, currentTokens);
}
}
return tokens;
}
/**
* Helper function for calling Customizations.getSettings falling back to default fields.
*
* @param displayName Displayable name for component.
* @param context React context passed to component containing contextual settings.
* @param fields Optional list of properties to grab from global store and context.
*/
function _getCustomizations(displayName, context, fields) {
// TODO: do we want field props? should fields be part of IComponent and used here?
// TODO: should we centrally define DefaultFields? (not exported from styling)
// TODO: tie this array to ICustomizationProps, such that each array element is keyof ICustomizationProps
var DefaultFields = ['theme', 'styles', 'tokens'];
return utilities_1.Customizations.getSettings(fields || DefaultFields, displayName, context.customizations);
}
});
//# sourceMappingURL=createComponent.js.map
File diff suppressed because one or more lines are too long
+23
View File
@@ -0,0 +1,23 @@
import * as React from 'react';
export interface IControlledStateOptions<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps> {
defaultPropValue?: TProps[TProp];
defaultPropName?: TDefaultProp;
}
/**
* Controlled state helper that gives priority to props value. Useful for components that have props with both
* controlled and uncontrolled modes. Any props values will override state, but will not update internal state.
* If prop is defined and then later undefined, state will revert to its previous value.
*
* @param props - The props object containing controlled prop values.
* @param propName - The controlled prop name.
* @param options - Options. defaultPropValue is only used if defaultPropName (or its value) is undefined.
*/
export declare function useControlledState<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps>(props: Readonly<TProps>, propName: TProp, options?: IControlledStateOptions<TProps, TProp, TDefaultProp>): [TProps[TProp] | undefined, React.Dispatch<React.SetStateAction<TProps[TProp]>>];
/**
* Simple controlled helper that gives priority to props value and falls back to derived value.
*
* @param props - The props object containing controlled prop values.
* @param propName - The controlled prop name.
* @param derivedValue - Derived value. Returned when controlled value is not present.
*/
export declare function getControlledDerivedProps<TProps, TProp extends keyof TProps>(props: Readonly<TProps>, propName: TProp, derivedValue: TProps[TProp]): TProps[TProp];
+50
View File
@@ -0,0 +1,50 @@
define(["require", "exports", "react"], function (require, exports, React) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useControlledState = useControlledState;
exports.getControlledDerivedProps = getControlledDerivedProps;
/**
* Controlled state helper that gives priority to props value. Useful for components that have props with both
* controlled and uncontrolled modes. Any props values will override state, but will not update internal state.
* If prop is defined and then later undefined, state will revert to its previous value.
*
* @param props - The props object containing controlled prop values.
* @param propName - The controlled prop name.
* @param options - Options. defaultPropValue is only used if defaultPropName (or its value) is undefined.
*/
function useControlledState(props, propName, options) {
var defaultValue;
if (options) {
if (options.defaultPropName && props[options.defaultPropName] !== undefined) {
// No easy way to coerce TProps[TDefaultProp] to match TProps[TProp] in generic typings, so cast it here.
defaultValue = props[options.defaultPropName];
}
else {
defaultValue = options && options.defaultPropValue;
}
}
var _a = React.useState(defaultValue), state = _a[0], setState = _a[1];
if (props[propName] !== undefined) {
return [props[propName], setState];
}
else {
return [state, setState];
}
}
/**
* Simple controlled helper that gives priority to props value and falls back to derived value.
*
* @param props - The props object containing controlled prop values.
* @param propName - The controlled prop name.
* @param derivedValue - Derived value. Returned when controlled value is not present.
*/
function getControlledDerivedProps(props, propName, derivedValue) {
if (props[propName] !== undefined) {
return props[propName];
}
else {
return derivedValue;
}
}
});
//# sourceMappingURL=controlled.js.map
@@ -0,0 +1 @@
{"version":3,"file":"controlled.js","sourceRoot":"../src/","sources":["hooks/controlled.ts"],"names":[],"mappings":";;;IAgBA,gDAsBC;IASD,8DAUC;IAlDD;;;;;;;;OAQG;IACH,SAAgB,kBAAkB,CAChC,KAAuB,EACvB,QAAe,EACf,OAA8D;QAE9D,IAAI,YAAuC,CAAC;QAC5C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,OAAO,CAAC,eAAe,IAAI,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC5E,yGAAyG;gBACzG,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAA6B,CAAC;YAC5E,CAAC;iBAAM,CAAC;gBACN,YAAY,GAAG,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC;YACrD,CAAC;QACH,CAAC;QAEK,IAAA,KAAoB,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,EAA/C,KAAK,QAAA,EAAE,QAAQ,QAAgC,CAAC;QAEvD,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,SAAgB,yBAAyB,CACvC,KAAuB,EACvB,QAAe,EACf,YAA2B;QAE3B,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC","sourcesContent":["import * as React from 'react';\n\nexport interface IControlledStateOptions<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps> {\n defaultPropValue?: TProps[TProp];\n defaultPropName?: TDefaultProp;\n}\n\n/**\n * Controlled state helper that gives priority to props value. Useful for components that have props with both\n * controlled and uncontrolled modes. Any props values will override state, but will not update internal state.\n * If prop is defined and then later undefined, state will revert to its previous value.\n *\n * @param props - The props object containing controlled prop values.\n * @param propName - The controlled prop name.\n * @param options - Options. defaultPropValue is only used if defaultPropName (or its value) is undefined.\n */\nexport function useControlledState<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps>(\n props: Readonly<TProps>,\n propName: TProp,\n options?: IControlledStateOptions<TProps, TProp, TDefaultProp>,\n): [TProps[TProp] | undefined, React.Dispatch<React.SetStateAction<TProps[TProp]>>] {\n let defaultValue: TProps[TProp] | undefined;\n if (options) {\n if (options.defaultPropName && props[options.defaultPropName] !== undefined) {\n // No easy way to coerce TProps[TDefaultProp] to match TProps[TProp] in generic typings, so cast it here.\n defaultValue = props[options.defaultPropName] as unknown as TProps[TProp];\n } else {\n defaultValue = options && options.defaultPropValue;\n }\n }\n\n const [state, setState] = React.useState(defaultValue);\n\n if (props[propName] !== undefined) {\n return [props[propName], setState];\n } else {\n return [state, setState];\n }\n}\n\n/**\n * Simple controlled helper that gives priority to props value and falls back to derived value.\n *\n * @param props - The props object containing controlled prop values.\n * @param propName - The controlled prop name.\n * @param derivedValue - Derived value. Returned when controlled value is not present.\n */\nexport function getControlledDerivedProps<TProps, TProp extends keyof TProps>(\n props: Readonly<TProps>,\n propName: TProp,\n derivedValue: TProps[TProp],\n): TProps[TProp] {\n if (props[propName] !== undefined) {\n return props[propName];\n } else {\n return derivedValue;\n }\n}\n"]}
+1
View File
@@ -0,0 +1 @@
export * from './controlled';
+6
View File
@@ -0,0 +1,6 @@
define(["require", "exports", "tslib", "./controlled"], function (require, exports, tslib_1, controlled_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
tslib_1.__exportStar(controlled_1, exports);
});
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["hooks/index.ts"],"names":[],"mappings":";;;IAAA,4CAA6B","sourcesContent":["export * from './controlled';\n"]}
+9
View File
@@ -0,0 +1,9 @@
export * from './createComponent';
export * from './IComponent';
export * from './IHTMLSlots';
export * from './ISlots';
export * from './slots';
export * from './ThemeProvider';
export * from './hooks/index';
export { styled as legacyStyled } from '@fluentui/utilities';
import './version';
+14
View File
@@ -0,0 +1,14 @@
define(["require", "exports", "tslib", "./createComponent", "./IComponent", "./IHTMLSlots", "./ISlots", "./slots", "./ThemeProvider", "./hooks/index", "@fluentui/utilities", "./version"], function (require, exports, tslib_1, createComponent_1, IComponent_1, IHTMLSlots_1, ISlots_1, slots_1, ThemeProvider_1, index_1, utilities_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.legacyStyled = void 0;
tslib_1.__exportStar(createComponent_1, exports);
tslib_1.__exportStar(IComponent_1, exports);
tslib_1.__exportStar(IHTMLSlots_1, exports);
tslib_1.__exportStar(ISlots_1, exports);
tslib_1.__exportStar(slots_1, exports);
tslib_1.__exportStar(ThemeProvider_1, exports);
tslib_1.__exportStar(index_1, exports);
Object.defineProperty(exports, "legacyStyled", { enumerable: true, get: function () { return utilities_1.styled; } });
});
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["index.ts"],"names":[],"mappings":";;;;IAAA,iDAAkC;IAClC,4CAA6B;IAC7B,4CAA6B;IAC7B,wCAAyB;IACzB,uCAAwB;IACxB,+CAAgC;IAChC,uCAA8B;IAErB,yGAAA,MAAM,OAAgB","sourcesContent":["export * from './createComponent';\nexport * from './IComponent';\nexport * from './IHTMLSlots';\nexport * from './ISlots';\nexport * from './slots';\nexport * from './ThemeProvider';\nexport * from './hooks/index';\n\nexport { styled as legacyStyled } from '@fluentui/utilities';\n\nimport './version';\n"]}
+51
View File
@@ -0,0 +1,51 @@
import * as React from 'react';
import { IStyleSetBase } from '@fluentui/style-utilities';
import { IComponentOptions as IOldComponentOptions } from '../IComponent';
import { ISlots, ISlotDefinition, ISlottableProps } from '../ISlots';
/**
* Defines the contract for view components.
*/
export type IViewComponent<TViewProps, TComponentSlots = {}> = (props: React.PropsWithChildren<TViewProps>, slots: ISlots<Required<TComponentSlots>>) => ReturnType<React.FunctionComponent>;
/**
* Defines the contract for slot components.
*/
export type ISlotComponent<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots> = ISlotDefinition<Required<TComponentSlots>> | ((props: TComponentProps) => ISlotDefinition<Required<TComponentSlots>>);
/**
* Defines the contract for partial slot components used in recomposition.
*/
export type IPartialSlotComponent<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots> = ISlotDefinition<TComponentSlots> | ((props: TComponentProps) => ISlotDefinition<TComponentSlots>);
/**
* Component options used by foundation to tie elements together.
*
* * TComponentProps: A styleable props interface for the created component.
* * TTokens: The type for tokens props.
* * TStyleSet: The type for styles properties.
* * TViewProps: The props specific to the view, including processed properties outputted by optional state component.
* If state component is not provided, TComponentProps is the same as TViewProps.
* * TComponentSlots: The slottable components used to build the HOC.
* * TStatics: Static type for statics applied to created component object.
*/
export interface IComponentOptions<TComponentProps extends ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TComponentSlots = {}, TStatics = {}> extends IOldComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics> {
/**
* Slot definition object defining the slot component for each slot.
*/
slots?: ISlotComponent<TComponentProps, TComponentSlots>;
/**
* Stateless pure function that receives props to render the output of the component.
*/
view?: IViewComponent<TViewProps, TComponentSlots>;
}
export interface IRecompositionComponentOptions<TComponentProps extends ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TComponentSlots = {}, TStatics = {}> extends IOldComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics> {
/**
* Slot definition object defining the slot component for each slot.
*/
slots?: IPartialSlotComponent<TComponentProps, TComponentSlots>;
/**
* Stateless pure function that receives props to render the output of the component.
*/
view?: IViewComponent<TViewProps, TComponentSlots>;
}
/**
* Component helper that defines options as required for ease of use by component consumers.
*/
export type IComponent<TComponentProps extends ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TComponentSlots = {}, TStatics = {}> = Required<IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>>;
+5
View File
@@ -0,0 +1,5 @@
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
});
//# sourceMappingURL=IComponent.js.map
@@ -0,0 +1 @@
{"version":3,"file":"IComponent.js","sourceRoot":"../src/","sources":["next/IComponent.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { IStyleSetBase } from '@fluentui/style-utilities';\nimport { IComponentOptions as IOldComponentOptions } from '../IComponent';\nimport { ISlots, ISlotDefinition, ISlottableProps } from '../ISlots';\n\n/**\n * Defines the contract for view components.\n */\nexport type IViewComponent<TViewProps, TComponentSlots = {}> = (\n props: React.PropsWithChildren<TViewProps>,\n slots: ISlots<Required<TComponentSlots>>,\n) => ReturnType<React.FunctionComponent>;\n\n/**\n * Defines the contract for slot components.\n */\nexport type ISlotComponent<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots> =\n | ISlotDefinition<Required<TComponentSlots>>\n | ((props: TComponentProps) => ISlotDefinition<Required<TComponentSlots>>);\n\n/**\n * Defines the contract for partial slot components used in recomposition.\n */\nexport type IPartialSlotComponent<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots> =\n | ISlotDefinition<TComponentSlots>\n | ((props: TComponentProps) => ISlotDefinition<TComponentSlots>);\n\n/**\n * Component options used by foundation to tie elements together.\n *\n * * TComponentProps: A styleable props interface for the created component.\n * * TTokens: The type for tokens props.\n * * TStyleSet: The type for styles properties.\n * * TViewProps: The props specific to the view, including processed properties outputted by optional state component.\n * If state component is not provided, TComponentProps is the same as TViewProps.\n * * TComponentSlots: The slottable components used to build the HOC.\n * * TStatics: Static type for statics applied to created component object.\n */\nexport interface IComponentOptions<\n TComponentProps extends ISlottableProps<TComponentSlots>,\n TTokens,\n TStyleSet extends IStyleSetBase,\n TViewProps = TComponentProps,\n TComponentSlots = {},\n TStatics = {},\n> extends IOldComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics> {\n /**\n * Slot definition object defining the slot component for each slot.\n */\n slots?: ISlotComponent<TComponentProps, TComponentSlots>;\n /**\n * Stateless pure function that receives props to render the output of the component.\n */\n view?: IViewComponent<TViewProps, TComponentSlots>;\n}\n\nexport interface IRecompositionComponentOptions<\n TComponentProps extends ISlottableProps<TComponentSlots>,\n TTokens,\n TStyleSet extends IStyleSetBase,\n TViewProps = TComponentProps,\n TComponentSlots = {},\n TStatics = {},\n> extends IOldComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics> {\n /**\n * Slot definition object defining the slot component for each slot.\n */\n slots?: IPartialSlotComponent<TComponentProps, TComponentSlots>;\n /**\n * Stateless pure function that receives props to render the output of the component.\n */\n view?: IViewComponent<TViewProps, TComponentSlots>;\n}\n\n/**\n * Component helper that defines options as required for ease of use by component consumers.\n */\nexport type IComponent<\n TComponentProps extends ISlottableProps<TComponentSlots>,\n TTokens,\n TStyleSet extends IStyleSetBase,\n TViewProps = TComponentProps,\n TComponentSlots = {},\n TStatics = {},\n> = Required<IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>>;\n"]}
+10
View File
@@ -0,0 +1,10 @@
import * as React from 'react';
import { IStyleSetBase } from '@fluentui/style-utilities';
import { ISlottableProps, ValidProps } from '../ISlots';
import { IComponentOptions } from './IComponent';
/**
* Signature of components created using composed.
*/
export interface IFoundationComponent<TComponentProps extends ValidProps & ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps extends TComponentProps = TComponentProps, TComponentSlots = {}, TStatics = {}> extends React.FunctionComponent {
__options?: IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>;
}
+5
View File
@@ -0,0 +1,5 @@
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
});
//# sourceMappingURL=ISlots.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ISlots.js","sourceRoot":"../src/","sources":["next/ISlots.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { IStyleSetBase } from '@fluentui/style-utilities';\nimport { ISlottableProps, ValidProps } from '../ISlots';\nimport { IComponentOptions } from './IComponent';\n\n/**\n * Signature of components created using composed.\n */\nexport interface IFoundationComponent<\n TComponentProps extends ValidProps & ISlottableProps<TComponentSlots>,\n TTokens,\n TStyleSet extends IStyleSetBase,\n TViewProps extends TComponentProps = TComponentProps,\n TComponentSlots = {},\n TStatics = {},\n> extends React.FunctionComponent {\n __options?: IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>;\n}\n"]}
+53
View File
@@ -0,0 +1,53 @@
import * as React from 'react';
import { IStyleSetBase } from '@fluentui/style-utilities';
import { IComponentOptions, IPartialSlotComponent, IRecompositionComponentOptions, ISlotComponent } from './IComponent';
import { ValidProps, ISlottableProps, ISlotDefinition } from '../ISlots';
import { IFoundationComponent } from './ISlots';
/**
* Assembles a higher order component based on the following: styles, theme, view, and state.
* Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param options - component Component options. See IComponentOptions for more detail.
*/
export declare function composed<TComponentProps extends ValidProps & ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps extends TComponentProps = TComponentProps, TComponentSlots = {}, TStatics = {}>(options: IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>): IFoundationComponent<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics> & TStatics;
/**
* Recomposes a functional component based on a base component and the following set of options: styles, theme, view,
* and state. Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param baseComponent - base component to recompose
* @param options - component Component recomposition options. See IComponentOptions for more detail.
*/
export declare function composed<TComponentProps extends ValidProps & ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps extends TComponentProps = TComponentProps, TComponentSlots = {}, TStatics = {}>(baseComponent: React.FunctionComponent, options: IRecompositionComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>): IFoundationComponent<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics> & TStatics;
/**
* Resolve the passed slots as a function or an object.
*
* @param slots - Slots that need to be resolved as a function or an object.
* @param data - Data to pass to resolve if the first argument was a function.
*/
export declare function resolveSlots<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots>(slots: IPartialSlotComponent<TComponentProps, TComponentSlots> | ISlotComponent<TComponentProps, TComponentSlots> | undefined, data: TComponentProps): ISlotDefinition<Required<TComponentSlots>>;
+201
View File
@@ -0,0 +1,201 @@
define(["require", "exports", "tslib", "react", "@fluentui/merge-styles", "@fluentui/style-utilities", "@fluentui/utilities", "../slots", "../utilities"], function (require, exports, tslib_1, React, merge_styles_1, style_utilities_1, utilities_1, slots_1, utilities_2) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.composed = composed;
exports.resolveSlots = resolveSlots;
var memoizedClassNamesMap = {};
/**
* Assembles a higher order component based on a set of options or recomposes a functional component based on a
* base component and the a set of options. This set of options is comprised by: styles, theme, view, and state.
*
* Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param baseComponentOrOptions - base component to recompose or component Component options to compose an HOC.
* See IComponentOptions for more detail.
* @param recompositionOptions - component Component recomposition options. See IComponentOptions for more detail.
*/
function composed(baseComponentOrOptions, recompositionOptions) {
if (baseComponentOrOptions === void 0) { baseComponentOrOptions = {}; }
// Check if we are composing or recomposing.
var options;
if (typeof baseComponentOrOptions === 'function' && baseComponentOrOptions.__options) {
var baseComponentOptions_1 = baseComponentOrOptions.__options;
var recompositionSlots_1 = recompositionOptions ? recompositionOptions.slots : undefined;
options = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, baseComponentOptions_1), recompositionOptions), { slots: function (props) { return (tslib_1.__assign(tslib_1.__assign({}, resolveSlots(baseComponentOptions_1.slots, props)), resolveSlots(recompositionSlots_1, props))); } });
}
else {
options = baseComponentOrOptions;
}
var _a = options.factoryOptions, factoryOptions = _a === void 0 ? {} : _a, view = options.view;
var defaultProp = factoryOptions.defaultProp;
var ResultComponent = function (componentProps) {
var settings = _getCustomizations(options.displayName, React.useContext(utilities_1.CustomizerContext), options.fields);
var stateReducer = options.state;
if (stateReducer) {
// Don't assume state will return all props, so spread useState result over component props.
componentProps = tslib_1.__assign(tslib_1.__assign({}, componentProps), stateReducer(componentProps));
}
var theme = componentProps.theme || settings.theme;
var tokens = _resolveTokens(componentProps, theme, options.tokens, settings.tokens, componentProps.tokens);
var styles;
var finalStyles = {};
// We get the entry in the memoized classNamesMap for the current component or create one if it doesn't exist.
var displayName = options.displayName;
// If no displayName has been specified, then do not use caching.
if (displayName) {
if (!memoizedClassNamesMap.hasOwnProperty(displayName)) {
memoizedClassNamesMap[displayName] = { map: {} };
}
var current = memoizedClassNamesMap[displayName];
// Memoize based on the tokens definition.
var tokenKeys = Object.keys(tokens).sort();
for (var _i = 0, tokenKeys_1 = tokenKeys; _i < tokenKeys_1.length; _i++) {
var key = tokenKeys_1[_i];
var nextToken = tokens[key];
if (nextToken === undefined) {
nextToken = '__undefined__';
}
if (!current.map.hasOwnProperty(nextToken)) {
current.map[nextToken] = { map: {} };
}
current = current.map[nextToken];
}
// Memoize the slots so we only have to get Object.keys once.
var slots = memoizedClassNamesMap[displayName].slots;
var defaultStyles = void 0;
if (!slots) {
defaultStyles = _resolveStyles(componentProps, theme, tokens, options.styles, settings.styles);
memoizedClassNamesMap[displayName].slots = Object.keys(defaultStyles);
slots = memoizedClassNamesMap[displayName].slots;
}
// Memoize based on the base styling of the component (i.e. without user specified props).
for (var _a = 0, slots_2 = slots; _a < slots_2.length; _a++) {
var key = slots_2[_a];
if (!current.map.hasOwnProperty(key)) {
// Get default styles once if we didn't get them before.
if (!defaultStyles) {
defaultStyles = _resolveStyles(componentProps, theme, tokens, options.styles, settings.styles);
}
current.map[key] = { className: (0, merge_styles_1.mergeStyles)(defaultStyles[key]), map: {} };
}
finalStyles[key] = current.map[key].className;
}
if (componentProps.styles) {
var userStyles = typeof componentProps.styles === 'function'
? componentProps.styles(componentProps, theme, tokens)
: componentProps.styles;
styles = (0, style_utilities_1.concatStyleSets)(styles, userStyles);
if (userStyles) {
var userStyleKeys = Object.keys(userStyles);
for (var _b = 0, userStyleKeys_1 = userStyleKeys; _b < userStyleKeys_1.length; _b++) {
var key = userStyleKeys_1[_b];
if (finalStyles.hasOwnProperty(key)) {
finalStyles[key] = (0, merge_styles_1.mergeStyles)([current.map[key].className], userStyles[key]);
}
else {
finalStyles[key] = (0, merge_styles_1.mergeStyles)(userStyles[key]);
}
}
}
}
}
else {
styles = _resolveStyles(componentProps, theme, tokens, options.styles, settings.styles, componentProps.styles);
}
var viewProps = tslib_1.__assign(tslib_1.__assign({}, componentProps), { styles: styles, tokens: tokens, _defaultStyles: displayName ? finalStyles : styles });
if (!options.slots) {
throw new Error("Component ".concat(options.displayName || (view && view.name) || '', " is missing slot definitions."));
}
var Slots = typeof options.slots === 'function'
? (0, slots_1.getSlots)(viewProps, options.slots(viewProps))
: (0, slots_1.getSlots)(viewProps, options.slots);
return view ? view(viewProps, Slots) : null;
};
ResultComponent.displayName = options.displayName || (view && view.name);
// If a shorthand prop is defined, create a factory for the component.
// TODO: This shouldn't be a concern of createComponent.. factoryOptions should just be forwarded.
// Need to weigh creating default factories on component creation vs. memoizing them on use in slots.tsx.
if (defaultProp) {
ResultComponent.create = (0, slots_1.createFactory)(ResultComponent, { defaultProp: defaultProp });
}
ResultComponent.__options = options;
(0, utilities_2.assign)(ResultComponent, options.statics);
// Later versions of TypeSript should allow us to merge objects in a type safe way and avoid this cast.
return ResultComponent;
}
/**
* Resolve the passed slots as a function or an object.
*
* @param slots - Slots that need to be resolved as a function or an object.
* @param data - Data to pass to resolve if the first argument was a function.
*/
function resolveSlots(slots, data) {
var resolvedSlots = slots ? (typeof slots === 'function' ? slots(data) : slots) : {};
return resolvedSlots;
}
/**
* Resolve all styles functions with both props and tokens and flatten results along with all styles objects.
*/
function _resolveStyles(props, theme, tokens) {
var allStyles = [];
for (var _i = 3; _i < arguments.length; _i++) {
allStyles[_i - 3] = arguments[_i];
}
return style_utilities_1.concatStyleSets.apply(void 0, allStyles.map(function (styles) {
return typeof styles === 'function' ? styles(props, theme, tokens) : styles;
}));
}
/**
* Resolve all tokens functions with props flatten results along with all tokens objects.
*/
function _resolveTokens(props, theme) {
var allTokens = [];
for (var _i = 2; _i < arguments.length; _i++) {
allTokens[_i - 2] = arguments[_i];
}
var tokens = {};
for (var _a = 0, allTokens_1 = allTokens; _a < allTokens_1.length; _a++) {
var currentTokens = allTokens_1[_a];
if (currentTokens) {
// TODO: why is this cast needed? TS seems to think there is a (TToken | Function) union from somewhere.
currentTokens =
typeof currentTokens === 'function'
? currentTokens(props, theme)
: currentTokens;
if (Array.isArray(currentTokens)) {
currentTokens = _resolveTokens.apply(void 0, tslib_1.__spreadArray([props, theme], currentTokens, false));
}
(0, utilities_2.assign)(tokens, currentTokens);
}
}
return tokens;
}
/**
* Helper function for calling Customizations.getSettings falling back to default fields.
*
* @param displayName Displayable name for component.
* @param context React context passed to component containing contextual settings.
* @param fields Optional list of properties to grab from global store and context.
*/
function _getCustomizations(displayName, context, fields) {
// TODO: do we want field props? should fields be part of IComponent and used here?
// TODO: should we centrally define DefaultFields? (not exported from styling)
// TODO: tie this array to ICustomizationProps, such that each array element is keyof ICustomizationProps
var DefaultFields = ['theme', 'styles', 'tokens'];
return utilities_1.Customizations.getSettings(fields || DefaultFields, displayName, context.customizations);
}
});
//# sourceMappingURL=composed.js.map
File diff suppressed because one or more lines are too long
+30
View File
@@ -0,0 +1,30 @@
import * as React from 'react';
import { IFactoryOptions } from './IComponent';
import { ISlot, ISlots, ISlotDefinition, ISlotFactory, ISlottableProps, ValidProps, ValidShorthand } from './ISlots';
/**
* This function is required for any module that uses slots.
*
* This function is a slot resolver that automatically evaluates slot functions to generate React elements.
* A byproduct of this resolver is that it removes slots from the React hierarchy by bypassing React.createElement.
*
* To use this function on a per-file basis, use the jsx directive targeting withSlots.
* This directive must be the FIRST LINE in the file to work correctly.
* Usage of this pragma also requires withSlots import statement.
*
* See React.createElement
*/
export declare function withSlots<P extends {}>(type: ISlot<P> | React.FunctionComponent<P> | string, props?: (React.Attributes & P) | null, ...children: React.ReactNode[]): ReturnType<React.FunctionComponent<P>>;
/**
* This function creates factories that render ouput depending on the user ISlotProp props passed in.
* @param DefaultComponent - Base component to render when not overridden by user props.
* @param options - Factory options, including defaultProp value for shorthand prop mapping.
* @returns ISlotFactory function used for rendering slots.
*/
export declare function createFactory<TProps extends ValidProps, TShorthandProp extends ValidShorthand = never>(DefaultComponent: React.ComponentType<TProps>, options?: IFactoryOptions<TProps>): ISlotFactory<TProps, TShorthandProp>;
/**
* This function generates slots that can be used in JSX given a definition of slots and their corresponding types.
* @param userProps - Props as pass to component.
* @param slots - Slot definition object defining the default slot component for each slot.
* @returns A set of created slots that components can render in JSX.
*/
export declare function getSlots<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots>(userProps: TComponentProps, slots: ISlotDefinition<Required<TComponentSlots>>): ISlots<Required<TComponentSlots>>;
+187
View File
@@ -0,0 +1,187 @@
define(["require", "exports", "tslib", "react", "@fluentui/merge-styles", "@fluentui/utilities", "./utilities"], function (require, exports, tslib_1, React, merge_styles_1, utilities_1, utilities_2) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.withSlots = withSlots;
exports.createFactory = createFactory;
exports.getSlots = getSlots;
/**
* This function is required for any module that uses slots.
*
* This function is a slot resolver that automatically evaluates slot functions to generate React elements.
* A byproduct of this resolver is that it removes slots from the React hierarchy by bypassing React.createElement.
*
* To use this function on a per-file basis, use the jsx directive targeting withSlots.
* This directive must be the FIRST LINE in the file to work correctly.
* Usage of this pragma also requires withSlots import statement.
*
* See React.createElement
*/
// Can't use typeof on React.createElement since it's overloaded. Approximate createElement's signature for now
// and widen as needed.
function withSlots(type, props) {
var children = [];
for (var _i = 2; _i < arguments.length; _i++) {
children[_i - 2] = arguments[_i];
}
var slotType = type;
if (slotType.isSlot) {
// Since we are bypassing createElement, use React.Children.toArray to make sure children are
// properly assigned keys.
// TODO: should this be mutating? does React mutate children subprop with createElement?
// TODO: will toArray clobber existing keys?
// TODO: React generates warnings because it doesn't detect hidden member _store that is set in createElement.
// Even children passed to createElement without keys don't generate this warning.
// Is there a better way to prevent slots from appearing in hierarchy? toArray doesn't address root issue.
children = React.Children.toArray(children);
// TODO: There is something weird going on here with children embedded in props vs. rest args.
// Comment out these lines to see. Make sure this function is doing the right things.
if (children.length === 0) {
return slotType(props);
}
return slotType(tslib_1.__assign(tslib_1.__assign({}, props), { children: children }));
}
else {
// TODO: Are there some cases where children should NOT be spread? Also, spreading reraises perf question.
// Children had to be spread to avoid breaking KeytipData in Toggle.view:
// react-dom.development.js:18931 Uncaught TypeError: children is not a function
// Without spread, function child is a child array of one element
// TODO: is there a reason this can't be:
// return React.createElement.apply(this, arguments);
return React.createElement.apply(React, tslib_1.__spreadArray([type, props], children, false));
}
}
/**
* This function creates factories that render ouput depending on the user ISlotProp props passed in.
* @param DefaultComponent - Base component to render when not overridden by user props.
* @param options - Factory options, including defaultProp value for shorthand prop mapping.
* @returns ISlotFactory function used for rendering slots.
*/
function createFactory(DefaultComponent, options) {
if (options === void 0) { options = {}; }
var _a = options.defaultProp, defaultProp = _a === void 0 ? 'children' : _a;
var result = function (componentProps, userProps, userSlotOptions, defaultStyles, theme) {
// If they passed in raw JSX, just return that.
if (React.isValidElement(userProps)) {
return userProps;
}
var flattenedUserProps = _translateShorthand(defaultProp, userProps);
var finalProps = _constructFinalProps(defaultStyles, theme, componentProps, flattenedUserProps);
if (userSlotOptions) {
if (userSlotOptions.component) {
// TODO: Remove cast if possible. This cast is needed because TS errors on the intrinsic portion of ReactType.
// return <userSlotOptions.component {...finalProps} />;
var UserComponent = userSlotOptions.component;
return React.createElement(UserComponent, tslib_1.__assign({}, finalProps));
}
if (userSlotOptions.render) {
return userSlotOptions.render(finalProps, DefaultComponent);
}
}
return React.createElement(DefaultComponent, tslib_1.__assign({}, finalProps));
};
return result;
}
/**
* Default factory for components without explicit factories.
*/
var defaultFactory = (0, utilities_1.memoizeFunction)(function (type) { return createFactory(type); });
/**
* This function generates slots that can be used in JSX given a definition of slots and their corresponding types.
* @param userProps - Props as pass to component.
* @param slots - Slot definition object defining the default slot component for each slot.
* @returns A set of created slots that components can render in JSX.
*/
function getSlots(userProps, slots) {
var result = {};
// userProps already has default props mixed in by createComponent. Recast here to gain typing for this function.
var mixedProps = userProps;
var _loop_1 = function (name_1) {
if (slots.hasOwnProperty(name_1)) {
// This closure method requires the use of withSlots to prevent unnecessary rerenders. This is because React
// detects each closure as a different component (since it is a new instance) from the previous one and then
// forces a rerender of the entire slot subtree. For now, the only way to avoid this is to use withSlots, which
// bypasses the call to React.createElement.
var slot = function (componentProps) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
if (args.length > 0) {
// If React.createElement is being incorrectly used with slots, there will be additional arguments.
// We can detect these additional arguments and error on their presence.
throw new Error('Any module using getSlots must use withSlots. Please see withSlots javadoc for more info.');
}
// TODO: having TS infer types here seems to cause infinite loop.
// use explicit types or casting to preserve typing if possible.
// TODO: this should be a lookup on TProps property instead of being TProps directly, which is probably
// causing the infinite loop
return _renderSlot(slots[name_1],
// TODO: this cast to any is hiding a relationship issue between the first two args
componentProps, mixedProps[name_1], mixedProps.slots && mixedProps.slots[name_1],
// _defaultStyles should always be present, but a check for existence is added to make view tests
// easier to use.
mixedProps._defaultStyles && mixedProps._defaultStyles[name_1], mixedProps.theme);
};
slot.isSlot = true;
result[name_1] = slot;
}
};
for (var name_1 in slots) {
_loop_1(name_1);
}
return result;
}
/**
* Helper function that translates shorthand as needed.
* @param defaultProp
* @param slotProps
*/
function _translateShorthand(defaultProp, slotProps) {
var _a;
var transformedProps;
if (typeof slotProps === 'string' || typeof slotProps === 'number' || typeof slotProps === 'boolean') {
transformedProps = (_a = {},
_a[defaultProp] = slotProps,
_a);
}
else {
transformedProps = slotProps;
}
return transformedProps;
}
/**
* Helper function that constructs final styles and props given a series of props ordered by increasing priority.
*/
function _constructFinalProps(defaultStyles, theme) {
var allProps = [];
for (var _i = 2; _i < arguments.length; _i++) {
allProps[_i - 2] = arguments[_i];
}
var finalProps = {};
var classNames = [];
for (var _a = 0, allProps_1 = allProps; _a < allProps_1.length; _a++) {
var props = allProps_1[_a];
classNames.push(props && props.className);
(0, utilities_2.assign)(finalProps, props);
}
finalProps.className = (0, merge_styles_1.mergeCss)([defaultStyles, classNames], { rtl: (0, utilities_1.getRTL)(theme) });
return finalProps;
}
/**
* Render a slot given component and user props. Uses component factory if available, otherwise falls back
* to default factory.
* @param ComponentType Factory component type.
* @param componentProps The properties passed into slot from within the component.
* @param userProps The user properties passed in from outside of the component.
*/
function _renderSlot(ComponentType, componentProps, userProps, slotOptions, defaultStyles, theme) {
if (ComponentType.create !== undefined) {
return ComponentType.create(componentProps, userProps, slotOptions, defaultStyles);
}
else {
// TODO: need to resolve typing / generic issues passing through memoizeFunction. for now, cast to 'unknown'
return defaultFactory(ComponentType)(componentProps, userProps, slotOptions, defaultStyles, theme);
}
}
});
//# sourceMappingURL=slots.js.map
File diff suppressed because one or more lines are too long
+2
View File
@@ -0,0 +1,2 @@
import { __assign } from 'tslib';
export declare const assign: typeof __assign;
+7
View File
@@ -0,0 +1,7 @@
define(["require", "exports", "tslib"], function (require, exports, tslib_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.assign = void 0;
exports.assign = tslib_1.__assign;
});
//# sourceMappingURL=utilities.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"utilities.js","sourceRoot":"../src/","sources":["utilities.ts"],"names":[],"mappings":";;;;IACa,QAAA,MAAM,GAAG,gBAAQ,CAAC","sourcesContent":["import { __assign } from 'tslib';\nexport const assign = __assign;\n"]}
+1
View File
@@ -0,0 +1 @@
export {};
+6
View File
@@ -0,0 +1,6 @@
define(["require", "exports", "@fluentui/set-version"], function (require, exports, set_version_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(0, set_version_1.setVersion)('@fluentui/foundation-legacy', '8.6.5');
});
//# sourceMappingURL=version.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"version.js","sourceRoot":"../src/","sources":["version.ts"],"names":[],"mappings":";;;IAGA,IAAA,wBAAU,EAAC,6BAA6B,EAAE,OAAO,CAAC,CAAC","sourcesContent":["// Do not modify this file; it is generated as part of publish.\n// The checked in version is a placeholder only and will not be updated.\nimport { setVersion } from '@fluentui/set-version';\nsetVersion('@fluentui/foundation-legacy', '8.6.5');"]}
+120
View File
@@ -0,0 +1,120 @@
import * as React from 'react';
import { IStyle, IStyleSetBase, ITheme } from '@fluentui/style-utilities';
/**
* Helper interface for accessing user props children.
* @deprecated Use React.PropsWithChildren.
*/
export type IPropsWithChildren<TProps> = React.PropsWithChildren<TProps>;
/**
* Helper type defining style sections, one for each component slot.
*/
export type IComponentStyles<TSlots> = {
[key in keyof TSlots]?: IStyle;
};
/**
* Function declaration for component styles functions.
*/
export type IStylesFunction<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = (props: TViewProps, theme: ITheme, tokens: TTokens) => TStyleSet;
/**
* Composite type for component styles functions and objects.
*/
export type IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = IStylesFunction<TViewProps, TTokens, TStyleSet> | TStyleSet;
/**
* Tokens can be defined as an object, function, or an array of objects and functions.
*/
export type IToken<TViewProps, TTokens> = ITokenBase<TViewProps, TTokens> | ITokenBaseArray<TViewProps, TTokens>;
/**
* Function declaration for component token functions.
*/
export type ITokenFunction<TViewProps, TTokens> = (props: TViewProps, theme: ITheme) => IToken<TViewProps, TTokens>;
/**
* Composite type for component token functions and objects.
*/
export type ITokenFunctionOrObject<TViewProps, TTokens> = ITokenFunction<TViewProps, TTokens> | TTokens;
/**
* Composite base type that includes all possible resolutions of token functions in an array.
*/
export type ITokenBase<TViewProps, TTokens> = ITokenFunctionOrObject<TViewProps, TTokens> | false | null | undefined;
/**
* Composite token base array type allowing for token objects, functions, and function resolutions.
*/
export interface ITokenBaseArray<TViewProps, TTokens> extends Array<IToken<TViewProps, TTokens>> {
}
/**
* Optional props for styleable components. If these props are present, they will automatically be
* used by Foundation when applying theming and styling.
*/
export interface IStyleableComponentProps<TViewProps, TTokens, TStyleSet extends IStyleSetBase> {
className?: string;
styles?: IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet>;
theme?: ITheme;
tokens?: ITokenFunctionOrObject<TViewProps, TTokens>;
}
export type ICustomizationProps<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = IStyleableComponentProps<TViewProps, TTokens, TStyleSet> & Required<Pick<IStyleableComponentProps<TViewProps, TTokens, TStyleSet>, 'theme'>>;
/**
* Defines the contract for state components.
*/
export type IStateComponentType<TComponentProps, TViewProps> = (props: Readonly<TComponentProps>) => TViewProps;
/**
* Defines the contract for view components.
*/
export type IViewComponent<TViewProps> = (props: React.PropsWithChildren<TViewProps>) => ReturnType<React.FunctionComponent>;
/**
* Component options used by foundation to tie elements together.
*
* * TComponentProps: A styleable props interface for the created component.
* * TTokens: The type for tokens props.
* * TStyleSet: The type for styles properties.
* * TViewProps: The props specific to the view, including processed properties outputted by optional state component.
* If state component is not provided, TComponentProps is the same as TViewProps.
* * TStatics: Static type for statics applied to created component object.
*/
export interface IComponentOptions<TComponentProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TStatics = {}> {
/**
* Display name to identify component in React hierarchy. This parameter is required for targeted component styling
* via theming.
*/
displayName?: string;
/**
* List of fields which can be customized.
*/
fields?: string[];
/**
* Styles prop to pass into component.
*/
styles?: IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet>;
/**
* Optional state component that processes TComponentProps into TViewProps.
*/
state?: IStateComponentType<TComponentProps, TViewProps>;
/**
* Optional static object to assign to constructed component.
*/
statics?: TStatics;
/**
* Tokens prop to pass into component.
*/
tokens?: ITokenFunctionOrObject<TViewProps, TTokens>;
/**
* Default prop for which to map primitive values.
*/
factoryOptions?: IFactoryOptions<TComponentProps>;
}
/**
* Component helper that defines options as required for ease of use by component consumers.
*/
export type IComponent<TComponentProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TStatics = {}> = Required<IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics>> & {
/**
* Component that generates view output.
*/
view: IViewComponent<TViewProps>;
};
/**
* Factory options for creating component.
*/
export interface IFactoryOptions<TProps> {
/**
* Default prop for which to map primitive values.
*/
defaultProp?: keyof TProps | 'children';
}
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IComponent.js.map
File diff suppressed because one or more lines are too long
+15
View File
@@ -0,0 +1,15 @@
import * as React from 'react';
import type { JSXIntrinsicElement, JSXIntrinsicElementKeys } from '@fluentui/utilities';
import { ISlotProp } from './ISlots';
/**
* Generic slot definition allowing common HTML attributes. Applicable for most intrinsic slots. Please note certain
* elements such as buttons and inputs should make use of IHTMLElementSlot to provide access to specialized attributes
* of those elements.
*/
export type IHTMLSlot = ISlotProp<React.DetailedHTMLProps<React.HTMLAttributes<any>, any>>;
/**
* Optional HTML element typing to confine or expand HTML attribute usage for an intrinsic slot.
* Useful for slots that need to allow access to specialized HTML attributes, such as for buttons and inputs.
* Example usage: root?: IHTMLElementSlot\<'button'\>;
*/
export type IHTMLElementSlot<TElement extends JSXIntrinsicElementKeys> = ISlotProp<JSXIntrinsicElement<TElement>>;
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IHTMLSlots.js.map
@@ -0,0 +1 @@
{"version":3,"file":"IHTMLSlots.js","sourceRoot":"../src/","sources":["IHTMLSlots.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport type { JSXIntrinsicElement, JSXIntrinsicElementKeys } from '@fluentui/utilities';\nimport { ISlotProp } from './ISlots';\n\n/**\n * Generic slot definition allowing common HTML attributes. Applicable for most intrinsic slots. Please note certain\n * elements such as buttons and inputs should make use of IHTMLElementSlot to provide access to specialized attributes\n * of those elements.\n */\nexport type IHTMLSlot = ISlotProp<React.DetailedHTMLProps<React.HTMLAttributes<any>, any>>;\n\n/**\n * Optional HTML element typing to confine or expand HTML attribute usage for an intrinsic slot.\n * Useful for slots that need to allow access to specialized HTML attributes, such as for buttons and inputs.\n * Example usage: root?: IHTMLElementSlot\\<'button'\\>;\n */\nexport type IHTMLElementSlot<TElement extends JSXIntrinsicElementKeys> = ISlotProp<JSXIntrinsicElement<TElement>>;\n"]}
+94
View File
@@ -0,0 +1,94 @@
import * as React from 'react';
import { IStyle, ITheme } from '@fluentui/style-utilities';
import { IComponentStyles } from './IComponent';
/**
* Signature of components that have component factories.
*/
export interface ISlotCreator<TProps extends ValidProps, TShorthandProp extends ValidShorthand> {
create?: ISlotFactory<TProps, TShorthandProp>;
}
/**
* Slottable version of React.ComponentType.
*/
export type ISlottableComponentType<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = React.ComponentType<TProps> & ISlotCreator<TProps, TShorthandProp>;
/**
* Slottable version of React.ReactType.
*/
export type ISlottableReactType<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = React.ElementType<TProps> & ISlotCreator<TProps, TShorthandProp>;
/**
* Props generated by Foundation.
*/
export interface IProcessedSlotProps {
className?: string;
}
/**
* An interface for defining slots. Each key in TSlot must point to an ISlottableType.
*/
export type ISlotDefinition<TSlots> = {
[slot in keyof TSlots]: React.ElementType<ExtractProps<TSlots[slot]>>;
};
/**
* Created Slot structure used for rendering by components.
*/
export interface ISlot<TProps> {
(componentProps: React.PropsWithChildren<TProps> | undefined | null): ReturnType<React.FunctionComponent>;
isSlot?: boolean;
}
/**
* Interface for a slot factory that consumes both component and user slot prop and generates rendered output.
*/
export type ISlotFactory<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = (componentProps: TProps & IProcessedSlotProps, userProps: ISlotProp<TProps, TShorthandProp>, slotOptions: ISlotOptions<TProps> | undefined, defaultStyles: IStyle, theme?: ITheme) => ReturnType<React.FunctionComponent<TProps>>;
/**
* Defines valid shorthand prop types. These should match the defaultProp type provided to createComponent.
*/
export type ValidShorthand = string | number | boolean;
/**
* Defines valid prop types.
*/
export type ValidProps = object;
/**
* Extracts props type from ISlotProp definition.
*/
export type ExtractProps<TUnion> = TUnion extends ISlotProp<infer TProps> ? TProps : never;
/**
* Extracts shorthand type from union of ValidShorthand types.
*/
export type ExtractShorthand<TUnion> = TUnion extends boolean ? boolean : TUnion extends number ? number : TUnion extends string ? string : never;
/**
* Interface for aggregated slots objects used internally by components. Extract the TProps type passed
* into ISlotProp<TProps> to define the ISlot using TProps.
*/
export type ISlots<TSlots> = {
[slot in keyof TSlots]: ISlot<ExtractProps<TSlots[slot]>>;
};
/**
* Automatically defines 'slots' prop based on TSlots props.
*/
export type ISlottableProps<TSlots> = TSlots & {
slots?: {
[key in keyof TSlots]+?: ISlotOptions<ExtractProps<TSlots[key]>>;
};
};
/**
* Defines user properties that are automatically applied by Slot utilities using slot name.
*/
export interface IDefaultSlotProps<TSlots> {
_defaultStyles: IComponentStyles<TSlots>;
}
/**
* Defines the primary slot prop interface components should use to define their slot props.
*/
export type ISlotProp<TProps extends ValidProps, TShorthandProp extends ValidShorthand = never> = TShorthandProp | TProps;
/**
* Defines the slot options object for all slot props:
* 1. ISlotRender function.
* 2. React component with TProps interface.
*/
export interface ISlotOptions<TProps> {
component?: React.ElementType<TProps>;
render?: ISlotRender<TProps>;
}
/**
* Content rendering provided by component.
*/
export type ISlotRender<TProps> = (props: React.PropsWithChildren<TProps>, defaultComponent: React.ComponentType<React.PropsWithChildren<TProps>>) => ReturnType<React.FunctionComponent<React.PropsWithChildren<TProps>>>;
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=ISlots.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ISlots.js","sourceRoot":"../src/","sources":["ISlots.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { IStyle, ITheme } from '@fluentui/style-utilities';\nimport { IComponentStyles } from './IComponent';\n\n/**\n * Signature of components that have component factories.\n */\nexport interface ISlotCreator<TProps extends ValidProps, TShorthandProp extends ValidShorthand> {\n create?: ISlotFactory<TProps, TShorthandProp>;\n}\n\n/**\n * Slottable version of React.ComponentType.\n */\nexport type ISlottableComponentType<\n TProps extends ValidProps,\n TShorthandProp extends ValidShorthand,\n> = React.ComponentType<TProps> & ISlotCreator<TProps, TShorthandProp>;\n\n/**\n * Slottable version of React.ReactType.\n */\nexport type ISlottableReactType<\n TProps extends ValidProps,\n TShorthandProp extends ValidShorthand,\n> = React.ElementType<TProps> & ISlotCreator<TProps, TShorthandProp>;\n\n/**\n * Props generated by Foundation.\n */\nexport interface IProcessedSlotProps {\n className?: string;\n}\n\n/**\n * An interface for defining slots. Each key in TSlot must point to an ISlottableType.\n */\nexport type ISlotDefinition<TSlots> = { [slot in keyof TSlots]: React.ElementType<ExtractProps<TSlots[slot]>> };\n\n/**\n * Created Slot structure used for rendering by components.\n */\nexport interface ISlot<TProps> {\n (componentProps: React.PropsWithChildren<TProps> | undefined | null): ReturnType<React.FunctionComponent>;\n isSlot?: boolean;\n}\n\n/**\n * Interface for a slot factory that consumes both component and user slot prop and generates rendered output.\n */\nexport type ISlotFactory<TProps extends ValidProps, TShorthandProp extends ValidShorthand> = (\n componentProps: TProps & IProcessedSlotProps,\n userProps: ISlotProp<TProps, TShorthandProp>,\n slotOptions: ISlotOptions<TProps> | undefined,\n defaultStyles: IStyle,\n theme?: ITheme,\n) => ReturnType<React.FunctionComponent<TProps>>;\n\n/**\n * Defines valid shorthand prop types. These should match the defaultProp type provided to createComponent.\n */\nexport type ValidShorthand = string | number | boolean;\n\n/**\n * Defines valid prop types.\n */\n// We can constrain TProps more clearly (notably also exclude Functions) once this TS PR is merged:\n// https://github.com/Microsoft/TypeScript/pull/29317\nexport type ValidProps = object;\n\n/**\n * Extracts props type from ISlotProp definition.\n */\nexport type ExtractProps<TUnion> = TUnion extends ISlotProp<infer TProps> ? TProps : never;\n\n/**\n * Extracts shorthand type from union of ValidShorthand types.\n */\nexport type ExtractShorthand<TUnion> = TUnion extends boolean\n ? boolean\n : TUnion extends number\n ? number\n : TUnion extends string\n ? string\n : never;\n\n/**\n * Interface for aggregated slots objects used internally by components. Extract the TProps type passed\n * into ISlotProp<TProps> to define the ISlot using TProps.\n */\nexport type ISlots<TSlots> = { [slot in keyof TSlots]: ISlot<ExtractProps<TSlots[slot]>> };\n\n/**\n * Automatically defines 'slots' prop based on TSlots props.\n */\nexport type ISlottableProps<TSlots> = TSlots & {\n slots?: { [key in keyof TSlots]+?: ISlotOptions<ExtractProps<TSlots[key]>> };\n};\n\n/**\n * Defines user properties that are automatically applied by Slot utilities using slot name.\n */\nexport interface IDefaultSlotProps<TSlots> {\n _defaultStyles: IComponentStyles<TSlots>;\n}\n\n/**\n * Defines the primary slot prop interface components should use to define their slot props.\n */\n// TODO: Constrain TProps more clearly (notably also exclude Functions) once this TS PR is merged:\n// https://github.com/Microsoft/TypeScript/pull/29317\nexport type ISlotProp<TProps extends ValidProps, TShorthandProp extends ValidShorthand = never> =\n | TShorthandProp\n | TProps;\n\n/**\n * Defines the slot options object for all slot props:\n * 1. ISlotRender function.\n * 2. React component with TProps interface.\n */\n\n// TODO: create mutually exclusive type for component & render, but only if it's a readable error for users.\nexport interface ISlotOptions<TProps> {\n component?: React.ElementType<TProps>;\n render?: ISlotRender<TProps>;\n}\n\n/**\n * Content rendering provided by component.\n */\nexport type ISlotRender<TProps> = (\n props: React.PropsWithChildren<TProps>,\n defaultComponent: React.ComponentType<React.PropsWithChildren<TProps>>,\n) => ReturnType<React.FunctionComponent<React.PropsWithChildren<TProps>>>;\n"]}
@@ -0,0 +1,15 @@
import * as React from 'react';
import { ISchemeNames, ITheme } from '@fluentui/style-utilities';
export interface IThemeProviderProps {
scheme?: ISchemeNames;
theme?: ITheme;
}
/**
* Theme provider is a simplified version of Customizer that activates the appropriate theme data
* for a given scheme name.
*
* @param providers - Injected providers for accessing theme data and providing it via a Customizer component.
* @deprecated This is an old ThemeProvider implementation. New code should use the ThemeProvider exported from
* `@fluentui/react` (or `@fluentui/react/lib/Theme`) instead.
*/
export declare const ThemeProvider: React.FunctionComponent<React.PropsWithChildren<IThemeProviderProps>>;
+28
View File
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ThemeProvider = void 0;
var tslib_1 = require("tslib");
var React = require("react");
var style_utilities_1 = require("@fluentui/style-utilities");
var utilities_1 = require("@fluentui/utilities");
/**
* Theme provider is a simplified version of Customizer that activates the appropriate theme data
* for a given scheme name.
*
* @param providers - Injected providers for accessing theme data and providing it via a Customizer component.
* @deprecated This is an old ThemeProvider implementation. New code should use the ThemeProvider exported from
* `@fluentui/react` (or `@fluentui/react/lib/Theme`) instead.
*/
var ThemeProvider = function (props) {
var scheme = props.scheme, theme = props.theme, rest = tslib_1.__rest(props, ["scheme", "theme"]);
// TODO: consider merging implementation with theme-proto, which only stores a reference / scheme name to theme
// in context and uses quick global store accessor to trigger change by passing in theme object as child and
// triggering re-render. (perf benefits need verification)
var contextTransform = function (context) {
return (0, style_utilities_1.getThemedContext)(context, scheme, theme);
};
// eslint-disable-next-line react/jsx-no-bind, @typescript-eslint/no-deprecated
return React.createElement(utilities_1.Customizer, tslib_1.__assign({}, rest, { contextTransform: contextTransform }));
};
exports.ThemeProvider = ThemeProvider;
//# sourceMappingURL=ThemeProvider.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ThemeProvider.js","sourceRoot":"../src/","sources":["ThemeProvider.tsx"],"names":[],"mappings":";;;;AAAA,6BAA+B;AAC/B,6DAAmF;AACnF,iDAAmE;AAOnE;;;;;;;GAOG;AACI,IAAM,aAAa,GAA0E,UAClG,KAA0B;IAElB,IAAA,MAAM,GAAqB,KAAK,OAA1B,EAAE,KAAK,GAAc,KAAK,MAAnB,EAAK,IAAI,kBAAK,KAAK,EAAlC,mBAA0B,CAAF,CAAW;IAEzC,+GAA+G;IAC/G,8GAA8G;IAC9G,4DAA4D;IAC5D,IAAM,gBAAgB,GAAyC,UAAA,OAAO;QACpE,OAAO,IAAA,kCAAgB,EAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC;IAEF,+EAA+E;IAC/E,OAAO,oBAAC,sBAAU,uBAAK,IAAI,IAAE,gBAAgB,EAAE,gBAAgB,IAAI,CAAC;AACtE,CAAC,CAAC;AAdW,QAAA,aAAa,iBAcxB","sourcesContent":["import * as React from 'react';\nimport { getThemedContext, ISchemeNames, ITheme } from '@fluentui/style-utilities';\nimport { Customizer, ICustomizerProps } from '@fluentui/utilities';\n\nexport interface IThemeProviderProps {\n scheme?: ISchemeNames;\n theme?: ITheme;\n}\n\n/**\n * Theme provider is a simplified version of Customizer that activates the appropriate theme data\n * for a given scheme name.\n *\n * @param providers - Injected providers for accessing theme data and providing it via a Customizer component.\n * @deprecated This is an old ThemeProvider implementation. New code should use the ThemeProvider exported from\n * `@fluentui/react` (or `@fluentui/react/lib/Theme`) instead.\n */\nexport const ThemeProvider: React.FunctionComponent<React.PropsWithChildren<IThemeProviderProps>> = (\n props: IThemeProviderProps,\n) => {\n const { scheme, theme, ...rest } = props;\n\n // TODO: consider merging implementation with theme-proto, which only stores a reference / scheme name to theme\n // in context and uses quick global store accessor to trigger change by passing in theme object as child and\n // triggering re-render. (perf benefits need verification)\n const contextTransform: ICustomizerProps['contextTransform'] = context => {\n return getThemedContext(context, scheme, theme);\n };\n\n // eslint-disable-next-line react/jsx-no-bind, @typescript-eslint/no-deprecated\n return <Customizer {...rest} contextTransform={contextTransform} />;\n};\n"]}
@@ -0,0 +1,24 @@
import * as React from 'react';
import { IStyleSetBase } from '@fluentui/style-utilities';
import { IComponentOptions, IViewComponent } from './IComponent';
import { ValidProps } from './ISlots';
/**
* Assembles a higher order component based on the following: styles, theme, view, and state.
* Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param options - component Component options. See IComponentOptions for more detail.
*/
export declare function createComponent<TComponentProps extends ValidProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps extends TComponentProps = TComponentProps, TStatics = {}>(view: IViewComponent<TViewProps>, options?: IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics>): React.FunctionComponent<TComponentProps> & TStatics;
@@ -0,0 +1,108 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createComponent = createComponent;
var tslib_1 = require("tslib");
var React = require("react");
var style_utilities_1 = require("@fluentui/style-utilities");
var utilities_1 = require("@fluentui/utilities");
var slots_1 = require("./slots");
var utilities_2 = require("./utilities");
/**
* Assembles a higher order component based on the following: styles, theme, view, and state.
* Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param options - component Component options. See IComponentOptions for more detail.
*/
function createComponent(view, options) {
if (options === void 0) { options = {}; }
var _a = options.factoryOptions, factoryOptions = _a === void 0 ? {} : _a;
var defaultProp = factoryOptions.defaultProp;
var ResultComponent = function (componentProps) {
var settings = _getCustomizations(options.displayName, React.useContext(utilities_1.CustomizerContext), options.fields);
var stateReducer = options.state;
if (stateReducer) {
// Don't assume state will return all props, so spread useState result over component props.
componentProps = tslib_1.__assign(tslib_1.__assign({}, componentProps), stateReducer(componentProps));
}
var theme = componentProps.theme || settings.theme;
var tokens = _resolveTokens(componentProps, theme, options.tokens, settings.tokens, componentProps.tokens);
var styles = _resolveStyles(componentProps, theme, tokens, options.styles, settings.styles, componentProps.styles);
var viewProps = tslib_1.__assign(tslib_1.__assign({}, componentProps), { styles: styles, tokens: tokens, _defaultStyles: styles, theme: theme });
return view(viewProps);
};
ResultComponent.displayName = options.displayName || view.name;
// If a shorthand prop is defined, create a factory for the component.
// TODO: This shouldn't be a concern of createComponent.. factoryOptions should just be forwarded.
// Need to weigh creating default factories on component creation vs. memoizing them on use in slots.tsx.
if (defaultProp) {
ResultComponent.create = (0, slots_1.createFactory)(ResultComponent, { defaultProp: defaultProp });
}
(0, utilities_2.assign)(ResultComponent, options.statics);
// Later versions of TypeSript should allow us to merge objects in a type safe way and avoid this cast.
return ResultComponent;
}
/**
* Resolve all styles functions with both props and tokens and flatten results along with all styles objects.
*/
function _resolveStyles(props, theme, tokens) {
var allStyles = [];
for (var _i = 3; _i < arguments.length; _i++) {
allStyles[_i - 3] = arguments[_i];
}
return style_utilities_1.concatStyleSets.apply(void 0, allStyles.map(function (styles) {
return typeof styles === 'function' ? styles(props, theme, tokens) : styles;
}));
}
/**
* Resolve all tokens functions with props flatten results along with all tokens objects.
*/
function _resolveTokens(props, theme) {
var allTokens = [];
for (var _i = 2; _i < arguments.length; _i++) {
allTokens[_i - 2] = arguments[_i];
}
var tokens = {};
for (var _a = 0, allTokens_1 = allTokens; _a < allTokens_1.length; _a++) {
var currentTokens = allTokens_1[_a];
if (currentTokens) {
// TODO: why is this cast needed? TS seems to think there is a (TToken | Function) union from somewhere.
currentTokens =
typeof currentTokens === 'function'
? currentTokens(props, theme)
: currentTokens;
if (Array.isArray(currentTokens)) {
currentTokens = _resolveTokens.apply(void 0, tslib_1.__spreadArray([props, theme], currentTokens, false));
}
(0, utilities_2.assign)(tokens, currentTokens);
}
}
return tokens;
}
/**
* Helper function for calling Customizations.getSettings falling back to default fields.
*
* @param displayName Displayable name for component.
* @param context React context passed to component containing contextual settings.
* @param fields Optional list of properties to grab from global store and context.
*/
function _getCustomizations(displayName, context, fields) {
// TODO: do we want field props? should fields be part of IComponent and used here?
// TODO: should we centrally define DefaultFields? (not exported from styling)
// TODO: tie this array to ICustomizationProps, such that each array element is keyof ICustomizationProps
var DefaultFields = ['theme', 'styles', 'tokens'];
return utilities_1.Customizations.getSettings(fields || DefaultFields, displayName, context.customizations);
}
//# sourceMappingURL=createComponent.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,23 @@
import * as React from 'react';
export interface IControlledStateOptions<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps> {
defaultPropValue?: TProps[TProp];
defaultPropName?: TDefaultProp;
}
/**
* Controlled state helper that gives priority to props value. Useful for components that have props with both
* controlled and uncontrolled modes. Any props values will override state, but will not update internal state.
* If prop is defined and then later undefined, state will revert to its previous value.
*
* @param props - The props object containing controlled prop values.
* @param propName - The controlled prop name.
* @param options - Options. defaultPropValue is only used if defaultPropName (or its value) is undefined.
*/
export declare function useControlledState<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps>(props: Readonly<TProps>, propName: TProp, options?: IControlledStateOptions<TProps, TProp, TDefaultProp>): [TProps[TProp] | undefined, React.Dispatch<React.SetStateAction<TProps[TProp]>>];
/**
* Simple controlled helper that gives priority to props value and falls back to derived value.
*
* @param props - The props object containing controlled prop values.
* @param propName - The controlled prop name.
* @param derivedValue - Derived value. Returned when controlled value is not present.
*/
export declare function getControlledDerivedProps<TProps, TProp extends keyof TProps>(props: Readonly<TProps>, propName: TProp, derivedValue: TProps[TProp]): TProps[TProp];
@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useControlledState = useControlledState;
exports.getControlledDerivedProps = getControlledDerivedProps;
var React = require("react");
/**
* Controlled state helper that gives priority to props value. Useful for components that have props with both
* controlled and uncontrolled modes. Any props values will override state, but will not update internal state.
* If prop is defined and then later undefined, state will revert to its previous value.
*
* @param props - The props object containing controlled prop values.
* @param propName - The controlled prop name.
* @param options - Options. defaultPropValue is only used if defaultPropName (or its value) is undefined.
*/
function useControlledState(props, propName, options) {
var defaultValue;
if (options) {
if (options.defaultPropName && props[options.defaultPropName] !== undefined) {
// No easy way to coerce TProps[TDefaultProp] to match TProps[TProp] in generic typings, so cast it here.
defaultValue = props[options.defaultPropName];
}
else {
defaultValue = options && options.defaultPropValue;
}
}
var _a = React.useState(defaultValue), state = _a[0], setState = _a[1];
if (props[propName] !== undefined) {
return [props[propName], setState];
}
else {
return [state, setState];
}
}
/**
* Simple controlled helper that gives priority to props value and falls back to derived value.
*
* @param props - The props object containing controlled prop values.
* @param propName - The controlled prop name.
* @param derivedValue - Derived value. Returned when controlled value is not present.
*/
function getControlledDerivedProps(props, propName, derivedValue) {
if (props[propName] !== undefined) {
return props[propName];
}
else {
return derivedValue;
}
}
//# sourceMappingURL=controlled.js.map
@@ -0,0 +1 @@
{"version":3,"file":"controlled.js","sourceRoot":"../src/","sources":["hooks/controlled.ts"],"names":[],"mappings":";;AAgBA,gDAsBC;AASD,8DAUC;AAzDD,6BAA+B;AAO/B;;;;;;;;GAQG;AACH,SAAgB,kBAAkB,CAChC,KAAuB,EACvB,QAAe,EACf,OAA8D;IAE9D,IAAI,YAAuC,CAAC;IAC5C,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,OAAO,CAAC,eAAe,IAAI,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,SAAS,EAAE,CAAC;YAC5E,yGAAyG;YACzG,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAA6B,CAAC;QAC5E,CAAC;aAAM,CAAC;YACN,YAAY,GAAG,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC;QACrD,CAAC;IACH,CAAC;IAEK,IAAA,KAAoB,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,EAA/C,KAAK,QAAA,EAAE,QAAQ,QAAgC,CAAC;IAEvD,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,yBAAyB,CACvC,KAAuB,EACvB,QAAe,EACf,YAA2B;IAE3B,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;SAAM,CAAC;QACN,OAAO,YAAY,CAAC;IACtB,CAAC;AACH,CAAC","sourcesContent":["import * as React from 'react';\n\nexport interface IControlledStateOptions<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps> {\n defaultPropValue?: TProps[TProp];\n defaultPropName?: TDefaultProp;\n}\n\n/**\n * Controlled state helper that gives priority to props value. Useful for components that have props with both\n * controlled and uncontrolled modes. Any props values will override state, but will not update internal state.\n * If prop is defined and then later undefined, state will revert to its previous value.\n *\n * @param props - The props object containing controlled prop values.\n * @param propName - The controlled prop name.\n * @param options - Options. defaultPropValue is only used if defaultPropName (or its value) is undefined.\n */\nexport function useControlledState<TProps, TProp extends keyof TProps, TDefaultProp extends keyof TProps>(\n props: Readonly<TProps>,\n propName: TProp,\n options?: IControlledStateOptions<TProps, TProp, TDefaultProp>,\n): [TProps[TProp] | undefined, React.Dispatch<React.SetStateAction<TProps[TProp]>>] {\n let defaultValue: TProps[TProp] | undefined;\n if (options) {\n if (options.defaultPropName && props[options.defaultPropName] !== undefined) {\n // No easy way to coerce TProps[TDefaultProp] to match TProps[TProp] in generic typings, so cast it here.\n defaultValue = props[options.defaultPropName] as unknown as TProps[TProp];\n } else {\n defaultValue = options && options.defaultPropValue;\n }\n }\n\n const [state, setState] = React.useState(defaultValue);\n\n if (props[propName] !== undefined) {\n return [props[propName], setState];\n } else {\n return [state, setState];\n }\n}\n\n/**\n * Simple controlled helper that gives priority to props value and falls back to derived value.\n *\n * @param props - The props object containing controlled prop values.\n * @param propName - The controlled prop name.\n * @param derivedValue - Derived value. Returned when controlled value is not present.\n */\nexport function getControlledDerivedProps<TProps, TProp extends keyof TProps>(\n props: Readonly<TProps>,\n propName: TProp,\n derivedValue: TProps[TProp],\n): TProps[TProp] {\n if (props[propName] !== undefined) {\n return props[propName];\n } else {\n return derivedValue;\n }\n}\n"]}
@@ -0,0 +1 @@
export * from './controlled';
+5
View File
@@ -0,0 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("./controlled"), exports);
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["hooks/index.ts"],"names":[],"mappings":";;;AAAA,uDAA6B","sourcesContent":["export * from './controlled';\n"]}
+9
View File
@@ -0,0 +1,9 @@
export * from './createComponent';
export * from './IComponent';
export * from './IHTMLSlots';
export * from './ISlots';
export * from './slots';
export * from './ThemeProvider';
export * from './hooks/index';
export { styled as legacyStyled } from '@fluentui/utilities';
import './version';
+15
View File
@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.legacyStyled = void 0;
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("./createComponent"), exports);
tslib_1.__exportStar(require("./IComponent"), exports);
tslib_1.__exportStar(require("./IHTMLSlots"), exports);
tslib_1.__exportStar(require("./ISlots"), exports);
tslib_1.__exportStar(require("./slots"), exports);
tslib_1.__exportStar(require("./ThemeProvider"), exports);
tslib_1.__exportStar(require("./hooks/index"), exports);
var utilities_1 = require("@fluentui/utilities");
Object.defineProperty(exports, "legacyStyled", { enumerable: true, get: function () { return utilities_1.styled; } });
require("./version");
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["index.ts"],"names":[],"mappings":";;;;AAAA,4DAAkC;AAClC,uDAA6B;AAC7B,uDAA6B;AAC7B,mDAAyB;AACzB,kDAAwB;AACxB,0DAAgC;AAChC,wDAA8B;AAE9B,iDAA6D;AAApD,yGAAA,MAAM,OAAgB;AAE/B,qBAAmB","sourcesContent":["export * from './createComponent';\nexport * from './IComponent';\nexport * from './IHTMLSlots';\nexport * from './ISlots';\nexport * from './slots';\nexport * from './ThemeProvider';\nexport * from './hooks/index';\n\nexport { styled as legacyStyled } from '@fluentui/utilities';\n\nimport './version';\n"]}
@@ -0,0 +1,51 @@
import * as React from 'react';
import { IStyleSetBase } from '@fluentui/style-utilities';
import { IComponentOptions as IOldComponentOptions } from '../IComponent';
import { ISlots, ISlotDefinition, ISlottableProps } from '../ISlots';
/**
* Defines the contract for view components.
*/
export type IViewComponent<TViewProps, TComponentSlots = {}> = (props: React.PropsWithChildren<TViewProps>, slots: ISlots<Required<TComponentSlots>>) => ReturnType<React.FunctionComponent>;
/**
* Defines the contract for slot components.
*/
export type ISlotComponent<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots> = ISlotDefinition<Required<TComponentSlots>> | ((props: TComponentProps) => ISlotDefinition<Required<TComponentSlots>>);
/**
* Defines the contract for partial slot components used in recomposition.
*/
export type IPartialSlotComponent<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots> = ISlotDefinition<TComponentSlots> | ((props: TComponentProps) => ISlotDefinition<TComponentSlots>);
/**
* Component options used by foundation to tie elements together.
*
* * TComponentProps: A styleable props interface for the created component.
* * TTokens: The type for tokens props.
* * TStyleSet: The type for styles properties.
* * TViewProps: The props specific to the view, including processed properties outputted by optional state component.
* If state component is not provided, TComponentProps is the same as TViewProps.
* * TComponentSlots: The slottable components used to build the HOC.
* * TStatics: Static type for statics applied to created component object.
*/
export interface IComponentOptions<TComponentProps extends ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TComponentSlots = {}, TStatics = {}> extends IOldComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics> {
/**
* Slot definition object defining the slot component for each slot.
*/
slots?: ISlotComponent<TComponentProps, TComponentSlots>;
/**
* Stateless pure function that receives props to render the output of the component.
*/
view?: IViewComponent<TViewProps, TComponentSlots>;
}
export interface IRecompositionComponentOptions<TComponentProps extends ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TComponentSlots = {}, TStatics = {}> extends IOldComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics> {
/**
* Slot definition object defining the slot component for each slot.
*/
slots?: IPartialSlotComponent<TComponentProps, TComponentSlots>;
/**
* Stateless pure function that receives props to render the output of the component.
*/
view?: IViewComponent<TViewProps, TComponentSlots>;
}
/**
* Component helper that defines options as required for ease of use by component consumers.
*/
export type IComponent<TComponentProps extends ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TComponentSlots = {}, TStatics = {}> = Required<IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>>;
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IComponent.js.map
@@ -0,0 +1 @@
{"version":3,"file":"IComponent.js","sourceRoot":"../src/","sources":["next/IComponent.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { IStyleSetBase } from '@fluentui/style-utilities';\nimport { IComponentOptions as IOldComponentOptions } from '../IComponent';\nimport { ISlots, ISlotDefinition, ISlottableProps } from '../ISlots';\n\n/**\n * Defines the contract for view components.\n */\nexport type IViewComponent<TViewProps, TComponentSlots = {}> = (\n props: React.PropsWithChildren<TViewProps>,\n slots: ISlots<Required<TComponentSlots>>,\n) => ReturnType<React.FunctionComponent>;\n\n/**\n * Defines the contract for slot components.\n */\nexport type ISlotComponent<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots> =\n | ISlotDefinition<Required<TComponentSlots>>\n | ((props: TComponentProps) => ISlotDefinition<Required<TComponentSlots>>);\n\n/**\n * Defines the contract for partial slot components used in recomposition.\n */\nexport type IPartialSlotComponent<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots> =\n | ISlotDefinition<TComponentSlots>\n | ((props: TComponentProps) => ISlotDefinition<TComponentSlots>);\n\n/**\n * Component options used by foundation to tie elements together.\n *\n * * TComponentProps: A styleable props interface for the created component.\n * * TTokens: The type for tokens props.\n * * TStyleSet: The type for styles properties.\n * * TViewProps: The props specific to the view, including processed properties outputted by optional state component.\n * If state component is not provided, TComponentProps is the same as TViewProps.\n * * TComponentSlots: The slottable components used to build the HOC.\n * * TStatics: Static type for statics applied to created component object.\n */\nexport interface IComponentOptions<\n TComponentProps extends ISlottableProps<TComponentSlots>,\n TTokens,\n TStyleSet extends IStyleSetBase,\n TViewProps = TComponentProps,\n TComponentSlots = {},\n TStatics = {},\n> extends IOldComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics> {\n /**\n * Slot definition object defining the slot component for each slot.\n */\n slots?: ISlotComponent<TComponentProps, TComponentSlots>;\n /**\n * Stateless pure function that receives props to render the output of the component.\n */\n view?: IViewComponent<TViewProps, TComponentSlots>;\n}\n\nexport interface IRecompositionComponentOptions<\n TComponentProps extends ISlottableProps<TComponentSlots>,\n TTokens,\n TStyleSet extends IStyleSetBase,\n TViewProps = TComponentProps,\n TComponentSlots = {},\n TStatics = {},\n> extends IOldComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics> {\n /**\n * Slot definition object defining the slot component for each slot.\n */\n slots?: IPartialSlotComponent<TComponentProps, TComponentSlots>;\n /**\n * Stateless pure function that receives props to render the output of the component.\n */\n view?: IViewComponent<TViewProps, TComponentSlots>;\n}\n\n/**\n * Component helper that defines options as required for ease of use by component consumers.\n */\nexport type IComponent<\n TComponentProps extends ISlottableProps<TComponentSlots>,\n TTokens,\n TStyleSet extends IStyleSetBase,\n TViewProps = TComponentProps,\n TComponentSlots = {},\n TStatics = {},\n> = Required<IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>>;\n"]}
+10
View File
@@ -0,0 +1,10 @@
import * as React from 'react';
import { IStyleSetBase } from '@fluentui/style-utilities';
import { ISlottableProps, ValidProps } from '../ISlots';
import { IComponentOptions } from './IComponent';
/**
* Signature of components created using composed.
*/
export interface IFoundationComponent<TComponentProps extends ValidProps & ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps extends TComponentProps = TComponentProps, TComponentSlots = {}, TStatics = {}> extends React.FunctionComponent {
__options?: IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>;
}
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=ISlots.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ISlots.js","sourceRoot":"../src/","sources":["next/ISlots.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { IStyleSetBase } from '@fluentui/style-utilities';\nimport { ISlottableProps, ValidProps } from '../ISlots';\nimport { IComponentOptions } from './IComponent';\n\n/**\n * Signature of components created using composed.\n */\nexport interface IFoundationComponent<\n TComponentProps extends ValidProps & ISlottableProps<TComponentSlots>,\n TTokens,\n TStyleSet extends IStyleSetBase,\n TViewProps extends TComponentProps = TComponentProps,\n TComponentSlots = {},\n TStatics = {},\n> extends React.FunctionComponent {\n __options?: IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>;\n}\n"]}
@@ -0,0 +1,53 @@
import * as React from 'react';
import { IStyleSetBase } from '@fluentui/style-utilities';
import { IComponentOptions, IPartialSlotComponent, IRecompositionComponentOptions, ISlotComponent } from './IComponent';
import { ValidProps, ISlottableProps, ISlotDefinition } from '../ISlots';
import { IFoundationComponent } from './ISlots';
/**
* Assembles a higher order component based on the following: styles, theme, view, and state.
* Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param options - component Component options. See IComponentOptions for more detail.
*/
export declare function composed<TComponentProps extends ValidProps & ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps extends TComponentProps = TComponentProps, TComponentSlots = {}, TStatics = {}>(options: IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>): IFoundationComponent<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics> & TStatics;
/**
* Recomposes a functional component based on a base component and the following set of options: styles, theme, view,
* and state. Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param baseComponent - base component to recompose
* @param options - component Component recomposition options. See IComponentOptions for more detail.
*/
export declare function composed<TComponentProps extends ValidProps & ISlottableProps<TComponentSlots>, TTokens, TStyleSet extends IStyleSetBase, TViewProps extends TComponentProps = TComponentProps, TComponentSlots = {}, TStatics = {}>(baseComponent: React.FunctionComponent, options: IRecompositionComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics>): IFoundationComponent<TComponentProps, TTokens, TStyleSet, TViewProps, TComponentSlots, TStatics> & TStatics;
/**
* Resolve the passed slots as a function or an object.
*
* @param slots - Slots that need to be resolved as a function or an object.
* @param data - Data to pass to resolve if the first argument was a function.
*/
export declare function resolveSlots<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots>(slots: IPartialSlotComponent<TComponentProps, TComponentSlots> | ISlotComponent<TComponentProps, TComponentSlots> | undefined, data: TComponentProps): ISlotDefinition<Required<TComponentSlots>>;
+206
View File
@@ -0,0 +1,206 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.composed = composed;
exports.resolveSlots = resolveSlots;
var tslib_1 = require("tslib");
var React = require("react");
var merge_styles_1 = require("@fluentui/merge-styles");
var style_utilities_1 = require("@fluentui/style-utilities");
var utilities_1 = require("@fluentui/utilities");
var slots_1 = require("../slots");
var utilities_2 = require("../utilities");
var memoizedClassNamesMap = {};
/**
* Assembles a higher order component based on a set of options or recomposes a functional component based on a
* base component and the a set of options. This set of options is comprised by: styles, theme, view, and state.
*
* Imposes a separation of concern and centralizes styling processing to increase ease of use and robustness
* in how components use and apply styling and theming.
*
* Automatically merges and applies themes and styles with theme / styleprops having the highest priority.
* State component, if provided, is passed in props for processing. Props from state / user are automatically processed
* and styled before finally being passed to view.
*
* State components should contain all stateful behavior and should not generate any JSX, but rather simply call
* the view prop.
*
* Views should simply be stateless pure functions that receive all props needed for rendering their output.
*
* State component is optional. If state is not provided, created component is essentially a functional
* stateless component.
*
* @param baseComponentOrOptions - base component to recompose or component Component options to compose an HOC.
* See IComponentOptions for more detail.
* @param recompositionOptions - component Component recomposition options. See IComponentOptions for more detail.
*/
function composed(baseComponentOrOptions, recompositionOptions) {
if (baseComponentOrOptions === void 0) { baseComponentOrOptions = {}; }
// Check if we are composing or recomposing.
var options;
if (typeof baseComponentOrOptions === 'function' && baseComponentOrOptions.__options) {
var baseComponentOptions_1 = baseComponentOrOptions.__options;
var recompositionSlots_1 = recompositionOptions ? recompositionOptions.slots : undefined;
options = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, baseComponentOptions_1), recompositionOptions), { slots: function (props) { return (tslib_1.__assign(tslib_1.__assign({}, resolveSlots(baseComponentOptions_1.slots, props)), resolveSlots(recompositionSlots_1, props))); } });
}
else {
options = baseComponentOrOptions;
}
var _a = options.factoryOptions, factoryOptions = _a === void 0 ? {} : _a, view = options.view;
var defaultProp = factoryOptions.defaultProp;
var ResultComponent = function (componentProps) {
var settings = _getCustomizations(options.displayName, React.useContext(utilities_1.CustomizerContext), options.fields);
var stateReducer = options.state;
if (stateReducer) {
// Don't assume state will return all props, so spread useState result over component props.
componentProps = tslib_1.__assign(tslib_1.__assign({}, componentProps), stateReducer(componentProps));
}
var theme = componentProps.theme || settings.theme;
var tokens = _resolveTokens(componentProps, theme, options.tokens, settings.tokens, componentProps.tokens);
var styles;
var finalStyles = {};
// We get the entry in the memoized classNamesMap for the current component or create one if it doesn't exist.
var displayName = options.displayName;
// If no displayName has been specified, then do not use caching.
if (displayName) {
if (!memoizedClassNamesMap.hasOwnProperty(displayName)) {
memoizedClassNamesMap[displayName] = { map: {} };
}
var current = memoizedClassNamesMap[displayName];
// Memoize based on the tokens definition.
var tokenKeys = Object.keys(tokens).sort();
for (var _i = 0, tokenKeys_1 = tokenKeys; _i < tokenKeys_1.length; _i++) {
var key = tokenKeys_1[_i];
var nextToken = tokens[key];
if (nextToken === undefined) {
nextToken = '__undefined__';
}
if (!current.map.hasOwnProperty(nextToken)) {
current.map[nextToken] = { map: {} };
}
current = current.map[nextToken];
}
// Memoize the slots so we only have to get Object.keys once.
var slots = memoizedClassNamesMap[displayName].slots;
var defaultStyles = void 0;
if (!slots) {
defaultStyles = _resolveStyles(componentProps, theme, tokens, options.styles, settings.styles);
memoizedClassNamesMap[displayName].slots = Object.keys(defaultStyles);
slots = memoizedClassNamesMap[displayName].slots;
}
// Memoize based on the base styling of the component (i.e. without user specified props).
for (var _a = 0, slots_2 = slots; _a < slots_2.length; _a++) {
var key = slots_2[_a];
if (!current.map.hasOwnProperty(key)) {
// Get default styles once if we didn't get them before.
if (!defaultStyles) {
defaultStyles = _resolveStyles(componentProps, theme, tokens, options.styles, settings.styles);
}
current.map[key] = { className: (0, merge_styles_1.mergeStyles)(defaultStyles[key]), map: {} };
}
finalStyles[key] = current.map[key].className;
}
if (componentProps.styles) {
var userStyles = typeof componentProps.styles === 'function'
? componentProps.styles(componentProps, theme, tokens)
: componentProps.styles;
styles = (0, style_utilities_1.concatStyleSets)(styles, userStyles);
if (userStyles) {
var userStyleKeys = Object.keys(userStyles);
for (var _b = 0, userStyleKeys_1 = userStyleKeys; _b < userStyleKeys_1.length; _b++) {
var key = userStyleKeys_1[_b];
if (finalStyles.hasOwnProperty(key)) {
finalStyles[key] = (0, merge_styles_1.mergeStyles)([current.map[key].className], userStyles[key]);
}
else {
finalStyles[key] = (0, merge_styles_1.mergeStyles)(userStyles[key]);
}
}
}
}
}
else {
styles = _resolveStyles(componentProps, theme, tokens, options.styles, settings.styles, componentProps.styles);
}
var viewProps = tslib_1.__assign(tslib_1.__assign({}, componentProps), { styles: styles, tokens: tokens, _defaultStyles: displayName ? finalStyles : styles });
if (!options.slots) {
throw new Error("Component ".concat(options.displayName || (view && view.name) || '', " is missing slot definitions."));
}
var Slots = typeof options.slots === 'function'
? (0, slots_1.getSlots)(viewProps, options.slots(viewProps))
: (0, slots_1.getSlots)(viewProps, options.slots);
return view ? view(viewProps, Slots) : null;
};
ResultComponent.displayName = options.displayName || (view && view.name);
// If a shorthand prop is defined, create a factory for the component.
// TODO: This shouldn't be a concern of createComponent.. factoryOptions should just be forwarded.
// Need to weigh creating default factories on component creation vs. memoizing them on use in slots.tsx.
if (defaultProp) {
ResultComponent.create = (0, slots_1.createFactory)(ResultComponent, { defaultProp: defaultProp });
}
ResultComponent.__options = options;
(0, utilities_2.assign)(ResultComponent, options.statics);
// Later versions of TypeSript should allow us to merge objects in a type safe way and avoid this cast.
return ResultComponent;
}
/**
* Resolve the passed slots as a function or an object.
*
* @param slots - Slots that need to be resolved as a function or an object.
* @param data - Data to pass to resolve if the first argument was a function.
*/
function resolveSlots(slots, data) {
var resolvedSlots = slots ? (typeof slots === 'function' ? slots(data) : slots) : {};
return resolvedSlots;
}
/**
* Resolve all styles functions with both props and tokens and flatten results along with all styles objects.
*/
function _resolveStyles(props, theme, tokens) {
var allStyles = [];
for (var _i = 3; _i < arguments.length; _i++) {
allStyles[_i - 3] = arguments[_i];
}
return style_utilities_1.concatStyleSets.apply(void 0, allStyles.map(function (styles) {
return typeof styles === 'function' ? styles(props, theme, tokens) : styles;
}));
}
/**
* Resolve all tokens functions with props flatten results along with all tokens objects.
*/
function _resolveTokens(props, theme) {
var allTokens = [];
for (var _i = 2; _i < arguments.length; _i++) {
allTokens[_i - 2] = arguments[_i];
}
var tokens = {};
for (var _a = 0, allTokens_1 = allTokens; _a < allTokens_1.length; _a++) {
var currentTokens = allTokens_1[_a];
if (currentTokens) {
// TODO: why is this cast needed? TS seems to think there is a (TToken | Function) union from somewhere.
currentTokens =
typeof currentTokens === 'function'
? currentTokens(props, theme)
: currentTokens;
if (Array.isArray(currentTokens)) {
currentTokens = _resolveTokens.apply(void 0, tslib_1.__spreadArray([props, theme], currentTokens, false));
}
(0, utilities_2.assign)(tokens, currentTokens);
}
}
return tokens;
}
/**
* Helper function for calling Customizations.getSettings falling back to default fields.
*
* @param displayName Displayable name for component.
* @param context React context passed to component containing contextual settings.
* @param fields Optional list of properties to grab from global store and context.
*/
function _getCustomizations(displayName, context, fields) {
// TODO: do we want field props? should fields be part of IComponent and used here?
// TODO: should we centrally define DefaultFields? (not exported from styling)
// TODO: tie this array to ICustomizationProps, such that each array element is keyof ICustomizationProps
var DefaultFields = ['theme', 'styles', 'tokens'];
return utilities_1.Customizations.getSettings(fields || DefaultFields, displayName, context.customizations);
}
//# sourceMappingURL=composed.js.map
File diff suppressed because one or more lines are too long
+30
View File
@@ -0,0 +1,30 @@
import * as React from 'react';
import { IFactoryOptions } from './IComponent';
import { ISlot, ISlots, ISlotDefinition, ISlotFactory, ISlottableProps, ValidProps, ValidShorthand } from './ISlots';
/**
* This function is required for any module that uses slots.
*
* This function is a slot resolver that automatically evaluates slot functions to generate React elements.
* A byproduct of this resolver is that it removes slots from the React hierarchy by bypassing React.createElement.
*
* To use this function on a per-file basis, use the jsx directive targeting withSlots.
* This directive must be the FIRST LINE in the file to work correctly.
* Usage of this pragma also requires withSlots import statement.
*
* See React.createElement
*/
export declare function withSlots<P extends {}>(type: ISlot<P> | React.FunctionComponent<P> | string, props?: (React.Attributes & P) | null, ...children: React.ReactNode[]): ReturnType<React.FunctionComponent<P>>;
/**
* This function creates factories that render ouput depending on the user ISlotProp props passed in.
* @param DefaultComponent - Base component to render when not overridden by user props.
* @param options - Factory options, including defaultProp value for shorthand prop mapping.
* @returns ISlotFactory function used for rendering slots.
*/
export declare function createFactory<TProps extends ValidProps, TShorthandProp extends ValidShorthand = never>(DefaultComponent: React.ComponentType<TProps>, options?: IFactoryOptions<TProps>): ISlotFactory<TProps, TShorthandProp>;
/**
* This function generates slots that can be used in JSX given a definition of slots and their corresponding types.
* @param userProps - Props as pass to component.
* @param slots - Slot definition object defining the default slot component for each slot.
* @returns A set of created slots that components can render in JSX.
*/
export declare function getSlots<TComponentProps extends ISlottableProps<TComponentSlots>, TComponentSlots>(userProps: TComponentProps, slots: ISlotDefinition<Required<TComponentSlots>>): ISlots<Required<TComponentSlots>>;
+190
View File
@@ -0,0 +1,190 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.withSlots = withSlots;
exports.createFactory = createFactory;
exports.getSlots = getSlots;
var tslib_1 = require("tslib");
var React = require("react");
var merge_styles_1 = require("@fluentui/merge-styles");
var utilities_1 = require("@fluentui/utilities");
var utilities_2 = require("./utilities");
/**
* This function is required for any module that uses slots.
*
* This function is a slot resolver that automatically evaluates slot functions to generate React elements.
* A byproduct of this resolver is that it removes slots from the React hierarchy by bypassing React.createElement.
*
* To use this function on a per-file basis, use the jsx directive targeting withSlots.
* This directive must be the FIRST LINE in the file to work correctly.
* Usage of this pragma also requires withSlots import statement.
*
* See React.createElement
*/
// Can't use typeof on React.createElement since it's overloaded. Approximate createElement's signature for now
// and widen as needed.
function withSlots(type, props) {
var children = [];
for (var _i = 2; _i < arguments.length; _i++) {
children[_i - 2] = arguments[_i];
}
var slotType = type;
if (slotType.isSlot) {
// Since we are bypassing createElement, use React.Children.toArray to make sure children are
// properly assigned keys.
// TODO: should this be mutating? does React mutate children subprop with createElement?
// TODO: will toArray clobber existing keys?
// TODO: React generates warnings because it doesn't detect hidden member _store that is set in createElement.
// Even children passed to createElement without keys don't generate this warning.
// Is there a better way to prevent slots from appearing in hierarchy? toArray doesn't address root issue.
children = React.Children.toArray(children);
// TODO: There is something weird going on here with children embedded in props vs. rest args.
// Comment out these lines to see. Make sure this function is doing the right things.
if (children.length === 0) {
return slotType(props);
}
return slotType(tslib_1.__assign(tslib_1.__assign({}, props), { children: children }));
}
else {
// TODO: Are there some cases where children should NOT be spread? Also, spreading reraises perf question.
// Children had to be spread to avoid breaking KeytipData in Toggle.view:
// react-dom.development.js:18931 Uncaught TypeError: children is not a function
// Without spread, function child is a child array of one element
// TODO: is there a reason this can't be:
// return React.createElement.apply(this, arguments);
return React.createElement.apply(React, tslib_1.__spreadArray([type, props], children, false));
}
}
/**
* This function creates factories that render ouput depending on the user ISlotProp props passed in.
* @param DefaultComponent - Base component to render when not overridden by user props.
* @param options - Factory options, including defaultProp value for shorthand prop mapping.
* @returns ISlotFactory function used for rendering slots.
*/
function createFactory(DefaultComponent, options) {
if (options === void 0) { options = {}; }
var _a = options.defaultProp, defaultProp = _a === void 0 ? 'children' : _a;
var result = function (componentProps, userProps, userSlotOptions, defaultStyles, theme) {
// If they passed in raw JSX, just return that.
if (React.isValidElement(userProps)) {
return userProps;
}
var flattenedUserProps = _translateShorthand(defaultProp, userProps);
var finalProps = _constructFinalProps(defaultStyles, theme, componentProps, flattenedUserProps);
if (userSlotOptions) {
if (userSlotOptions.component) {
// TODO: Remove cast if possible. This cast is needed because TS errors on the intrinsic portion of ReactType.
// return <userSlotOptions.component {...finalProps} />;
var UserComponent = userSlotOptions.component;
return React.createElement(UserComponent, tslib_1.__assign({}, finalProps));
}
if (userSlotOptions.render) {
return userSlotOptions.render(finalProps, DefaultComponent);
}
}
return React.createElement(DefaultComponent, tslib_1.__assign({}, finalProps));
};
return result;
}
/**
* Default factory for components without explicit factories.
*/
var defaultFactory = (0, utilities_1.memoizeFunction)(function (type) { return createFactory(type); });
/**
* This function generates slots that can be used in JSX given a definition of slots and their corresponding types.
* @param userProps - Props as pass to component.
* @param slots - Slot definition object defining the default slot component for each slot.
* @returns A set of created slots that components can render in JSX.
*/
function getSlots(userProps, slots) {
var result = {};
// userProps already has default props mixed in by createComponent. Recast here to gain typing for this function.
var mixedProps = userProps;
var _loop_1 = function (name_1) {
if (slots.hasOwnProperty(name_1)) {
// This closure method requires the use of withSlots to prevent unnecessary rerenders. This is because React
// detects each closure as a different component (since it is a new instance) from the previous one and then
// forces a rerender of the entire slot subtree. For now, the only way to avoid this is to use withSlots, which
// bypasses the call to React.createElement.
var slot = function (componentProps) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
if (args.length > 0) {
// If React.createElement is being incorrectly used with slots, there will be additional arguments.
// We can detect these additional arguments and error on their presence.
throw new Error('Any module using getSlots must use withSlots. Please see withSlots javadoc for more info.');
}
// TODO: having TS infer types here seems to cause infinite loop.
// use explicit types or casting to preserve typing if possible.
// TODO: this should be a lookup on TProps property instead of being TProps directly, which is probably
// causing the infinite loop
return _renderSlot(slots[name_1],
// TODO: this cast to any is hiding a relationship issue between the first two args
componentProps, mixedProps[name_1], mixedProps.slots && mixedProps.slots[name_1],
// _defaultStyles should always be present, but a check for existence is added to make view tests
// easier to use.
mixedProps._defaultStyles && mixedProps._defaultStyles[name_1], mixedProps.theme);
};
slot.isSlot = true;
result[name_1] = slot;
}
};
for (var name_1 in slots) {
_loop_1(name_1);
}
return result;
}
/**
* Helper function that translates shorthand as needed.
* @param defaultProp
* @param slotProps
*/
function _translateShorthand(defaultProp, slotProps) {
var _a;
var transformedProps;
if (typeof slotProps === 'string' || typeof slotProps === 'number' || typeof slotProps === 'boolean') {
transformedProps = (_a = {},
_a[defaultProp] = slotProps,
_a);
}
else {
transformedProps = slotProps;
}
return transformedProps;
}
/**
* Helper function that constructs final styles and props given a series of props ordered by increasing priority.
*/
function _constructFinalProps(defaultStyles, theme) {
var allProps = [];
for (var _i = 2; _i < arguments.length; _i++) {
allProps[_i - 2] = arguments[_i];
}
var finalProps = {};
var classNames = [];
for (var _a = 0, allProps_1 = allProps; _a < allProps_1.length; _a++) {
var props = allProps_1[_a];
classNames.push(props && props.className);
(0, utilities_2.assign)(finalProps, props);
}
finalProps.className = (0, merge_styles_1.mergeCss)([defaultStyles, classNames], { rtl: (0, utilities_1.getRTL)(theme) });
return finalProps;
}
/**
* Render a slot given component and user props. Uses component factory if available, otherwise falls back
* to default factory.
* @param ComponentType Factory component type.
* @param componentProps The properties passed into slot from within the component.
* @param userProps The user properties passed in from outside of the component.
*/
function _renderSlot(ComponentType, componentProps, userProps, slotOptions, defaultStyles, theme) {
if (ComponentType.create !== undefined) {
return ComponentType.create(componentProps, userProps, slotOptions, defaultStyles);
}
else {
// TODO: need to resolve typing / generic issues passing through memoizeFunction. for now, cast to 'unknown'
return defaultFactory(ComponentType)(componentProps, userProps, slotOptions, defaultStyles, theme);
}
}
//# sourceMappingURL=slots.js.map
File diff suppressed because one or more lines are too long
+2
View File
@@ -0,0 +1,2 @@
import { __assign } from 'tslib';
export declare const assign: typeof __assign;
+6
View File
@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.assign = void 0;
var tslib_1 = require("tslib");
exports.assign = tslib_1.__assign;
//# sourceMappingURL=utilities.js.map
@@ -0,0 +1 @@
{"version":3,"file":"utilities.js","sourceRoot":"../src/","sources":["utilities.ts"],"names":[],"mappings":";;;AAAA,+BAAiC;AACpB,QAAA,MAAM,GAAG,gBAAQ,CAAC","sourcesContent":["import { __assign } from 'tslib';\nexport const assign = __assign;\n"]}
+1
View File
@@ -0,0 +1 @@
export {};
+7
View File
@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// Do not modify this file; it is generated as part of publish.
// The checked in version is a placeholder only and will not be updated.
var set_version_1 = require("@fluentui/set-version");
(0, set_version_1.setVersion)('@fluentui/foundation-legacy', '8.6.5');
//# sourceMappingURL=version.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"version.js","sourceRoot":"../src/","sources":["version.ts"],"names":[],"mappings":";;AAAA,+DAA+D;AAC/D,wEAAwE;AACxE,qDAAmD;AACnD,IAAA,wBAAU,EAAC,6BAA6B,EAAE,OAAO,CAAC,CAAC","sourcesContent":["// Do not modify this file; it is generated as part of publish.\n// The checked in version is a placeholder only and will not be updated.\nimport { setVersion } from '@fluentui/set-version';\nsetVersion('@fluentui/foundation-legacy', '8.6.5');"]}
+120
View File
@@ -0,0 +1,120 @@
import * as React from 'react';
import { IStyle, IStyleSetBase, ITheme } from '@fluentui/style-utilities';
/**
* Helper interface for accessing user props children.
* @deprecated Use React.PropsWithChildren.
*/
export type IPropsWithChildren<TProps> = React.PropsWithChildren<TProps>;
/**
* Helper type defining style sections, one for each component slot.
*/
export type IComponentStyles<TSlots> = {
[key in keyof TSlots]?: IStyle;
};
/**
* Function declaration for component styles functions.
*/
export type IStylesFunction<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = (props: TViewProps, theme: ITheme, tokens: TTokens) => TStyleSet;
/**
* Composite type for component styles functions and objects.
*/
export type IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = IStylesFunction<TViewProps, TTokens, TStyleSet> | TStyleSet;
/**
* Tokens can be defined as an object, function, or an array of objects and functions.
*/
export type IToken<TViewProps, TTokens> = ITokenBase<TViewProps, TTokens> | ITokenBaseArray<TViewProps, TTokens>;
/**
* Function declaration for component token functions.
*/
export type ITokenFunction<TViewProps, TTokens> = (props: TViewProps, theme: ITheme) => IToken<TViewProps, TTokens>;
/**
* Composite type for component token functions and objects.
*/
export type ITokenFunctionOrObject<TViewProps, TTokens> = ITokenFunction<TViewProps, TTokens> | TTokens;
/**
* Composite base type that includes all possible resolutions of token functions in an array.
*/
export type ITokenBase<TViewProps, TTokens> = ITokenFunctionOrObject<TViewProps, TTokens> | false | null | undefined;
/**
* Composite token base array type allowing for token objects, functions, and function resolutions.
*/
export interface ITokenBaseArray<TViewProps, TTokens> extends Array<IToken<TViewProps, TTokens>> {
}
/**
* Optional props for styleable components. If these props are present, they will automatically be
* used by Foundation when applying theming and styling.
*/
export interface IStyleableComponentProps<TViewProps, TTokens, TStyleSet extends IStyleSetBase> {
className?: string;
styles?: IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet>;
theme?: ITheme;
tokens?: ITokenFunctionOrObject<TViewProps, TTokens>;
}
export type ICustomizationProps<TViewProps, TTokens, TStyleSet extends IStyleSetBase> = IStyleableComponentProps<TViewProps, TTokens, TStyleSet> & Required<Pick<IStyleableComponentProps<TViewProps, TTokens, TStyleSet>, 'theme'>>;
/**
* Defines the contract for state components.
*/
export type IStateComponentType<TComponentProps, TViewProps> = (props: Readonly<TComponentProps>) => TViewProps;
/**
* Defines the contract for view components.
*/
export type IViewComponent<TViewProps> = (props: React.PropsWithChildren<TViewProps>) => ReturnType<React.FunctionComponent>;
/**
* Component options used by foundation to tie elements together.
*
* * TComponentProps: A styleable props interface for the created component.
* * TTokens: The type for tokens props.
* * TStyleSet: The type for styles properties.
* * TViewProps: The props specific to the view, including processed properties outputted by optional state component.
* If state component is not provided, TComponentProps is the same as TViewProps.
* * TStatics: Static type for statics applied to created component object.
*/
export interface IComponentOptions<TComponentProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TStatics = {}> {
/**
* Display name to identify component in React hierarchy. This parameter is required for targeted component styling
* via theming.
*/
displayName?: string;
/**
* List of fields which can be customized.
*/
fields?: string[];
/**
* Styles prop to pass into component.
*/
styles?: IStylesFunctionOrObject<TViewProps, TTokens, TStyleSet>;
/**
* Optional state component that processes TComponentProps into TViewProps.
*/
state?: IStateComponentType<TComponentProps, TViewProps>;
/**
* Optional static object to assign to constructed component.
*/
statics?: TStatics;
/**
* Tokens prop to pass into component.
*/
tokens?: ITokenFunctionOrObject<TViewProps, TTokens>;
/**
* Default prop for which to map primitive values.
*/
factoryOptions?: IFactoryOptions<TComponentProps>;
}
/**
* Component helper that defines options as required for ease of use by component consumers.
*/
export type IComponent<TComponentProps, TTokens, TStyleSet extends IStyleSetBase, TViewProps = TComponentProps, TStatics = {}> = Required<IComponentOptions<TComponentProps, TTokens, TStyleSet, TViewProps, TStatics>> & {
/**
* Component that generates view output.
*/
view: IViewComponent<TViewProps>;
};
/**
* Factory options for creating component.
*/
export interface IFactoryOptions<TProps> {
/**
* Default prop for which to map primitive values.
*/
defaultProp?: keyof TProps | 'children';
}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=IComponent.js.map
File diff suppressed because one or more lines are too long
+15
View File
@@ -0,0 +1,15 @@
import * as React from 'react';
import type { JSXIntrinsicElement, JSXIntrinsicElementKeys } from '@fluentui/utilities';
import { ISlotProp } from './ISlots';
/**
* Generic slot definition allowing common HTML attributes. Applicable for most intrinsic slots. Please note certain
* elements such as buttons and inputs should make use of IHTMLElementSlot to provide access to specialized attributes
* of those elements.
*/
export type IHTMLSlot = ISlotProp<React.DetailedHTMLProps<React.HTMLAttributes<any>, any>>;
/**
* Optional HTML element typing to confine or expand HTML attribute usage for an intrinsic slot.
* Useful for slots that need to allow access to specialized HTML attributes, such as for buttons and inputs.
* Example usage: root?: IHTMLElementSlot\<'button'\>;
*/
export type IHTMLElementSlot<TElement extends JSXIntrinsicElementKeys> = ISlotProp<JSXIntrinsicElement<TElement>>;
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=IHTMLSlots.js.map

Some files were not shown because too many files have changed in this diff Show More