Socket
Socket
Sign inDemoInstall

@uifabric/foundation

Package Overview
Dependencies
Maintainers
3
Versions
196
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@uifabric/foundation - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

14

CHANGELOG.json

@@ -5,2 +5,16 @@ {

{
"version": "0.2.0",
"tag": "@uifabric/foundation_v0.2.0",
"date": "Wed, 01 Aug 2018 10:25:51 GMT",
"comments": {
"minor": [
{
"author": "Jason Gore <jagore@microsoft.com>",
"commit": "a6e83781f6720a39c24f6ee58f9ad27e11d4fde2",
"comment": "Major improvements to typing and functionality."
}
]
}
},
{
"version": "0.1.0",

@@ -7,0 +21,0 @@ "tag": "@uifabric/foundation_v0.1.0",

9

CHANGELOG.md
# Change Log - @uifabric/foundation
This log was last generated on Mon, 23 Jul 2018 10:28:08 GMT and should not be manually modified.
This log was last generated on Wed, 01 Aug 2018 10:25:51 GMT and should not be manually modified.
## 0.2.0
Wed, 01 Aug 2018 10:25:51 GMT
### Minor changes
- Major improvements to typing and functionality.
## 0.1.0

@@ -6,0 +13,0 @@ Mon, 23 Jul 2018 10:28:08 GMT

import * as React from 'react';
export interface IThemeProps<TTheme> {
/**
* Props contract for themed components.
*/
export interface IThemedComponent<TTheme> {
theme: TTheme;
}
export declare type IStyledProps<TProps, TTheme> = TProps & IThemeProps<TTheme>;
export declare type IStyleFunction<TStylesProps extends IThemeProps<TTheme>, TStyles, TTheme> = (props: TStylesProps) => TStyles;
export declare type IStateProps<TProps> = TProps & {
view: (props: TProps) => JSX.Element;
/**
* Styles can be a function or an object taking in TViewProps for processing.
*/
export declare type IStyleFunction<TViewProps, TStyleSet> = (props: TViewProps) => Partial<TStyleSet>;
export declare type IStylesProp<TViewProps, TStyleSet> = IStyleFunction<TViewProps, TStyleSet> | Partial<TStyleSet>;
/**
* Foundation interface for styleable components.
*/
export interface IStyleableComponent<TProps, TStyleSet, TTheme> {
styles?: IStylesProp<TProps, TStyleSet>;
theme?: TTheme;
}
export declare type IStyleableComponentProps<TProps, TStyleSet, TTheme> = TProps & IStyleableComponent<TProps, TStyleSet, TTheme>;
/**
* Enforce props contract on state components, including the view prop and its shape.
*/
export declare type IStateComponentProps<TComponentProps, TViewProps> = TComponentProps & {
renderView: (props: TViewProps) => JSX.Element;
};
export declare type IStylesProp<TProps extends IThemeProps<TTheme>, TStyles, TTheme> = IStyleFunction<TProps, TStyles, TTheme> | TStyles;
export declare type IViewProps<TProps, TStylesSet> = TProps & {
styles: TStylesSet;
/**
* Imposed state component props contract with styling props as well as a renderView
* prop that the StateComponent should make use of in its render output (and should be its only render output.)
*/
export declare type IStateComponent<TComponentProps, TViewProps extends IViewComponent<TViewProps, TProcessedStyleSet>, TProcessedStyleSet> = React.ComponentType<IStateComponentProps<TComponentProps, TViewProps>>;
/**
* The extended view interface provided to views, including the component's children
* and processed style.
*/
export declare type IViewComponent<TViewProps, TProcessedStyleSet> = React.Props<TViewProps> & {
classNames: TProcessedStyleSet;
};
export interface IAugmentations<TUserProps extends IThemeProps<TTheme>, TStyles, TStyleSet, TTheme> {
[scope: string]: IComponentOptions<TUserProps, TStyles, TStyleSet, TTheme>;
export declare type IViewComponentProps<TViewProps, TProcessedStyledSet> = TViewProps & IViewComponent<TViewProps, TProcessedStyledSet>;
/**
* Component options used by foundation to tie elements together.
* @param {IComponentOptions} displayName Display name to identify component in React hierarchy.
* @param {IStylesProp<TViewProps, TStyleSet>} styles Styles prop to pass into component.
* @param {IStateComponent} view Functional React view component.
* @param {TStatics} statics Optional static object to pass into constructed component.
*/
export interface IComponentOptions<TViewProps, TStyleSet, TProcessedStyledSet, TTheme, TStatics> {
displayName: string;
styles: IStylesProp<TViewProps, TStyleSet>;
view: (props: IViewComponentProps<TViewProps, TProcessedStyledSet>) => JSX.Element;
statics?: TStatics;
}
export interface IComponentOptions<TUserProps, TStyles, TStyleSet, TTheme> {
scope: string;
state?: React.ComponentType<IStateProps<TUserProps>>;
styles: IStylesProp<TUserProps & IThemeProps<TTheme>, TStyles, TTheme>;
view: React.ComponentType<IViewProps<TUserProps, TStyleSet>>;
}
export interface IStylingProviders<TStyles, TStyleSet, TTheme> {
/**
* Providers used by createComponent to process and apply styling.
*/
export interface IStylingProviders<TStyleSet, TProcessedStyleSet, TTheme> {
getTheme: () => TTheme;
mergeStyleSets: (styles: TStyles) => TStyleSet;
mergeStyleSets: (...styles: (Partial<TStyleSet> | undefined)[]) => TProcessedStyleSet;
}
export declare function createComponentWithProviders<TProps, TStyles, TStyleSet, TTheme>(options: IComponentOptions<TProps, TStyles, TStyleSet, TTheme>, providers: IStylingProviders<TStyles, TStyleSet, TTheme>): React.StatelessComponent<TProps>;
export declare function augmentComponent<TProps, TStyles, TStyleSet, TTheme>(options: IComponentOptions<TProps, TStyles, TStyleSet, TTheme>): void;
/**
* 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 not provided, created component is essentially a functional stateless component.
*
* TComponentProps: A styleable props interface for the created component.
* 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.
* TStyleSet: The type for styles properties.
* TProcessedStyleSet: The type provided by mergeStyleSets provider after processing TStyleSet and provided to views.
* TTheme: The type for theme properties as well as the getTheme provider.
*
* @param {IComponentOptions} options
* @param {IStylingProviders} providers
* @param {IStateComponent} StateComponent
*
* If your package has common types for any of the type arguments, such as TTheme and TProcessedStyleSet, it is strongly
* recommended to make an interface file for your package that reduces the number of types individual components need
* to provide. For example:
* @example
* export type IViewProps<TProps, TStyleSet extends IStyleSet<TStyleSet>> = IViewProps<TProps, IProcessedStyleSet<TStyleSet>>;
* export type IStyleableComponent<TProps, TStyleSet> = IStyleableComponent<TProps, TStyleSet, ITheme>;
*
*/
export declare function createComponentWithState<TComponentProps extends IStyleableComponent<TViewProps, TStyleSet, TTheme>, TViewProps, TStyleSet, TProcessedStyleSet, TTheme, TStatics>(options: IComponentOptions<TViewProps, TStyleSet, TProcessedStyleSet, TTheme, TStatics>, providers: IStylingProviders<TStyleSet, TProcessedStyleSet, TTheme>, StateComponent: IStateComponent<TComponentProps, TViewProps & IViewComponent<TViewProps, TProcessedStyleSet>, TProcessedStyleSet>): React.StatelessComponent<TComponentProps> & TStatics;
/**
* This is essentially the same as createComponentWithState. The primary differences are that TComponentProps and TViewProps
* are equivalent and there is no state component argument.
*
* @see {@link createComponentWithState} for more information.
*/
export declare function createComponent<TComponentProps extends IStyleableComponent<TComponentProps, TStyleSet, TTheme>, TStyleSet, TProcessedStyleSet, TTheme, TStatics>(options: IComponentOptions<TComponentProps, TStyleSet, TProcessedStyleSet, TTheme, TStatics>, providers: IStylingProviders<TStyleSet, TProcessedStyleSet, TTheme>): React.StatelessComponent<TComponentProps> & TStatics;

116

lib-amd/createComponent.js
define(["require", "exports", "tslib", "react"], function (require, exports, tslib_1, React) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// TODO: what is our augmentation story and uses cases?
// TODO: if merged, figure out typing. could maybe provide a template accessor to prevent 'any' type arg
// tslint:disable-next-line:no-any
var _augmentations = {};
// Helper function to tie them together.
function createComponentWithProviders(options, providers) {
/**
* Evaluate styles based on type to return consistent TStyleSet.
*/
function evaluateStyle(props, styles) {
if (typeof styles === 'function') {
return styles(props);
}
return styles;
}
/**
* 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 not provided, created component is essentially a functional stateless component.
*
* TComponentProps: A styleable props interface for the created component.
* 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.
* TStyleSet: The type for styles properties.
* TProcessedStyleSet: The type provided by mergeStyleSets provider after processing TStyleSet and provided to views.
* TTheme: The type for theme properties as well as the getTheme provider.
*
* @param {IComponentOptions} options
* @param {IStylingProviders} providers
* @param {IStateComponent} StateComponent
*
* If your package has common types for any of the type arguments, such as TTheme and TProcessedStyleSet, it is strongly
* recommended to make an interface file for your package that reduces the number of types individual components need
* to provide. For example:
* @example
* export type IViewProps<TProps, TStyleSet extends IStyleSet<TStyleSet>> = IViewProps<TProps, IProcessedStyleSet<TStyleSet>>;
* export type IStyleableComponent<TProps, TStyleSet> = IStyleableComponent<TProps, TStyleSet, ITheme>;
*
*/
// TODO: Combine these functions into one once conditional types (TS 2.8) can be used. This will allow us to define
// TComponentProps as being the same as TViewProps when StateComponent is not provided.
// TODO: use theming prop when provided and reconcile with global theme
function createComponentWithState(options, providers, StateComponent) {
var result = function (userProps) {
var augmented = _augmentations[options.scope] || {};
var StateComponent = augmented.state || options.state;
var ViewComponent = augmented.view || options.view;
var getStyles = augmented.styles || options.styles;
var theme = providers.getTheme();
ViewComponent.displayName = ViewComponent.displayName || options.scope + 'View';
var content = function (processedProps) {
var styles = undefined;
if (typeof getStyles === 'function') {
// TODO: TS issues with spreading generic (even if that generic extends object)
// https://github.com/Microsoft/TypeScript/issues/13557
// workaround: Object.assign usage
// styles = (getStyles as IStyleFunction<TTheme, TProps & IThemeProps<TTheme>, TStyles>)({ theme, ...(processedProps as {}) });
var mergedProps = Object.assign({}, { theme: theme }, userProps);
styles = getStyles(mergedProps);
}
else {
styles = getStyles;
}
return React.createElement(ViewComponent, tslib_1.__assign({}, processedProps, { styles: providers.mergeStyleSets(styles) }));
// The approach here is to allow state components to provide only the props they care about, automatically
// merging user props and processed props together. This ensures all props are passed properly to view,
// including children and styles.
var styles = processedProps.styles || userProps.styles;
var themedProps = Object.assign({}, { theme: theme }, userProps, processedProps);
var viewProps = Object.assign({}, userProps, processedProps, {
classNames: providers.mergeStyleSets(evaluateStyle(themedProps, options.styles), evaluateStyle(themedProps, styles))
});
// TODO: consider rendering view as JSX component with display name in debug mode to aid in debugging
return options.view(viewProps);
};
return !!StateComponent ? React.createElement(StateComponent, tslib_1.__assign({}, userProps, { view: content })) : content(userProps);
return React.createElement(StateComponent, tslib_1.__assign({}, userProps, { renderView: content }));
};
result.displayName = options.scope;
result.displayName = options.displayName;
Object.assign(result, options.statics);
// Later versions of TypeSript should allow us to merge objects in a type safe way and avoid this cast.
return result;
}
exports.createComponentWithProviders = createComponentWithProviders;
// Helper function to augment existing components that have been created.
function augmentComponent(options) {
_augmentations[options.scope] = tslib_1.__assign({}, _augmentations[options.scope], options);
exports.createComponentWithState = createComponentWithState;
/**
* This is essentially the same as createComponentWithState. The primary differences are that TComponentProps and TViewProps
* are equivalent and there is no state component argument.
*
* @see {@link createComponentWithState} for more information.
*/
function createComponent(options, providers) {
var result = function (userProps) {
var theme = providers.getTheme();
var content = function (processedProps) {
var styles = processedProps.styles;
var themedProps = Object.assign({}, { theme: theme }, processedProps);
var viewProps = Object.assign({}, processedProps, {
classNames: providers.mergeStyleSets(evaluateStyle(themedProps, options.styles), evaluateStyle(themedProps, styles))
});
// TODO: consider rendering view as JSX component with display name in debug mode to aid in debugging
return options.view(viewProps);
};
return content(userProps);
};
result.displayName = options.displayName;
Object.assign(result, options.statics);
// Later versions of TypeSript should allow us to merge objects in a type safe way and avoid this cast.
return result;
}
exports.augmentComponent = augmentComponent;
exports.createComponent = createComponent;
});
//# sourceMappingURL=createComponent.js.map
import * as React from 'react';
export interface IThemeProps<TTheme> {
/**
* Props contract for themed components.
*/
export interface IThemedComponent<TTheme> {
theme: TTheme;
}
export declare type IStyledProps<TProps, TTheme> = TProps & IThemeProps<TTheme>;
export declare type IStyleFunction<TStylesProps extends IThemeProps<TTheme>, TStyles, TTheme> = (props: TStylesProps) => TStyles;
export declare type IStateProps<TProps> = TProps & {
view: (props: TProps) => JSX.Element;
/**
* Styles can be a function or an object taking in TViewProps for processing.
*/
export declare type IStyleFunction<TViewProps, TStyleSet> = (props: TViewProps) => Partial<TStyleSet>;
export declare type IStylesProp<TViewProps, TStyleSet> = IStyleFunction<TViewProps, TStyleSet> | Partial<TStyleSet>;
/**
* Foundation interface for styleable components.
*/
export interface IStyleableComponent<TProps, TStyleSet, TTheme> {
styles?: IStylesProp<TProps, TStyleSet>;
theme?: TTheme;
}
export declare type IStyleableComponentProps<TProps, TStyleSet, TTheme> = TProps & IStyleableComponent<TProps, TStyleSet, TTheme>;
/**
* Enforce props contract on state components, including the view prop and its shape.
*/
export declare type IStateComponentProps<TComponentProps, TViewProps> = TComponentProps & {
renderView: (props: TViewProps) => JSX.Element;
};
export declare type IStylesProp<TProps extends IThemeProps<TTheme>, TStyles, TTheme> = IStyleFunction<TProps, TStyles, TTheme> | TStyles;
export declare type IViewProps<TProps, TStylesSet> = TProps & {
styles: TStylesSet;
/**
* Imposed state component props contract with styling props as well as a renderView
* prop that the StateComponent should make use of in its render output (and should be its only render output.)
*/
export declare type IStateComponent<TComponentProps, TViewProps extends IViewComponent<TViewProps, TProcessedStyleSet>, TProcessedStyleSet> = React.ComponentType<IStateComponentProps<TComponentProps, TViewProps>>;
/**
* The extended view interface provided to views, including the component's children
* and processed style.
*/
export declare type IViewComponent<TViewProps, TProcessedStyleSet> = React.Props<TViewProps> & {
classNames: TProcessedStyleSet;
};
export interface IAugmentations<TUserProps extends IThemeProps<TTheme>, TStyles, TStyleSet, TTheme> {
[scope: string]: IComponentOptions<TUserProps, TStyles, TStyleSet, TTheme>;
export declare type IViewComponentProps<TViewProps, TProcessedStyledSet> = TViewProps & IViewComponent<TViewProps, TProcessedStyledSet>;
/**
* Component options used by foundation to tie elements together.
* @param {IComponentOptions} displayName Display name to identify component in React hierarchy.
* @param {IStylesProp<TViewProps, TStyleSet>} styles Styles prop to pass into component.
* @param {IStateComponent} view Functional React view component.
* @param {TStatics} statics Optional static object to pass into constructed component.
*/
export interface IComponentOptions<TViewProps, TStyleSet, TProcessedStyledSet, TTheme, TStatics> {
displayName: string;
styles: IStylesProp<TViewProps, TStyleSet>;
view: (props: IViewComponentProps<TViewProps, TProcessedStyledSet>) => JSX.Element;
statics?: TStatics;
}
export interface IComponentOptions<TUserProps, TStyles, TStyleSet, TTheme> {
scope: string;
state?: React.ComponentType<IStateProps<TUserProps>>;
styles: IStylesProp<TUserProps & IThemeProps<TTheme>, TStyles, TTheme>;
view: React.ComponentType<IViewProps<TUserProps, TStyleSet>>;
}
export interface IStylingProviders<TStyles, TStyleSet, TTheme> {
/**
* Providers used by createComponent to process and apply styling.
*/
export interface IStylingProviders<TStyleSet, TProcessedStyleSet, TTheme> {
getTheme: () => TTheme;
mergeStyleSets: (styles: TStyles) => TStyleSet;
mergeStyleSets: (...styles: (Partial<TStyleSet> | undefined)[]) => TProcessedStyleSet;
}
export declare function createComponentWithProviders<TProps, TStyles, TStyleSet, TTheme>(options: IComponentOptions<TProps, TStyles, TStyleSet, TTheme>, providers: IStylingProviders<TStyles, TStyleSet, TTheme>): React.StatelessComponent<TProps>;
export declare function augmentComponent<TProps, TStyles, TStyleSet, TTheme>(options: IComponentOptions<TProps, TStyles, TStyleSet, TTheme>): void;
/**
* 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 not provided, created component is essentially a functional stateless component.
*
* TComponentProps: A styleable props interface for the created component.
* 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.
* TStyleSet: The type for styles properties.
* TProcessedStyleSet: The type provided by mergeStyleSets provider after processing TStyleSet and provided to views.
* TTheme: The type for theme properties as well as the getTheme provider.
*
* @param {IComponentOptions} options
* @param {IStylingProviders} providers
* @param {IStateComponent} StateComponent
*
* If your package has common types for any of the type arguments, such as TTheme and TProcessedStyleSet, it is strongly
* recommended to make an interface file for your package that reduces the number of types individual components need
* to provide. For example:
* @example
* export type IViewProps<TProps, TStyleSet extends IStyleSet<TStyleSet>> = IViewProps<TProps, IProcessedStyleSet<TStyleSet>>;
* export type IStyleableComponent<TProps, TStyleSet> = IStyleableComponent<TProps, TStyleSet, ITheme>;
*
*/
export declare function createComponentWithState<TComponentProps extends IStyleableComponent<TViewProps, TStyleSet, TTheme>, TViewProps, TStyleSet, TProcessedStyleSet, TTheme, TStatics>(options: IComponentOptions<TViewProps, TStyleSet, TProcessedStyleSet, TTheme, TStatics>, providers: IStylingProviders<TStyleSet, TProcessedStyleSet, TTheme>, StateComponent: IStateComponent<TComponentProps, TViewProps & IViewComponent<TViewProps, TProcessedStyleSet>, TProcessedStyleSet>): React.StatelessComponent<TComponentProps> & TStatics;
/**
* This is essentially the same as createComponentWithState. The primary differences are that TComponentProps and TViewProps
* are equivalent and there is no state component argument.
*
* @see {@link createComponentWithState} for more information.
*/
export declare function createComponent<TComponentProps extends IStyleableComponent<TComponentProps, TStyleSet, TTheme>, TStyleSet, TProcessedStyleSet, TTheme, TStatics>(options: IComponentOptions<TComponentProps, TStyleSet, TProcessedStyleSet, TTheme, TStatics>, providers: IStylingProviders<TStyleSet, TProcessedStyleSet, TTheme>): React.StatelessComponent<TComponentProps> & TStatics;

@@ -5,41 +5,95 @@ "use strict";

var React = require("react");
// TODO: what is our augmentation story and uses cases?
// TODO: if merged, figure out typing. could maybe provide a template accessor to prevent 'any' type arg
// tslint:disable-next-line:no-any
var _augmentations = {};
// Helper function to tie them together.
function createComponentWithProviders(options, providers) {
/**
* Evaluate styles based on type to return consistent TStyleSet.
*/
function evaluateStyle(props, styles) {
if (typeof styles === 'function') {
return styles(props);
}
return styles;
}
/**
* 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 not provided, created component is essentially a functional stateless component.
*
* TComponentProps: A styleable props interface for the created component.
* 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.
* TStyleSet: The type for styles properties.
* TProcessedStyleSet: The type provided by mergeStyleSets provider after processing TStyleSet and provided to views.
* TTheme: The type for theme properties as well as the getTheme provider.
*
* @param {IComponentOptions} options
* @param {IStylingProviders} providers
* @param {IStateComponent} StateComponent
*
* If your package has common types for any of the type arguments, such as TTheme and TProcessedStyleSet, it is strongly
* recommended to make an interface file for your package that reduces the number of types individual components need
* to provide. For example:
* @example
* export type IViewProps<TProps, TStyleSet extends IStyleSet<TStyleSet>> = IViewProps<TProps, IProcessedStyleSet<TStyleSet>>;
* export type IStyleableComponent<TProps, TStyleSet> = IStyleableComponent<TProps, TStyleSet, ITheme>;
*
*/
// TODO: Combine these functions into one once conditional types (TS 2.8) can be used. This will allow us to define
// TComponentProps as being the same as TViewProps when StateComponent is not provided.
// TODO: use theming prop when provided and reconcile with global theme
function createComponentWithState(options, providers, StateComponent) {
var result = function (userProps) {
var augmented = _augmentations[options.scope] || {};
var StateComponent = augmented.state || options.state;
var ViewComponent = augmented.view || options.view;
var getStyles = augmented.styles || options.styles;
var theme = providers.getTheme();
ViewComponent.displayName = ViewComponent.displayName || options.scope + 'View';
var content = function (processedProps) {
var styles = undefined;
if (typeof getStyles === 'function') {
// TODO: TS issues with spreading generic (even if that generic extends object)
// https://github.com/Microsoft/TypeScript/issues/13557
// workaround: Object.assign usage
// styles = (getStyles as IStyleFunction<TTheme, TProps & IThemeProps<TTheme>, TStyles>)({ theme, ...(processedProps as {}) });
var mergedProps = Object.assign({}, { theme: theme }, userProps);
styles = getStyles(mergedProps);
}
else {
styles = getStyles;
}
return React.createElement(ViewComponent, tslib_1.__assign({}, processedProps, { styles: providers.mergeStyleSets(styles) }));
// The approach here is to allow state components to provide only the props they care about, automatically
// merging user props and processed props together. This ensures all props are passed properly to view,
// including children and styles.
var styles = processedProps.styles || userProps.styles;
var themedProps = Object.assign({}, { theme: theme }, userProps, processedProps);
var viewProps = Object.assign({}, userProps, processedProps, {
classNames: providers.mergeStyleSets(evaluateStyle(themedProps, options.styles), evaluateStyle(themedProps, styles))
});
// TODO: consider rendering view as JSX component with display name in debug mode to aid in debugging
return options.view(viewProps);
};
return !!StateComponent ? React.createElement(StateComponent, tslib_1.__assign({}, userProps, { view: content })) : content(userProps);
return React.createElement(StateComponent, tslib_1.__assign({}, userProps, { renderView: content }));
};
result.displayName = options.scope;
result.displayName = options.displayName;
Object.assign(result, options.statics);
// Later versions of TypeSript should allow us to merge objects in a type safe way and avoid this cast.
return result;
}
exports.createComponentWithProviders = createComponentWithProviders;
// Helper function to augment existing components that have been created.
function augmentComponent(options) {
_augmentations[options.scope] = tslib_1.__assign({}, _augmentations[options.scope], options);
exports.createComponentWithState = createComponentWithState;
/**
* This is essentially the same as createComponentWithState. The primary differences are that TComponentProps and TViewProps
* are equivalent and there is no state component argument.
*
* @see {@link createComponentWithState} for more information.
*/
function createComponent(options, providers) {
var result = function (userProps) {
var theme = providers.getTheme();
var content = function (processedProps) {
var styles = processedProps.styles;
var themedProps = Object.assign({}, { theme: theme }, processedProps);
var viewProps = Object.assign({}, processedProps, {
classNames: providers.mergeStyleSets(evaluateStyle(themedProps, options.styles), evaluateStyle(themedProps, styles))
});
// TODO: consider rendering view as JSX component with display name in debug mode to aid in debugging
return options.view(viewProps);
};
return content(userProps);
};
result.displayName = options.displayName;
Object.assign(result, options.statics);
// Later versions of TypeSript should allow us to merge objects in a type safe way and avoid this cast.
return result;
}
exports.augmentComponent = augmentComponent;
exports.createComponent = createComponent;
//# sourceMappingURL=createComponent.js.map
import * as React from 'react';
export interface IThemeProps<TTheme> {
/**
* Props contract for themed components.
*/
export interface IThemedComponent<TTheme> {
theme: TTheme;
}
export declare type IStyledProps<TProps, TTheme> = TProps & IThemeProps<TTheme>;
export declare type IStyleFunction<TStylesProps extends IThemeProps<TTheme>, TStyles, TTheme> = (props: TStylesProps) => TStyles;
export declare type IStateProps<TProps> = TProps & {
view: (props: TProps) => JSX.Element;
/**
* Styles can be a function or an object taking in TViewProps for processing.
*/
export declare type IStyleFunction<TViewProps, TStyleSet> = (props: TViewProps) => Partial<TStyleSet>;
export declare type IStylesProp<TViewProps, TStyleSet> = IStyleFunction<TViewProps, TStyleSet> | Partial<TStyleSet>;
/**
* Foundation interface for styleable components.
*/
export interface IStyleableComponent<TProps, TStyleSet, TTheme> {
styles?: IStylesProp<TProps, TStyleSet>;
theme?: TTheme;
}
export declare type IStyleableComponentProps<TProps, TStyleSet, TTheme> = TProps & IStyleableComponent<TProps, TStyleSet, TTheme>;
/**
* Enforce props contract on state components, including the view prop and its shape.
*/
export declare type IStateComponentProps<TComponentProps, TViewProps> = TComponentProps & {
renderView: (props: TViewProps) => JSX.Element;
};
export declare type IStylesProp<TProps extends IThemeProps<TTheme>, TStyles, TTheme> = IStyleFunction<TProps, TStyles, TTheme> | TStyles;
export declare type IViewProps<TProps, TStylesSet> = TProps & {
styles: TStylesSet;
/**
* Imposed state component props contract with styling props as well as a renderView
* prop that the StateComponent should make use of in its render output (and should be its only render output.)
*/
export declare type IStateComponent<TComponentProps, TViewProps extends IViewComponent<TViewProps, TProcessedStyleSet>, TProcessedStyleSet> = React.ComponentType<IStateComponentProps<TComponentProps, TViewProps>>;
/**
* The extended view interface provided to views, including the component's children
* and processed style.
*/
export declare type IViewComponent<TViewProps, TProcessedStyleSet> = React.Props<TViewProps> & {
classNames: TProcessedStyleSet;
};
export interface IAugmentations<TUserProps extends IThemeProps<TTheme>, TStyles, TStyleSet, TTheme> {
[scope: string]: IComponentOptions<TUserProps, TStyles, TStyleSet, TTheme>;
export declare type IViewComponentProps<TViewProps, TProcessedStyledSet> = TViewProps & IViewComponent<TViewProps, TProcessedStyledSet>;
/**
* Component options used by foundation to tie elements together.
* @param {IComponentOptions} displayName Display name to identify component in React hierarchy.
* @param {IStylesProp<TViewProps, TStyleSet>} styles Styles prop to pass into component.
* @param {IStateComponent} view Functional React view component.
* @param {TStatics} statics Optional static object to pass into constructed component.
*/
export interface IComponentOptions<TViewProps, TStyleSet, TProcessedStyledSet, TTheme, TStatics> {
displayName: string;
styles: IStylesProp<TViewProps, TStyleSet>;
view: (props: IViewComponentProps<TViewProps, TProcessedStyledSet>) => JSX.Element;
statics?: TStatics;
}
export interface IComponentOptions<TUserProps, TStyles, TStyleSet, TTheme> {
scope: string;
state?: React.ComponentType<IStateProps<TUserProps>>;
styles: IStylesProp<TUserProps & IThemeProps<TTheme>, TStyles, TTheme>;
view: React.ComponentType<IViewProps<TUserProps, TStyleSet>>;
}
export interface IStylingProviders<TStyles, TStyleSet, TTheme> {
/**
* Providers used by createComponent to process and apply styling.
*/
export interface IStylingProviders<TStyleSet, TProcessedStyleSet, TTheme> {
getTheme: () => TTheme;
mergeStyleSets: (styles: TStyles) => TStyleSet;
mergeStyleSets: (...styles: (Partial<TStyleSet> | undefined)[]) => TProcessedStyleSet;
}
export declare function createComponentWithProviders<TProps, TStyles, TStyleSet, TTheme>(options: IComponentOptions<TProps, TStyles, TStyleSet, TTheme>, providers: IStylingProviders<TStyles, TStyleSet, TTheme>): React.StatelessComponent<TProps>;
export declare function augmentComponent<TProps, TStyles, TStyleSet, TTheme>(options: IComponentOptions<TProps, TStyles, TStyleSet, TTheme>): void;
/**
* 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 not provided, created component is essentially a functional stateless component.
*
* TComponentProps: A styleable props interface for the created component.
* 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.
* TStyleSet: The type for styles properties.
* TProcessedStyleSet: The type provided by mergeStyleSets provider after processing TStyleSet and provided to views.
* TTheme: The type for theme properties as well as the getTheme provider.
*
* @param {IComponentOptions} options
* @param {IStylingProviders} providers
* @param {IStateComponent} StateComponent
*
* If your package has common types for any of the type arguments, such as TTheme and TProcessedStyleSet, it is strongly
* recommended to make an interface file for your package that reduces the number of types individual components need
* to provide. For example:
* @example
* export type IViewProps<TProps, TStyleSet extends IStyleSet<TStyleSet>> = IViewProps<TProps, IProcessedStyleSet<TStyleSet>>;
* export type IStyleableComponent<TProps, TStyleSet> = IStyleableComponent<TProps, TStyleSet, ITheme>;
*
*/
export declare function createComponentWithState<TComponentProps extends IStyleableComponent<TViewProps, TStyleSet, TTheme>, TViewProps, TStyleSet, TProcessedStyleSet, TTheme, TStatics>(options: IComponentOptions<TViewProps, TStyleSet, TProcessedStyleSet, TTheme, TStatics>, providers: IStylingProviders<TStyleSet, TProcessedStyleSet, TTheme>, StateComponent: IStateComponent<TComponentProps, TViewProps & IViewComponent<TViewProps, TProcessedStyleSet>, TProcessedStyleSet>): React.StatelessComponent<TComponentProps> & TStatics;
/**
* This is essentially the same as createComponentWithState. The primary differences are that TComponentProps and TViewProps
* are equivalent and there is no state component argument.
*
* @see {@link createComponentWithState} for more information.
*/
export declare function createComponent<TComponentProps extends IStyleableComponent<TComponentProps, TStyleSet, TTheme>, TStyleSet, TProcessedStyleSet, TTheme, TStatics>(options: IComponentOptions<TComponentProps, TStyleSet, TProcessedStyleSet, TTheme, TStatics>, providers: IStylingProviders<TStyleSet, TProcessedStyleSet, TTheme>): React.StatelessComponent<TComponentProps> & TStatics;
import * as tslib_1 from "tslib";
import * as React from 'react';
// TODO: what is our augmentation story and uses cases?
// TODO: if merged, figure out typing. could maybe provide a template accessor to prevent 'any' type arg
// tslint:disable-next-line:no-any
var _augmentations = {};
// Helper function to tie them together.
export function createComponentWithProviders(options, providers) {
/**
* Evaluate styles based on type to return consistent TStyleSet.
*/
function evaluateStyle(props, styles) {
if (typeof styles === 'function') {
return styles(props);
}
return styles;
}
/**
* 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 not provided, created component is essentially a functional stateless component.
*
* TComponentProps: A styleable props interface for the created component.
* 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.
* TStyleSet: The type for styles properties.
* TProcessedStyleSet: The type provided by mergeStyleSets provider after processing TStyleSet and provided to views.
* TTheme: The type for theme properties as well as the getTheme provider.
*
* @param {IComponentOptions} options
* @param {IStylingProviders} providers
* @param {IStateComponent} StateComponent
*
* If your package has common types for any of the type arguments, such as TTheme and TProcessedStyleSet, it is strongly
* recommended to make an interface file for your package that reduces the number of types individual components need
* to provide. For example:
* @example
* export type IViewProps<TProps, TStyleSet extends IStyleSet<TStyleSet>> = IViewProps<TProps, IProcessedStyleSet<TStyleSet>>;
* export type IStyleableComponent<TProps, TStyleSet> = IStyleableComponent<TProps, TStyleSet, ITheme>;
*
*/
// TODO: Combine these functions into one once conditional types (TS 2.8) can be used. This will allow us to define
// TComponentProps as being the same as TViewProps when StateComponent is not provided.
// TODO: use theming prop when provided and reconcile with global theme
export function createComponentWithState(options, providers, StateComponent) {
var result = function (userProps) {
var augmented = _augmentations[options.scope] || {};
var StateComponent = augmented.state || options.state;
var ViewComponent = augmented.view || options.view;
var getStyles = augmented.styles || options.styles;
var theme = providers.getTheme();
ViewComponent.displayName = ViewComponent.displayName || options.scope + 'View';
var content = function (processedProps) {
var styles = undefined;
if (typeof getStyles === 'function') {
// TODO: TS issues with spreading generic (even if that generic extends object)
// https://github.com/Microsoft/TypeScript/issues/13557
// workaround: Object.assign usage
// styles = (getStyles as IStyleFunction<TTheme, TProps & IThemeProps<TTheme>, TStyles>)({ theme, ...(processedProps as {}) });
var mergedProps = Object.assign({}, { theme: theme }, userProps);
styles = getStyles(mergedProps);
}
else {
styles = getStyles;
}
return React.createElement(ViewComponent, tslib_1.__assign({}, processedProps, { styles: providers.mergeStyleSets(styles) }));
// The approach here is to allow state components to provide only the props they care about, automatically
// merging user props and processed props together. This ensures all props are passed properly to view,
// including children and styles.
var styles = processedProps.styles || userProps.styles;
var themedProps = Object.assign({}, { theme: theme }, userProps, processedProps);
var viewProps = Object.assign({}, userProps, processedProps, {
classNames: providers.mergeStyleSets(evaluateStyle(themedProps, options.styles), evaluateStyle(themedProps, styles))
});
// TODO: consider rendering view as JSX component with display name in debug mode to aid in debugging
return options.view(viewProps);
};
return !!StateComponent ? React.createElement(StateComponent, tslib_1.__assign({}, userProps, { view: content })) : content(userProps);
return React.createElement(StateComponent, tslib_1.__assign({}, userProps, { renderView: content }));
};
result.displayName = options.scope;
result.displayName = options.displayName;
Object.assign(result, options.statics);
// Later versions of TypeSript should allow us to merge objects in a type safe way and avoid this cast.
return result;
}
// Helper function to augment existing components that have been created.
export function augmentComponent(options) {
_augmentations[options.scope] = tslib_1.__assign({}, _augmentations[options.scope], options);
/**
* This is essentially the same as createComponentWithState. The primary differences are that TComponentProps and TViewProps
* are equivalent and there is no state component argument.
*
* @see {@link createComponentWithState} for more information.
*/
export function createComponent(options, providers) {
var result = function (userProps) {
var theme = providers.getTheme();
var content = function (processedProps) {
var styles = processedProps.styles;
var themedProps = Object.assign({}, { theme: theme }, processedProps);
var viewProps = Object.assign({}, processedProps, {
classNames: providers.mergeStyleSets(evaluateStyle(themedProps, options.styles), evaluateStyle(themedProps, styles))
});
// TODO: consider rendering view as JSX component with display name in debug mode to aid in debugging
return options.view(viewProps);
};
return content(userProps);
};
result.displayName = options.displayName;
Object.assign(result, options.statics);
// Later versions of TypeSript should allow us to merge objects in a type safe way and avoid this cast.
return result;
}
//# sourceMappingURL=createComponent.js.map

@@ -7,4 +7,4 @@ {

"packages/foundation/.vscode/settings.json": "a47d61e2fb865a31a0ee471e65cfb447269f23f2",
"packages/foundation/CHANGELOG.json": "1148b769c1111204b846728be2c9943007e9518e",
"packages/foundation/CHANGELOG.md": "b8377ec1183eea725ad0c333495d31d2b9925e29",
"packages/foundation/CHANGELOG.json": "46cf57e24d8c0ccbeff3bd9c34ce6ff9d52b507e",
"packages/foundation/CHANGELOG.md": "8c0941421de129e6230c989f68d89901752ea9af",
"packages/foundation/LICENSE": "f40682078e868be480a62821f1def5fbe0dd965e",

@@ -16,10 +16,10 @@ "packages/foundation/README.md": "87ad8e5781287ca710d32d79abd8cbe53593a151",

"packages/foundation/jsconfig.json": "c25b2cc60e6443982c62d0847d67b6ac6960dddc",
"packages/foundation/package.json": "6126501ffff07f8c625ac8c04ba8892cffc31454",
"packages/foundation/src/createComponent.tsx": "1e0be30d3a1cd09fd81ac0842e88a8752d054eca",
"packages/foundation/package.json": "a639bd32c724235f30bf2dfd570fc636ebe9ea77",
"packages/foundation/src/createComponent.tsx": "1d31a5ba1280ff526d54c16245060e36f0de0422",
"packages/foundation/src/index.ts": "ee6e311e0dfffc26dda52974ea5e34c58ea94e51",
"packages/foundation/tsconfig.json": "3758c6c261a8af0f1c243da01fcd0a0c221684ae",
"packages/foundation/tslint.json": "621ee6ba046052113aa7042fb5bb5323594253ff",
"common/config/rush/npm-shrinkwrap.json": "9bb2e55aa1b827375e3969ba9666196733e838b3"
"packages/foundation/tslint.json": "b057578463d41940f663b0e7047f45a09b19a164",
"common/config/rush/npm-shrinkwrap.json": "65d4a026ce0c6b5a7abb5299a2452f23ceee98d1"
},
"arguments": "node ../../scripts/build.js --production"
}
{
"name": "@uifabric/foundation",
"version": "0.1.0",
"version": "0.2.0",
"description": "Foundation library for building Fabric components.",

@@ -5,0 +5,0 @@ "main": "lib-commonjs/index.js",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc