Merge pull request #136 from ksiler/fluent-variant-support

Add new fluent typeramp to fluent native text with variants
This commit is contained in:
Krystal Siler 2020-04-13 15:23:26 -07:00 коммит произвёл GitHub
Родитель cf2dc6f865 b6a46410e6
Коммит fbbdcfe760
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
32 изменённых файлов: 1755 добавлений и 1566 удалений

Просмотреть файл

@ -0,0 +1,48 @@
import * as React from 'react';
import { View } from 'react-native';
import { Stack } from '@fluentui-react-native/stack';
import { Text } from '@fluentui-react-native/text';
import { stackStyle } from '../Common/styles';
import { styles } from './styles';
export const CustomizeUsage: React.FunctionComponent<{}> = () => {
const RedCaptionBold = Text.customize({ tokens: { fontVariant: 'captionStandard', fontWeight: 'semiBold', color: '#ff0000' } });
const OrangeSecondaryBold = Text.customize({ tokens: { fontVariant: 'secondaryStandard', fontWeight: 'semiBold', color: '#ff9900' } });
const YellowBodyBold = Text.customize({ tokens: { fontVariant: 'bodyStandard', fontWeight: 'semiBold', color: '#f3ce00' } });
const GreenSubheaderBold = Text.customize({ tokens: { fontVariant: 'subheaderStandard', fontWeight: 'semiBold', color: '#02c440' } });
const BlueHeaderBold = Text.customize({ tokens: { fontVariant: 'headerStandard', fontWeight: 'semiBold', color: '#0229c4' } });
const IndigoHeroBold = Text.customize({ tokens: { fontVariant: 'heroStandard', fontWeight: 'semiBold', color: '#4b0082' } });
const PurpleHeroLargeBold = Text.customize({ tokens: { fontVariant: 'heroLargeStandard', fontWeight: 'semiBold', color: '#8402c4' } });
const ArialBlack = Text.customize({ tokens: { fontVariant: 'heroLargeStandard', fontFamily: 'Arial Black' } });
const BrushScriptMT = Text.customize({ tokens: { fontVariant: 'heroStandard', fontFamily: 'Brush Script MT' } });
const CourierNew = Text.customize({ tokens: { fontVariant: 'headerStandard', fontFamily: 'Courier New' } });
const Georgia = Text.customize({ tokens: { fontVariant: 'subheaderStandard', fontFamily: 'Georgia' } });
const SegoeScript = Text.customize({ tokens: { fontVariant: 'bodyStandard', fontFamily: 'Segoe Script' } });
const TimesNewRoman = Text.customize({ tokens: { fontVariant: 'secondaryStandard', fontFamily: 'Times New Roman' } });
const Wingdings = Text.customize({ tokens: { fontVariant: 'captionStandard', fontFamily: 'Wingdings' } });
return (
<View style={styles.root}>
<Stack style={stackStyle} gap={5}>
<RedCaptionBold>RedCaptionBold</RedCaptionBold>
<OrangeSecondaryBold>OrangeSecondaryBold</OrangeSecondaryBold>
<YellowBodyBold>YellowBodyBold</YellowBodyBold>
<GreenSubheaderBold>GreenSubheaderBold</GreenSubheaderBold>
<BlueHeaderBold>BlueHeaderBold</BlueHeaderBold>
<IndigoHeroBold>IndigoHeroBold</IndigoHeroBold>
<PurpleHeroLargeBold>PurpleHeroLargeBold</PurpleHeroLargeBold>
</Stack>
<Stack style={stackStyle} gap={5}>
<ArialBlack>Arial Black</ArialBlack>
<BrushScriptMT>Brush Script MT</BrushScriptMT>
<CourierNew>Courier New</CourierNew>
<Georgia>Georgia</Georgia>
<SegoeScript>Segoe Script</SegoeScript>
<TimesNewRoman>TimesNewRoman</TimesNewRoman>
<Wingdings>Wingdings</Wingdings>
</Stack>
</View>
);
};

Просмотреть файл

@ -0,0 +1,24 @@
import * as React from 'react';
import { View } from 'react-native';
import { Text } from '@fluentui-react-native/text';
import { styles } from './styles';
export const StandardUsage: React.FunctionComponent<{}> = () => {
return (
<View style={styles.root}>
<Text fontVariant="captionStandard">CaptionStandard</Text>
<Text fontVariant="secondaryStandard">SecondaryStandard</Text>
<Text fontVariant="secondarySemibold">SecondarySemibold</Text>
<Text fontVariant="bodyStandard">BodyStandard</Text>
<Text fontVariant="bodySemibold">BodySemibold</Text>
<Text fontVariant="subheaderStandard">SubheaderStandard</Text>
<Text fontVariant="subheaderSemibold">SubheaderSemibold</Text>
<Text fontVariant="headerStandard">HeaderStandard</Text>
<Text fontVariant="headerSemibold">HeaderSemibold</Text>
<Text fontVariant="heroStandard">HeroStandard</Text>
<Text fontVariant="heroSemibold">HeroSemibold</Text>
<Text fontVariant="heroLargeStandard">HeroLargeStandard</Text>
<Text fontVariant="heroLargeSemibold">HeroLargeSemibold</Text>
</View>
);
};

Просмотреть файл

@ -0,0 +1,21 @@
import * as React from 'react';
import { View } from 'react-native';
import { Separator } from '@fluentui-react-native/separator';
import { StandardUsage } from './StandardUsage';
import { CustomizeUsage } from './CustomizeUsage';
import { styles } from './styles';
import { Text } from '@fluentui-react-native/text';
export const TextTest: React.FunctionComponent<{}> = () => {
return (
<View>
<Text style={styles.section}>Standard Usage</Text>
<Separator />
<StandardUsage />
<Text style={styles.section}>Customize Usage</Text>
<Separator />
<CustomizeUsage />
</View>
);
};

Просмотреть файл

@ -0,0 +1 @@
export * from './TextTest';

Просмотреть файл

@ -0,0 +1,16 @@
import { StyleSheet } from 'react-native';
export const styles = StyleSheet.create({
root: {
marginTop: 16,
marginRight: 32,
flexDirection: 'column',
alignItems: 'flex-start'
},
section: {
fontSize: 15,
fontWeight: 'bold',
color: '#0B6A0B',
marginTop: 12
}
});

Просмотреть файл

@ -1,207 +1,207 @@
import * as React from 'react';
import * as ReactNative from 'react-native';
import { getHostSettingsWin32, ThemeProvider, useTheme, IThemeDefinition, ThemingModuleHelper } from '@uifabricshared/theming-react-native';
import { themedStyleSheet } from '@uifabricshared/themed-stylesheet';
import { commonTestStyles } from '../Common/styles';
import { Button, PrimaryButton, Separator, StealthButton, Text, RadioGroup, RadioButton } from '@fluentui/react-native';
import { ITheme, IPartialTheme } from '@uifabricshared/theming-ramp';
import { customRegistry } from './CustomThemes';
let brand = 'Office';
const brandColors = {
Word: ['#E3ECFA', '#A5B9D1', '#7DA3C6', '#4A78B0', '#3C65A4', '#2B579A', '#124078', '#002050'],
Excel: ['#E9F5EE', '#9FCDB3', '#6EB38A', '#4E9668', '#3F8159', '#217346', '#0E5C2F', '#004B1C'],
Powerpoint: ['#FCF0ED', '#FDC9B5', '#ED9583', '#E86E58', '#C75033', '#B7472A', '#A92B1A', '#740912'],
Outlook: ['#CCE3F5', '#B3D6F2', '#69AFE5', '#2488D8', '#0078D7', '#106EBE', '#1664A7', '#135995']
};
// This IProcessTheme takes the parent theme and shims in the brand colors selected in the RadioGroup
const fakeBrandTheme: IThemeDefinition = (theme: ITheme): IPartialTheme => {
if (brand === 'Office') {
return {};
}
const brandValues = theme.colors.brand.values;
const brandedTheme = { colors: {}, host: { palette: {} } };
Object.keys(theme.colors).forEach((value: string) => {
if (typeof theme.colors[value] === 'string') {
const index = brandValues.indexOf(theme.colors[value].toString());
if (index !== -1) brandedTheme.colors[value] = brandColors[brand][index];
}
});
const hostThemeSettings = getHostSettingsWin32(theme);
if (hostThemeSettings === undefined) return brandedTheme;
Object.keys(hostThemeSettings.palette).forEach((value: string) => {
const index = brandValues.indexOf(hostThemeSettings.palette[value].toString());
if (index !== -1) brandedTheme.host.palette[value] = brandColors[brand][index];
});
return brandedTheme;
};
// this applies the shim to the default theme
customRegistry.setTheme(fakeBrandTheme, 'Default');
// this registers platform white colors
customRegistry.setTheme(ThemingModuleHelper.getPlatformThemeDefinition('WhiteColors'), 'RealWhiteColors');
// this applies the shim to the white colors theme
customRegistry.setTheme(fakeBrandTheme, 'WhiteColors', 'RealWhiteColors');
const getThemedStyles = themedStyleSheet((theme: ITheme) => {
const hostSettings = getHostSettingsWin32(theme);
return {
swatch: {
width: 80,
height: 20,
marginRight: 5,
borderWidth: 2,
borderColor: theme.colors.bodyText
},
extraLargeStandardEmphasis: {
color: hostSettings ? hostSettings.palette.TextEmphasis : theme.colors.bodyText,
fontSize: theme.typography.sizes.xxLarge,
fontWeight: theme.typography.weights.medium,
fontFamily: theme.typography.families.primary
} as ReactNative.TextStyle,
largeStandard: {
color: theme.colors.bodyText,
fontSize: theme.typography.sizes.large,
fontWeight: theme.typography.weights.medium,
fontFamily: theme.typography.families.primary,
marginBottom: 5
} as ReactNative.TextStyle,
stackStyle: {
borderWidth: 2,
borderColor: theme.colors.focusBorder,
padding: 12,
margin: 8,
backgroundColor: theme.colors.background
}
};
});
const styles = ReactNative.StyleSheet.create({
swatchItem: {
flexDirection: 'row',
alignItems: 'center',
marginVertical: 5
},
pickerContainer: {
flexDirection: 'row',
justifyContent: 'space-evenly'
}
});
const Panel: React.FunctionComponent = () => {
const [disabled, setDisabled] = React.useState(false);
const onClick = React.useCallback(() => setDisabled(!disabled), [disabled, setDisabled]);
const themedStyles = getThemedStyles(useTheme());
return (
<ReactNative.View style={[commonTestStyles.view, themedStyles.stackStyle]}>
<PrimaryButton onClick={onClick} content="Primary Button" disabled={disabled} />
<Button onClick={onClick} content="Default Button" disabled={disabled} />
<StealthButton onClick={onClick} content="Stealth Button" disabled={disabled} />
<Text>This is a text element</Text>
<Button onClick={onClick} content="This button has longer text" disabled={disabled} />
</ReactNative.View>
);
};
const getSwatchColorStyle = (color: string): ReactNative.ViewStyle => {
styles[color] = styles[color] || { backgroundColor: color };
return styles[color];
};
type SemanticColorProps = { color: string; name: string };
const SemanticColor: React.FunctionComponent<SemanticColorProps> = (p: SemanticColorProps) => {
const themedStyles = getThemedStyles(useTheme());
return (
<ReactNative.View style={styles.swatchItem}>
<ReactNative.View style={[getSwatchColorStyle(p.color), themedStyles.swatch]} />
<Text>{p.name}</Text>
</ReactNative.View>
);
};
const SwatchList: React.FunctionComponent = () => {
const hostSettings = getHostSettingsWin32(useTheme());
const themedStyles = getThemedStyles(useTheme());
if (hostSettings === undefined) return <Text>Error</Text>;
const aggregator = React.useCallback(
(key: string) => {
return { name: key + ' (' + hostSettings.palette[key] + ')', color: hostSettings.palette[key] };
},
[hostSettings.palette]
);
const flattenArray = React.useCallback(() => {
return Object.keys(hostSettings.palette)
.sort()
.map(aggregator);
}, [hostSettings.palette, aggregator]);
const paletteAsArray = React.useMemo(flattenArray, [flattenArray]);
const renderSwatch = React.useCallback(({ item }) => {
const { color, name } = item;
return <SemanticColor key={name} color={color} name={name} />;
}, []);
return (
<ReactNative.View style={[commonTestStyles.view]}>
<Text style={themedStyles.largeStandard}>getHostSettingsWin32(theme: ITheme).palette</Text>
<ReactNative.View style={themedStyles.stackStyle}>
<ReactNative.FlatList data={paletteAsArray} renderItem={renderSwatch} />
</ReactNative.View>
</ReactNative.View>
);
};
const ThemeTestInner: React.FunctionComponent = () => {
const themedStyles = getThemedStyles(useTheme());
const onAppChange = React.useCallback((app: string) => {
brand = app;
// Invalidate the DAG children of the shimmed brand colors
customRegistry.setTheme(fakeBrandTheme, 'Default');
customRegistry.setTheme(fakeBrandTheme, 'WhiteColors', 'RealWhiteColors');
}, []);
const [theme, setTheme] = React.useState('Default');
return (
<ReactNative.View>
<Text style={themedStyles.extraLargeStandardEmphasis}>Configure Theme</Text>
<Separator />
<ReactNative.View style={styles.pickerContainer}>
<RadioGroup label="Pick App Colors" onChange={onAppChange} defaultSelectedKey="Office">
<RadioButton buttonKey="Office" content="Office" />
{Object.keys(brandColors).map((app: string) => (
<RadioButton key={app} buttonKey={app} content={app} />
))}
</RadioGroup>
<Separator vertical />
<RadioGroup label="Pick Theme" onChange={setTheme} defaultSelectedKey="Default">
<RadioButton buttonKey="Default" content="Default (GrayB / TaskPane)" />
<RadioButton buttonKey="Caterpillar" content="Caterpillar (Custom JS Theme)" />
<RadioButton buttonKey="WhiteColors" content="WhiteColors (Platform Theme)" />
</RadioGroup>
</ReactNative.View>
<Text style={themedStyles.extraLargeStandardEmphasis}>{theme + ' Theme'}</Text>
<Separator />
<ThemeProvider theme={theme}>
<Panel />
</ThemeProvider>
<Text style={themedStyles.extraLargeStandardEmphasis}>Host-specific Theme Settings</Text>
<Separator />
<SwatchList />
</ReactNative.View>
);
};
export const ThemeTest: React.FunctionComponent = () => {
return (
<ThemeProvider theme="Default">
<ThemeTestInner />
</ThemeProvider>
);
};
import * as React from 'react';
import * as ReactNative from 'react-native';
import { getHostSettingsWin32, ThemeProvider, useTheme, IThemeDefinition, ThemingModuleHelper } from '@uifabricshared/theming-react-native';
import { themedStyleSheet } from '@uifabricshared/themed-stylesheet';
import { commonTestStyles } from '../Common/styles';
import { Button, PrimaryButton, Separator, StealthButton, Text, RadioGroup, RadioButton } from '@fluentui/react-native';
import { ITheme, IPartialTheme } from '@uifabricshared/theming-ramp';
import { customRegistry } from './CustomThemes';
let brand = 'Office';
const brandColors = {
Word: ['#E3ECFA', '#A5B9D1', '#7DA3C6', '#4A78B0', '#3C65A4', '#2B579A', '#124078', '#002050'],
Excel: ['#E9F5EE', '#9FCDB3', '#6EB38A', '#4E9668', '#3F8159', '#217346', '#0E5C2F', '#004B1C'],
Powerpoint: ['#FCF0ED', '#FDC9B5', '#ED9583', '#E86E58', '#C75033', '#B7472A', '#A92B1A', '#740912'],
Outlook: ['#CCE3F5', '#B3D6F2', '#69AFE5', '#2488D8', '#0078D7', '#106EBE', '#1664A7', '#135995']
};
// This IProcessTheme takes the parent theme and shims in the brand colors selected in the RadioGroup
const fakeBrandTheme: IThemeDefinition = (theme: ITheme): IPartialTheme => {
if (brand === 'Office') {
return {};
}
const brandValues = theme.colors.brand.values;
const brandedTheme = { colors: {}, host: { palette: {} } };
Object.keys(theme.colors).forEach((value: string) => {
if (typeof theme.colors[value] === 'string') {
const index = brandValues.indexOf(theme.colors[value].toString());
if (index !== -1) brandedTheme.colors[value] = brandColors[brand][index];
}
});
const hostThemeSettings = getHostSettingsWin32(theme);
if (hostThemeSettings === undefined) return brandedTheme;
Object.keys(hostThemeSettings.palette).forEach((value: string) => {
const index = brandValues.indexOf(hostThemeSettings.palette[value].toString());
if (index !== -1) brandedTheme.host.palette[value] = brandColors[brand][index];
});
return brandedTheme;
};
// this applies the shim to the default theme
customRegistry.setTheme(fakeBrandTheme, 'Default');
// this registers platform white colors
customRegistry.setTheme(ThemingModuleHelper.getPlatformThemeDefinition('WhiteColors'), 'RealWhiteColors');
// this applies the shim to the white colors theme
customRegistry.setTheme(fakeBrandTheme, 'WhiteColors', 'RealWhiteColors');
const getThemedStyles = themedStyleSheet((theme: ITheme) => {
const hostSettings = getHostSettingsWin32(theme);
return {
swatch: {
width: 80,
height: 20,
marginRight: 5,
borderWidth: 2,
borderColor: theme.colors.bodyText
},
extraLargeStandardEmphasis: {
color: hostSettings ? hostSettings.palette.TextEmphasis : theme.colors.bodyText,
fontSize: theme.typography.sizes.header,
fontWeight: theme.typography.weights.regular,
fontFamily: theme.typography.families.primary
} as ReactNative.TextStyle,
largeStandard: {
color: theme.colors.bodyText,
fontSize: theme.typography.sizes.body,
fontWeight: theme.typography.weights.regular,
fontFamily: theme.typography.families.primary,
marginBottom: 5
} as ReactNative.TextStyle,
stackStyle: {
borderWidth: 2,
borderColor: theme.colors.focusBorder,
padding: 12,
margin: 8,
backgroundColor: theme.colors.background
}
};
});
const styles = ReactNative.StyleSheet.create({
swatchItem: {
flexDirection: 'row',
alignItems: 'center',
marginVertical: 5
},
pickerContainer: {
flexDirection: 'row',
justifyContent: 'space-evenly'
}
});
const Panel: React.FunctionComponent = () => {
const [disabled, setDisabled] = React.useState(false);
const onClick = React.useCallback(() => setDisabled(!disabled), [disabled, setDisabled]);
const themedStyles = getThemedStyles(useTheme());
return (
<ReactNative.View style={[commonTestStyles.view, themedStyles.stackStyle]}>
<PrimaryButton onClick={onClick} content="Primary Button" disabled={disabled} />
<Button onClick={onClick} content="Default Button" disabled={disabled} />
<StealthButton onClick={onClick} content="Stealth Button" disabled={disabled} />
<Text>This is a text element</Text>
<Button onClick={onClick} content="This button has longer text" disabled={disabled} />
</ReactNative.View>
);
};
const getSwatchColorStyle = (color: string): ReactNative.ViewStyle => {
styles[color] = styles[color] || { backgroundColor: color };
return styles[color];
};
type SemanticColorProps = { color: string; name: string };
const SemanticColor: React.FunctionComponent<SemanticColorProps> = (p: SemanticColorProps) => {
const themedStyles = getThemedStyles(useTheme());
return (
<ReactNative.View style={styles.swatchItem}>
<ReactNative.View style={[getSwatchColorStyle(p.color), themedStyles.swatch]} />
<Text>{p.name}</Text>
</ReactNative.View>
);
};
const SwatchList: React.FunctionComponent = () => {
const hostSettings = getHostSettingsWin32(useTheme());
const themedStyles = getThemedStyles(useTheme());
if (hostSettings === undefined) return <Text>Error</Text>;
const aggregator = React.useCallback(
(key: string) => {
return { name: key + ' (' + hostSettings.palette[key] + ')', color: hostSettings.palette[key] };
},
[hostSettings.palette]
);
const flattenArray = React.useCallback(() => {
return Object.keys(hostSettings.palette)
.sort()
.map(aggregator);
}, [hostSettings.palette, aggregator]);
const paletteAsArray = React.useMemo(flattenArray, [flattenArray]);
const renderSwatch = React.useCallback(({ item }) => {
const { color, name } = item;
return <SemanticColor key={name} color={color} name={name} />;
}, []);
return (
<ReactNative.View style={[commonTestStyles.view]}>
<Text style={themedStyles.largeStandard}>getHostSettingsWin32(theme: ITheme).palette</Text>
<ReactNative.View style={themedStyles.stackStyle}>
<ReactNative.FlatList data={paletteAsArray} renderItem={renderSwatch} />
</ReactNative.View>
</ReactNative.View>
);
};
const ThemeTestInner: React.FunctionComponent = () => {
const themedStyles = getThemedStyles(useTheme());
const onAppChange = React.useCallback((app: string) => {
brand = app;
// Invalidate the DAG children of the shimmed brand colors
customRegistry.setTheme(fakeBrandTheme, 'Default');
customRegistry.setTheme(fakeBrandTheme, 'WhiteColors', 'RealWhiteColors');
}, []);
const [theme, setTheme] = React.useState('Default');
return (
<ReactNative.View>
<Text style={themedStyles.extraLargeStandardEmphasis}>Configure Theme</Text>
<Separator />
<ReactNative.View style={styles.pickerContainer}>
<RadioGroup label="Pick App Colors" onChange={onAppChange} defaultSelectedKey="Office">
<RadioButton buttonKey="Office" content="Office" />
{Object.keys(brandColors).map((app: string) => (
<RadioButton key={app} buttonKey={app} content={app} />
))}
</RadioGroup>
<Separator vertical />
<RadioGroup label="Pick Theme" onChange={setTheme} defaultSelectedKey="Default">
<RadioButton buttonKey="Default" content="Default (GrayB / TaskPane)" />
<RadioButton buttonKey="Caterpillar" content="Caterpillar (Custom JS Theme)" />
<RadioButton buttonKey="WhiteColors" content="WhiteColors (Platform Theme)" />
</RadioGroup>
</ReactNative.View>
<Text style={themedStyles.extraLargeStandardEmphasis}>{theme + ' Theme'}</Text>
<Separator />
<ThemeProvider theme={theme}>
<Panel />
</ThemeProvider>
<Text style={themedStyles.extraLargeStandardEmphasis}>Host-specific Theme Settings</Text>
<Separator />
<SwatchList />
</ReactNative.View>
);
};
export const ThemeTest: React.FunctionComponent = () => {
return (
<ThemeProvider theme="Default">
<ThemeTestInner />
</ThemeProvider>
);
};

Просмотреть файл

@ -9,6 +9,7 @@ import { PersonaCoinTest } from './PersonaCoin';
import { PressableTest } from './Pressable';
import { RadioGroupTest } from './RadioGroup';
import { SeparatorTest } from './Separator';
import { TextTest } from './Text';
import { ThemeTest } from './Theme';
export type TestDescription = {
@ -41,6 +42,10 @@ export const allTestComponents: TestDescription[] = [
name: 'Separator Test',
component: SeparatorTest
},
{
name: 'Text Test',
component: TextTest
},
{
name: 'Theme Test',
component: ThemeTest

Просмотреть файл

@ -0,0 +1,8 @@
{
"type": "patch",
"comment": "Update button snapshot",
"packageName": "@fluentui-react-native/button",
"email": "krsiler@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-04-13T19:48:50.385Z"
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"type": "minor",
"comment": "Update new fontSize and fontWeight names",
"packageName": "@fluentui-react-native/link",
"email": "krsiler@microsoft.com",
"commit": "0b43086face022949813d6712d5833cd78fb407a",
"dependentChangeType": "patch",
"date": "2020-03-25T00:21:35.396Z"
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"type": "minor",
"comment": "Update fontSizes to new fluent typeramp names",
"packageName": "@fluentui-react-native/persona",
"email": "krsiler@microsoft.com",
"commit": "97ee7fa9bd026481f68201c05a1e23c8494b0b54",
"dependentChangeType": "patch",
"date": "2020-03-25T20:15:38.956Z"
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"type": "minor",
"comment": "Add variants and fluent typeramp to text",
"packageName": "@fluentui-react-native/text",
"email": "krsiler@microsoft.com",
"commit": "0b43086face022949813d6712d5833cd78fb407a",
"dependentChangeType": "patch",
"date": "2020-03-25T00:22:52.817Z"
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"type": "minor",
"comment": "Add variants and fluent typeramp to text",
"packageName": "@fluentui-react-native/tokens",
"email": "krsiler@microsoft.com",
"commit": "0b43086face022949813d6712d5833cd78fb407a",
"dependentChangeType": "patch",
"date": "2020-03-25T00:24:21.918Z"
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"type": "minor",
"comment": "Add variants and fluent typeramp to text",
"packageName": "@uifabricshared/theming-ramp",
"email": "krsiler@microsoft.com",
"commit": "0b43086face022949813d6712d5833cd78fb407a",
"dependentChangeType": "patch",
"date": "2020-03-25T00:23:45.697Z"
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"type": "minor",
"comment": "Add variants and fluent typeramp to text",
"packageName": "@uifabricshared/theming-react-native",
"email": "krsiler@microsoft.com",
"commit": "0b43086face022949813d6712d5833cd78fb407a",
"dependentChangeType": "patch",
"date": "2020-03-25T00:24:07.483Z"
}

Просмотреть файл

@ -0,0 +1,8 @@
{
"type": "minor",
"comment": "add docs for text",
"packageName": "fluent-rn-website",
"email": "krsiler@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-04-13T19:47:42.978Z"
}

Просмотреть файл

@ -1,3 +1,18 @@
# Text
### Not Yet Implemented
# Text
## Example
```
import * as React from 'react';
import { View } from 'react-native';
import { Text } from '@fluentui-react-native/text';
export const StandardUsage: React.FunctionComponent<{}> = () => {
return (
<View>
<Text fontVariant="bodyStandard">Some body text</Text>
<Text fontVariant="captionStandard">Some caption text</Text>
</View>
);
};
```

Просмотреть файл

@ -47,8 +47,8 @@ exports[`Button default 1`] = `
Object {
"color": "#323130",
"fontFamily": "Segoe UI",
"fontSize": 12,
"fontWeight": "500",
"fontSize": 9,
"fontWeight": "400",
"margin": 0,
}
}

Просмотреть файл

@ -1,45 +1,43 @@
import { linkName, ILinkType } from './Link.types';
import { IComposeSettings } from '@uifabricshared/foundation-compose';
// import { IViewWin32Props } from '@office-iss/react-native-win32';
import { IViewProps } from '@fluentui-react-native/adapters';
export const settings: IComposeSettings<ILinkType> = [
{
tokens: {
fontFamily: 'primary',
fontSize: 'medium',
fontWeight: 'medium',
color: 'link'
},
root: {
style: {
margin: 0,
textDecorationLine: 'underline'
} as IViewProps['style']
},
_precedence: ['visited', 'hovered', 'pressed', 'disabled'],
_overrides: {
disabled: {
tokens: {
color: 'link'
}
},
hovered: {
tokens: {
color: 'linkHovered'
}
},
pressed: {
tokens: {
color: 'linkPressed'
}
},
visited: {
tokens: {
color: 'link'
}
}
}
},
linkName
];
import { linkName, ILinkType } from './Link.types';
import { IComposeSettings } from '@uifabricshared/foundation-compose';
// import { IViewWin32Props } from '@office-iss/react-native-win32';
import { IViewProps } from '@fluentui-react-native/adapters';
export const settings: IComposeSettings<ILinkType> = [
{
tokens: {
fontVariant: 'secondaryStandard',
color: 'link'
},
root: {
style: {
margin: 0,
textDecorationLine: 'underline'
} as IViewProps['style']
},
_precedence: ['visited', 'hovered', 'pressed', 'disabled'],
_overrides: {
disabled: {
tokens: {
color: 'link'
}
},
hovered: {
tokens: {
color: 'linkHovered'
}
},
pressed: {
tokens: {
color: 'linkPressed'
}
},
visited: {
tokens: {
color: 'link'
}
}
}
},
linkName
];

Просмотреть файл

@ -1,86 +1,86 @@
import { PersonaSize } from '@fluentui-react-native/persona-coin';
import { ITextTokens } from '@fluentui-react-native/tokens';
type IPersonaFontTable = {
[key in PersonaSize]: ITextTokens;
};
const textFontTable: IPersonaFontTable = {
size8: { fontSize: 'small' },
size24: { fontSize: 'medium' },
size32: { fontSize: 'medium' },
size40: { fontSize: 'medium' },
size48: { fontSize: 'medium' },
size56: { fontSize: 'xLarge' },
size72: { fontSize: 'xLarge' },
size100: { fontSize: 'xLarge' },
size120: { fontSize: 'xLarge' }
};
const secondaryFontTable: IPersonaFontTable = {
size8: { fontSize: 0 },
size24: { fontSize: 0 },
size32: { fontSize: 0 },
size40: { fontSize: 'small' },
size48: { fontSize: 'small' },
size56: { fontSize: 'medium' },
size72: { fontSize: 'medium' },
size100: { fontSize: 'medium' },
size120: { fontSize: 'medium' }
};
const tertiaryFontTable: IPersonaFontTable = {
size8: { fontSize: 0 },
size24: { fontSize: 0 },
size32: { fontSize: 0 },
size40: { fontSize: 0 },
size48: { fontSize: 0 },
size56: { fontSize: 0 },
size72: { fontSize: 'medium' },
size100: { fontSize: 'medium' },
size120: { fontSize: 'medium' }
};
const optionalFontTable: IPersonaFontTable = {
size8: { fontSize: 0 },
size24: { fontSize: 0 },
size32: { fontSize: 0 },
size40: { fontSize: 0 },
size48: { fontSize: 0 },
size56: { fontSize: 0 },
size72: { fontSize: 0 },
size100: { fontSize: 'medium' },
size120: { fontSize: 'medium' }
};
export function getTextFont(size: PersonaSize): ITextTokens {
return textFontTable[size];
}
export function getSecondaryFont(size: PersonaSize): ITextTokens {
return secondaryFontTable[size];
}
export function getTertiaryFont(size: PersonaSize): ITextTokens {
return tertiaryFontTable[size];
}
export function getOptionalFont(size: PersonaSize): ITextTokens {
return optionalFontTable[size];
}
const horizontalGapTable: { [P in PersonaSize]: number } = {
size8: 17,
size24: 8,
size32: 8,
size40: 12,
size48: 12,
size56: 16,
size72: 16,
size100: 16,
size120: 16
};
export function getHorizontalGap(size: PersonaSize | undefined): number {
return horizontalGapTable[size || 'size40'];
}
import { PersonaSize } from '@fluentui-react-native/persona-coin';
import { ITextTokens } from '@fluentui-react-native/tokens';
type IPersonaFontTable = {
[key in PersonaSize]: ITextTokens;
};
const textFontTable: IPersonaFontTable = {
size8: { fontSize: 'caption' },
size24: { fontSize: 'secondary' },
size32: { fontSize: 'secondary' },
size40: { fontSize: 'secondary' },
size48: { fontSize: 'secondary' },
size56: { fontSize: 'subheader' },
size72: { fontSize: 'subheader' },
size100: { fontSize: 'subheader' },
size120: { fontSize: 'subheader' }
};
const secondaryFontTable: IPersonaFontTable = {
size8: { fontSize: 0 },
size24: { fontSize: 0 },
size32: { fontSize: 0 },
size40: { fontSize: 'caption' },
size48: { fontSize: 'caption' },
size56: { fontSize: 'secondary' },
size72: { fontSize: 'secondary' },
size100: { fontSize: 'secondary' },
size120: { fontSize: 'secondary' }
};
const tertiaryFontTable: IPersonaFontTable = {
size8: { fontSize: 0 },
size24: { fontSize: 0 },
size32: { fontSize: 0 },
size40: { fontSize: 0 },
size48: { fontSize: 0 },
size56: { fontSize: 0 },
size72: { fontSize: 'secondary' },
size100: { fontSize: 'secondary' },
size120: { fontSize: 'secondary' }
};
const optionalFontTable: IPersonaFontTable = {
size8: { fontSize: 0 },
size24: { fontSize: 0 },
size32: { fontSize: 0 },
size40: { fontSize: 0 },
size48: { fontSize: 0 },
size56: { fontSize: 0 },
size72: { fontSize: 0 },
size100: { fontSize: 'secondary' },
size120: { fontSize: 'secondary' }
};
export function getTextFont(size: PersonaSize): ITextTokens {
return textFontTable[size];
}
export function getSecondaryFont(size: PersonaSize): ITextTokens {
return secondaryFontTable[size];
}
export function getTertiaryFont(size: PersonaSize): ITextTokens {
return tertiaryFontTable[size];
}
export function getOptionalFont(size: PersonaSize): ITextTokens {
return optionalFontTable[size];
}
const horizontalGapTable: { [P in PersonaSize]: number } = {
size8: 17,
size24: 8,
size32: 8,
size40: 12,
size48: 12,
size56: 16,
size72: 16,
size100: 16,
size120: 16
};
export function getHorizontalGap(size: PersonaSize | undefined): number {
return horizontalGapTable[size || 'size40'];
}

Просмотреть файл

@ -1,28 +1,26 @@
import { textName, ITextType } from './Text.types';
import { TextStyle } from 'react-native';
import { IComposeSettings } from '@uifabricshared/foundation-compose';
export const settings: IComposeSettings<ITextType> = [
{
tokens: {
fontFamily: 'primary',
fontSize: 'medium',
fontWeight: 'medium',
color: 'bodyText'
},
root: {
style: {
margin: 0
} as TextStyle
},
_overrides: {
disabled: {
tokens: {
color: 'disabledText'
}
}
},
_precedence: ['disabled']
},
textName
];
import { textName, ITextType } from './Text.types';
import { TextStyle } from 'react-native';
import { IComposeSettings } from '@uifabricshared/foundation-compose';
export const settings: IComposeSettings<ITextType> = [
{
tokens: {
fontVariant: 'secondaryStandard',
color: 'bodyText'
},
root: {
style: {
margin: 0
} as TextStyle
},
_overrides: {
disabled: {
tokens: {
color: 'disabledText'
}
}
},
_precedence: ['disabled']
},
textName
];

Просмотреть файл

@ -1,20 +1,21 @@
import { ITextTokens, IForegroundColorTokens } from '@fluentui-react-native/tokens';
import { ITextProps as INativeTextProps } from '@fluentui-react-native/adapters';
export const textName = 'RNFText';
/**
* Properties for fabric native text field, these extend the default props for text
*/
export type ITextProps<TBase = INativeTextProps> = TBase &
ITextTokens &
IForegroundColorTokens & {
disabled?: boolean;
};
export type ITextType<TBase = INativeTextProps> = {
props: ITextProps<TBase>;
slotProps: {
root: TBase;
};
};
import { ITextTokens, ITextVariantTokens, IForegroundColorTokens, IColorTokens } from '@fluentui-react-native/tokens';
import { ITextProps as INativeTextProps } from '@fluentui-react-native/adapters';
export const textName = 'RNFText';
/**
* Properties for fabric native text field, these extend the default props for text
*/
export type ITextProps<TBase = INativeTextProps> = TBase &
ITextVariantTokens &
IForegroundColorTokens & {
disabled?: boolean;
};
export type ITextType<TBase = INativeTextProps> = {
props: ITextProps<TBase>;
tokens: ITextTokens & IColorTokens;
slotProps: {
root: TBase;
};
};

Просмотреть файл

@ -1,24 +1,31 @@
import * as React from 'react';
import { Text } from '..';
import * as renderer from 'react-test-renderer';
it('Text default', () => {
const tree = renderer.create(<Text>Text default</Text>).toJSON();
expect(tree).toMatchSnapshot();
});
it('Text all props', () => {
const tree = renderer.create(<Text disabled>All props</Text>).toJSON();
expect(tree).toMatchSnapshot();
});
it('Text all tokens', () => {
const tree = renderer
.create(
<Text color="orange" fontFamily="Wingdings" fontSize={15} fontWeight="bold">
All tokens
</Text>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
import * as React from 'react';
import { Text } from '..';
import * as renderer from 'react-test-renderer';
it('Text default', () => {
const tree = renderer.create(<Text>Text default</Text>).toJSON();
expect(tree).toMatchSnapshot();
});
it('Text all props', () => {
const tree = renderer
.create(
<Text disabled fontVariant="bodyStandard">
All props
</Text>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
it('Text all tokens', () => {
const BoldText = Text.customize({
tokens: {
fontFamily: 'Wingdings',
fontWeight: '900',
fontSize: 15
}
});
const tree = renderer.create(<BoldText>All tokens</BoldText>).toJSON();
expect(tree).toMatchSnapshot();
});

Просмотреть файл

@ -1,49 +1,49 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Text all props 1`] = `
<Text
style={
Object {
"color": "#a19f9d",
"fontFamily": "Segoe UI",
"fontSize": 12,
"fontWeight": "500",
"margin": 0,
}
}
>
All props
</Text>
`;
exports[`Text all tokens 1`] = `
<Text
style={
Object {
"color": "orange",
"fontFamily": "Wingdings",
"fontSize": 15,
"fontWeight": "900",
"margin": 0,
}
}
>
All tokens
</Text>
`;
exports[`Text default 1`] = `
<Text
style={
Object {
"color": "#323130",
"fontFamily": "Segoe UI",
"fontSize": 12,
"fontWeight": "500",
"margin": 0,
}
}
>
Text default
</Text>
`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Text all props 1`] = `
<Text
style={
Object {
"color": "#a19f9d",
"fontFamily": "Segoe UI",
"fontSize": 11,
"fontWeight": "400",
"margin": 0,
}
}
>
All props
</Text>
`;
exports[`Text all tokens 1`] = `
<Text
style={
Object {
"color": "#323130",
"fontFamily": "Wingdings",
"fontSize": 15,
"fontWeight": "900",
"margin": 0,
}
}
>
All tokens
</Text>
`;
exports[`Text default 1`] = `
<Text
style={
Object {
"color": "#323130",
"fontFamily": "Segoe UI",
"fontSize": 9,
"fontWeight": "400",
"margin": 0,
}
}
>
Text default
</Text>
`;

Просмотреть файл

@ -1,492 +1,381 @@
## API Report File for "@uifabricshared/theming-ramp"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { IComponentSettings } from '@uifabricshared/foundation-settings';
import { IComponentSettingsCollection } from '@uifabricshared/foundation-settings';
// @public
export type Color = keyof IPalette | ColorValue;
// @public
export type ColorValue = string;
// @public
export type FontFamily = keyof IFontFamilies | FontFamilyValue;
// @public
export type FontFamilyValue = string;
// @public
export type FontSize = keyof IFontSizes | FontSizeValuePoints;
// @public
export type FontSizeValuePoints = number;
// @public
export type FontWeight = keyof IFontWeights | FontWeightValue;
// @public
export type FontWeightValue = '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
// @public (undocumented)
export function getSettings(theme: ITheme, name: string): IComponentSettings;
// @public (undocumented)
export function getStockWebPalette(): IPalette;
// @public (undocumented)
export interface IFabricWebPalette {
// (undocumented)
accent: ColorValue;
// (undocumented)
black: ColorValue;
// (undocumented)
blackTranslucent40: ColorValue;
// (undocumented)
neutralDark: ColorValue;
// (undocumented)
neutralLight: ColorValue;
// (undocumented)
neutralLighter: ColorValue;
// (undocumented)
neutralLighterAlt: ColorValue;
// (undocumented)
neutralPrimary: ColorValue;
// (undocumented)
neutralPrimaryAlt: ColorValue;
// (undocumented)
neutralQuaternary: ColorValue;
// (undocumented)
neutralQuaternaryAlt: ColorValue;
// (undocumented)
neutralSecondary: ColorValue;
// (undocumented)
neutralSecondaryAlt: ColorValue;
// (undocumented)
neutralTertiary: ColorValue;
// (undocumented)
neutralTertiaryAlt: ColorValue;
// (undocumented)
red: ColorValue;
// (undocumented)
redDark: ColorValue;
// (undocumented)
themeDark: ColorValue;
// (undocumented)
themeDarkAlt: ColorValue;
// (undocumented)
themeDarker: ColorValue;
// (undocumented)
themeLight: ColorValue;
// (undocumented)
themeLighter: ColorValue;
// (undocumented)
themeLighterAlt: ColorValue;
// (undocumented)
themePrimary: ColorValue;
// (undocumented)
themeSecondary: ColorValue;
// (undocumented)
themeTertiary: ColorValue;
// (undocumented)
white: ColorValue;
}
// @public
export interface IFontFamilies {
// (undocumented)
cursive: FontFamilyValue;
// (undocumented)
monospace: FontFamilyValue;
// (undocumented)
primary: FontFamilyValue;
// (undocumented)
sansSerif: FontFamilyValue;
// (undocumented)
secondary: FontFamilyValue;
// (undocumented)
serif: FontFamilyValue;
}
// @public
export interface IFontSizes {
// (undocumented)
large: FontSizeValuePoints;
// (undocumented)
medium: FontSizeValuePoints;
// (undocumented)
small: FontSizeValuePoints;
// (undocumented)
xLarge: FontSizeValuePoints;
// (undocumented)
xSmall: FontSizeValuePoints;
// (undocumented)
xxLarge: FontSizeValuePoints;
// (undocumented)
xxSmall: FontSizeValuePoints;
// (undocumented)
xxxLarge: FontSizeValuePoints;
// (undocumented)
xxxSmall: FontSizeValuePoints;
}
// @public
export interface IFontWeights {
// (undocumented)
bold: FontWeightValue;
// (undocumented)
light: FontWeightValue;
// (undocumented)
medium: FontWeightValue;
// (undocumented)
semiBold: FontWeightValue;
// (undocumented)
semiLight: FontWeightValue;
}
// @public
export type IPalette = IPaletteTextColors & IPaletteBackgroundColors;
// @public
export interface IPaletteBackgroundColors {
accentButtonBackground: ColorValue;
blockingBackground: ColorValue;
bodyBackground: ColorValue;
bodyDivider: ColorValue;
bodyFrameBackground: ColorValue;
bodyFrameDivider: ColorValue;
bodyStandoutBackground: ColorValue;
buttonBackground: ColorValue;
buttonBackgroundChecked: ColorValue;
buttonBackgroundCheckedHovered: ColorValue;
buttonBackgroundDisabled: ColorValue;
buttonBackgroundHovered: ColorValue;
buttonBackgroundPressed: ColorValue;
buttonBorder: ColorValue;
buttonBorderDisabled: ColorValue;
defaultStateBackground: ColorValue;
disabledBackground: ColorValue;
errorBackground: ColorValue;
focusBorder: ColorValue;
inputBackground: ColorValue;
inputBackgroundChecked: ColorValue;
inputBackgroundCheckedHovered: ColorValue;
inputBorder: ColorValue;
inputBorderHovered: ColorValue;
inputFocusBorderAlt: ColorValue;
inputForegroundChecked: ColorValue;
listBackground: ColorValue;
listHeaderBackgroundHovered: ColorValue;
listHeaderBackgroundPressed: ColorValue;
listItemBackgroundChecked: ColorValue;
listItemBackgroundCheckedHovered: ColorValue;
listItemBackgroundHovered: ColorValue;
listText: ColorValue;
menuBackground: ColorValue;
menuDivider: ColorValue;
menuHeader: ColorValue;
menuIcon: ColorValue;
menuItemBackgroundHovered: ColorValue;
menuItemBackgroundPressed: ColorValue;
menuItemText: ColorValue;
menuItemTextHovered: ColorValue;
primaryButtonBackground: ColorValue;
primaryButtonBackgroundDisabled: ColorValue;
primaryButtonBackgroundHovered: ColorValue;
primaryButtonBackgroundPressed: ColorValue;
primaryButtonBorder: ColorValue;
smallInputBorder: ColorValue;
successBackground: ColorValue;
variantBorder: ColorValue;
variantBorderHovered: ColorValue;
warningBackground: ColorValue;
warningHighlight: ColorValue;
}
// @public
export interface IPaletteTextColors {
accentButtonText: ColorValue;
actionLink: ColorValue;
actionLinkHovered: ColorValue;
bodySubtext: ColorValue;
bodyText: ColorValue;
bodyTextChecked: ColorValue;
buttonText: ColorValue;
buttonTextChecked: ColorValue;
buttonTextCheckedHovered: ColorValue;
buttonTextDisabled: ColorValue;
buttonTextHovered: ColorValue;
buttonTextPressed: ColorValue;
disabledBodySubtext: ColorValue;
disabledBodyText: ColorValue;
disabledSubtext: ColorValue;
disabledText: ColorValue;
errorText: ColorValue;
inputPlaceholderText: ColorValue;
inputText: ColorValue;
inputTextHovered: ColorValue;
link: ColorValue;
linkDisabled: ColorValue;
linkHovered: ColorValue;
linkPressed: ColorValue;
linkVisited: ColorValue;
listText: ColorValue;
primaryButtonText: ColorValue;
primaryButtonTextDisabled: ColorValue;
primaryButtonTextHovered: ColorValue;
primaryButtonTextPressed: ColorValue;
warningText: ColorValue;
}
// @public
export type IPartialPalette = Partial<IPalette>;
// @public
export interface IPartialTheme {
// (undocumented)
palette?: IPartialPalette;
// (undocumented)
settings?: IComponentSettingsCollection;
// (undocumented)
spacing?: ISpacing;
// (undocumented)
typography?: IPartialTypography;
}
// @public
export type IPartialTypography = {
[P in keyof ITypography]?: Partial<ITypography[P]>;
};
// @public (undocumented)
export interface ISpacing {
// (undocumented)
l1: string;
// (undocumented)
l2: string;
// (undocumented)
m: string;
// (undocumented)
s1: string;
// (undocumented)
s2: string;
}
// @public
export interface ITheme {
// (undocumented)
palette: IPalette;
// (undocumented)
settings: IComponentSettingsCollection;
// (undocumented)
spacing: ISpacing;
// (undocumented)
typography: ITypography;
}
// @public
export interface ITypography {
// (undocumented)
families: IFontFamilies;
// (undocumented)
sizes: IFontSizes;
// (undocumented)
weights: IFontWeights;
}
// @public (undocumented)
export interface IWindowsPalette {
accentDark: ColorValue;
// (undocumented)
accentEmphasis: ColorValue;
// (undocumented)
accentLight: ColorValue;
// (undocumented)
accentOutline: ColorValue;
background: ColorValue;
backgroundControl: ColorValue;
// (undocumented)
backgroundControlDisabled: ColorValue;
backgroundControlEmphasis: ColorValue;
// (undocumented)
backgroundControlEmphasisDisabled: ColorValue;
// (undocumented)
backgroundControlEmphasisHover: ColorValue;
// (undocumented)
backgroundControlEmphasisPressed: ColorValue;
// (undocumented)
backgroundControlHover: ColorValue;
// (undocumented)
backgroundControlPressed: ColorValue;
// (undocumented)
backgroundControlSelected: ColorValue;
backgroundControlSubtle: ColorValue;
// (undocumented)
backgroundControlSubtleDisabled: ColorValue;
// (undocumented)
backgroundControlSubtleHover: ColorValue;
// (undocumented)
backgroundControlSubtlePressed: ColorValue;
// (undocumented)
backgroundControlSubtleSelectionHighlight: ColorValue;
backgroundHeader: ColorValue;
// (undocumented)
backgroundHover: ColorValue;
// (undocumented)
backgroundPressed: ColorValue;
// (undocumented)
backgroundSelected: ColorValue;
// (undocumented)
backgroundSelectionHighlight: ColorValue;
// (undocumented)
strokeControl: ColorValue;
// (undocumented)
strokeControlDisabled: ColorValue;
// (undocumented)
strokeControlEmphasis: ColorValue;
// (undocumented)
strokeControlEmphasisDisabled: ColorValue;
// (undocumented)
strokeControlEmphasisHover: ColorValue;
// (undocumented)
strokeControlEmphasisKeyboard: ColorValue;
// (undocumented)
strokeControlEmphasisPressed: ColorValue;
// (undocumented)
strokeControlHover: ColorValue;
// (undocumented)
strokeControlKeyboard: ColorValue;
// (undocumented)
strokeControlPressed: ColorValue;
// (undocumented)
strokeControlSelected: ColorValue;
// (undocumented)
strokeControlSubtle: ColorValue;
// (undocumented)
strokeControlSubtleDisabled: ColorValue;
// (undocumented)
strokeControlSubtleHover: ColorValue;
// (undocumented)
strokeControlSubtleKeyboard: ColorValue;
// (undocumented)
strokeControlSubtlePressed: ColorValue;
// (undocumented)
strokeKeyboard: ColorValue;
// (undocumented)
strokeOverlayHover: ColorValue;
// (undocumented)
strokeOverlayPressed: ColorValue;
// (undocumented)
strokeOverlayRest: ColorValue;
// (undocumented)
strokeOverlaySelectedHover: ColorValue;
// (undocumented)
strokeOverlaySelectedPressed: ColorValue;
// (undocumented)
strokeOverlaySelectedRest: ColorValue;
// (undocumented)
strokeSelectedHover: ColorValue;
text: ColorValue;
textActive: ColorValue;
// (undocumented)
textActiveHover: ColorValue;
// (undocumented)
textActivePressed: ColorValue;
// (undocumented)
textActiveSelected: ColorValue;
// (undocumented)
textControl: ColorValue;
// (undocumented)
textControlDisabled: ColorValue;
// (undocumented)
textControlEmphasis: ColorValue;
// (undocumented)
textControlEmphasisDisabled: ColorValue;
// (undocumented)
textControlEmphasisHover: ColorValue;
// (undocumented)
textControlEmphasisPressed: ColorValue;
// (undocumented)
textControlHover: ColorValue;
// (undocumented)
textControlPressed: ColorValue;
// (undocumented)
textControlSelected: ColorValue;
// (undocumented)
textControlSubtle: ColorValue;
// (undocumented)
textControlSubtleDisabled: ColorValue;
// (undocumented)
textControlSubtleHover: ColorValue;
// (undocumented)
textControlSubtlePlaceholder: ColorValue;
// (undocumented)
textControlSubtlePressed: ColorValue;
// (undocumented)
textControlSubtleSelectionHighlight: ColorValue;
// (undocumented)
textDisabled: ColorValue;
// (undocumented)
textEmphasis: ColorValue;
// (undocumented)
textEmphasisHover: ColorValue;
// (undocumented)
textEmphasisPressed: ColorValue;
// (undocumented)
textEmphasisRest: ColorValue;
// (undocumented)
textEmphasisSelected: ColorValue;
textError: ColorValue;
// (undocumented)
textErrorHover: ColorValue;
// (undocumented)
textErrorPressed: ColorValue;
// (undocumented)
textErrorSelected: ColorValue;
// (undocumented)
textHeader: ColorValue;
// (undocumented)
textHover: ColorValue;
textHyperlink: ColorValue;
// (undocumented)
textHyperlinkHover: ColorValue;
// (undocumented)
textHyperlinkPressed: ColorValue;
// (undocumented)
textHyperlinkVisited: ColorValue;
// (undocumented)
textPressed: ColorValue;
// (undocumented)
textRest: ColorValue;
// (undocumented)
textSecondary: ColorValue;
// (undocumented)
textSecondaryHover: ColorValue;
// (undocumented)
textSecondaryPressed: ColorValue;
// (undocumented)
textSecondaryRest: ColorValue;
// (undocumented)
textSecondarySelected: ColorValue;
// (undocumented)
textSelected: ColorValue;
// (undocumented)
textSelectionHighlight: ColorValue;
}
// @public
export function paletteFromFabricColors(p: IFabricWebPalette, isInverted?: boolean): IPalette;
// @public
export function resolvePartialTheme(theme: ITheme, partialTheme?: IPartialTheme): ITheme;
// @public
export function returnAsSlotProps(target: IComponentSettings): IComponentSettings;
// (No @packageDocumentation comment for this package)
```
## API Report File for "@uifabricshared/theming-ramp"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { IComponentSettings } from '@uifabricshared/foundation-settings';
import { IComponentSettingsCollection } from '@uifabricshared/foundation-settings';
// @public
export type Color = keyof IPalette | ColorValue;
// @public
export type ColorValue = string;
// @public
export type FontFamily = keyof IFontFamilies | FontFamilyValue;
// @public
export type FontFamilyValue = string;
// @public
export type FontSize = keyof IFontSizes | FontSizeValuePoints;
// @public
export type FontSizeValuePoints = number;
// @public
export type FontVariant = keyof IFontVariants | FontVariantValue;
// @public
export type FontVariantValue = {
face: FontFamily;
size: FontSize;
weight: FontWeight;
};
// @public
export type FontWeight = keyof IFontWeights | FontWeightValue;
// @public
export type FontWeightValue = '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
// @public (undocumented)
export function getSettings(theme: ITheme, name: string): IComponentSettings;
// @public (undocumented)
export function getStockWebPalette(): IThemeColorDefinition;
// @public (undocumented)
export interface ICastableToString {
// (undocumented)
toString: () => string;
}
// @public (undocumented)
export interface IColorRamp extends ICastableToString {
// (undocumented)
index: number;
// (undocumented)
values: string[];
}
// @public (undocumented)
export interface IFabricWebPalette {
// (undocumented)
accent: ColorValue;
// (undocumented)
black: ColorValue;
// (undocumented)
blackTranslucent40: ColorValue;
// (undocumented)
neutralDark: ColorValue;
// (undocumented)
neutralLight: ColorValue;
// (undocumented)
neutralLighter: ColorValue;
// (undocumented)
neutralLighterAlt: ColorValue;
// (undocumented)
neutralPrimary: ColorValue;
// (undocumented)
neutralPrimaryAlt: ColorValue;
// (undocumented)
neutralQuaternary: ColorValue;
// (undocumented)
neutralQuaternaryAlt: ColorValue;
// (undocumented)
neutralSecondary: ColorValue;
// (undocumented)
neutralSecondaryAlt: ColorValue;
// (undocumented)
neutralTertiary: ColorValue;
// (undocumented)
neutralTertiaryAlt: ColorValue;
// (undocumented)
red: ColorValue;
// (undocumented)
redDark: ColorValue;
// (undocumented)
themeDark: ColorValue;
// (undocumented)
themeDarkAlt: ColorValue;
// (undocumented)
themeDarker: ColorValue;
// (undocumented)
themeLight: ColorValue;
// (undocumented)
themeLighter: ColorValue;
// (undocumented)
themeLighterAlt: ColorValue;
// (undocumented)
themePrimary: ColorValue;
// (undocumented)
themeSecondary: ColorValue;
// (undocumented)
themeTertiary: ColorValue;
// (undocumented)
white: ColorValue;
}
// @public
export interface IFontFamilies {
// (undocumented)
cursive: FontFamilyValue;
// (undocumented)
monospace: FontFamilyValue;
// (undocumented)
primary: FontFamilyValue;
// (undocumented)
sansSerif: FontFamilyValue;
// (undocumented)
secondary: FontFamilyValue;
// (undocumented)
serif: FontFamilyValue;
}
// @public
export interface IFontSizes {
// (undocumented)
body: FontSizeValuePoints;
// (undocumented)
caption: FontSizeValuePoints;
// (undocumented)
header: FontSizeValuePoints;
// (undocumented)
hero: FontSizeValuePoints;
// (undocumented)
heroLarge: FontSizeValuePoints;
// (undocumented)
secondary: FontSizeValuePoints;
// (undocumented)
subheader: FontSizeValuePoints;
}
// @public
export interface IFontVariants {
// (undocumented)
bodySemibold: FontVariantValue;
// (undocumented)
bodyStandard: FontVariantValue;
// (undocumented)
captionStandard: FontVariantValue;
// (undocumented)
headerSemibold: FontVariantValue;
// (undocumented)
headerStandard: FontVariantValue;
// (undocumented)
heroLargeSemibold: FontVariantValue;
// (undocumented)
heroLargeStandard: FontVariantValue;
// (undocumented)
heroSemibold: FontVariantValue;
// (undocumented)
heroStandard: FontVariantValue;
// (undocumented)
secondarySemibold: FontVariantValue;
// (undocumented)
secondaryStandard: FontVariantValue;
// (undocumented)
subheaderSemibold: FontVariantValue;
// (undocumented)
subheaderStandard: FontVariantValue;
}
// @public
export interface IFontWeights {
// (undocumented)
regular: FontWeightValue;
// (undocumented)
semiBold: FontWeightValue;
}
// @public
export type IPalette = IPaletteTextColors & IPaletteBackgroundColors;
// @public
export interface IPaletteBackgroundColors {
accentButtonBackground: ColorValue;
background: ColorValue;
blockingBackground: ColorValue;
bodyDivider: ColorValue;
bodyFrameBackground: ColorValue;
bodyFrameDivider: ColorValue;
bodyStandoutBackground: ColorValue;
buttonBackground: ColorValue;
buttonBackgroundChecked: ColorValue;
buttonBackgroundCheckedHovered: ColorValue;
buttonBackgroundDisabled: ColorValue;
buttonBackgroundHovered: ColorValue;
buttonBackgroundPressed: ColorValue;
buttonBorder: ColorValue;
buttonBorderDisabled: ColorValue;
buttonBorderFocused: ColorValue;
defaultStateBackground: ColorValue;
disabledBackground: ColorValue;
errorBackground: ColorValue;
focusBorder: ColorValue;
inputBackground: ColorValue;
inputBackgroundChecked: ColorValue;
inputBackgroundCheckedHovered: ColorValue;
inputBorder: ColorValue;
inputBorderHovered: ColorValue;
inputFocusBorderAlt: ColorValue;
inputForegroundChecked: ColorValue;
listBackground: ColorValue;
listHeaderBackgroundHovered: ColorValue;
listHeaderBackgroundPressed: ColorValue;
listItemBackgroundChecked: ColorValue;
listItemBackgroundCheckedHovered: ColorValue;
listItemBackgroundHovered: ColorValue;
listText: ColorValue;
menuBackground: ColorValue;
menuDivider: ColorValue;
menuHeader: ColorValue;
menuIcon: ColorValue;
menuItemBackgroundHovered: ColorValue;
menuItemBackgroundPressed: ColorValue;
menuItemText: ColorValue;
menuItemTextHovered: ColorValue;
primaryButtonBackground: ColorValue;
primaryButtonBackgroundDisabled: ColorValue;
primaryButtonBackgroundHovered: ColorValue;
primaryButtonBackgroundPressed: ColorValue;
primaryButtonBorder: ColorValue;
primaryButtonBorderFocused: ColorValue;
smallInputBorder: ColorValue;
successBackground: ColorValue;
variantBorder: ColorValue;
variantBorderHovered: ColorValue;
warningBackground: ColorValue;
warningHighlight: ColorValue;
}
// @public
export interface IPaletteTextColors {
accentButtonText: ColorValue;
actionLink: ColorValue;
actionLinkHovered: ColorValue;
bodyText: ColorValue;
bodyTextChecked: ColorValue;
buttonText: ColorValue;
buttonTextChecked: ColorValue;
buttonTextCheckedHovered: ColorValue;
buttonTextDisabled: ColorValue;
buttonTextHovered: ColorValue;
buttonTextPressed: ColorValue;
disabledBodySubtext: ColorValue;
disabledBodyText: ColorValue;
disabledSubtext: ColorValue;
disabledText: ColorValue;
errorText: ColorValue;
inputPlaceholderText: ColorValue;
inputText: ColorValue;
inputTextHovered: ColorValue;
link: ColorValue;
linkHovered: ColorValue;
linkPressed: ColorValue;
listText: ColorValue;
primaryButtonText: ColorValue;
primaryButtonTextDisabled: ColorValue;
primaryButtonTextHovered: ColorValue;
primaryButtonTextPressed: ColorValue;
subText: ColorValue;
warningText: ColorValue;
}
// @public
export type IPartialPalette = Partial<IPalette>;
// @public
export interface IPartialTheme {
// (undocumented)
colors?: Partial<IThemeColorDefinition>;
// (undocumented)
components?: IComponentSettingsCollection;
// (undocumented)
host?: object;
// (undocumented)
name?: string;
// (undocumented)
spacing?: ISpacing;
// (undocumented)
typography?: IPartialTypography;
}
// @public
export type IPartialTypography = {
[P in keyof ITypography]?: Partial<ITypography[P]>;
};
// @public (undocumented)
export interface ISpacing {
// (undocumented)
l1: string;
// (undocumented)
l2: string;
// (undocumented)
m: string;
// (undocumented)
s1: string;
// (undocumented)
s2: string;
}
// @public
export interface ITextStyle {
// (undocumented)
families: IFontFamilies;
// (undocumented)
sizes: IFontSizes;
// (undocumented)
variants: IFontVariants;
// (undocumented)
weights: IFontWeights;
}
// @public
export interface ITheme {
// (undocumented)
colors: IThemeColorDefinition;
// (undocumented)
components: IComponentSettingsCollection;
// (undocumented)
host: object;
// (undocumented)
name?: string;
// (undocumented)
spacing: ISpacing;
// (undocumented)
typography: ITypography;
}
// @public (undocumented)
export type IThemeColorDefinition = IPalette & {
background: ColorValue;
bodyText: ColorValue;
subText: ColorValue;
disabledText: ColorValue;
brand: IColorRamp;
neutral: IColorRamp;
warning: IColorRamp;
[key: string]: IColorRamp | string;
};
// @public (undocumented)
export type ITypography = ITextStyle;
// @public
export function paletteFromFabricColors(p: IFabricWebPalette, isInverted?: boolean): IPalette;
// @public
export function resolvePartialTheme(theme: ITheme, partialTheme?: IPartialTheme): ITheme;
// @public
export function returnAsSlotProps(target: IComponentSettings): IComponentSettings;
// (No @packageDocumentation comment for this package)
```

Просмотреть файл

@ -1,96 +1,110 @@
import { ITheme, IPartialTheme } from './Theme.types';
import { resolvePartialTheme } from './Theme';
import { IThemeColorDefinition } from './Color.types';
import { ITypography } from './Typography.types';
const theme: ITheme = {
colors: {
background: '#ff0000'
} as IThemeColorDefinition,
typography: {
families: {
primary: 'Arial'
},
sizes: {
medium: 14
},
weights: {
medium: '500'
}
} as ITypography,
spacing: { s2: '4px', s1: '8px', m: '16px', l1: '20px', l2: '32px' },
components: {
View: {
tokens: {
backgroundColor: 'bodyBackground',
fontFamily: 'primary'
}
}
},
host: {}
};
const partialTheme: IPartialTheme = {
colors: {
bodySubtext: 'rgb(100,100,100)'
},
components: {
Text: {
tokens: {
backgroundColor: 'cyan'
}
}
}
};
describe('Theme tests', () => {
test("resolvePartialTheme reuses the theme's colors object when the partial theme is empty", () => {
const resolved = resolvePartialTheme(theme, {});
expect(resolved.colors).toBe(theme.colors);
});
test("resolvePartialTheme reuses the theme's typography object when the partial theme is empty", () => {
const resolved = resolvePartialTheme(theme, {});
expect(resolved.typography).toBe(theme.typography);
});
test("resolvePartialTheme reuses the theme's layer collection object when the partial theme is empty", () => {
const resolved = resolvePartialTheme(theme, {});
expect(resolved.components).toBe(theme.components);
});
test('resolvePartialTheme returns a blend of the partial theme and the full theme', () => {
const resolved = resolvePartialTheme(theme, partialTheme);
expect(resolved).toEqual({
colors: ({
background: '#ff0000',
bodySubtext: 'rgb(100,100,100)'
} as unknown) as IThemeColorDefinition,
typography: {
families: {
primary: 'Arial'
},
sizes: {
medium: 14
},
weights: {
medium: '500'
}
} as ITypography,
spacing: { s2: '4px', s1: '8px', m: '16px', l1: '20px', l2: '32px' },
components: {
View: {
tokens: {
backgroundColor: 'bodyBackground',
fontFamily: 'primary'
}
},
Text: {
tokens: {
backgroundColor: 'cyan'
}
}
}
});
});
});
import { ITheme, IPartialTheme } from './Theme.types';
import { resolvePartialTheme } from './Theme';
import { IThemeColorDefinition } from './Color.types';
import { ITypography } from './Typography.types';
const theme: ITheme = {
colors: {
background: '#ff0000'
} as IThemeColorDefinition,
typography: {
families: {
primary: 'Arial'
},
sizes: {
secondary: 14
},
weights: {
regular: '400'
},
variants: {
secondaryStandard: {
face: 'Arial',
size: 14,
weight: '400'
}
}
} as ITypography,
spacing: { s2: '4px', s1: '8px', m: '16px', l1: '20px', l2: '32px' },
components: {
View: {
tokens: {
backgroundColor: 'bodyBackground',
fontFamily: 'primary'
}
}
},
host: {}
};
const partialTheme: IPartialTheme = {
colors: {
bodySubtext: 'rgb(100,100,100)'
},
components: {
Text: {
tokens: {
backgroundColor: 'cyan'
}
}
}
};
describe('Theme tests', () => {
test("resolvePartialTheme reuses the theme's colors object when the partial theme is empty", () => {
const resolved = resolvePartialTheme(theme, {});
expect(resolved.colors).toBe(theme.colors);
});
test("resolvePartialTheme reuses the theme's typography object when the partial theme is empty", () => {
const resolved = resolvePartialTheme(theme, {});
expect(resolved.typography).toBe(theme.typography);
});
test("resolvePartialTheme reuses the theme's layer collection object when the partial theme is empty", () => {
const resolved = resolvePartialTheme(theme, {});
expect(resolved.components).toBe(theme.components);
});
test('resolvePartialTheme returns a blend of the partial theme and the full theme', () => {
const resolved = resolvePartialTheme(theme, partialTheme);
expect(resolved).toEqual({
colors: ({
background: '#ff0000',
bodySubtext: 'rgb(100,100,100)'
} as unknown) as IThemeColorDefinition,
typography: {
families: {
primary: 'Arial'
},
sizes: {
secondary: 14
},
weights: {
regular: '400'
},
variants: {
secondaryStandard: {
face: 'Arial',
size: 14,
weight: '400'
}
}
} as ITypography,
spacing: { s2: '4px', s1: '8px', m: '16px', l1: '20px', l2: '32px' },
components: {
View: {
tokens: {
backgroundColor: 'bodyBackground',
fontFamily: 'primary'
}
},
Text: {
tokens: {
backgroundColor: 'cyan'
}
}
}
});
});
});

Просмотреть файл

@ -1,49 +1,68 @@
import { IFontFamilies, IFontSizes, IFontWeights, ITypography } from './Typography.types';
import { resolveFontFamily, resolveFontSize, resolveFontWeight } from './Typography';
const families = {
primary: 'Verdana',
monospace: 'Courier New'
} as IFontFamilies;
const sizes = {
xSmall: 8,
xLarge: 16
} as IFontSizes;
const weights = {
medium: '500',
semiBold: '700'
} as IFontWeights;
const typography: ITypography = {
families,
sizes,
weights
};
describe('Typography tests', () => {
test('resolveFontFamily "monospace" returns "Courier New"', () => {
expect(resolveFontFamily(typography, 'monospace')).toBe('Courier New');
});
test('resolveFontFamily "Arial" returns "Arial"', () => {
expect(resolveFontFamily(typography, 'Arial')).toBe('Arial');
});
test('resolveFontSize "xSmall" returns 8', () => {
expect(resolveFontSize(typography, 'xSmall')).toBe(8);
});
test('resolveFontSize 15 returns 15', () => {
expect(resolveFontSize(typography, 15)).toBe(15);
});
test('resolveFontSize "semiBold" returns 700', () => {
expect(resolveFontWeight(typography, 'semiBold')).toBe('700');
});
test('resolveFontSize 200 returns 200', () => {
expect(resolveFontWeight(typography, '200')).toBe('200');
});
});
import { IFontFamilies, IFontSizes, IFontWeights, IFontVariants, ITypography } from './Typography.types';
import { resolveFontFamily, resolveFontSize, resolveFontWeight } from './Typography';
const families = {
primary: 'Verdana',
monospace: 'Courier New'
} as IFontFamilies;
const sizes = {
caption: 8,
subheader: 16
} as IFontSizes;
const weights = {
regular: '500',
semiBold: '700'
} as IFontWeights;
const variants = {
captionStandard: {
face: 'Verdana',
size: 8,
weight: '500'
},
subheaderStandard: {
face: 'Verdana',
size: 16,
weight: '500'
},
subheaderSemibold: {
face: 'Verdana',
size: 16,
weight: '700'
}
} as IFontVariants;
const typography: ITypography = {
families,
sizes,
weights,
variants
};
describe('Typography tests', () => {
test('resolveFontFamily "monospace" returns "Courier New"', () => {
expect(resolveFontFamily(typography, 'monospace')).toBe('Courier New');
});
test('resolveFontFamily "Arial" returns "Arial"', () => {
expect(resolveFontFamily(typography, 'Arial')).toBe('Arial');
});
test('resolveFontSize "caption" returns 8', () => {
expect(resolveFontSize(typography, 'caption')).toBe(8);
});
test('resolveFontSize 15 returns 15', () => {
expect(resolveFontSize(typography, 15)).toBe(15);
});
test('resolveFontSize "semiBold" returns 700', () => {
expect(resolveFontWeight(typography, 'semiBold')).toBe('700');
});
test('resolveFontSize 200 returns 200', () => {
expect(resolveFontWeight(typography, '200')).toBe('200');
});
});

Просмотреть файл

@ -1,114 +1,146 @@
/**
* A font family designation, made up of one or more font names or groupings
* (comma-separated):
*
* - `Calibri Light`, `Calibri, Times`
* - `Menlo, Monaco`, `Courier New`, `Courier`
* - `Consolas`
*
* The font family expresses an ordered preference of fonts to use, working
* from the first entry to the last. This "fallback" mechanism is necessary
* because the availability of specific fonts varies between native platforms,
* as well as between operating system versions.
*/
export type FontFamilyValue = string;
/**
* A collection of named font families.
*
* The names express the fundamental character of the assigned font family. They
* should be used when defining a theme.
*
* **NOTE:** `primary` and `secondary` are both meant to be assigned a 'normal' family.
*/
export interface IFontFamilies {
primary: FontFamilyValue;
secondary: FontFamilyValue;
cursive: FontFamilyValue;
monospace: FontFamilyValue;
sansSerif: FontFamilyValue;
serif: FontFamilyValue;
}
/**
* A font family, used when defining a visual element in a theme.
*/
export type FontFamily = keyof IFontFamilies | FontFamilyValue;
/**
* A font size value, specified in points (pt).
*/
export type FontSizeValuePoints = number;
/**
* A collection of named font sizes.
*
* The names express a spectrum of relative sizes. Words are used instead
* of numbers to avoid implying anything about the size value, or its
* relationship to size values near it.
*
* These names should be used when defining a theme.
*/
export interface IFontSizes {
xxxSmall: FontSizeValuePoints;
xxSmall: FontSizeValuePoints;
xSmall: FontSizeValuePoints;
small: FontSizeValuePoints;
medium: FontSizeValuePoints;
large: FontSizeValuePoints;
xLarge: FontSizeValuePoints;
xxLarge: FontSizeValuePoints;
xxxLarge: FontSizeValuePoints;
}
/**
* A font size, used when defining a visual element in a theme.
*/
export type FontSize = keyof IFontSizes | FontSizeValuePoints;
/**
* A font weight value.
*
* Smaller numbers yield a thinner, lighter font. Larger numbers yield a thicker, farker
* font.
*/
export type FontWeightValue = '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
/**
* A collection of named font weights.
*
* The names express a spectrum of relative weights. Words are used instead
* of numbers to avoid implying anything about the weight value, or its
* relationship to weight values near it.
*
* These names should be used when defining a theme.
*/
export interface IFontWeights {
light: FontWeightValue;
semiLight: FontWeightValue;
medium: FontWeightValue;
semiBold: FontWeightValue;
bold: FontWeightValue;
}
/**
* A font weight, used when defining a visual element in a theme.
*/
export type FontWeight = keyof IFontWeights | FontWeightValue;
/**
* A collection of typographic (font) information.
*
* When setting a font in a theme, choose a family, size and weight from
* this collection.
*/
export interface ITypography {
families: IFontFamilies;
sizes: IFontSizes;
weights: IFontWeights;
}
/**
* A partially specified typography.
*/
export type IPartialTypography = { [P in keyof ITypography]?: Partial<ITypography[P]> };
/**
* A font family designation, made up of one or more font names or groupings
* (comma-separated):
*
* - `Calibri Light`, `Calibri, Times`
* - `Menlo, Monaco`, `Courier New`, `Courier`
* - `Consolas`
*
* The font family expresses an ordered preference of fonts to use, working
* from the first entry to the last. This "fallback" mechanism is necessary
* because the availability of specific fonts varies between native platforms,
* as well as between operating system versions.
*/
export type FontFamilyValue = string;
/**
* A collection of named font families.
*
* The names express the fundamental character of the assigned font family. They
* should be used when defining a theme.
*
* **NOTE:** `primary` and `secondary` are both meant to be assigned a 'normal' family.
*/
export interface IFontFamilies {
primary: FontFamilyValue;
secondary: FontFamilyValue;
cursive: FontFamilyValue;
monospace: FontFamilyValue;
sansSerif: FontFamilyValue;
serif: FontFamilyValue;
}
/**
* A font family, used when defining a visual element in a theme.
*/
export type FontFamily = keyof IFontFamilies | FontFamilyValue;
/**
* A font size value, specified in points (pt).
*/
export type FontSizeValuePoints = number;
/**
* A collection of named font sizes.
*
* The names express a spectrum of relative sizes. Words are used instead
* of numbers to avoid implying anything about the size value, or its
* relationship to size values near it.
*
* These names should be used when defining a theme.
*/
export interface IFontSizes {
caption: FontSizeValuePoints;
secondary: FontSizeValuePoints;
body: FontSizeValuePoints;
subheader: FontSizeValuePoints;
header: FontSizeValuePoints;
hero: FontSizeValuePoints;
heroLarge: FontSizeValuePoints;
}
/**
* A font size, used when defining a visual element in a theme.
*/
export type FontSize = keyof IFontSizes | FontSizeValuePoints;
/**
* A font weight value.
*
* Smaller numbers yield a thinner, lighter font. Larger numbers yield a thicker, farker
* font.
*/
export type FontWeightValue = '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
/**
* A collection of named font weights.
*
* The names express a spectrum of relative weights. Words are used instead
* of numbers to avoid implying anything about the weight value, or its
* relationship to weight values near it.
*
* These names should be used when defining a theme.
*/
export interface IFontWeights {
regular: FontWeightValue;
semiBold: FontWeightValue;
}
/**
* A font weight, used when defining a visual element in a theme.
*/
export type FontWeight = keyof IFontWeights | FontWeightValue;
/**
* A font variant value.
*/
export type FontVariantValue = {
face: FontFamily;
size: FontSize;
weight: FontWeight;
};
/**
* A collection of named font variants.
*/
export interface IFontVariants {
captionStandard: FontVariantValue;
secondaryStandard: FontVariantValue;
secondarySemibold: FontVariantValue;
bodyStandard: FontVariantValue;
bodySemibold: FontVariantValue;
subheaderStandard: FontVariantValue;
subheaderSemibold: FontVariantValue;
headerStandard: FontVariantValue;
headerSemibold: FontVariantValue;
heroStandard: FontVariantValue;
heroSemibold: FontVariantValue;
heroLargeStandard: FontVariantValue;
heroLargeSemibold: FontVariantValue;
}
/**
* A font variant, used when defining a visual element in a theme.
*/
export type FontVariant = keyof IFontVariants | FontVariantValue;
/**
* A collection of typographic (font) information.
*
* When setting a font in a theme, choose a family, size and weight from
* this collection.
*/
export interface ITextStyle {
families: IFontFamilies;
sizes: IFontSizes;
weights: IFontWeights;
variants: IFontVariants;
}
export type ITypography = ITextStyle;
/**
* A partially specified typography.
*/
export type IPartialTypography = { [P in keyof ITypography]?: Partial<ITypography[P]> };

Просмотреть файл

@ -1,47 +1,57 @@
import { ITheme } from './Theme.types';
import { getStockWebPalette, ITypography, ISpacing } from '@uifabricshared/theming-ramp';
function _defaultTypography(): ITypography {
return {
sizes: {
xxxSmall: 8,
xxSmall: 9,
xSmall: 10,
small: 11,
medium: 12,
large: 14,
xLarge: 18,
xxLarge: 24,
xxxLarge: 32
},
weights: {
light: '200',
semiLight: '300',
medium: '500',
semiBold: '700',
bold: '900'
},
families: {
primary: 'Segoe UI',
secondary: 'System',
cursive: 'System',
monospace: 'System',
sansSerif: 'System',
serif: 'System'
}
};
}
export function defaultSpacing(): ISpacing {
return { s2: '4px', s1: '8px', m: '16px', l1: '20px', l2: '32px' };
}
export function getBaselinePlatformTheme(): ITheme {
return {
colors: getStockWebPalette(),
typography: _defaultTypography(),
spacing: defaultSpacing(),
components: {},
host: {}
};
}
import { ITheme } from './Theme.types';
import { getStockWebPalette, ITypography, ISpacing } from '@uifabricshared/theming-ramp';
function _defaultTypography(): ITypography {
return {
sizes: {
caption: 8,
secondary: 9,
body: 11,
subheader: 12,
header: 15,
hero: 21,
heroLarge: 32
},
weights: {
regular: '400',
semiBold: '600'
},
families: {
primary: 'Segoe UI',
secondary: 'System',
cursive: 'System',
monospace: 'System',
sansSerif: 'System',
serif: 'System'
},
variants: {
captionStandard: { face: 'primary', size: 'caption', weight: 'regular' },
secondaryStandard: { face: 'primary', size: 'secondary', weight: 'regular' },
secondarySemibold: { face: 'primary', size: 'secondary', weight: 'semiBold' },
bodyStandard: { face: 'primary', size: 'body', weight: 'regular' },
bodySemibold: { face: 'primary', size: 'body', weight: 'semiBold' },
subheaderStandard: { face: 'primary', size: 'subheader', weight: 'regular' },
subheaderSemibold: { face: 'primary', size: 'subheader', weight: 'semiBold' },
headerStandard: { face: 'primary', size: 'header', weight: 'regular' },
headerSemibold: { face: 'primary', size: 'header', weight: 'semiBold' },
heroStandard: { face: 'primary', size: 'hero', weight: 'regular' },
heroSemibold: { face: 'primary', size: 'hero', weight: 'semiBold' },
heroLargeStandard: { face: 'primary', size: 'heroLarge', weight: 'regular' },
heroLargeSemibold: { face: 'primary', size: 'heroLarge', weight: 'semiBold' }
}
};
}
export function defaultSpacing(): ISpacing {
return { s2: '4px', s1: '8px', m: '16px', l1: '20px', l2: '32px' };
}
export function getBaselinePlatformTheme(): ITheme {
return {
colors: getStockWebPalette(),
typography: _defaultTypography(),
spacing: defaultSpacing(),
components: {},
host: {}
};
}

Просмотреть файл

@ -1,157 +1,158 @@
import { IOfficeThemingModule, IThemingModuleHelper, IEventEmitter } from './ThemingModule.types';
import { getBaselinePlatformTheme } from '../BaselinePlatformDefaults';
import { IOfficePalette } from './office';
import { createThemingModuleHelper } from './ThemingModuleHelpers';
const whiteColorsPalette: IOfficePalette = {
Bkg: 'antiquewhite',
BkgHover: '#E6E6E6',
BkgPressed: '#969696',
BkgSelected: '#D2D2D2',
BkgSelectionHighlight: '#737373',
Text: '#505050',
TextRest: '#505050',
TextHover: '#505050',
TextPressed: 'white',
TextSelected: '#505050',
TextDisabled: '#D2D2D2',
TextSelectionHighlight: 'white',
TextSecondary: '#737373',
TextSecondaryRest: '#737373',
TextSecondaryHover: '#505050',
TextSecondaryPressed: '#F3F3F3',
TextSecondarySelected: '#505050',
TextEmphasis: '#2B579A',
TextEmphasisRest: '#2B579A',
TextEmphasisHover: '#2B579A',
TextEmphasisPressed: '#2B579A',
TextEmphasisSelected: '#002050',
StrokeSelectedHover: '#969696',
StrokeKeyboard: '#505050',
StrokeOverlayRest: 'transparent',
StrokeOverlayHover: 'transparent',
StrokeOverlayPressed: 'transparent',
StrokeOverlaySelectedRest: 'transparent',
StrokeOverlaySelectedHover: '#969696',
StrokeOverlaySelectedPressed: 'transparent',
BkgCtl: '#D2D2D2',
BkgCtlHover: '#E6E6E6',
BkgCtlPressed: '#969696',
BkgCtlSelected: '#D2D2D2',
BkgCtlDisabled: '#D2D2D24D',
TextCtl: '#505050',
TextCtlHover: '#505050',
TextCtlPressed: '#505050',
TextCtlSelected: '#505050',
TextCtlDisabled: '#D2D2D24D',
StrokeCtl: 'transparent',
StrokeCtlHover: 'transparent',
StrokeCtlPressed: 'transparent',
StrokeCtlSelected: '#969696',
StrokeCtlDisabled: '#E6E6E6',
StrokeCtlKeyboard: '#737373',
BkgCtlEmphasis: 'pink',
BkgCtlEmphasisHover: 'pink',
BkgCtlEmphasisPressed: 'pink',
BkgCtlEmphasisDisabled: 'pink',
TextCtlEmphasis: 'white',
TextCtlEmphasisHover: 'white',
TextCtlEmphasisPressed: 'white',
TextCtlEmphasisDisabled: 'white',
StrokeCtlEmphasis: 'pink',
StrokeCtlEmphasisHover: 'pink',
StrokeCtlEmphasisPressed: 'pink',
StrokeCtlEmphasisDisabled: 'pink',
StrokeCtlEmphasisKeyboard: 'white',
BkgCtlSubtle: 'antiquewhite',
BkgCtlSubtleHover: 'white',
BkgCtlSubtlePressed: '#D2D2D24D',
BkgCtlSubtleDisabled: 'pink',
BkgCtlSubtleSelectionHighlight: 'pink',
TextCtlSubtle: 'pink',
TextCtlSubtlePlaceholder: 'pink',
TextCtlSubtleHover: 'pink',
TextCtlSubtlePressed: 'pink',
TextCtlSubtleDisabled: 'pink',
TextCtlSubtleSelectionHighlight: 'pink',
StrokeCtlSubtle: 'pink',
StrokeCtlSubtleHover: 'pink',
StrokeCtlSubtlePressed: 'pink',
StrokeCtlSubtleDisabled: 'pink',
StrokeCtlSubtleKeyboard: 'pink',
TextHyperlink: 'pink',
TextHyperlinkHover: 'pink',
TextHyperlinkPressed: 'pink',
TextActive: 'pink',
TextActiveHover: 'pink',
TextActivePressed: 'pink',
TextActiveSelected: 'pink',
TextError: 'pink',
TextErrorHover: 'pink',
TextErrorPressed: 'pink',
TextErrorSelected: 'pink',
AccentDark: 'pink',
AccentLight: 'pink',
AccentEmphasis: 'pink',
AccentOutline: 'pink',
BkgHeader: 'pink',
TextHeader: 'pink'
};
const taskPanePalette: IOfficePalette = {
...whiteColorsPalette,
Bkg: '#E6E6E6',
BkgCtlEmphasis: 'green',
TextCtlEmphasis: 'white'
};
const baseline = getBaselinePlatformTheme();
export const mockGetPaletteImpl = (pal?: string) => {
return (pal === 'TaskPane' && taskPanePalette) || whiteColorsPalette;
};
const mockModule: IOfficeThemingModule = {
ramps: {
App: ['#F8F8F8', '#EFF6FC', '#BBDAF3', '#55A4E2', '#359EDD', '#0078d7', '#283E4A', '#030C13'],
FluentGrays: ['#FAF9F8', '#797775', '#11100F'],
ClassicGrays: ['#FFFFFF', '#737373', '#000000'],
Sepias: ['#ECE6DE']
},
getPalette: mockGetPaletteImpl,
typography: baseline.typography
};
export function createMockThemingModule(module?: Partial<IOfficeThemingModule>) {
return { ...mockModule, ...module };
}
export function createMockThemingModuleHelper(
module?: Partial<IOfficeThemingModule>,
emitter?: IEventEmitter,
behaviorOverrides?: Partial<IThemingModuleHelper>
): IThemingModuleHelper {
return {
...createThemingModuleHelper(createMockThemingModule(module), emitter),
...behaviorOverrides
};
}
import { IOfficeThemingModule, IThemingModuleHelper, IEventEmitter } from './ThemingModule.types';
import { getBaselinePlatformTheme } from '../BaselinePlatformDefaults';
import { IOfficePalette } from './office';
import { createThemingModuleHelper } from './ThemingModuleHelpers';
const whiteColorsPalette: IOfficePalette = {
Bkg: 'antiquewhite',
BkgHover: '#E6E6E6',
BkgPressed: '#969696',
BkgSelected: '#D2D2D2',
BkgSelectionHighlight: '#737373',
Text: '#505050',
TextRest: '#505050',
TextHover: '#505050',
TextPressed: 'white',
TextSelected: '#505050',
TextDisabled: '#D2D2D2',
TextSelectionHighlight: 'white',
TextSecondary: '#737373',
TextSecondaryRest: '#737373',
TextSecondaryHover: '#505050',
TextSecondaryPressed: '#F3F3F3',
TextSecondarySelected: '#505050',
TextEmphasis: '#2B579A',
TextEmphasisRest: '#2B579A',
TextEmphasisHover: '#2B579A',
TextEmphasisPressed: '#2B579A',
TextEmphasisSelected: '#002050',
StrokeSelectedHover: '#969696',
StrokeKeyboard: '#505050',
StrokeOverlayRest: 'transparent',
StrokeOverlayHover: 'transparent',
StrokeOverlayPressed: 'transparent',
StrokeOverlaySelectedRest: 'transparent',
StrokeOverlaySelectedHover: '#969696',
StrokeOverlaySelectedPressed: 'transparent',
BkgCtl: '#D2D2D2',
BkgCtlHover: '#E6E6E6',
BkgCtlPressed: '#969696',
BkgCtlSelected: '#D2D2D2',
BkgCtlDisabled: '#D2D2D24D',
TextCtl: '#505050',
TextCtlHover: '#505050',
TextCtlPressed: '#505050',
TextCtlSelected: '#505050',
TextCtlDisabled: '#D2D2D24D',
StrokeCtl: 'transparent',
StrokeCtlHover: 'transparent',
StrokeCtlPressed: 'transparent',
StrokeCtlSelected: '#969696',
StrokeCtlDisabled: '#E6E6E6',
StrokeCtlKeyboard: '#737373',
BkgCtlEmphasis: 'pink',
BkgCtlEmphasisHover: 'pink',
BkgCtlEmphasisPressed: 'pink',
BkgCtlEmphasisDisabled: 'pink',
TextCtlEmphasis: 'white',
TextCtlEmphasisHover: 'white',
TextCtlEmphasisPressed: 'white',
TextCtlEmphasisDisabled: 'white',
StrokeCtlEmphasis: 'pink',
StrokeCtlEmphasisHover: 'pink',
StrokeCtlEmphasisPressed: 'pink',
StrokeCtlEmphasisDisabled: 'pink',
StrokeCtlEmphasisKeyboard: 'white',
BkgCtlSubtle: 'antiquewhite',
BkgCtlSubtleHover: 'white',
BkgCtlSubtlePressed: '#D2D2D24D',
BkgCtlSubtleDisabled: 'pink',
BkgCtlSubtleSelectionHighlight: 'pink',
TextCtlSubtle: 'pink',
TextCtlSubtlePlaceholder: 'pink',
TextCtlSubtleHover: 'pink',
TextCtlSubtlePressed: 'pink',
TextCtlSubtleDisabled: 'pink',
TextCtlSubtleSelectionHighlight: 'pink',
StrokeCtlSubtle: 'pink',
StrokeCtlSubtleHover: 'pink',
StrokeCtlSubtlePressed: 'pink',
StrokeCtlSubtleDisabled: 'pink',
StrokeCtlSubtleKeyboard: 'pink',
TextHyperlink: 'pink',
TextHyperlinkHover: 'pink',
TextHyperlinkPressed: 'pink',
TextActive: 'pink',
TextActiveHover: 'pink',
TextActivePressed: 'pink',
TextActiveSelected: 'pink',
TextError: 'pink',
TextErrorHover: 'pink',
TextErrorPressed: 'pink',
TextErrorSelected: 'pink',
AccentDark: 'pink',
AccentLight: 'pink',
AccentEmphasis: 'pink',
AccentOutline: 'pink',
BkgHeader: 'pink',
TextHeader: 'pink'
};
const taskPanePalette: IOfficePalette = {
...whiteColorsPalette,
Bkg: '#E6E6E6',
BkgCtlEmphasis: 'green',
TextCtlEmphasis: 'white'
};
const baseline = getBaselinePlatformTheme();
export const mockGetPaletteImpl = (pal?: string) => {
return (pal === 'TaskPane' && taskPanePalette) || whiteColorsPalette;
};
const mockModule: IOfficeThemingModule = {
ramps: {
App: ['#F8F8F8', '#EFF6FC', '#BBDAF3', '#55A4E2', '#359EDD', '#0078d7', '#283E4A', '#030C13'],
FluentGrays: ['#FAF9F8', '#797775', '#11100F'],
ClassicGrays: ['#FFFFFF', '#737373', '#000000'],
Sepias: ['#ECE6DE']
},
getPalette: mockGetPaletteImpl,
typography: baseline.typography,
fluentTypography: baseline.typography
};
export function createMockThemingModule(module?: Partial<IOfficeThemingModule>) {
return { ...mockModule, ...module };
}
export function createMockThemingModuleHelper(
module?: Partial<IOfficeThemingModule>,
emitter?: IEventEmitter,
behaviorOverrides?: Partial<IThemingModuleHelper>
): IThemingModuleHelper {
return {
...createThemingModuleHelper(createMockThemingModule(module), emitter),
...behaviorOverrides
};
}

Просмотреть файл

@ -1,49 +1,50 @@
import { ITypography, ColorValue } from '@uifabricshared/theming-ramp';
import { ITheme, IPartialTheme } from '@uifabricshared/theming-ramp';
import { IOfficePalette } from './office';
import { IProcessTheme } from '@uifabricshared/theme-registry';
export type PlatformDefaultsChangedArgs = { hostThemeSetting: string };
export type PlatformDefaultsChangedCallback = (args?: PlatformDefaultsChangedArgs) => void;
export interface ICxxException {
message: string;
}
export interface INativeColorRamps {
FluentGrays: ColorValue[];
ClassicGrays: ColorValue[];
App: ColorValue[];
Sepias: ColorValue[];
[key: string]: ColorValue[];
}
export interface IOfficeThemingModule {
getPalette(palette?: string): IOfficePalette | ICxxException;
typography: ITypography;
ramps: INativeColorRamps;
initialHostThemeSetting?: string;
}
export interface IEventEmitter {
addListener: (event: string, PlatformDefaultsChangedCallback) => void;
}
export type IPlatformThemeDefinition = IPartialTheme | IProcessTheme<ITheme, IPartialTheme>;
export interface IThemingModuleHelper {
/**
* Gets a complete platform theme suitable for using with a Theme Registry
*/
getPlatformDefaults: (themeId?: string) => ITheme;
/**
* Gets a theme definition to register with a Theme Registry & use with the theme context to create a subtree with the
* look & feel of a platform theme.
*/
getPlatformThemeDefinition: (themeId?: string) => IPlatformThemeDefinition;
addListener: (listener: PlatformDefaultsChangedCallback) => void; // TODO: Should probably be able to remove
}
export type IHostSettingsWin32 = {
palette: IOfficePalette;
};
import { ITypography, ColorValue } from '@uifabricshared/theming-ramp';
import { ITheme, IPartialTheme } from '@uifabricshared/theming-ramp';
import { IOfficePalette } from './office';
import { IProcessTheme } from '@uifabricshared/theme-registry';
export type PlatformDefaultsChangedArgs = { hostThemeSetting: string };
export type PlatformDefaultsChangedCallback = (args?: PlatformDefaultsChangedArgs) => void;
export interface ICxxException {
message: string;
}
export interface INativeColorRamps {
FluentGrays: ColorValue[];
ClassicGrays: ColorValue[];
App: ColorValue[];
Sepias: ColorValue[];
[key: string]: ColorValue[];
}
export interface IOfficeThemingModule {
getPalette(palette?: string): IOfficePalette | ICxxException;
typography: ITypography;
fluentTypography: ITypography;
ramps: INativeColorRamps;
initialHostThemeSetting?: string;
}
export interface IEventEmitter {
addListener: (event: string, PlatformDefaultsChangedCallback) => void;
}
export type IPlatformThemeDefinition = IPartialTheme | IProcessTheme<ITheme, IPartialTheme>;
export interface IThemingModuleHelper {
/**
* Gets a complete platform theme suitable for using with a Theme Registry
*/
getPlatformDefaults: (themeId?: string) => ITheme;
/**
* Gets a theme definition to register with a Theme Registry & use with the theme context to create a subtree with the
* look & feel of a platform theme.
*/
getPlatformThemeDefinition: (themeId?: string) => IPlatformThemeDefinition;
addListener: (listener: PlatformDefaultsChangedCallback) => void; // TODO: Should probably be able to remove
}
export type IHostSettingsWin32 = {
palette: IOfficePalette;
};

Просмотреть файл

@ -1,86 +1,86 @@
import { ITheme, IPartialPalette, IColorRamp, resolvePartialTheme } from '@uifabricshared/theming-ramp';
import {
IOfficeThemingModule,
ICxxException,
PlatformDefaultsChangedCallback,
IThemingModuleHelper,
IEventEmitter,
PlatformDefaultsChangedArgs
} from './ThemingModule.types';
import { getBaselinePlatformTheme } from '../BaselinePlatformDefaults';
import { IOfficePalette, paletteFromOfficeColors } from './office';
import { useFakePalette } from './useFakePalette';
const createColorRamp = ({ values, index = -1 }: Partial<IColorRamp>) => ({
values,
index,
toString() {
return this.values[Math.round(values.length / 2)];
}
});
type PaletteCache = { [key: string]: IOfficePalette };
function isException(palette: IOfficePalette | ICxxException): palette is ICxxException {
return (palette as ICxxException).message !== undefined;
}
function updatePaletteInCache(module: IOfficeThemingModule, cache: PaletteCache, palette: string) {
const paletteValue = module.getPalette(palette);
if (!isException(paletteValue)) {
cache[palette] = paletteValue;
}
}
function translatePalette(module: IOfficeThemingModule, paletteCache: PaletteCache, palette?: string): IPartialPalette {
const key = useFakePalette ? 'debug' : palette || 'WhiteColors';
if (!paletteCache[key]) {
updatePaletteInCache(module, paletteCache, key);
}
return paletteCache[key] ? paletteFromOfficeColors(paletteCache[key]) : {};
}
export function translateOfficeTheme(module: IOfficeThemingModule, cache: PaletteCache, id?: string) {
const palette = translatePalette(module, cache, id);
return {
colors: {
brand: createColorRamp({ values: module.ramps.App }),
neutrals: createColorRamp({ values: module.ramps.FluentGrays }),
warning: createColorRamp({ values: module.ramps.Sepias }),
neutrals2: createColorRamp({ values: module.ramps.ClassicGrays }),
...palette
},
typography: module.typography,
host: {
palette: cache[id]
}
};
}
export function createThemingModuleHelper(themingModule?: IOfficeThemingModule, emitter?: IEventEmitter): IThemingModuleHelper {
themingModule || console.error('No NativeModule for Theming found');
const paletteCache: PaletteCache = {};
let _hostTheme = themingModule.initialHostThemeSetting || '';
emitter &&
emitter.addListener('onPlatformDefaultsChanged', (args: PlatformDefaultsChangedArgs) => {
_hostTheme = (args && args.hostThemeSetting) || _hostTheme;
Object.keys(paletteCache).forEach((key: string) => delete paletteCache[key]);
});
return {
getPlatformDefaults: (themeId?: string) => {
return resolvePartialTheme(
getBaselinePlatformTheme(),
Object.assign(translateOfficeTheme(themingModule, paletteCache, themeId), { name: _hostTheme })
);
},
getPlatformThemeDefinition: (themeId?: string) => {
return (_parent: ITheme) => {
updatePaletteInCache(themingModule, paletteCache, themeId);
return translateOfficeTheme(themingModule, paletteCache, themeId);
};
},
addListener: (callback: PlatformDefaultsChangedCallback) => {
emitter && emitter.addListener('onPlatformDefaultsChanged', callback);
}
};
}
import { ITheme, IPartialPalette, IColorRamp, resolvePartialTheme } from '@uifabricshared/theming-ramp';
import {
IOfficeThemingModule,
ICxxException,
PlatformDefaultsChangedCallback,
IThemingModuleHelper,
IEventEmitter,
PlatformDefaultsChangedArgs
} from './ThemingModule.types';
import { getBaselinePlatformTheme } from '../BaselinePlatformDefaults';
import { IOfficePalette, paletteFromOfficeColors } from './office';
import { useFakePalette } from './useFakePalette';
const createColorRamp = ({ values, index = -1 }: Partial<IColorRamp>) => ({
values,
index,
toString() {
return this.values[Math.round(values.length / 2)];
}
});
type PaletteCache = { [key: string]: IOfficePalette };
function isException(palette: IOfficePalette | ICxxException): palette is ICxxException {
return (palette as ICxxException).message !== undefined;
}
function updatePaletteInCache(module: IOfficeThemingModule, cache: PaletteCache, palette: string) {
const paletteValue = module.getPalette(palette);
if (!isException(paletteValue)) {
cache[palette] = paletteValue;
}
}
function translatePalette(module: IOfficeThemingModule, paletteCache: PaletteCache, palette?: string): IPartialPalette {
const key = useFakePalette ? 'debug' : palette || 'WhiteColors';
if (!paletteCache[key]) {
updatePaletteInCache(module, paletteCache, key);
}
return paletteCache[key] ? paletteFromOfficeColors(paletteCache[key]) : {};
}
export function translateOfficeTheme(module: IOfficeThemingModule, cache: PaletteCache, id?: string) {
const palette = translatePalette(module, cache, id);
return {
colors: {
brand: createColorRamp({ values: module.ramps.App }),
neutrals: createColorRamp({ values: module.ramps.FluentGrays }),
warning: createColorRamp({ values: module.ramps.Sepias }),
neutrals2: createColorRamp({ values: module.ramps.ClassicGrays }),
...palette
},
typography: module.fluentTypography,
host: {
palette: cache[id]
}
};
}
export function createThemingModuleHelper(themingModule?: IOfficeThemingModule, emitter?: IEventEmitter): IThemingModuleHelper {
themingModule || console.error('No NativeModule for Theming found');
const paletteCache: PaletteCache = {};
let _hostTheme = themingModule.initialHostThemeSetting || '';
emitter &&
emitter.addListener('onPlatformDefaultsChanged', (args: PlatformDefaultsChangedArgs) => {
_hostTheme = (args && args.hostThemeSetting) || _hostTheme;
Object.keys(paletteCache).forEach((key: string) => delete paletteCache[key]);
});
return {
getPlatformDefaults: (themeId?: string) => {
return resolvePartialTheme(
getBaselinePlatformTheme(),
Object.assign(translateOfficeTheme(themingModule, paletteCache, themeId), { name: _hostTheme })
);
},
getPlatformThemeDefinition: (themeId?: string) => {
return (_parent: ITheme) => {
updatePaletteInCache(themingModule, paletteCache, themeId);
return translateOfficeTheme(themingModule, paletteCache, themeId);
};
},
addListener: (callback: PlatformDefaultsChangedCallback) => {
emitter && emitter.addListener('onPlatformDefaultsChanged', callback);
}
};
}

Просмотреть файл

@ -1,15 +1,34 @@
import { TextStyle } from 'react-native';
import { IOperationSet } from '@uifabricshared/foundation-tokens';
import { ITheme } from '@uifabricshared/theming-ramp';
import { TextStyle, TextProps } from 'react-native';
import { ITheme, ITypography } from '@uifabricshared/theming-ramp';
import { styleFunction } from '@uifabricshared/foundation-tokens';
export interface ITextTokens {
fontFamily?: TextStyle['fontFamily'] | string;
fontSize?: TextStyle['fontSize'] | string;
fontWeight?: TextStyle['fontWeight'] | string;
export interface ITextVariantTokens {
fontVariant?: keyof ITypography['variants'];
}
export const textTokens: IOperationSet<ITextTokens, ITheme> = [
{ source: 'fontFamily', lookup: (t: ITheme) => t.typography.families },
{ source: 'fontSize', lookup: (t: ITheme) => t.typography.sizes },
{ source: 'fontWeight', lookup: (t: ITheme) => t.typography.weights }
];
export interface ITextStyleTokens {
fontFamily?: keyof ITypography['families'] | TextStyle['fontFamily'];
fontSize?: keyof ITypography['sizes'] | TextStyle['fontSize'];
fontWeight?: keyof ITypography['weights'] | TextStyle['fontWeight'];
}
export type ITextTokens = ITextStyleTokens & ITextVariantTokens;
export function _buildTextStyles({ fontFamily, fontSize, fontWeight, fontVariant }: ITextTokens, { typography }: ITheme): TextProps {
const { families, sizes, weights, variants } = typography;
if (fontFamily || fontSize || fontWeight || fontVariant) {
return {
style: {
fontFamily: families[fontFamily] || fontFamily || families[variants[fontVariant].face] || variants[fontVariant].face,
fontSize: sizes[fontSize] || fontSize || sizes[variants[fontVariant].size] || variants[fontVariant].size,
fontWeight: weights[fontWeight] || fontWeight || weights[variants[fontVariant].weight] || variants[fontVariant].weight
}
};
}
return {};
}
const _keyProps: (keyof ITextTokens)[] = ['fontFamily', 'fontSize', 'fontWeight', 'fontVariant'];
export const textTokens = styleFunction<TextProps, ITextTokens, ITheme>(_buildTextStyles, _keyProps);