Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Foundation: Support contextual theming and styles #5867

Merged
merged 2 commits into from
Aug 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,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);
Copy link
Member

Choose a reason for hiding this comment

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

defaultfields are default... some components, like Layer, can mark additional fields as customizable (such as "hostId"). How is this piped in?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I wanted to talk to you about that. I have the TODO on line 106 for exactly that. 😄

}
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
Copy link
Member

@dzearing dzearing Aug 9, 2018

Choose a reason for hiding this comment

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

customizableProps: ['foo', 'bar', 'baz']; maybe

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, that's what I was thinking, assuming we still needed to pipe them in (tied to other comment)

});
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