Skip to content

Commit

Permalink
Foundation: Support contextual theming and styles (#5867)
Browse files Browse the repository at this point in the history
* Add support for contextual theming, styles, settings and scoped settings to createComponent. Create examples to demo.

* Change files.
  • Loading branch information
JasonGore authored Aug 9, 2018
1 parent 4f6c97b commit e70852b
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@uifabric/experiments",
"comment": "Inject customizations into Foundation. Add contextual theming and styling examples.",
"type": "patch"
}
],
"packageName": "@uifabric/experiments",
"email": "[email protected]"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@uifabric/foundation",
"comment": "Add support for contextual theming and styling.",
"type": "patch"
}
],
"packageName": "@uifabric/foundation",
"email": "[email protected]"
}
27 changes: 23 additions & 4 deletions packages/experiments/src/Foundation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mergeStyleSets, getTheme, ITheme } from 'office-ui-fabric-react';
import { mergeStyleSets, ITheme } from 'office-ui-fabric-react';
import {
createStatelessComponent as foundationCreateStatelessComponent,
createComponent as foundationCreateComponent,
Expand All @@ -13,6 +13,7 @@ import {
} from '@uifabric/foundation';
export { IStateComponentProps } from '@uifabric/foundation';
import { IProcessedStyleSet, IStyleSet } from './Styling';
import { Customizations, CustomizableContextTypes, ICustomizations } from './Utilities';

// Centralize Foundation interaction for use throughout this package. These convenience types provide types
// that are global for all of OUFR, such as ITheme and IProcessedStyleSet.
Expand All @@ -34,10 +35,17 @@ export type IStyleableComponentProps<TProps, TStyleSet> = IStyleableComponentPro
*/
export type IThemedProps<TProps> = TProps & IThemedComponent<ITheme>;

/**
* The shape of customizations within context.
*/
type IContextCustomization = { customizations: ICustomizations };

// TODO: remove any if possible
// tslint:disable-next-line:no-any
const providers: IStylingProviders<any, any, ITheme> = {
getTheme,
mergeStyleSets
const providers: IStylingProviders<any, any, any, IContextCustomization, ITheme> = {
mergeStyleSets,
getCustomizations,
CustomizableContextTypes
};

/**
Expand All @@ -56,6 +64,7 @@ export function createStatelessComponent<
TComponentProps,
TStyleSet,
IProcessedStyleSet<TStyleSet>,
IContextCustomization,
ITheme,
TStatics
>(options, providers);
Expand Down Expand Up @@ -85,7 +94,17 @@ export function createComponent<
TViewProps,
TStyleSet,
IProcessedStyleSet<TStyleSet>,
IContextCustomization,
ITheme,
TStatics
>(options, providers, state);
}

// TODO: remove any if possible
// tslint:disable-next-line:no-any
function getCustomizations(displayName: string, context: IContextCustomization): any {
// TODO: do we want field props? should fields be part of IComponentOptions and used here?
// TODO: should we centrally define DefaultFields? (not exported from styling)
const DefaultFields = ['theme', 'styles'];
return Customizations.getSettings(DefaultFields, displayName, context.customizations);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CollapsibleSectionView } from './CollapsibleSection.view';
import { getStyles as styles } from './CollapsibleSection.styles';
import { createComponent } from '../../Foundation';
import { createComponent, createStatelessComponent } from '../../Foundation';
import { CollapsibleSectionState } from './CollapsibleSection.state';

import {
Expand All @@ -21,3 +21,13 @@ export const CollapsibleSection: React.StatelessComponent<ICollapsibleSectionPro
},
CollapsibleSectionState
);

// TODO: This is only here for testing createComponent and should be removed before promoting to production
export const CollapsibleSectionStateless: React.StatelessComponent<ICollapsibleSectionProps> = createStatelessComponent<
ICollapsibleSectionViewProps,
ICollapsibleSectionStyles
>({
displayName: 'CollapsibleSection',
view: CollapsibleSectionView,
styles
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { ITheme, createTheme, DefaultPalette } from 'office-ui-fabric-react/lib/
import { FocusZone } from 'office-ui-fabric-react/lib/FocusZone';
import {
CollapsibleSection,
CollapsibleSectionStateless,
ICollapsibleSectionStyleProps,
ICollapsibleSectionStyles,
ICollapsibleSectionTitleStyleProps,
ICollapsibleSectionTitleStyles
} from '@uifabric/experiments/lib/CollapsibleSection';

function getStyles(props: ICollapsibleSectionStyleProps): Partial<ICollapsibleSectionStyles> {
function getPropStyles(props: ICollapsibleSectionStyleProps): Partial<ICollapsibleSectionStyles> {
const { theme } = props;
return {
root: [
Expand All @@ -27,13 +28,32 @@ function getStyles(props: ICollapsibleSectionStyleProps): Partial<ICollapsibleSe
};
}

function getTitleStyles(props: ICollapsibleSectionTitleStyleProps): Partial<ICollapsibleSectionTitleStyles> {
function getCustomizerStyles(props: ICollapsibleSectionStyleProps): Partial<ICollapsibleSectionStyles> {
const { theme } = props;
return {
body: [
{
color: theme.semanticColors.link
}
]
};
}

function getPropTitleStyles(props: ICollapsibleSectionTitleStyleProps): Partial<ICollapsibleSectionTitleStyles> {
const { theme } = props;
return {
text: [theme.fonts.large]
};
}

function getCustomizerTitleStyles(props: ICollapsibleSectionTitleStyleProps): Partial<ICollapsibleSectionTitleStyles> {
const { theme } = props;
return {
icon: { color: theme.semanticColors.link },
text: { color: theme.semanticColors.link }
};
}

const csCustomizerTheme: ITheme = createTheme({
semanticColors: {
disabledBackground: DefaultPalette.themeLight,
Expand Down Expand Up @@ -61,6 +81,9 @@ export class CollapsibleSectionStyledExample extends React.Component<{}, {}> {
If everything is working correctly color gradients should gradually get darker within each type of component
with any variant having Theme prop looking identical.
</p>
<p>
<b>Stateful Components</b>
</p>
<FocusZone>
<CollapsibleSection
key={1}
Expand All @@ -73,58 +96,162 @@ export class CollapsibleSectionStyledExample extends React.Component<{}, {}> {
</CollapsibleSection>
<br />
<CollapsibleSection
key={1}
key={2}
defaultCollapsed={false}
titleProps={{
text: `JS Styling`,
styles: getTitleStyles
text: `Prop Styles`,
styles: getPropTitleStyles
}}
styles={getStyles}
styles={getPropStyles}
>
Body
</CollapsibleSection>
<br />
<Customizer
scopedSettings={{
CollapsibleSection: { styles: getCustomizerStyles },
CollapsibleSectionTitle: { styles: getCustomizerTitleStyles }
}}
>
<CollapsibleSection
key={3}
defaultCollapsed={false}
titleProps={{
text: `Prop Styles + Customizer Styles`,
styles: getPropTitleStyles
}}
styles={getPropStyles}
>
Body
</CollapsibleSection>
</Customizer>
<br />
<Customizer settings={{ theme: csCustomizerTheme }}>
<CollapsibleSection
key={1}
key={4}
defaultCollapsed={false}
titleProps={{
text: `JS Styling + Customizer`,
styles: getTitleStyles
text: `Prop Styles + Customizer Theme`,
styles: getPropTitleStyles
}}
styles={getStyles}
styles={getPropStyles}
>
TODO: Fix me. Customizer theme is not applying to me.
Body
</CollapsibleSection>
</Customizer>
<br />
<CollapsibleSection
key={1}
key={5}
defaultCollapsed={false}
titleProps={{
text: `JS Styling + Theme Prop`,
styles: getTitleStyles
text: `Prop Styles + Prop Theme`,
styles: getPropTitleStyles
}}
styles={getStyles}
styles={getPropStyles}
theme={csPropTheme}
>
Body
</CollapsibleSection>
<br />
<Customizer settings={{ theme: csCustomizerTheme }}>
<CollapsibleSection
key={1}
key={6}
defaultCollapsed={false}
titleProps={{
text: `JS Styling + Customizer + Theme Prop`,
styles: getTitleStyles
text: `Prop Styles + Customizer Theme + Prop Theme`,
styles: getPropTitleStyles
}}
styles={getStyles}
styles={getPropStyles}
theme={csPropTheme}
>
Body
</CollapsibleSection>
</Customizer>
<p>
<b>Stateless Components</b>
</p>
<CollapsibleSectionStateless
key={7}
defaultCollapsed={false}
titleProps={{
text: `No Styling`
}}
>
Body
</CollapsibleSectionStateless>
<br />
<CollapsibleSectionStateless
key={8}
defaultCollapsed={false}
titleProps={{
text: `Prop Styles`,
styles: getPropTitleStyles
}}
styles={getPropStyles}
>
Body
</CollapsibleSectionStateless>
<br />
<Customizer
scopedSettings={{
CollapsibleSection: { styles: getCustomizerStyles },
CollapsibleSectionTitle: { styles: getCustomizerTitleStyles }
}}
>
<CollapsibleSectionStateless
key={9}
defaultCollapsed={false}
titleProps={{
text: `Prop Styles + Customizer Styles`,
styles: getPropTitleStyles
}}
styles={getPropStyles}
>
Body
</CollapsibleSectionStateless>
</Customizer>
<br />
<Customizer settings={{ theme: csCustomizerTheme }}>
<CollapsibleSectionStateless
key={10}
defaultCollapsed={false}
titleProps={{
text: `Prop Styles + Customizer Theme`,
styles: getPropTitleStyles
}}
styles={getPropStyles}
>
Body
</CollapsibleSectionStateless>
</Customizer>
<br />
<CollapsibleSectionStateless
key={11}
defaultCollapsed={false}
titleProps={{
text: `Prop Styles + Prop Theme`,
styles: getPropTitleStyles
}}
styles={getPropStyles}
theme={csPropTheme}
>
Body
</CollapsibleSectionStateless>
<br />
<Customizer settings={{ theme: csCustomizerTheme }}>
<CollapsibleSectionStateless
key={12}
defaultCollapsed={false}
titleProps={{
text: `Prop Styles + Customizer Theme + Prop Theme`,
styles: getPropTitleStyles
}}
styles={getPropStyles}
theme={csPropTheme}
>
Body
</CollapsibleSectionStateless>
</Customizer>
</FocusZone>
</div>
);
Expand Down
Loading

0 comments on commit e70852b

Please sign in to comment.