Add a git attributes file for line ending settings (#180)
* bump beachball version to one with prepublish fix * update beachball hook to use new prepublish strategy * add gitattributes for auto text line endings * update values * renormalize files * Change files
This commit is contained in:
Родитель
4392f30963
Коммит
dc062498d6
|
@ -0,0 +1,2 @@
|
|||
# Set the default line ending behavior for text, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
|
@ -1,9 +1,9 @@
|
|||
# Microsoft Open Source Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
|
||||
Resources:
|
||||
|
||||
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
|
||||
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
||||
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
|
||||
# Microsoft Open Source Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
|
||||
Resources:
|
||||
|
||||
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
|
||||
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
||||
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
|
||||
|
|
42
LICENSE
42
LICENSE
|
@ -1,21 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
|
|
168
README.md
168
README.md
|
@ -1,84 +1,84 @@
|
|||
# FluentUI React Native
|
||||
|
||||
FluentUI React Native is a javascript component library that provides developers with controls that are part of the [Fluent Design System](https://www.microsoft.com/design/fluent/). These controls are built on [React Native](https://reactnative.dev/) and fully customizable.
|
||||
|
||||
## Getting Started
|
||||
|
||||
If you have an existing React Native project, it's easy to begin using FluentUI React Native. If you need to setup a new React Native project, please see the [React Native Windows Getting Started documentation](https://microsoft.github.io/react-native-windows/docs/getting-started).
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Standard React Native dependencies](http://facebook.github.io/react-native/docs/getting-started.html#node-python2-jdk)
|
||||
- [Node.js](https://nodejs.org/en/download/)
|
||||
|
||||
### Install FluentUI React Native into an existing project
|
||||
|
||||
Navigate to the root folder of your project, and use npm to install the package:
|
||||
|
||||
```
|
||||
npm i @fluentui/react-native
|
||||
```
|
||||
|
||||
After successful installation, you can test the package by importing components at the top of your app's entry file, e.g. `App.js`:
|
||||
|
||||
```
|
||||
import { Checkbox } from '@fluentui/react-native';
|
||||
```
|
||||
|
||||
Once you have the package installed, check out our [Hello World Fluent page](https://github.com/microsoft/fluent-site/blob/master/packages/fluent-website/docs/windows/get-started/Hello-World.mdx) to start writing code (Coming Soon).
|
||||
|
||||
## Documentation
|
||||
|
||||
### Components and Controls
|
||||
|
||||
Our component documentation is hosted in a separate repository, [Microsoft FluentUI Site](https://github.com/Microsoft/fluent-site) that will be published to its own website (Coming Soon).
|
||||
|
||||
### Theming framework
|
||||
|
||||
Our FluentUI framework documentation is found in this repository alongside the implementation.
|
||||
|
||||
- [Theming Overview](./packages/framework/theming-react-native/README.md)
|
||||
- [StyleSheets](./packages/framework/themed-stylesheet/README.md)
|
||||
- [Customizing Theme Settings](./packages/framework/themed-settings/README.md)
|
||||
- [Theme Registry](./packages/framework/theme-registry/README.md)
|
||||
- [Tokens](./packages/framework/foundation-tokens/README.md)
|
||||
- [Settings and Slots](./packages/framework/foundation-settings/README.md)
|
||||
- [Compose](./packages/framework/foundation-compose/README.md) and [Composable](./packages/framework/foundation-composable/README.md)
|
||||
|
||||
## Developing in the repo
|
||||
|
||||
### Yarn + Lerna
|
||||
|
||||
This repo is set up as a monorepo using Lerna + Yarn workspaces. The yarn commands will trigger the lerna commands which will execute yarn commands in each package. To install yarn, please follow instructions in the [Yarn documentation](https://classic.yarnpkg.com/en/docs/install/).
|
||||
|
||||
### Setup your development environment
|
||||
|
||||
To start developing in the repository you can:
|
||||
|
||||
1. `git clone https://github.com/microsoft/fluentui-react-native.git`
|
||||
1. `cd fluentui-react-native`
|
||||
1. `yarn`
|
||||
1. `yarn build`
|
||||
|
||||
After a successful yarn build, you can explore FluentUI Tester, our demo application to play with each of the controls. To run FluentUI Tester, please follow instructions in the [FluentUI Tester readme](./apps/fluent-tester/README.md).
|
||||
|
||||
### Beachball
|
||||
|
||||
This repo manages semantic versioning and publishing using [Beachball](https://github.com/microsoft/beachball). When contributing, make sure to run the following before making a pull request:
|
||||
|
||||
1. `yarn change` will take you through a command line wizard to generate change files
|
||||
2. Make sure to commit and push the newly generated change file
|
||||
|
||||
## Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
# FluentUI React Native
|
||||
|
||||
FluentUI React Native is a javascript component library that provides developers with controls that are part of the [Fluent Design System](https://www.microsoft.com/design/fluent/). These controls are built on [React Native](https://reactnative.dev/) and fully customizable.
|
||||
|
||||
## Getting Started
|
||||
|
||||
If you have an existing React Native project, it's easy to begin using FluentUI React Native. If you need to setup a new React Native project, please see the [React Native Windows Getting Started documentation](https://microsoft.github.io/react-native-windows/docs/getting-started).
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Standard React Native dependencies](http://facebook.github.io/react-native/docs/getting-started.html#node-python2-jdk)
|
||||
- [Node.js](https://nodejs.org/en/download/)
|
||||
|
||||
### Install FluentUI React Native into an existing project
|
||||
|
||||
Navigate to the root folder of your project, and use npm to install the package:
|
||||
|
||||
```
|
||||
npm i @fluentui/react-native
|
||||
```
|
||||
|
||||
After successful installation, you can test the package by importing components at the top of your app's entry file, e.g. `App.js`:
|
||||
|
||||
```
|
||||
import { Checkbox } from '@fluentui/react-native';
|
||||
```
|
||||
|
||||
Once you have the package installed, check out our [Hello World Fluent page](https://github.com/microsoft/fluent-site/blob/master/packages/fluent-website/docs/windows/get-started/Hello-World.mdx) to start writing code (Coming Soon).
|
||||
|
||||
## Documentation
|
||||
|
||||
### Components and Controls
|
||||
|
||||
Our component documentation is hosted in a separate repository, [Microsoft FluentUI Site](https://github.com/Microsoft/fluent-site) that will be published to its own website (Coming Soon).
|
||||
|
||||
### Theming framework
|
||||
|
||||
Our FluentUI framework documentation is found in this repository alongside the implementation.
|
||||
|
||||
- [Theming Overview](./packages/framework/theming-react-native/README.md)
|
||||
- [StyleSheets](./packages/framework/themed-stylesheet/README.md)
|
||||
- [Customizing Theme Settings](./packages/framework/themed-settings/README.md)
|
||||
- [Theme Registry](./packages/framework/theme-registry/README.md)
|
||||
- [Tokens](./packages/framework/foundation-tokens/README.md)
|
||||
- [Settings and Slots](./packages/framework/foundation-settings/README.md)
|
||||
- [Compose](./packages/framework/foundation-compose/README.md) and [Composable](./packages/framework/foundation-composable/README.md)
|
||||
|
||||
## Developing in the repo
|
||||
|
||||
### Yarn + Lerna
|
||||
|
||||
This repo is set up as a monorepo using Lerna + Yarn workspaces. The yarn commands will trigger the lerna commands which will execute yarn commands in each package. To install yarn, please follow instructions in the [Yarn documentation](https://classic.yarnpkg.com/en/docs/install/).
|
||||
|
||||
### Setup your development environment
|
||||
|
||||
To start developing in the repository you can:
|
||||
|
||||
1. `git clone https://github.com/microsoft/fluentui-react-native.git`
|
||||
1. `cd fluentui-react-native`
|
||||
1. `yarn`
|
||||
1. `yarn build`
|
||||
|
||||
After a successful yarn build, you can explore FluentUI Tester, our demo application to play with each of the controls. To run FluentUI Tester, please follow instructions in the [FluentUI Tester readme](./apps/fluent-tester/README.md).
|
||||
|
||||
### Beachball
|
||||
|
||||
This repo manages semantic versioning and publishing using [Beachball](https://github.com/microsoft/beachball). When contributing, make sure to run the following before making a pull request:
|
||||
|
||||
1. `yarn change` will take you through a command line wizard to generate change files
|
||||
2. Make sure to commit and push the newly generated change file
|
||||
|
||||
## Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
|
|
@ -1,58 +1,58 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "512x512"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "512x512"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "512x512"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "512x512"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#import <AppKit/AppKit.h>
|
||||
|
||||
@interface FRNAppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@end
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
@interface FRNAppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#import "FRNAppDelegate.h"
|
||||
|
||||
@implementation FRNAppDelegate
|
||||
|
||||
@end
|
||||
#import "FRNAppDelegate.h"
|
||||
|
||||
@implementation FRNAppDelegate
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#import <AppKit/AppKit.h>
|
||||
|
||||
@interface FRNViewController : NSViewController
|
||||
|
||||
@end
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
@interface FRNViewController : NSViewController
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
#import "FRNViewController.h"
|
||||
#import "FRNAppDelegate.h"
|
||||
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
@interface FRNViewController () <RCTBridgeDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation FRNViewController
|
||||
|
||||
- (void)loadView {
|
||||
// The delegate must conform to RCTBridgeDelegate to retrieve the JS source file for the packager
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:nil];
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"FluentUITester" initialProperties:nil];
|
||||
|
||||
[self setView:rootView];
|
||||
}
|
||||
|
||||
#pragma mark - RCTBridgeDelegate Methods
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge {
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:@"main"]; // .jsbundle;
|
||||
}
|
||||
|
||||
@end
|
||||
#import "FRNViewController.h"
|
||||
#import "FRNAppDelegate.h"
|
||||
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
@interface FRNViewController () <RCTBridgeDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation FRNViewController
|
||||
|
||||
- (void)loadView {
|
||||
// The delegate must conform to RCTBridgeDelegate to retrieve the JS source file for the packager
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:nil];
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"FluentUITester" initialProperties:nil];
|
||||
|
||||
[self setView:rootView];
|
||||
}
|
||||
|
||||
#pragma mark - RCTBridgeDelegate Methods
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge {
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:@"main"]; // .jsbundle;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-only</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-only</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSSupportsAutomaticTermination</key>
|
||||
<true/>
|
||||
<key>NSSupportsSuddenTermination</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSSupportsAutomaticTermination</key>
|
||||
<true/>
|
||||
<key>NSSupportsSuddenTermination</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#import <AppKit/AppKit.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
# require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
|
||||
abstract_target 'Shared' do
|
||||
# use_native_modules!
|
||||
|
||||
pod 'React', :path => "../node_modules/react-native-macos/"
|
||||
pod 'React-Core', :path => "../node_modules/react-native-macos/React"
|
||||
pod 'React-fishhook', :path => "../node_modules/react-native-macos/Libraries/fishhook"
|
||||
pod 'React-RCTActionSheet', :path => "../node_modules/react-native-macos/Libraries/ActionSheetIOS"
|
||||
pod 'React-RCTAnimation', :path => "../node_modules/react-native-macos/Libraries/NativeAnimation"
|
||||
pod 'React-RCTBlob', :path => "../node_modules/react-native-macos/Libraries/Blob"
|
||||
pod 'React-RCTImage', :path => "../node_modules/react-native-macos/Libraries/Image"
|
||||
pod 'React-RCTLinking', :path => "../node_modules/react-native-macos/Libraries/LinkingIOS"
|
||||
pod 'React-RCTNetwork', :path => "../node_modules/react-native-macos/Libraries/Network"
|
||||
pod 'React-RCTSettings', :path => "../node_modules/react-native-macos/Libraries/Settings"
|
||||
pod 'React-RCTText', :path => "../node_modules/react-native-macos/Libraries/Text"
|
||||
pod 'React-RCTVibration', :path => "../node_modules/react-native-macos/Libraries/Vibration"
|
||||
pod 'React-RCTWebSocket', :path => "../node_modules/react-native-macos/Libraries/WebSocket"
|
||||
pod 'React-cxxreact', :path => "../node_modules/react-native-macos/ReactCommon/cxxreact"
|
||||
pod 'React-jscallinvoker', :path => "../node_modules/react-native-macos/ReactCommon/jscallinvoker"
|
||||
pod 'React-jsi', :path => "../node_modules/react-native-macos/ReactCommon/jsi"
|
||||
pod 'React-jsiexecutor', :path => "../node_modules/react-native-macos/ReactCommon/jsiexecutor"
|
||||
pod 'React-jsinspector', :path => "../node_modules/react-native-macos/ReactCommon/jsinspector"
|
||||
pod 'yoga', :path => "../node_modules/react-native-macos/ReactCommon/yoga"
|
||||
pod 'DoubleConversion', :podspec => "../node_modules/react-native-macos/third-party-podspecs/DoubleConversion.podspec"
|
||||
pod 'glog', :podspec => "../node_modules/react-native-macos/third-party-podspecs/glog.podspec"
|
||||
pod 'Folly', :podspec => "../node_modules/react-native-macos/third-party-podspecs/Folly.podspec"
|
||||
pod 'boost-for-react-native', :podspec => "../node_modules/react-native-macos/third-party-podspecs/boost-for-react-native.podspec"
|
||||
pod 'React-DevSupport', :path => "../node_modules/react-native-macos/React"
|
||||
|
||||
target 'FluentUITester-macOS' do
|
||||
platform :macos, '10.15'
|
||||
# Pods specifically for macOS target
|
||||
end
|
||||
|
||||
end
|
||||
# require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
|
||||
abstract_target 'Shared' do
|
||||
# use_native_modules!
|
||||
|
||||
pod 'React', :path => "../node_modules/react-native-macos/"
|
||||
pod 'React-Core', :path => "../node_modules/react-native-macos/React"
|
||||
pod 'React-fishhook', :path => "../node_modules/react-native-macos/Libraries/fishhook"
|
||||
pod 'React-RCTActionSheet', :path => "../node_modules/react-native-macos/Libraries/ActionSheetIOS"
|
||||
pod 'React-RCTAnimation', :path => "../node_modules/react-native-macos/Libraries/NativeAnimation"
|
||||
pod 'React-RCTBlob', :path => "../node_modules/react-native-macos/Libraries/Blob"
|
||||
pod 'React-RCTImage', :path => "../node_modules/react-native-macos/Libraries/Image"
|
||||
pod 'React-RCTLinking', :path => "../node_modules/react-native-macos/Libraries/LinkingIOS"
|
||||
pod 'React-RCTNetwork', :path => "../node_modules/react-native-macos/Libraries/Network"
|
||||
pod 'React-RCTSettings', :path => "../node_modules/react-native-macos/Libraries/Settings"
|
||||
pod 'React-RCTText', :path => "../node_modules/react-native-macos/Libraries/Text"
|
||||
pod 'React-RCTVibration', :path => "../node_modules/react-native-macos/Libraries/Vibration"
|
||||
pod 'React-RCTWebSocket', :path => "../node_modules/react-native-macos/Libraries/WebSocket"
|
||||
pod 'React-cxxreact', :path => "../node_modules/react-native-macos/ReactCommon/cxxreact"
|
||||
pod 'React-jscallinvoker', :path => "../node_modules/react-native-macos/ReactCommon/jscallinvoker"
|
||||
pod 'React-jsi', :path => "../node_modules/react-native-macos/ReactCommon/jsi"
|
||||
pod 'React-jsiexecutor', :path => "../node_modules/react-native-macos/ReactCommon/jsiexecutor"
|
||||
pod 'React-jsinspector', :path => "../node_modules/react-native-macos/ReactCommon/jsinspector"
|
||||
pod 'yoga', :path => "../node_modules/react-native-macos/ReactCommon/yoga"
|
||||
pod 'DoubleConversion', :podspec => "../node_modules/react-native-macos/third-party-podspecs/DoubleConversion.podspec"
|
||||
pod 'glog', :podspec => "../node_modules/react-native-macos/third-party-podspecs/glog.podspec"
|
||||
pod 'Folly', :podspec => "../node_modules/react-native-macos/third-party-podspecs/Folly.podspec"
|
||||
pod 'boost-for-react-native', :podspec => "../node_modules/react-native-macos/third-party-podspecs/boost-for-react-native.podspec"
|
||||
pod 'React-DevSupport', :path => "../node_modules/react-native-macos/React"
|
||||
|
||||
target 'FluentUITester-macOS' do
|
||||
platform :macos, '10.15'
|
||||
# Pods specifically for macOS target
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This cli config is needed for development purposes, e.g. for running
|
||||
* integration tests during local development or on CI services.
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const blacklist = require('metro-config/src/defaults/blacklist');
|
||||
|
||||
const rnmPath = path.resolve(__dirname, 'node_modules/react-native-macos');
|
||||
|
||||
module.exports = {
|
||||
resolver: {
|
||||
extraNodeModules: {
|
||||
'react-native': rnmPath,
|
||||
},
|
||||
platforms: ['macos', 'ios'],
|
||||
blacklistRE: blacklist([/node_modules\/react-native\/.*/]),
|
||||
},
|
||||
};
|
||||
/**
|
||||
* This cli config is needed for development purposes, e.g. for running
|
||||
* integration tests during local development or on CI services.
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const blacklist = require('metro-config/src/defaults/blacklist');
|
||||
|
||||
const rnmPath = path.resolve(__dirname, 'node_modules/react-native-macos');
|
||||
|
||||
module.exports = {
|
||||
resolver: {
|
||||
extraNodeModules: {
|
||||
'react-native': rnmPath,
|
||||
},
|
||||
platforms: ['macos', 'ios'],
|
||||
blacklistRE: blacklist([/node_modules\/react-native\/.*/]),
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
/**
|
||||
* This cli config is needed for the coexistance of react-native and other
|
||||
* out-of-tree implementations such react-native-macos.
|
||||
* The following issue is tracked by
|
||||
* https://github.com/react-native-community/discussions-and-proposals/issues/182
|
||||
*
|
||||
* The work-around involves having a metro.config.js for each out-of-tree
|
||||
* platform, i.e. metro.config.js for react-native and
|
||||
* metro.config.macos.js for react-native-macos.
|
||||
* This react-native.config.js looks for a --use-react-native-macos
|
||||
* switch and when present pushes --config=metro.config.macos.js
|
||||
* and specifies reactNativePath: 'node_modules/react-native-macos'.
|
||||
* The metro.config.js has to blacklist 'node_modules/react-native-macos',
|
||||
* and conversely metro.config.macos.js has to blacklist 'node_modules/react-native'.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const macSwitch = '--use-react-native-macos';
|
||||
const windowsSwitch = '--use-react-native-windows';
|
||||
|
||||
if (process.argv.includes(macSwitch)) {
|
||||
process.argv = process.argv.filter(arg => arg !== macSwitch);
|
||||
process.argv.push('--config=metro.config.macos.js');
|
||||
module.exports = {
|
||||
reactNativePath: 'node_modules/react-native-macos',
|
||||
};
|
||||
} else if (process.argv.includes(windowsSwitch)) {
|
||||
process.argv = process.argv.filter(arg => arg !== windowsSwitch);
|
||||
process.argv.push('--config=metro.config.windows.js');
|
||||
module.exports = {
|
||||
reactNativePath: 'node_modules/react-native-windows',
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This cli config is needed for the coexistance of react-native and other
|
||||
* out-of-tree implementations such react-native-macos.
|
||||
* The following issue is tracked by
|
||||
* https://github.com/react-native-community/discussions-and-proposals/issues/182
|
||||
*
|
||||
* The work-around involves having a metro.config.js for each out-of-tree
|
||||
* platform, i.e. metro.config.js for react-native and
|
||||
* metro.config.macos.js for react-native-macos.
|
||||
* This react-native.config.js looks for a --use-react-native-macos
|
||||
* switch and when present pushes --config=metro.config.macos.js
|
||||
* and specifies reactNativePath: 'node_modules/react-native-macos'.
|
||||
* The metro.config.js has to blacklist 'node_modules/react-native-macos',
|
||||
* and conversely metro.config.macos.js has to blacklist 'node_modules/react-native'.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const macSwitch = '--use-react-native-macos';
|
||||
const windowsSwitch = '--use-react-native-windows';
|
||||
|
||||
if (process.argv.includes(macSwitch)) {
|
||||
process.argv = process.argv.filter(arg => arg !== macSwitch);
|
||||
process.argv.push('--config=metro.config.macos.js');
|
||||
module.exports = {
|
||||
reactNativePath: 'node_modules/react-native-macos',
|
||||
};
|
||||
} else if (process.argv.includes(windowsSwitch)) {
|
||||
process.argv = process.argv.filter(arg => arg !== windowsSwitch);
|
||||
process.argv.push('--config=metro.config.windows.js');
|
||||
module.exports = {
|
||||
reactNativePath: 'node_modules/react-native-windows',
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
import * as React from 'react';
|
||||
import { undefinedText } from '../PersonaCoin/styles';
|
||||
import { IconAlignment } from '@fluentui/react-native';
|
||||
import { Picker, StyleProp, ViewStyle } from 'react-native';
|
||||
|
||||
const alignmentValues: Array<typeof undefinedText | IconAlignment> = [undefinedText, 'start', 'center', 'end'];
|
||||
|
||||
interface IAlignmentPickerProps {
|
||||
style?: StyleProp<ViewStyle>;
|
||||
label: string;
|
||||
onSelectionChange: (value: IconAlignment | undefined) => void;
|
||||
}
|
||||
|
||||
export const AlignmentPicker: React.FunctionComponent<IAlignmentPickerProps> = (props: IAlignmentPickerProps) => {
|
||||
const { label, onSelectionChange, style } = props;
|
||||
return (
|
||||
<Picker
|
||||
style={style}
|
||||
prompt={label}
|
||||
selectedValue={undefinedText}
|
||||
onValueChange={(value, index) => onSelectionChange(index == 0 ? undefined : value)}
|
||||
>
|
||||
{alignmentValues.map((alignment, index) => (
|
||||
<Picker.Item label={alignment} key={index} value={alignment} />
|
||||
))}
|
||||
</Picker>
|
||||
);
|
||||
};
|
||||
import * as React from 'react';
|
||||
import { undefinedText } from '../PersonaCoin/styles';
|
||||
import { IconAlignment } from '@fluentui/react-native';
|
||||
import { Picker, StyleProp, ViewStyle } from 'react-native';
|
||||
|
||||
const alignmentValues: Array<typeof undefinedText | IconAlignment> = [undefinedText, 'start', 'center', 'end'];
|
||||
|
||||
interface IAlignmentPickerProps {
|
||||
style?: StyleProp<ViewStyle>;
|
||||
label: string;
|
||||
onSelectionChange: (value: IconAlignment | undefined) => void;
|
||||
}
|
||||
|
||||
export const AlignmentPicker: React.FunctionComponent<IAlignmentPickerProps> = (props: IAlignmentPickerProps) => {
|
||||
const { label, onSelectionChange, style } = props;
|
||||
return (
|
||||
<Picker
|
||||
style={style}
|
||||
prompt={label}
|
||||
selectedValue={undefinedText}
|
||||
onValueChange={(value, index) => onSelectionChange(index == 0 ? undefined : value)}
|
||||
>
|
||||
{alignmentValues.map((alignment, index) => (
|
||||
<Picker.Item label={alignment} key={index} value={alignment} />
|
||||
))}
|
||||
</Picker>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,168 +1,168 @@
|
|||
import * as React from 'react';
|
||||
import { ViewProps, StyleSheet, StyleProp, ViewStyle, UIManager, Text, findNodeHandle, View } from 'react-native';
|
||||
import { Separator, Pressable, IPressableState } from '@fluentui/react-native';
|
||||
|
||||
const thumbSize = 20;
|
||||
const defaultMaximumValue = 100;
|
||||
const defaultMinimumValue = 1;
|
||||
|
||||
interface ISliderProps extends ViewProps {
|
||||
minimum?: number;
|
||||
maximum?: number;
|
||||
initialValue?: number;
|
||||
onChange?: (value: number) => void;
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
slider: {
|
||||
minWidth: thumbSize * 2,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
alignContent: 'stretch',
|
||||
height: thumbSize,
|
||||
width: 200
|
||||
},
|
||||
track: {
|
||||
flexGrow: 1
|
||||
},
|
||||
thumb: {
|
||||
width: thumbSize,
|
||||
height: thumbSize,
|
||||
borderRadius: thumbSize,
|
||||
borderWidth: 2,
|
||||
borderColor: '#7A7574',
|
||||
backgroundColor: '#FFFFFF',
|
||||
position: 'absolute'
|
||||
},
|
||||
label: {
|
||||
margin: 8,
|
||||
fontSize: 12
|
||||
}
|
||||
});
|
||||
|
||||
const Track = Separator.customize({ tokens: { separatorWidth: 4 } });
|
||||
|
||||
function onThumbRenderStyle(state: IPressableState, thumbLocation: number): StyleProp<ViewStyle> {
|
||||
return {
|
||||
...styles.thumb,
|
||||
borderColor: state.pressed ? 'black' : state.hovered ? 'red' : '#7A7574',
|
||||
marginLeft: thumbLocation
|
||||
};
|
||||
}
|
||||
|
||||
function calculateThumbLocationAndValue(
|
||||
startTouchThumbLocation: number,
|
||||
startTouchPosition: number,
|
||||
currentTouchPosition: number,
|
||||
trackLength: number,
|
||||
minimum: number,
|
||||
maximum: number
|
||||
): [number, number] {
|
||||
let newThumbLocation = startTouchThumbLocation + currentTouchPosition - startTouchPosition;
|
||||
newThumbLocation = Math.max(0, newThumbLocation);
|
||||
newThumbLocation = Math.min(newThumbLocation, trackLength);
|
||||
|
||||
const newValue = minimum + (newThumbLocation / trackLength) * (maximum - minimum);
|
||||
const intValue = Math.min(maximum, Math.floor(newValue + 0.3)); // snap to nearest integer value
|
||||
newThumbLocation = (trackLength * (intValue - minimum)) / (maximum - minimum);
|
||||
|
||||
return [newThumbLocation, intValue];
|
||||
}
|
||||
|
||||
function verifyProps(initialValue: number, minimum: number, maximum: number) {
|
||||
if (minimum >= maximum) {
|
||||
throw new Error(`'minimum' must not be greater than or equal 'maximum'.`);
|
||||
}
|
||||
|
||||
if (initialValue < minimum) {
|
||||
throw new Error(`'initialValue' must not be less than 'minimum'.`);
|
||||
}
|
||||
|
||||
if (initialValue > maximum) {
|
||||
throw new Error(`'initialValue' must not be greater than 'maximum'.`);
|
||||
}
|
||||
}
|
||||
|
||||
export const Slider: React.FunctionComponent<ISliderProps> = (props: ISliderProps) => {
|
||||
let { minimum, maximum, initialValue } = props;
|
||||
minimum = minimum || defaultMinimumValue;
|
||||
maximum = maximum || defaultMaximumValue;
|
||||
initialValue = initialValue || minimum;
|
||||
verifyProps(initialValue, minimum, maximum);
|
||||
|
||||
const { style: userStyle, onChange } = props;
|
||||
|
||||
const [thumbLocation, setThumbLocation] = React.useState<number>(0);
|
||||
|
||||
const startTouchPosition = React.useRef<number>(-1);
|
||||
const startTouchThumbLocation = React.useRef<number>(-1);
|
||||
const trackLength = React.useRef<number>(-1);
|
||||
const sliderValue = React.useRef<number>(initialValue);
|
||||
|
||||
const ref = React.useRef<View>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
const parent = findNodeHandle(ref.current);
|
||||
if (parent) {
|
||||
UIManager.measure(parent, (_x, _y, width) => {
|
||||
if (width <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// track length is the entire view width subtracted by the thumb size.
|
||||
trackLength.current = Math.max(0, width - thumbSize);
|
||||
|
||||
const initialThumbLocation = (trackLength.current * (initialValue! - minimum!)) / (maximum! - minimum!);
|
||||
setThumbLocation(initialThumbLocation);
|
||||
});
|
||||
}
|
||||
}, [ref.current, initialValue, maximum, minimum]);
|
||||
|
||||
return (
|
||||
<View style={[userStyle, styles.root]}>
|
||||
<View ref={ref} {...props} style={styles.slider}>
|
||||
<Track style={styles.track} />
|
||||
{trackLength.current > 0 && (
|
||||
<Pressable
|
||||
renderStyle={state => onThumbRenderStyle(state, thumbLocation)}
|
||||
onStartShouldSetResponder={() => trackLength.current > 0}
|
||||
onResponderStart={e => {
|
||||
startTouchPosition.current = e.nativeEvent.pageX;
|
||||
startTouchThumbLocation.current = thumbLocation;
|
||||
}}
|
||||
onResponderMove={e => {
|
||||
if (startTouchPosition.current !== -1 && trackLength.current > 0) {
|
||||
const [newThumbLocation, newValue] = calculateThumbLocationAndValue(
|
||||
startTouchThumbLocation.current,
|
||||
startTouchPosition.current,
|
||||
e.nativeEvent.pageX,
|
||||
trackLength.current,
|
||||
minimum || defaultMinimumValue,
|
||||
maximum || defaultMaximumValue
|
||||
);
|
||||
|
||||
sliderValue.current = newValue;
|
||||
setThumbLocation(newThumbLocation);
|
||||
}
|
||||
}}
|
||||
onResponderEnd={() => {
|
||||
startTouchPosition.current = -1;
|
||||
startTouchThumbLocation.current = -1;
|
||||
}}
|
||||
onResponderRelease={() => {
|
||||
if (onChange) {
|
||||
onChange(sliderValue.current);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<Text style={styles.label}>{sliderValue.current}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
import * as React from 'react';
|
||||
import { ViewProps, StyleSheet, StyleProp, ViewStyle, UIManager, Text, findNodeHandle, View } from 'react-native';
|
||||
import { Separator, Pressable, IPressableState } from '@fluentui/react-native';
|
||||
|
||||
const thumbSize = 20;
|
||||
const defaultMaximumValue = 100;
|
||||
const defaultMinimumValue = 1;
|
||||
|
||||
interface ISliderProps extends ViewProps {
|
||||
minimum?: number;
|
||||
maximum?: number;
|
||||
initialValue?: number;
|
||||
onChange?: (value: number) => void;
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
slider: {
|
||||
minWidth: thumbSize * 2,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
alignContent: 'stretch',
|
||||
height: thumbSize,
|
||||
width: 200
|
||||
},
|
||||
track: {
|
||||
flexGrow: 1
|
||||
},
|
||||
thumb: {
|
||||
width: thumbSize,
|
||||
height: thumbSize,
|
||||
borderRadius: thumbSize,
|
||||
borderWidth: 2,
|
||||
borderColor: '#7A7574',
|
||||
backgroundColor: '#FFFFFF',
|
||||
position: 'absolute'
|
||||
},
|
||||
label: {
|
||||
margin: 8,
|
||||
fontSize: 12
|
||||
}
|
||||
});
|
||||
|
||||
const Track = Separator.customize({ tokens: { separatorWidth: 4 } });
|
||||
|
||||
function onThumbRenderStyle(state: IPressableState, thumbLocation: number): StyleProp<ViewStyle> {
|
||||
return {
|
||||
...styles.thumb,
|
||||
borderColor: state.pressed ? 'black' : state.hovered ? 'red' : '#7A7574',
|
||||
marginLeft: thumbLocation
|
||||
};
|
||||
}
|
||||
|
||||
function calculateThumbLocationAndValue(
|
||||
startTouchThumbLocation: number,
|
||||
startTouchPosition: number,
|
||||
currentTouchPosition: number,
|
||||
trackLength: number,
|
||||
minimum: number,
|
||||
maximum: number
|
||||
): [number, number] {
|
||||
let newThumbLocation = startTouchThumbLocation + currentTouchPosition - startTouchPosition;
|
||||
newThumbLocation = Math.max(0, newThumbLocation);
|
||||
newThumbLocation = Math.min(newThumbLocation, trackLength);
|
||||
|
||||
const newValue = minimum + (newThumbLocation / trackLength) * (maximum - minimum);
|
||||
const intValue = Math.min(maximum, Math.floor(newValue + 0.3)); // snap to nearest integer value
|
||||
newThumbLocation = (trackLength * (intValue - minimum)) / (maximum - minimum);
|
||||
|
||||
return [newThumbLocation, intValue];
|
||||
}
|
||||
|
||||
function verifyProps(initialValue: number, minimum: number, maximum: number) {
|
||||
if (minimum >= maximum) {
|
||||
throw new Error(`'minimum' must not be greater than or equal 'maximum'.`);
|
||||
}
|
||||
|
||||
if (initialValue < minimum) {
|
||||
throw new Error(`'initialValue' must not be less than 'minimum'.`);
|
||||
}
|
||||
|
||||
if (initialValue > maximum) {
|
||||
throw new Error(`'initialValue' must not be greater than 'maximum'.`);
|
||||
}
|
||||
}
|
||||
|
||||
export const Slider: React.FunctionComponent<ISliderProps> = (props: ISliderProps) => {
|
||||
let { minimum, maximum, initialValue } = props;
|
||||
minimum = minimum || defaultMinimumValue;
|
||||
maximum = maximum || defaultMaximumValue;
|
||||
initialValue = initialValue || minimum;
|
||||
verifyProps(initialValue, minimum, maximum);
|
||||
|
||||
const { style: userStyle, onChange } = props;
|
||||
|
||||
const [thumbLocation, setThumbLocation] = React.useState<number>(0);
|
||||
|
||||
const startTouchPosition = React.useRef<number>(-1);
|
||||
const startTouchThumbLocation = React.useRef<number>(-1);
|
||||
const trackLength = React.useRef<number>(-1);
|
||||
const sliderValue = React.useRef<number>(initialValue);
|
||||
|
||||
const ref = React.useRef<View>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
const parent = findNodeHandle(ref.current);
|
||||
if (parent) {
|
||||
UIManager.measure(parent, (_x, _y, width) => {
|
||||
if (width <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// track length is the entire view width subtracted by the thumb size.
|
||||
trackLength.current = Math.max(0, width - thumbSize);
|
||||
|
||||
const initialThumbLocation = (trackLength.current * (initialValue! - minimum!)) / (maximum! - minimum!);
|
||||
setThumbLocation(initialThumbLocation);
|
||||
});
|
||||
}
|
||||
}, [ref.current, initialValue, maximum, minimum]);
|
||||
|
||||
return (
|
||||
<View style={[userStyle, styles.root]}>
|
||||
<View ref={ref} {...props} style={styles.slider}>
|
||||
<Track style={styles.track} />
|
||||
{trackLength.current > 0 && (
|
||||
<Pressable
|
||||
renderStyle={state => onThumbRenderStyle(state, thumbLocation)}
|
||||
onStartShouldSetResponder={() => trackLength.current > 0}
|
||||
onResponderStart={e => {
|
||||
startTouchPosition.current = e.nativeEvent.pageX;
|
||||
startTouchThumbLocation.current = thumbLocation;
|
||||
}}
|
||||
onResponderMove={e => {
|
||||
if (startTouchPosition.current !== -1 && trackLength.current > 0) {
|
||||
const [newThumbLocation, newValue] = calculateThumbLocationAndValue(
|
||||
startTouchThumbLocation.current,
|
||||
startTouchPosition.current,
|
||||
e.nativeEvent.pageX,
|
||||
trackLength.current,
|
||||
minimum || defaultMinimumValue,
|
||||
maximum || defaultMaximumValue
|
||||
);
|
||||
|
||||
sliderValue.current = newValue;
|
||||
setThumbLocation(newThumbLocation);
|
||||
}
|
||||
}}
|
||||
onResponderEnd={() => {
|
||||
startTouchPosition.current = -1;
|
||||
startTouchThumbLocation.current = -1;
|
||||
}}
|
||||
onResponderRelease={() => {
|
||||
if (onChange) {
|
||||
onChange(sliderValue.current);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<Text style={styles.label}>{sliderValue.current}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,116 +1,116 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
import { IStackProps } from '@fluentui-react-native/stack';
|
||||
|
||||
export const commonTestStyles = StyleSheet.create({
|
||||
root: {
|
||||
marginTop: 16,
|
||||
marginRight: 32,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start'
|
||||
},
|
||||
header: {
|
||||
marginVertical: 6,
|
||||
fontSize: 12
|
||||
},
|
||||
section: {
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
color: '#0B6A0B',
|
||||
marginTop: 12
|
||||
},
|
||||
separatorStack: {
|
||||
height: 200,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-evenly'
|
||||
},
|
||||
settings: {
|
||||
flexGrow: 1
|
||||
},
|
||||
slider: {
|
||||
marginVertical: 6
|
||||
},
|
||||
stack: {
|
||||
borderWidth: 2,
|
||||
borderColor: '#bdbdbd',
|
||||
padding: 12,
|
||||
margin: 8
|
||||
},
|
||||
switch: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
textBox: {
|
||||
borderWidth: 1,
|
||||
height: 25,
|
||||
fontSize: 12,
|
||||
width: 150,
|
||||
marginBottom: 8
|
||||
},
|
||||
view: {
|
||||
minHeight: 200,
|
||||
justifyContent: 'space-between'
|
||||
}
|
||||
});
|
||||
|
||||
export const fabricTesterStyles = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
flexGrow: 1,
|
||||
flexDirection: 'row',
|
||||
minHeight: 550,
|
||||
minWidth: 300,
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'stretch',
|
||||
padding: 4
|
||||
},
|
||||
|
||||
testHeader: {
|
||||
marginBottom: 8,
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
|
||||
testList: {
|
||||
width: 160
|
||||
},
|
||||
|
||||
testListContainerStyle: {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'stretch'
|
||||
},
|
||||
|
||||
testListItem: {
|
||||
width: 150
|
||||
},
|
||||
|
||||
testSection: {
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
color: '#0B6A0B',
|
||||
marginTop: 12
|
||||
},
|
||||
|
||||
separator: {
|
||||
marginHorizontal: 8,
|
||||
width: 2
|
||||
},
|
||||
|
||||
noTest: {
|
||||
alignSelf: 'center',
|
||||
fontSize: 14
|
||||
}
|
||||
});
|
||||
|
||||
export const stackStyle: IStackProps['style'] = {
|
||||
borderWidth: 1,
|
||||
borderColor: '#bdbdbd',
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 12,
|
||||
margin: 8
|
||||
};
|
||||
|
||||
export const separatorStackStyle: IStackProps['style'] = {
|
||||
height: 200,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-evenly'
|
||||
};
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { IStackProps } from '@fluentui-react-native/stack';
|
||||
|
||||
export const commonTestStyles = StyleSheet.create({
|
||||
root: {
|
||||
marginTop: 16,
|
||||
marginRight: 32,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start'
|
||||
},
|
||||
header: {
|
||||
marginVertical: 6,
|
||||
fontSize: 12
|
||||
},
|
||||
section: {
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
color: '#0B6A0B',
|
||||
marginTop: 12
|
||||
},
|
||||
separatorStack: {
|
||||
height: 200,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-evenly'
|
||||
},
|
||||
settings: {
|
||||
flexGrow: 1
|
||||
},
|
||||
slider: {
|
||||
marginVertical: 6
|
||||
},
|
||||
stack: {
|
||||
borderWidth: 2,
|
||||
borderColor: '#bdbdbd',
|
||||
padding: 12,
|
||||
margin: 8
|
||||
},
|
||||
switch: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
textBox: {
|
||||
borderWidth: 1,
|
||||
height: 25,
|
||||
fontSize: 12,
|
||||
width: 150,
|
||||
marginBottom: 8
|
||||
},
|
||||
view: {
|
||||
minHeight: 200,
|
||||
justifyContent: 'space-between'
|
||||
}
|
||||
});
|
||||
|
||||
export const fabricTesterStyles = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
flexGrow: 1,
|
||||
flexDirection: 'row',
|
||||
minHeight: 550,
|
||||
minWidth: 300,
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'stretch',
|
||||
padding: 4
|
||||
},
|
||||
|
||||
testHeader: {
|
||||
marginBottom: 8,
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
|
||||
testList: {
|
||||
width: 160
|
||||
},
|
||||
|
||||
testListContainerStyle: {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'stretch'
|
||||
},
|
||||
|
||||
testListItem: {
|
||||
width: 150
|
||||
},
|
||||
|
||||
testSection: {
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
color: '#0B6A0B',
|
||||
marginTop: 12
|
||||
},
|
||||
|
||||
separator: {
|
||||
marginHorizontal: 8,
|
||||
width: 2
|
||||
},
|
||||
|
||||
noTest: {
|
||||
alignSelf: 'center',
|
||||
fontSize: 14
|
||||
}
|
||||
});
|
||||
|
||||
export const stackStyle: IStackProps['style'] = {
|
||||
borderWidth: 1,
|
||||
borderColor: '#bdbdbd',
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 12,
|
||||
margin: 8
|
||||
};
|
||||
|
||||
export const separatorStackStyle: IStackProps['style'] = {
|
||||
height: 200,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-evenly'
|
||||
};
|
||||
|
|
|
@ -1,114 +1,114 @@
|
|||
import * as React from 'react';
|
||||
import { View, Text, Switch, TextInput } from 'react-native';
|
||||
import { IPersonaTokens, Persona } from '@fluentui/react-native';
|
||||
import { michaelImageUrl } from './styles';
|
||||
import { commonTestStyles as commonStyles } from '../Common/styles';
|
||||
import { useTheme } from '@uifabricshared/theming-react-native';
|
||||
import { Slider } from '../Common/Slider';
|
||||
|
||||
export const CustomizeUsage: React.FunctionComponent<{}> = () => {
|
||||
const [showImage, setShowImage] = React.useState(true);
|
||||
const [coinColor, setCoinColor] = React.useState<string>();
|
||||
const [textColor, setTextColor] = React.useState<string>();
|
||||
|
||||
const [textSize, setTextSize] = React.useState<number>(23);
|
||||
const [secondarySize, setSecondarySize] = React.useState<number>(20);
|
||||
const [tertiarySize, setTertiarySize] = React.useState<number>(17);
|
||||
const [optionalSize, setOptionalSize] = React.useState<number>(14);
|
||||
|
||||
const [horizontalGap, setHorizontalGap] = React.useState<number>();
|
||||
const [verticalGap, setVerticalGap] = React.useState<number>();
|
||||
|
||||
const tokens: Partial<IPersonaTokens> = {};
|
||||
if (coinColor) {
|
||||
tokens.coinBackgroundColor = coinColor;
|
||||
}
|
||||
if (textColor) {
|
||||
tokens.color = textColor;
|
||||
}
|
||||
if (textSize) {
|
||||
tokens.textFont = { fontSize: textSize };
|
||||
}
|
||||
if (secondarySize) {
|
||||
tokens.secondaryFont = { fontSize: secondarySize };
|
||||
}
|
||||
if (tertiarySize) {
|
||||
tokens.tertiaryFont = { fontSize: tertiarySize };
|
||||
}
|
||||
if (optionalSize) {
|
||||
tokens.optionalFont = { fontSize: optionalSize };
|
||||
}
|
||||
if (horizontalGap !== undefined) {
|
||||
tokens.horizontalGap = horizontalGap;
|
||||
}
|
||||
if (verticalGap !== undefined) {
|
||||
tokens.verticalGap = verticalGap;
|
||||
}
|
||||
|
||||
const theme = useTheme();
|
||||
const textBoxBorderStyle = {
|
||||
borderColor: theme.colors.inputBorder
|
||||
};
|
||||
|
||||
const CustomizedPersona = Persona.customize({ tokens });
|
||||
return (
|
||||
<View style={commonStyles.root}>
|
||||
{/* settings */}
|
||||
<View style={commonStyles.settings}>
|
||||
<View style={commonStyles.switch}>
|
||||
<Text>Show image</Text>
|
||||
<Switch value={showImage} onValueChange={setShowImage} />
|
||||
</View>
|
||||
|
||||
<TextInput
|
||||
style={[commonStyles.textBox, textBoxBorderStyle]}
|
||||
placeholder="Background color"
|
||||
blurOnSubmit={true}
|
||||
onSubmitEditing={e => {
|
||||
setCoinColor(e.nativeEvent.text);
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
style={[commonStyles.textBox, textBoxBorderStyle]}
|
||||
placeholder="Initials text color"
|
||||
blurOnSubmit={true}
|
||||
onSubmitEditing={e => {
|
||||
setTextColor(e.nativeEvent.text);
|
||||
}}
|
||||
/>
|
||||
|
||||
<Text>Primary text size</Text>
|
||||
<Slider maximum={50} minimum={5} initialValue={textSize} style={commonStyles.slider} onChange={setTextSize} />
|
||||
|
||||
<Text>Secondary text size</Text>
|
||||
<Slider maximum={50} minimum={5} initialValue={secondarySize} style={commonStyles.slider} onChange={setSecondarySize} />
|
||||
|
||||
<Text>Tertiary text size</Text>
|
||||
<Slider maximum={50} minimum={5} initialValue={tertiarySize} style={commonStyles.slider} onChange={setTertiarySize} />
|
||||
|
||||
<Text>Optional text size</Text>
|
||||
<Slider maximum={50} minimum={5} initialValue={optionalSize} style={commonStyles.slider} onChange={setOptionalSize} />
|
||||
|
||||
<Text>Horizontal gap</Text>
|
||||
<Slider maximum={100} initialValue={5} minimum={0} style={commonStyles.slider} onChange={setHorizontalGap} />
|
||||
|
||||
<Text>Vertical gap</Text>
|
||||
<Slider maximum={20} initialValue={5} minimum={0} style={commonStyles.slider} onChange={setVerticalGap} />
|
||||
</View>
|
||||
|
||||
{/* component under test */}
|
||||
<CustomizedPersona
|
||||
initials="MJ"
|
||||
size="size72"
|
||||
text="Michael Jackson"
|
||||
secondaryText="Pop singer"
|
||||
tertiaryText="King of pop"
|
||||
optionalText="Indiana"
|
||||
imageDescription="Legendary pop singer"
|
||||
presence="offline"
|
||||
imageUrl={showImage ? michaelImageUrl : undefined}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
import * as React from 'react';
|
||||
import { View, Text, Switch, TextInput } from 'react-native';
|
||||
import { IPersonaTokens, Persona } from '@fluentui/react-native';
|
||||
import { michaelImageUrl } from './styles';
|
||||
import { commonTestStyles as commonStyles } from '../Common/styles';
|
||||
import { useTheme } from '@uifabricshared/theming-react-native';
|
||||
import { Slider } from '../Common/Slider';
|
||||
|
||||
export const CustomizeUsage: React.FunctionComponent<{}> = () => {
|
||||
const [showImage, setShowImage] = React.useState(true);
|
||||
const [coinColor, setCoinColor] = React.useState<string>();
|
||||
const [textColor, setTextColor] = React.useState<string>();
|
||||
|
||||
const [textSize, setTextSize] = React.useState<number>(23);
|
||||
const [secondarySize, setSecondarySize] = React.useState<number>(20);
|
||||
const [tertiarySize, setTertiarySize] = React.useState<number>(17);
|
||||
const [optionalSize, setOptionalSize] = React.useState<number>(14);
|
||||
|
||||
const [horizontalGap, setHorizontalGap] = React.useState<number>();
|
||||
const [verticalGap, setVerticalGap] = React.useState<number>();
|
||||
|
||||
const tokens: Partial<IPersonaTokens> = {};
|
||||
if (coinColor) {
|
||||
tokens.coinBackgroundColor = coinColor;
|
||||
}
|
||||
if (textColor) {
|
||||
tokens.color = textColor;
|
||||
}
|
||||
if (textSize) {
|
||||
tokens.textFont = { fontSize: textSize };
|
||||
}
|
||||
if (secondarySize) {
|
||||
tokens.secondaryFont = { fontSize: secondarySize };
|
||||
}
|
||||
if (tertiarySize) {
|
||||
tokens.tertiaryFont = { fontSize: tertiarySize };
|
||||
}
|
||||
if (optionalSize) {
|
||||
tokens.optionalFont = { fontSize: optionalSize };
|
||||
}
|
||||
if (horizontalGap !== undefined) {
|
||||
tokens.horizontalGap = horizontalGap;
|
||||
}
|
||||
if (verticalGap !== undefined) {
|
||||
tokens.verticalGap = verticalGap;
|
||||
}
|
||||
|
||||
const theme = useTheme();
|
||||
const textBoxBorderStyle = {
|
||||
borderColor: theme.colors.inputBorder
|
||||
};
|
||||
|
||||
const CustomizedPersona = Persona.customize({ tokens });
|
||||
return (
|
||||
<View style={commonStyles.root}>
|
||||
{/* settings */}
|
||||
<View style={commonStyles.settings}>
|
||||
<View style={commonStyles.switch}>
|
||||
<Text>Show image</Text>
|
||||
<Switch value={showImage} onValueChange={setShowImage} />
|
||||
</View>
|
||||
|
||||
<TextInput
|
||||
style={[commonStyles.textBox, textBoxBorderStyle]}
|
||||
placeholder="Background color"
|
||||
blurOnSubmit={true}
|
||||
onSubmitEditing={e => {
|
||||
setCoinColor(e.nativeEvent.text);
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
style={[commonStyles.textBox, textBoxBorderStyle]}
|
||||
placeholder="Initials text color"
|
||||
blurOnSubmit={true}
|
||||
onSubmitEditing={e => {
|
||||
setTextColor(e.nativeEvent.text);
|
||||
}}
|
||||
/>
|
||||
|
||||
<Text>Primary text size</Text>
|
||||
<Slider maximum={50} minimum={5} initialValue={textSize} style={commonStyles.slider} onChange={setTextSize} />
|
||||
|
||||
<Text>Secondary text size</Text>
|
||||
<Slider maximum={50} minimum={5} initialValue={secondarySize} style={commonStyles.slider} onChange={setSecondarySize} />
|
||||
|
||||
<Text>Tertiary text size</Text>
|
||||
<Slider maximum={50} minimum={5} initialValue={tertiarySize} style={commonStyles.slider} onChange={setTertiarySize} />
|
||||
|
||||
<Text>Optional text size</Text>
|
||||
<Slider maximum={50} minimum={5} initialValue={optionalSize} style={commonStyles.slider} onChange={setOptionalSize} />
|
||||
|
||||
<Text>Horizontal gap</Text>
|
||||
<Slider maximum={100} initialValue={5} minimum={0} style={commonStyles.slider} onChange={setHorizontalGap} />
|
||||
|
||||
<Text>Vertical gap</Text>
|
||||
<Slider maximum={20} initialValue={5} minimum={0} style={commonStyles.slider} onChange={setVerticalGap} />
|
||||
</View>
|
||||
|
||||
{/* component under test */}
|
||||
<CustomizedPersona
|
||||
initials="MJ"
|
||||
size="size72"
|
||||
text="Michael Jackson"
|
||||
secondaryText="Pop singer"
|
||||
tertiaryText="King of pop"
|
||||
optionalText="Indiana"
|
||||
imageDescription="Legendary pop singer"
|
||||
presence="offline"
|
||||
imageUrl={showImage ? michaelImageUrl : undefined}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import * as React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { Separator, Text } from '@fluentui/react-native';
|
||||
import { commonTestStyles } from '../Common/styles';
|
||||
import { StandardUsage } from './StandardUsage';
|
||||
import { CustomizeUsage } from './CustomizeUsage';
|
||||
|
||||
export const PersonaTest: React.FunctionComponent<{}> = () => {
|
||||
return (
|
||||
<View>
|
||||
<Text style={commonTestStyles.section}>Standard Usage</Text>
|
||||
<Separator />
|
||||
<StandardUsage />
|
||||
|
||||
<Text style={commonTestStyles.section}>Customize Usage</Text>
|
||||
<Separator />
|
||||
<CustomizeUsage />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
import * as React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { Separator, Text } from '@fluentui/react-native';
|
||||
import { commonTestStyles } from '../Common/styles';
|
||||
import { StandardUsage } from './StandardUsage';
|
||||
import { CustomizeUsage } from './CustomizeUsage';
|
||||
|
||||
export const PersonaTest: React.FunctionComponent<{}> = () => {
|
||||
return (
|
||||
<View>
|
||||
<Text style={commonTestStyles.section}>Standard Usage</Text>
|
||||
<Separator />
|
||||
<StandardUsage />
|
||||
|
||||
<Text style={commonTestStyles.section}>Customize Usage</Text>
|
||||
<Separator />
|
||||
<CustomizeUsage />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,82 +1,82 @@
|
|||
import * as React from 'react';
|
||||
import { Persona, PersonaSize } from '@fluentui/react-native';
|
||||
import { rajeshImageUrl } from './styles';
|
||||
import { commonTestStyles as commonStyles } from '../Common/styles';
|
||||
import { View, Text, Switch, Picker } from 'react-native';
|
||||
import { undefinedText } from '../PersonaCoin/styles';
|
||||
|
||||
type WithUndefined<T> = T | typeof undefinedText;
|
||||
|
||||
const allSizes: WithUndefined<PersonaSize>[] = [
|
||||
undefinedText,
|
||||
'size8',
|
||||
'size24',
|
||||
'size32',
|
||||
'size40',
|
||||
'size48',
|
||||
'size56',
|
||||
'size72',
|
||||
'size100',
|
||||
'size120'
|
||||
];
|
||||
|
||||
interface ISwitchWithLabelProps {
|
||||
label: string;
|
||||
value: boolean;
|
||||
onValueChange: (value: boolean) => void;
|
||||
}
|
||||
|
||||
function SwitchWithLabel(props: ISwitchWithLabelProps): React.ReactElement {
|
||||
const { label, value, onValueChange } = props;
|
||||
return (
|
||||
<View style={commonStyles.switch}>
|
||||
<Text>{label}</Text>
|
||||
<Switch value={value} onValueChange={onValueChange} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export const StandardUsage: React.FunctionComponent<{}> = () => {
|
||||
const [showImage, setShowImage] = React.useState(true);
|
||||
const [showPrimary, setShowPrimary] = React.useState(true);
|
||||
const [showSecondary, setShowSecondary] = React.useState(true);
|
||||
const [showTertiary, setShowTertiary] = React.useState(true);
|
||||
const [showOptional, setShowOptional] = React.useState(true);
|
||||
const [imageSize, setImageSize] = React.useState<PersonaSize | undefined>('size72');
|
||||
|
||||
return (
|
||||
<View style={commonStyles.root}>
|
||||
{/* settings */}
|
||||
<View style={commonStyles.settings}>
|
||||
<SwitchWithLabel label="Show image" value={showImage} onValueChange={setShowImage} />
|
||||
<SwitchWithLabel label="Show primary text" value={showPrimary} onValueChange={setShowPrimary} />
|
||||
<SwitchWithLabel label="Show secondary text" value={showSecondary} onValueChange={setShowSecondary} />
|
||||
<SwitchWithLabel label="Show tertiary text" value={showTertiary} onValueChange={setShowTertiary} />
|
||||
<SwitchWithLabel label="Show optional text" value={showOptional} onValueChange={setShowOptional} />
|
||||
|
||||
<Picker
|
||||
prompt="Size"
|
||||
style={commonStyles.header}
|
||||
selectedValue={imageSize || undefinedText}
|
||||
onValueChange={size => setImageSize(size === undefinedText ? undefined : size)}
|
||||
>
|
||||
{allSizes.map((size, index) => (
|
||||
<Picker.Item label={size} key={index} value={size} />
|
||||
))}
|
||||
</Picker>
|
||||
</View>
|
||||
|
||||
<Persona
|
||||
text={showPrimary ? 'Rajesh Jha' : undefined}
|
||||
secondaryText={showSecondary ? 'Executive Vice President' : undefined}
|
||||
tertiaryText={showTertiary ? 'E & D' : undefined}
|
||||
optionalText={showOptional ? 'Building 36/5600' : undefined}
|
||||
size={imageSize}
|
||||
initials="RJ"
|
||||
imageUrl={showImage ? rajeshImageUrl : undefined}
|
||||
imageDescription="Profile photo of Rajesh Jha"
|
||||
presence={'away'}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
import * as React from 'react';
|
||||
import { Persona, PersonaSize } from '@fluentui/react-native';
|
||||
import { rajeshImageUrl } from './styles';
|
||||
import { commonTestStyles as commonStyles } from '../Common/styles';
|
||||
import { View, Text, Switch, Picker } from 'react-native';
|
||||
import { undefinedText } from '../PersonaCoin/styles';
|
||||
|
||||
type WithUndefined<T> = T | typeof undefinedText;
|
||||
|
||||
const allSizes: WithUndefined<PersonaSize>[] = [
|
||||
undefinedText,
|
||||
'size8',
|
||||
'size24',
|
||||
'size32',
|
||||
'size40',
|
||||
'size48',
|
||||
'size56',
|
||||
'size72',
|
||||
'size100',
|
||||
'size120'
|
||||
];
|
||||
|
||||
interface ISwitchWithLabelProps {
|
||||
label: string;
|
||||
value: boolean;
|
||||
onValueChange: (value: boolean) => void;
|
||||
}
|
||||
|
||||
function SwitchWithLabel(props: ISwitchWithLabelProps): React.ReactElement {
|
||||
const { label, value, onValueChange } = props;
|
||||
return (
|
||||
<View style={commonStyles.switch}>
|
||||
<Text>{label}</Text>
|
||||
<Switch value={value} onValueChange={onValueChange} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export const StandardUsage: React.FunctionComponent<{}> = () => {
|
||||
const [showImage, setShowImage] = React.useState(true);
|
||||
const [showPrimary, setShowPrimary] = React.useState(true);
|
||||
const [showSecondary, setShowSecondary] = React.useState(true);
|
||||
const [showTertiary, setShowTertiary] = React.useState(true);
|
||||
const [showOptional, setShowOptional] = React.useState(true);
|
||||
const [imageSize, setImageSize] = React.useState<PersonaSize | undefined>('size72');
|
||||
|
||||
return (
|
||||
<View style={commonStyles.root}>
|
||||
{/* settings */}
|
||||
<View style={commonStyles.settings}>
|
||||
<SwitchWithLabel label="Show image" value={showImage} onValueChange={setShowImage} />
|
||||
<SwitchWithLabel label="Show primary text" value={showPrimary} onValueChange={setShowPrimary} />
|
||||
<SwitchWithLabel label="Show secondary text" value={showSecondary} onValueChange={setShowSecondary} />
|
||||
<SwitchWithLabel label="Show tertiary text" value={showTertiary} onValueChange={setShowTertiary} />
|
||||
<SwitchWithLabel label="Show optional text" value={showOptional} onValueChange={setShowOptional} />
|
||||
|
||||
<Picker
|
||||
prompt="Size"
|
||||
style={commonStyles.header}
|
||||
selectedValue={imageSize || undefinedText}
|
||||
onValueChange={size => setImageSize(size === undefinedText ? undefined : size)}
|
||||
>
|
||||
{allSizes.map((size, index) => (
|
||||
<Picker.Item label={size} key={index} value={size} />
|
||||
))}
|
||||
</Picker>
|
||||
</View>
|
||||
|
||||
<Persona
|
||||
text={showPrimary ? 'Rajesh Jha' : undefined}
|
||||
secondaryText={showSecondary ? 'Executive Vice President' : undefined}
|
||||
tertiaryText={showTertiary ? 'E & D' : undefined}
|
||||
optionalText={showOptional ? 'Building 36/5600' : undefined}
|
||||
size={imageSize}
|
||||
initials="RJ"
|
||||
imageUrl={showImage ? rajeshImageUrl : undefined}
|
||||
imageDescription="Profile photo of Rajesh Jha"
|
||||
presence={'away'}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export * from '../PersonaCoin/styles';
|
||||
|
||||
export const rajeshImageUrl =
|
||||
'https://3er1viui9wo30pkxh1v2nh4w-wpengine.netdna-ssl.com/wp-content/uploads/prod/2016/09/Rajesh-BW-Square.jpg';
|
||||
|
||||
export const michaelImageUrl = 'http://www.rap-up.com/app/uploads/2014/12/michael-jackson.jpg';
|
||||
export * from '../PersonaCoin/styles';
|
||||
|
||||
export const rajeshImageUrl =
|
||||
'https://3er1viui9wo30pkxh1v2nh4w-wpengine.netdna-ssl.com/wp-content/uploads/prod/2016/09/Rajesh-BW-Square.jpg';
|
||||
|
||||
export const michaelImageUrl = 'http://www.rap-up.com/app/uploads/2014/12/michael-jackson.jpg';
|
||||
|
|
|
@ -1,99 +1,99 @@
|
|||
import * as React from 'react';
|
||||
import { PersonaCoin, IconAlignment, IPersonaCoinTokens } from '@fluentui/react-native';
|
||||
import { Switch, View, Text, TextInput } from 'react-native';
|
||||
import { Slider } from '../Common/Slider';
|
||||
import { steveBallmerPhotoUrl } from './styles';
|
||||
import { useTheme } from '@uifabricshared/theming-react-native';
|
||||
import { AlignmentPicker } from '../Common/AlignmentPicker';
|
||||
import { commonTestStyles as commonStyles } from '../Common/styles';
|
||||
|
||||
export const CustomizeUsage: React.FunctionComponent<{}> = () => {
|
||||
const [showImage, setShowImage] = React.useState(true);
|
||||
const [coinColor, setCoinColor] = React.useState<string>();
|
||||
const [textColor, setTextColor] = React.useState<string>();
|
||||
const [physicalSize, setPhysicalSize] = React.useState<number>(80);
|
||||
const [iconSize, setIconSize] = React.useState<number>(24);
|
||||
const [initialsSize, setInitialsSize] = React.useState<number>(14);
|
||||
const [horizontalAlignment, setHorizontalAlignment] = React.useState<IconAlignment>();
|
||||
const [verticalAlignment, setVerticalAlignment] = React.useState<IconAlignment>();
|
||||
|
||||
const theme = useTheme();
|
||||
const textBoxBorderStyle = {
|
||||
borderColor: theme.colors.inputBorder
|
||||
};
|
||||
|
||||
const tokens: Partial<IPersonaCoinTokens> = {};
|
||||
if (coinColor) {
|
||||
tokens.backgroundColor = coinColor;
|
||||
}
|
||||
if (textColor) {
|
||||
tokens.color = textColor;
|
||||
}
|
||||
if (horizontalAlignment) {
|
||||
tokens.horizontalIconAlignment = horizontalAlignment;
|
||||
}
|
||||
if (verticalAlignment) {
|
||||
tokens.verticalIconAlignment = verticalAlignment;
|
||||
}
|
||||
if (iconSize) {
|
||||
tokens.iconSize = iconSize;
|
||||
}
|
||||
if (initialsSize) {
|
||||
tokens.initialsSize = initialsSize;
|
||||
}
|
||||
if (physicalSize) {
|
||||
tokens.coinSize = physicalSize;
|
||||
}
|
||||
|
||||
const CustomizedPersonaCoin = PersonaCoin.customize({ tokens });
|
||||
|
||||
return (
|
||||
<View style={commonStyles.root}>
|
||||
{/* settings */}
|
||||
<View style={commonStyles.settings}>
|
||||
<View style={commonStyles.switch}>
|
||||
<Text>Show image</Text>
|
||||
<Switch value={showImage} onValueChange={setShowImage} />
|
||||
</View>
|
||||
|
||||
<TextInput
|
||||
style={[commonStyles.textBox, textBoxBorderStyle]}
|
||||
placeholder="Background color"
|
||||
blurOnSubmit={true}
|
||||
onSubmitEditing={e => {
|
||||
setCoinColor(e.nativeEvent.text);
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
style={[commonStyles.textBox, textBoxBorderStyle]}
|
||||
placeholder="Initials text color"
|
||||
blurOnSubmit={true}
|
||||
onSubmitEditing={e => {
|
||||
setTextColor(e.nativeEvent.text);
|
||||
}}
|
||||
/>
|
||||
|
||||
<AlignmentPicker style={commonStyles.header} label="Horizontal icon alignment" onSelectionChange={setHorizontalAlignment} />
|
||||
<AlignmentPicker style={commonStyles.header} label="Vertical icon alignment" onSelectionChange={setVerticalAlignment} />
|
||||
|
||||
<Text>Coin size</Text>
|
||||
<Slider minimum={8} maximum={200} initialValue={80} style={commonStyles.slider} onChange={setPhysicalSize} />
|
||||
|
||||
<Text>Icon size</Text>
|
||||
<Slider minimum={8} maximum={100} initialValue={24} style={commonStyles.slider} onChange={setIconSize} />
|
||||
|
||||
<Text>Font size</Text>
|
||||
<Slider minimum={5} maximum={50} initialValue={14} style={commonStyles.slider} onChange={setInitialsSize} />
|
||||
</View>
|
||||
|
||||
{/* component under test */}
|
||||
<CustomizedPersonaCoin
|
||||
initials="SB"
|
||||
imageDescription="Former CEO of Microsoft"
|
||||
presence="blocked"
|
||||
imageUrl={showImage ? steveBallmerPhotoUrl : undefined}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
import * as React from 'react';
|
||||
import { PersonaCoin, IconAlignment, IPersonaCoinTokens } from '@fluentui/react-native';
|
||||
import { Switch, View, Text, TextInput } from 'react-native';
|
||||
import { Slider } from '../Common/Slider';
|
||||
import { steveBallmerPhotoUrl } from './styles';
|
||||
import { useTheme } from '@uifabricshared/theming-react-native';
|
||||
import { AlignmentPicker } from '../Common/AlignmentPicker';
|
||||
import { commonTestStyles as commonStyles } from '../Common/styles';
|
||||
|
||||
export const CustomizeUsage: React.FunctionComponent<{}> = () => {
|
||||
const [showImage, setShowImage] = React.useState(true);
|
||||
const [coinColor, setCoinColor] = React.useState<string>();
|
||||
const [textColor, setTextColor] = React.useState<string>();
|
||||
const [physicalSize, setPhysicalSize] = React.useState<number>(80);
|
||||
const [iconSize, setIconSize] = React.useState<number>(24);
|
||||
const [initialsSize, setInitialsSize] = React.useState<number>(14);
|
||||
const [horizontalAlignment, setHorizontalAlignment] = React.useState<IconAlignment>();
|
||||
const [verticalAlignment, setVerticalAlignment] = React.useState<IconAlignment>();
|
||||
|
||||
const theme = useTheme();
|
||||
const textBoxBorderStyle = {
|
||||
borderColor: theme.colors.inputBorder
|
||||
};
|
||||
|
||||
const tokens: Partial<IPersonaCoinTokens> = {};
|
||||
if (coinColor) {
|
||||
tokens.backgroundColor = coinColor;
|
||||
}
|
||||
if (textColor) {
|
||||
tokens.color = textColor;
|
||||
}
|
||||
if (horizontalAlignment) {
|
||||
tokens.horizontalIconAlignment = horizontalAlignment;
|
||||
}
|
||||
if (verticalAlignment) {
|
||||
tokens.verticalIconAlignment = verticalAlignment;
|
||||
}
|
||||
if (iconSize) {
|
||||
tokens.iconSize = iconSize;
|
||||
}
|
||||
if (initialsSize) {
|
||||
tokens.initialsSize = initialsSize;
|
||||
}
|
||||
if (physicalSize) {
|
||||
tokens.coinSize = physicalSize;
|
||||
}
|
||||
|
||||
const CustomizedPersonaCoin = PersonaCoin.customize({ tokens });
|
||||
|
||||
return (
|
||||
<View style={commonStyles.root}>
|
||||
{/* settings */}
|
||||
<View style={commonStyles.settings}>
|
||||
<View style={commonStyles.switch}>
|
||||
<Text>Show image</Text>
|
||||
<Switch value={showImage} onValueChange={setShowImage} />
|
||||
</View>
|
||||
|
||||
<TextInput
|
||||
style={[commonStyles.textBox, textBoxBorderStyle]}
|
||||
placeholder="Background color"
|
||||
blurOnSubmit={true}
|
||||
onSubmitEditing={e => {
|
||||
setCoinColor(e.nativeEvent.text);
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
style={[commonStyles.textBox, textBoxBorderStyle]}
|
||||
placeholder="Initials text color"
|
||||
blurOnSubmit={true}
|
||||
onSubmitEditing={e => {
|
||||
setTextColor(e.nativeEvent.text);
|
||||
}}
|
||||
/>
|
||||
|
||||
<AlignmentPicker style={commonStyles.header} label="Horizontal icon alignment" onSelectionChange={setHorizontalAlignment} />
|
||||
<AlignmentPicker style={commonStyles.header} label="Vertical icon alignment" onSelectionChange={setVerticalAlignment} />
|
||||
|
||||
<Text>Coin size</Text>
|
||||
<Slider minimum={8} maximum={200} initialValue={80} style={commonStyles.slider} onChange={setPhysicalSize} />
|
||||
|
||||
<Text>Icon size</Text>
|
||||
<Slider minimum={8} maximum={100} initialValue={24} style={commonStyles.slider} onChange={setIconSize} />
|
||||
|
||||
<Text>Font size</Text>
|
||||
<Slider minimum={5} maximum={50} initialValue={14} style={commonStyles.slider} onChange={setInitialsSize} />
|
||||
</View>
|
||||
|
||||
{/* component under test */}
|
||||
<CustomizedPersonaCoin
|
||||
initials="SB"
|
||||
imageDescription="Former CEO of Microsoft"
|
||||
presence="blocked"
|
||||
imageUrl={showImage ? steveBallmerPhotoUrl : undefined}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import * as React from 'react';
|
||||
import { View, Text } from 'react-native';
|
||||
import { Separator } from '@fluentui/react-native';
|
||||
import { StandardUsage } from './StandardUsage';
|
||||
import { CustomizeUsage } from './CustomizeUsage';
|
||||
import { commonTestStyles as commonStyles } from '../Common/styles';
|
||||
|
||||
export const PersonaCoinTest: React.FunctionComponent<{}> = () => {
|
||||
return (
|
||||
<View>
|
||||
<Text style={commonStyles.section}>Standard Usage</Text>
|
||||
<Separator />
|
||||
<StandardUsage />
|
||||
|
||||
<Text style={commonStyles.section}>Customize Usage</Text>
|
||||
<Separator />
|
||||
<CustomizeUsage />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
import * as React from 'react';
|
||||
import { View, Text } from 'react-native';
|
||||
import { Separator } from '@fluentui/react-native';
|
||||
import { StandardUsage } from './StandardUsage';
|
||||
import { CustomizeUsage } from './CustomizeUsage';
|
||||
import { commonTestStyles as commonStyles } from '../Common/styles';
|
||||
|
||||
export const PersonaCoinTest: React.FunctionComponent<{}> = () => {
|
||||
return (
|
||||
<View>
|
||||
<Text style={commonStyles.section}>Standard Usage</Text>
|
||||
<Separator />
|
||||
<StandardUsage />
|
||||
|
||||
<Text style={commonStyles.section}>Customize Usage</Text>
|
||||
<Separator />
|
||||
<CustomizeUsage />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,96 +1,96 @@
|
|||
import * as React from 'react';
|
||||
import { PersonaSize, PersonaCoinColor, PersonaCoin, PersonaPresence } from '@fluentui/react-native';
|
||||
import { Switch, View, Text, Picker } from 'react-native';
|
||||
import { satyaPhotoUrl, undefinedText } from './styles';
|
||||
import { commonTestStyles as commonStyles } from '../Common/styles';
|
||||
|
||||
type WithUndefined<T> = T | typeof undefinedText;
|
||||
|
||||
const allSizes: WithUndefined<PersonaSize>[] = [
|
||||
undefinedText,
|
||||
'size8',
|
||||
'size24',
|
||||
'size32',
|
||||
'size40',
|
||||
'size48',
|
||||
'size56',
|
||||
'size72',
|
||||
'size100',
|
||||
'size120'
|
||||
];
|
||||
|
||||
const allColors: WithUndefined<PersonaCoinColor>[] = [
|
||||
undefinedText,
|
||||
'lightBlue',
|
||||
'blue',
|
||||
'darkBlue',
|
||||
'teal',
|
||||
'green',
|
||||
'darkGreen',
|
||||
'lightPink',
|
||||
'pink',
|
||||
'magenta',
|
||||
'purple',
|
||||
'orange',
|
||||
'darkRed',
|
||||
'violet',
|
||||
'lightRed',
|
||||
'gold',
|
||||
'burgundy',
|
||||
'warmGray',
|
||||
'coolGray',
|
||||
'cyan',
|
||||
'rust'
|
||||
];
|
||||
const allPresences: WithUndefined<PersonaPresence>[] = [undefinedText, 'none', 'online', 'offline', 'busy', 'dnd', 'blocked', 'away'];
|
||||
|
||||
export const StandardUsage: React.FunctionComponent<{}> = () => {
|
||||
const [showImage, setShowImage] = React.useState(true);
|
||||
const [imageSize, setImageSize] = React.useState<WithUndefined<PersonaSize>>('size72');
|
||||
const [coinColor, setCoinColor] = React.useState<WithUndefined<PersonaCoinColor>>('gold');
|
||||
const [presence, setPresence] = React.useState<WithUndefined<PersonaPresence>>('online');
|
||||
|
||||
const onSizeChange = React.useCallback(value => setImageSize(value), []);
|
||||
const onColorChange = React.useCallback(value => setCoinColor(value), []);
|
||||
const onPresenceChange = React.useCallback(value => setPresence(value), []);
|
||||
|
||||
return (
|
||||
<View style={commonStyles.root}>
|
||||
{/* settings */}
|
||||
<View style={commonStyles.settings}>
|
||||
<View style={commonStyles.switch}>
|
||||
<Text>Show image</Text>
|
||||
<Switch value={showImage} onValueChange={setShowImage} />
|
||||
</View>
|
||||
|
||||
<Picker prompt="Size" style={commonStyles.header} selectedValue={imageSize} onValueChange={onSizeChange}>
|
||||
{allSizes.map((size, index) => (
|
||||
<Picker.Item label={size} key={index} value={size} />
|
||||
))}
|
||||
</Picker>
|
||||
|
||||
<Picker prompt="Coin color" style={commonStyles.header} selectedValue={coinColor} onValueChange={onColorChange}>
|
||||
{allColors.map((color, index) => (
|
||||
<Picker.Item label={color} key={index} value={color} />
|
||||
))}
|
||||
</Picker>
|
||||
|
||||
<Picker prompt="Presence status" style={commonStyles.header} selectedValue={presence} onValueChange={onPresenceChange}>
|
||||
{allPresences.map((presence, index) => (
|
||||
<Picker.Item label={presence} key={index} value={presence} />
|
||||
))}
|
||||
</Picker>
|
||||
</View>
|
||||
|
||||
{/* component under test */}
|
||||
<PersonaCoin
|
||||
size={imageSize === undefinedText ? undefined : imageSize}
|
||||
initials="SN"
|
||||
imageDescription="Photo of Satya Nadella"
|
||||
presence={presence === undefinedText ? undefined : presence}
|
||||
imageUrl={showImage ? satyaPhotoUrl : undefined}
|
||||
coinColor={coinColor === undefinedText ? undefined : coinColor}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
import * as React from 'react';
|
||||
import { PersonaSize, PersonaCoinColor, PersonaCoin, PersonaPresence } from '@fluentui/react-native';
|
||||
import { Switch, View, Text, Picker } from 'react-native';
|
||||
import { satyaPhotoUrl, undefinedText } from './styles';
|
||||
import { commonTestStyles as commonStyles } from '../Common/styles';
|
||||
|
||||
type WithUndefined<T> = T | typeof undefinedText;
|
||||
|
||||
const allSizes: WithUndefined<PersonaSize>[] = [
|
||||
undefinedText,
|
||||
'size8',
|
||||
'size24',
|
||||
'size32',
|
||||
'size40',
|
||||
'size48',
|
||||
'size56',
|
||||
'size72',
|
||||
'size100',
|
||||
'size120'
|
||||
];
|
||||
|
||||
const allColors: WithUndefined<PersonaCoinColor>[] = [
|
||||
undefinedText,
|
||||
'lightBlue',
|
||||
'blue',
|
||||
'darkBlue',
|
||||
'teal',
|
||||
'green',
|
||||
'darkGreen',
|
||||
'lightPink',
|
||||
'pink',
|
||||
'magenta',
|
||||
'purple',
|
||||
'orange',
|
||||
'darkRed',
|
||||
'violet',
|
||||
'lightRed',
|
||||
'gold',
|
||||
'burgundy',
|
||||
'warmGray',
|
||||
'coolGray',
|
||||
'cyan',
|
||||
'rust'
|
||||
];
|
||||
const allPresences: WithUndefined<PersonaPresence>[] = [undefinedText, 'none', 'online', 'offline', 'busy', 'dnd', 'blocked', 'away'];
|
||||
|
||||
export const StandardUsage: React.FunctionComponent<{}> = () => {
|
||||
const [showImage, setShowImage] = React.useState(true);
|
||||
const [imageSize, setImageSize] = React.useState<WithUndefined<PersonaSize>>('size72');
|
||||
const [coinColor, setCoinColor] = React.useState<WithUndefined<PersonaCoinColor>>('gold');
|
||||
const [presence, setPresence] = React.useState<WithUndefined<PersonaPresence>>('online');
|
||||
|
||||
const onSizeChange = React.useCallback(value => setImageSize(value), []);
|
||||
const onColorChange = React.useCallback(value => setCoinColor(value), []);
|
||||
const onPresenceChange = React.useCallback(value => setPresence(value), []);
|
||||
|
||||
return (
|
||||
<View style={commonStyles.root}>
|
||||
{/* settings */}
|
||||
<View style={commonStyles.settings}>
|
||||
<View style={commonStyles.switch}>
|
||||
<Text>Show image</Text>
|
||||
<Switch value={showImage} onValueChange={setShowImage} />
|
||||
</View>
|
||||
|
||||
<Picker prompt="Size" style={commonStyles.header} selectedValue={imageSize} onValueChange={onSizeChange}>
|
||||
{allSizes.map((size, index) => (
|
||||
<Picker.Item label={size} key={index} value={size} />
|
||||
))}
|
||||
</Picker>
|
||||
|
||||
<Picker prompt="Coin color" style={commonStyles.header} selectedValue={coinColor} onValueChange={onColorChange}>
|
||||
{allColors.map((color, index) => (
|
||||
<Picker.Item label={color} key={index} value={color} />
|
||||
))}
|
||||
</Picker>
|
||||
|
||||
<Picker prompt="Presence status" style={commonStyles.header} selectedValue={presence} onValueChange={onPresenceChange}>
|
||||
{allPresences.map((presence, index) => (
|
||||
<Picker.Item label={presence} key={index} value={presence} />
|
||||
))}
|
||||
</Picker>
|
||||
</View>
|
||||
|
||||
{/* component under test */}
|
||||
<PersonaCoin
|
||||
size={imageSize === undefinedText ? undefined : imageSize}
|
||||
initials="SN"
|
||||
imageDescription="Photo of Satya Nadella"
|
||||
presence={presence === undefinedText ? undefined : presence}
|
||||
imageUrl={showImage ? satyaPhotoUrl : undefined}
|
||||
coinColor={coinColor === undefinedText ? undefined : coinColor}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
oneCoin: {
|
||||
margin: 8
|
||||
}
|
||||
});
|
||||
|
||||
export const satyaPhotoUrl =
|
||||
'https://www.microsoft.com/en-us/CMSImages/satya.jpg?version=0881eb71-4942-b627-d602-84c832b8a0b6&CollectionId=1b46ce2d-c90d-421e-94f1-cfb6bc6ef6ec';
|
||||
|
||||
export const steveBallmerPhotoUrl = 'http://www.rmndigital.com/wp-content/uploads/2012/11/stevems.jpg';
|
||||
|
||||
export const undefinedText = '(undefined)';
|
||||
import { StyleSheet } from 'react-native';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
oneCoin: {
|
||||
margin: 8
|
||||
}
|
||||
});
|
||||
|
||||
export const satyaPhotoUrl =
|
||||
'https://www.microsoft.com/en-us/CMSImages/satya.jpg?version=0881eb71-4942-b627-d602-84c832b8a0b6&CollectionId=1b46ce2d-c90d-421e-94f1-cfb6bc6ef6ec';
|
||||
|
||||
export const steveBallmerPhotoUrl = 'http://www.rmndigital.com/wp-content/uploads/2012/11/stevems.jpg';
|
||||
|
||||
export const undefinedText = '(undefined)';
|
||||
|
|
|
@ -1,48 +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: { variant: 'captionStandard', fontWeight: 'semiBold', color: '#ff0000' } });
|
||||
const OrangeSecondaryBold = Text.customize({ tokens: { variant: 'secondaryStandard', fontWeight: 'semiBold', color: '#ff9900' } });
|
||||
const YellowBodyBold = Text.customize({ tokens: { variant: 'bodyStandard', fontWeight: 'semiBold', color: '#f3ce00' } });
|
||||
const GreenSubheaderBold = Text.customize({ tokens: { variant: 'subheaderStandard', fontWeight: 'semiBold', color: '#02c440' } });
|
||||
const BlueHeaderBold = Text.customize({ tokens: { variant: 'headerStandard', fontWeight: 'semiBold', color: '#0229c4' } });
|
||||
const IndigoHeroBold = Text.customize({ tokens: { variant: 'heroStandard', fontWeight: 'semiBold', color: '#4b0082' } });
|
||||
const PurpleHeroLargeBold = Text.customize({ tokens: { variant: 'heroLargeStandard', fontWeight: 'semiBold', color: '#8402c4' } });
|
||||
|
||||
const ArialBlack = Text.customize({ tokens: { variant: 'heroLargeStandard', fontFamily: 'Arial Black' } });
|
||||
const BrushScriptMT = Text.customize({ tokens: { variant: 'heroStandard', fontFamily: 'Brush Script MT' } });
|
||||
const CourierNew = Text.customize({ tokens: { variant: 'headerStandard', fontFamily: 'Courier New' } });
|
||||
const Georgia = Text.customize({ tokens: { variant: 'subheaderStandard', fontFamily: 'Georgia' } });
|
||||
const SegoeScript = Text.customize({ tokens: { variant: 'bodyStandard', fontFamily: 'Segoe Script' } });
|
||||
const TimesNewRoman = Text.customize({ tokens: { variant: 'secondaryStandard', fontFamily: 'Times New Roman' } });
|
||||
const Wingdings = Text.customize({ tokens: { variant: '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>
|
||||
);
|
||||
};
|
||||
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: { variant: 'captionStandard', fontWeight: 'semiBold', color: '#ff0000' } });
|
||||
const OrangeSecondaryBold = Text.customize({ tokens: { variant: 'secondaryStandard', fontWeight: 'semiBold', color: '#ff9900' } });
|
||||
const YellowBodyBold = Text.customize({ tokens: { variant: 'bodyStandard', fontWeight: 'semiBold', color: '#f3ce00' } });
|
||||
const GreenSubheaderBold = Text.customize({ tokens: { variant: 'subheaderStandard', fontWeight: 'semiBold', color: '#02c440' } });
|
||||
const BlueHeaderBold = Text.customize({ tokens: { variant: 'headerStandard', fontWeight: 'semiBold', color: '#0229c4' } });
|
||||
const IndigoHeroBold = Text.customize({ tokens: { variant: 'heroStandard', fontWeight: 'semiBold', color: '#4b0082' } });
|
||||
const PurpleHeroLargeBold = Text.customize({ tokens: { variant: 'heroLargeStandard', fontWeight: 'semiBold', color: '#8402c4' } });
|
||||
|
||||
const ArialBlack = Text.customize({ tokens: { variant: 'heroLargeStandard', fontFamily: 'Arial Black' } });
|
||||
const BrushScriptMT = Text.customize({ tokens: { variant: 'heroStandard', fontFamily: 'Brush Script MT' } });
|
||||
const CourierNew = Text.customize({ tokens: { variant: 'headerStandard', fontFamily: 'Courier New' } });
|
||||
const Georgia = Text.customize({ tokens: { variant: 'subheaderStandard', fontFamily: 'Georgia' } });
|
||||
const SegoeScript = Text.customize({ tokens: { variant: 'bodyStandard', fontFamily: 'Segoe Script' } });
|
||||
const TimesNewRoman = Text.customize({ tokens: { variant: 'secondaryStandard', fontFamily: 'Times New Roman' } });
|
||||
const Wingdings = Text.customize({ tokens: { variant: '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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,24 +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 variant="captionStandard">CaptionStandard</Text>
|
||||
<Text variant="secondaryStandard">SecondaryStandard</Text>
|
||||
<Text variant="secondarySemibold">SecondarySemibold</Text>
|
||||
<Text variant="bodyStandard">BodyStandard</Text>
|
||||
<Text variant="bodySemibold">BodySemibold</Text>
|
||||
<Text variant="subheaderStandard">SubheaderStandard</Text>
|
||||
<Text variant="subheaderSemibold">SubheaderSemibold</Text>
|
||||
<Text variant="headerStandard">HeaderStandard</Text>
|
||||
<Text variant="headerSemibold">HeaderSemibold</Text>
|
||||
<Text variant="heroStandard">HeroStandard</Text>
|
||||
<Text variant="heroSemibold">HeroSemibold</Text>
|
||||
<Text variant="heroLargeStandard">HeroLargeStandard</Text>
|
||||
<Text variant="heroLargeSemibold">HeroLargeSemibold</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
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 variant="captionStandard">CaptionStandard</Text>
|
||||
<Text variant="secondaryStandard">SecondaryStandard</Text>
|
||||
<Text variant="secondarySemibold">SecondarySemibold</Text>
|
||||
<Text variant="bodyStandard">BodyStandard</Text>
|
||||
<Text variant="bodySemibold">BodySemibold</Text>
|
||||
<Text variant="subheaderStandard">SubheaderStandard</Text>
|
||||
<Text variant="subheaderSemibold">SubheaderSemibold</Text>
|
||||
<Text variant="headerStandard">HeaderStandard</Text>
|
||||
<Text variant="headerSemibold">HeaderSemibold</Text>
|
||||
<Text variant="heroStandard">HeroStandard</Text>
|
||||
<Text variant="heroSemibold">HeroSemibold</Text>
|
||||
<Text variant="heroLargeStandard">HeroLargeStandard</Text>
|
||||
<Text variant="heroLargeSemibold">HeroLargeSemibold</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,21 +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>
|
||||
);
|
||||
};
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1 +1 @@
|
|||
export * from './TextTest';
|
||||
export * from './TextTest';
|
||||
|
|
|
@ -1,16 +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
|
||||
}
|
||||
});
|
||||
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,205 +1,207 @@
|
|||
import * as React from 'react';
|
||||
import { FlatList, View, ViewStyle, TextStyle, StyleSheet } 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 TextStyle,
|
||||
largeStandard: {
|
||||
color: theme.colors.bodyText,
|
||||
fontSize: theme.typography.sizes.body,
|
||||
fontWeight: theme.typography.weights.regular,
|
||||
fontFamily: theme.typography.families.primary,
|
||||
marginBottom: 5,
|
||||
} as TextStyle,
|
||||
stackStyle: {
|
||||
borderWidth: 2,
|
||||
borderColor: theme.colors.focusBorder,
|
||||
padding: 12,
|
||||
margin: 8,
|
||||
backgroundColor: theme.colors.background,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const styles = 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 (
|
||||
<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} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const getSwatchColorStyle = (color: string): 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 (
|
||||
<View style={styles.swatchItem}>
|
||||
<View style={[getSwatchColorStyle(p.color), themedStyles.swatch]} />
|
||||
<Text>{p.name}</Text>
|
||||
</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 (
|
||||
<View style={[commonTestStyles.view]}>
|
||||
<Text style={themedStyles.largeStandard}>getHostSettingsWin32(theme: ITheme).palette</Text>
|
||||
<View style={themedStyles.stackStyle}>
|
||||
<FlatList data={paletteAsArray} renderItem={renderSwatch} />
|
||||
</View>
|
||||
</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 (
|
||||
<View>
|
||||
<Text style={themedStyles.extraLargeStandardEmphasis}>Configure Theme</Text>
|
||||
<Separator />
|
||||
<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>
|
||||
</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 />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export const ThemeTest: React.FunctionComponent = () => {
|
||||
return (
|
||||
<ThemeProvider theme="Default">
|
||||
<ThemeTestInner />
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
import * as React from 'react';
|
||||
import { FlatList, View, ViewStyle, TextStyle, StyleSheet } 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 TextStyle,
|
||||
largeStandard: {
|
||||
color: theme.colors.bodyText,
|
||||
fontSize: theme.typography.sizes.body,
|
||||
fontWeight: theme.typography.weights.regular,
|
||||
fontFamily: theme.typography.families.primary,
|
||||
marginBottom: 5
|
||||
} as TextStyle,
|
||||
stackStyle: {
|
||||
borderWidth: 2,
|
||||
borderColor: theme.colors.focusBorder,
|
||||
padding: 12,
|
||||
margin: 8,
|
||||
backgroundColor: theme.colors.background
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const styles = 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 (
|
||||
<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} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const getSwatchColorStyle = (color: string): 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 (
|
||||
<View style={styles.swatchItem}>
|
||||
<View style={[getSwatchColorStyle(p.color), themedStyles.swatch]} />
|
||||
<Text>{p.name}</Text>
|
||||
</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 (
|
||||
<View style={[commonTestStyles.view]}>
|
||||
<Text style={themedStyles.largeStandard}>getHostSettingsWin32(theme: ITheme).palette</Text>
|
||||
<View style={themedStyles.stackStyle}>
|
||||
<FlatList data={paletteAsArray} renderItem={renderSwatch} />
|
||||
</View>
|
||||
</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 (
|
||||
<View>
|
||||
<Text style={themedStyles.extraLargeStandardEmphasis}>Configure Theme</Text>
|
||||
<Separator />
|
||||
<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>
|
||||
</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 />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export const ThemeTest: React.FunctionComponent = () => {
|
||||
return (
|
||||
<ThemeProvider theme="Default">
|
||||
<ThemeTestInner />
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,74 +1,74 @@
|
|||
import * as React from 'react';
|
||||
import { ButtonFocusTest } from './Button';
|
||||
import { CalloutTest } from './Callout';
|
||||
import { CheckboxTest } from './Checkbox';
|
||||
import { FocusTrapTest } from './FocusTrapZone';
|
||||
import { LinkTest } from './Link';
|
||||
import { PersonaTest } from './Persona';
|
||||
import { PersonaCoinTest } from './PersonaCoin';
|
||||
import { PressableTest } from './Pressable';
|
||||
import { RadioGroupTest } from './RadioGroup';
|
||||
import { SeparatorTest } from './Separator';
|
||||
import { SvgTest } from './Svg';
|
||||
import { TextTest } from './Text';
|
||||
import { ThemeTest } from './Theme';
|
||||
|
||||
export type TestDescription = {
|
||||
name: string;
|
||||
component: React.FunctionComponent<{}>;
|
||||
};
|
||||
|
||||
export const allTestComponents: TestDescription[] = [
|
||||
{
|
||||
name: 'Button Test',
|
||||
component: ButtonFocusTest
|
||||
},
|
||||
{
|
||||
name: 'Callout Test',
|
||||
component: CalloutTest
|
||||
},
|
||||
{
|
||||
name: 'Focus Trap Zone Test',
|
||||
component: FocusTrapTest
|
||||
},
|
||||
{
|
||||
name: 'Pressable Test',
|
||||
component: PressableTest
|
||||
},
|
||||
{
|
||||
name: 'Link Test',
|
||||
component: LinkTest
|
||||
},
|
||||
{
|
||||
name: 'Separator Test',
|
||||
component: SeparatorTest
|
||||
},
|
||||
{
|
||||
name: 'Text Test',
|
||||
component: TextTest
|
||||
},
|
||||
{
|
||||
name: 'Theme Test',
|
||||
component: ThemeTest
|
||||
},
|
||||
{
|
||||
name: 'PersonaCoin Test',
|
||||
component: PersonaCoinTest
|
||||
},
|
||||
{
|
||||
name: 'RadioGroup Test',
|
||||
component: RadioGroupTest
|
||||
},
|
||||
{
|
||||
name: 'Persona Test',
|
||||
component: PersonaTest
|
||||
},
|
||||
{
|
||||
name: 'Checkbox Test',
|
||||
component: CheckboxTest
|
||||
},
|
||||
{
|
||||
name: 'Svg Test',
|
||||
component: SvgTest
|
||||
}
|
||||
];
|
||||
import * as React from 'react';
|
||||
import { ButtonFocusTest } from './Button';
|
||||
import { CalloutTest } from './Callout';
|
||||
import { CheckboxTest } from './Checkbox';
|
||||
import { FocusTrapTest } from './FocusTrapZone';
|
||||
import { LinkTest } from './Link';
|
||||
import { PersonaTest } from './Persona';
|
||||
import { PersonaCoinTest } from './PersonaCoin';
|
||||
import { PressableTest } from './Pressable';
|
||||
import { RadioGroupTest } from './RadioGroup';
|
||||
import { SeparatorTest } from './Separator';
|
||||
import { SvgTest } from './Svg';
|
||||
import { TextTest } from './Text';
|
||||
import { ThemeTest } from './Theme';
|
||||
|
||||
export type TestDescription = {
|
||||
name: string;
|
||||
component: React.FunctionComponent<{}>;
|
||||
};
|
||||
|
||||
export const allTestComponents: TestDescription[] = [
|
||||
{
|
||||
name: 'Button Test',
|
||||
component: ButtonFocusTest
|
||||
},
|
||||
{
|
||||
name: 'Callout Test',
|
||||
component: CalloutTest
|
||||
},
|
||||
{
|
||||
name: 'Focus Trap Zone Test',
|
||||
component: FocusTrapTest
|
||||
},
|
||||
{
|
||||
name: 'Pressable Test',
|
||||
component: PressableTest
|
||||
},
|
||||
{
|
||||
name: 'Link Test',
|
||||
component: LinkTest
|
||||
},
|
||||
{
|
||||
name: 'Separator Test',
|
||||
component: SeparatorTest
|
||||
},
|
||||
{
|
||||
name: 'Text Test',
|
||||
component: TextTest
|
||||
},
|
||||
{
|
||||
name: 'Theme Test',
|
||||
component: ThemeTest
|
||||
},
|
||||
{
|
||||
name: 'PersonaCoin Test',
|
||||
component: PersonaCoinTest
|
||||
},
|
||||
{
|
||||
name: 'RadioGroup Test',
|
||||
component: RadioGroupTest
|
||||
},
|
||||
{
|
||||
name: 'Persona Test',
|
||||
component: PersonaTest
|
||||
},
|
||||
{
|
||||
name: 'Checkbox Test',
|
||||
component: CheckboxTest
|
||||
},
|
||||
{
|
||||
name: 'Svg Test',
|
||||
component: SvgTest
|
||||
}
|
||||
];
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui/react-native",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:23.897Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/adapters",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:24.990Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/build-tools",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:26.061Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/button",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:04.618Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/callout",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:06.521Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/checkbox",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:07.762Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/focus-trap-zone",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:08.906Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/link",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:10.072Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/persona",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:11.164Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/persona-coin",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:12.343Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/pressable",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:13.471Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/radio-group",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:14.685Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/separator",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:15.929Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/text",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:17.203Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@fluentui-react-native/tokens",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:27.125Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@uifabricshared/foundation-compose",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:18.346Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@uifabricshared/themed-stylesheet",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:19.672Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@uifabricshared/theming-ramp",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:21.671Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "renormalize files",
|
||||
"packageName": "@uifabricshared/theming-react-native",
|
||||
"email": "jasonmo@microsoft.com",
|
||||
"dependentChangeType": "patch",
|
||||
"date": "2020-04-24T07:22:22.676Z"
|
||||
}
|
|
@ -1,48 +1,48 @@
|
|||
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: {
|
||||
variant: 'secondaryStandard',
|
||||
color: 'link'
|
||||
},
|
||||
root: {
|
||||
style: {
|
||||
margin: 0,
|
||||
textDecorationLine: 'underline'
|
||||
} as IViewProps['style']
|
||||
},
|
||||
content: {
|
||||
style: {
|
||||
textDecorationLine: 'underline'
|
||||
}
|
||||
},
|
||||
_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: {
|
||||
variant: 'secondaryStandard',
|
||||
color: 'link'
|
||||
},
|
||||
root: {
|
||||
style: {
|
||||
margin: 0,
|
||||
textDecorationLine: 'underline'
|
||||
} as IViewProps['style']
|
||||
},
|
||||
content: {
|
||||
style: {
|
||||
textDecorationLine: 'underline'
|
||||
}
|
||||
},
|
||||
_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: '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'];
|
||||
}
|
||||
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,26 +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: {
|
||||
variant: 'secondaryStandard',
|
||||
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: {
|
||||
variant: 'secondaryStandard',
|
||||
color: 'bodyText'
|
||||
},
|
||||
root: {
|
||||
style: {
|
||||
margin: 0
|
||||
} as TextStyle
|
||||
},
|
||||
_overrides: {
|
||||
disabled: {
|
||||
tokens: {
|
||||
color: 'disabledText'
|
||||
}
|
||||
}
|
||||
},
|
||||
_precedence: ['disabled']
|
||||
},
|
||||
textName
|
||||
];
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
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;
|
||||
};
|
||||
};
|
||||
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,31 +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 variant="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();
|
||||
});
|
||||
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 variant="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": 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>
|
||||
`;
|
||||
// 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,381 +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(): 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 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: IVariants;
|
||||
// (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 interface IVariants {
|
||||
// (undocumented)
|
||||
bodySemibold: VariantValue;
|
||||
// (undocumented)
|
||||
bodyStandard: VariantValue;
|
||||
// (undocumented)
|
||||
captionStandard: VariantValue;
|
||||
// (undocumented)
|
||||
headerSemibold: VariantValue;
|
||||
// (undocumented)
|
||||
headerStandard: VariantValue;
|
||||
// (undocumented)
|
||||
heroLargeSemibold: VariantValue;
|
||||
// (undocumented)
|
||||
heroLargeStandard: VariantValue;
|
||||
// (undocumented)
|
||||
heroSemibold: VariantValue;
|
||||
// (undocumented)
|
||||
heroStandard: VariantValue;
|
||||
// (undocumented)
|
||||
secondarySemibold: VariantValue;
|
||||
// (undocumented)
|
||||
secondaryStandard: VariantValue;
|
||||
// (undocumented)
|
||||
subheaderSemibold: VariantValue;
|
||||
// (undocumented)
|
||||
subheaderStandard: VariantValue;
|
||||
}
|
||||
|
||||
// @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;
|
||||
|
||||
// @public
|
||||
export type Variant = keyof IVariants | VariantValue;
|
||||
|
||||
// @public
|
||||
export type VariantValue = {
|
||||
face: FontFamily;
|
||||
size: FontSize;
|
||||
weight: FontWeight;
|
||||
};
|
||||
|
||||
|
||||
// (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 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 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: IVariants;
|
||||
// (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 interface IVariants {
|
||||
// (undocumented)
|
||||
bodySemibold: VariantValue;
|
||||
// (undocumented)
|
||||
bodyStandard: VariantValue;
|
||||
// (undocumented)
|
||||
captionStandard: VariantValue;
|
||||
// (undocumented)
|
||||
headerSemibold: VariantValue;
|
||||
// (undocumented)
|
||||
headerStandard: VariantValue;
|
||||
// (undocumented)
|
||||
heroLargeSemibold: VariantValue;
|
||||
// (undocumented)
|
||||
heroLargeStandard: VariantValue;
|
||||
// (undocumented)
|
||||
heroSemibold: VariantValue;
|
||||
// (undocumented)
|
||||
heroStandard: VariantValue;
|
||||
// (undocumented)
|
||||
secondarySemibold: VariantValue;
|
||||
// (undocumented)
|
||||
secondaryStandard: VariantValue;
|
||||
// (undocumented)
|
||||
subheaderSemibold: VariantValue;
|
||||
// (undocumented)
|
||||
subheaderStandard: VariantValue;
|
||||
}
|
||||
|
||||
// @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;
|
||||
|
||||
// @public
|
||||
export type Variant = keyof IVariants | VariantValue;
|
||||
|
||||
// @public
|
||||
export type VariantValue = {
|
||||
face: FontFamily;
|
||||
size: FontSize;
|
||||
weight: FontWeight;
|
||||
};
|
||||
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
|
||||
```
|
||||
|
|
|
@ -1,110 +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: {
|
||||
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'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
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,68 +1,68 @@
|
|||
import { IFontFamilies, IFontSizes, IFontWeights, IVariants, 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 IVariants;
|
||||
|
||||
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');
|
||||
});
|
||||
});
|
||||
import { IFontFamilies, IFontSizes, IFontWeights, IVariants, 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 IVariants;
|
||||
|
||||
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,146 +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 {
|
||||
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 VariantValue = {
|
||||
face: FontFamily;
|
||||
size: FontSize;
|
||||
weight: FontWeight;
|
||||
};
|
||||
|
||||
/**
|
||||
* A collection of named font variants.
|
||||
*/
|
||||
export interface IVariants {
|
||||
captionStandard: VariantValue;
|
||||
secondaryStandard: VariantValue;
|
||||
secondarySemibold: VariantValue;
|
||||
bodyStandard: VariantValue;
|
||||
bodySemibold: VariantValue;
|
||||
subheaderStandard: VariantValue;
|
||||
subheaderSemibold: VariantValue;
|
||||
headerStandard: VariantValue;
|
||||
headerSemibold: VariantValue;
|
||||
heroStandard: VariantValue;
|
||||
heroSemibold: VariantValue;
|
||||
heroLargeStandard: VariantValue;
|
||||
heroLargeSemibold: VariantValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* A font variant, used when defining a visual element in a theme.
|
||||
*/
|
||||
export type Variant = keyof IVariants | VariantValue;
|
||||
|
||||
/**
|
||||
* 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: IVariants;
|
||||
}
|
||||
|
||||
export type ITypography = ITextStyle;
|
||||
|
||||
/**
|
||||
* 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 VariantValue = {
|
||||
face: FontFamily;
|
||||
size: FontSize;
|
||||
weight: FontWeight;
|
||||
};
|
||||
|
||||
/**
|
||||
* A collection of named font variants.
|
||||
*/
|
||||
export interface IVariants {
|
||||
captionStandard: VariantValue;
|
||||
secondaryStandard: VariantValue;
|
||||
secondarySemibold: VariantValue;
|
||||
bodyStandard: VariantValue;
|
||||
bodySemibold: VariantValue;
|
||||
subheaderStandard: VariantValue;
|
||||
subheaderSemibold: VariantValue;
|
||||
headerStandard: VariantValue;
|
||||
headerSemibold: VariantValue;
|
||||
heroStandard: VariantValue;
|
||||
heroSemibold: VariantValue;
|
||||
heroLargeStandard: VariantValue;
|
||||
heroLargeSemibold: VariantValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* A font variant, used when defining a visual element in a theme.
|
||||
*/
|
||||
export type Variant = keyof IVariants | VariantValue;
|
||||
|
||||
/**
|
||||
* 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: IVariants;
|
||||
}
|
||||
|
||||
export type ITypography = ITextStyle;
|
||||
|
||||
/**
|
||||
* A partially specified typography.
|
||||
*/
|
||||
export type IPartialTypography = { [P in keyof ITypography]?: Partial<ITypography[P]> };
|
||||
|
|
|
@ -1,57 +1,57 @@
|
|||
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: {}
|
||||
};
|
||||
}
|
||||
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,158 +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,
|
||||
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
|
||||
};
|
||||
}
|
||||
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,50 +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: object;
|
||||
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;
|
||||
};
|
||||
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: object;
|
||||
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.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);
|
||||
}
|
||||
};
|
||||
}
|
||||
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,199 +1,199 @@
|
|||
// @ts-check
|
||||
import Metro from 'metro';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { logger, TaskFunction } from 'just-task';
|
||||
import { AllPlatforms } from './platforms';
|
||||
import { addPlatformMetroConfig } from './configureMetro';
|
||||
|
||||
export interface BundleDetails {
|
||||
/**
|
||||
* entry file such as './src/index.ts'
|
||||
*/
|
||||
entry?: string;
|
||||
outputPath?: string;
|
||||
bundleName?: string;
|
||||
noPlatformSuffix?: boolean;
|
||||
noJSExtension?: boolean;
|
||||
}
|
||||
|
||||
export type BundleDefinition = BundleDetails & {
|
||||
name?: string;
|
||||
targets?: AllPlatforms[];
|
||||
platforms?: {
|
||||
[K in AllPlatforms]: BundleDetails;
|
||||
};
|
||||
};
|
||||
|
||||
export type MetroBundles = BundleDefinition | BundleDefinition[];
|
||||
|
||||
function asArray<T>(opt: T | T[]): T[] {
|
||||
return Array.isArray(opt) ? opt : [opt || ({} as T)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a bundle definition from package.json. The bundle definition should be of type BundleDefinition and would
|
||||
* typically look something like:
|
||||
* "metroBundles": {
|
||||
* "targets": ["win32", "windows"],
|
||||
* "entryFile": "./src/index.ts",
|
||||
* "outputPath": "./dist",
|
||||
* "outputFile": "myBundleName"
|
||||
* }
|
||||
*
|
||||
* Platform specific overrides can be specified by using a platforms which works as a selector. In this case
|
||||
* add:
|
||||
* "metroBundles": {
|
||||
* ...stuff
|
||||
* "platforms": {
|
||||
* "ios": {
|
||||
* "outputFile": "myIOSName"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @param bundleName - optional name of the bundle, use if there are multiple bundles defined in package JSON
|
||||
*/
|
||||
function loadBundleDefinition(bundleName?: string): BundleDefinition {
|
||||
const packageConfigPath = path.resolve(process.cwd(), 'package.json');
|
||||
const packageConfig = JSON.parse(fs.readFileSync(packageConfigPath, 'utf8'));
|
||||
|
||||
const metroBundles = asArray<BundleDefinition>(packageConfig.metroBundles);
|
||||
if (bundleName) {
|
||||
return metroBundles.find(bundle => bundle.name === bundleName) || {};
|
||||
}
|
||||
|
||||
if (metroBundles.length > 1) {
|
||||
logger.error('Multiple bundles are specified in the package, so bundle is ambiguous');
|
||||
} else if (metroBundles.length === 0) {
|
||||
logger.error('The package must contain a bundle definition');
|
||||
}
|
||||
return metroBundles[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the platform selector for each bundle target
|
||||
* @param bundle - bundle definition, potentially including a platform selector
|
||||
* @param platform - current platform target
|
||||
*/
|
||||
function getOptionsForPlatform(bundle: BundleDefinition, platform: AllPlatforms): BundleDefinition {
|
||||
const platformValues = bundle.platforms && bundle.platforms[platform];
|
||||
return platformValues ? { ...bundle, ...platformValues } : bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* options for the metro task
|
||||
*/
|
||||
export interface MetroTaskOptions {
|
||||
/**
|
||||
* name of the bundle to target, can be blank if the package.json only includes one bundle
|
||||
*/
|
||||
bundleName?: string;
|
||||
|
||||
/**
|
||||
* platform to bundle for, if blank will bundle for all platforms in this folder
|
||||
*/
|
||||
platform?: AllPlatforms;
|
||||
|
||||
/**
|
||||
* whether to bundle in development mode
|
||||
*/
|
||||
dev?: boolean;
|
||||
|
||||
/**
|
||||
* run metro in server mode
|
||||
*/
|
||||
server?: boolean;
|
||||
|
||||
/**
|
||||
* port override for server mode
|
||||
*/
|
||||
port?: number;
|
||||
}
|
||||
|
||||
export function metroTask(options: MetroTaskOptions = {}): TaskFunction {
|
||||
const { bundleName, platform, dev = false, server } = options;
|
||||
const port = options.port || (platform === 'windows' ? 8081 : 8080);
|
||||
|
||||
return async function metroPack(done) {
|
||||
logger.verbose(`Starting metropack task with platform ${bundleName}...`);
|
||||
|
||||
// get the bundle definition
|
||||
const definition = loadBundleDefinition(bundleName);
|
||||
const targets = (platform && [platform]) || definition.targets || [];
|
||||
|
||||
for (const targetPlatform of targets) {
|
||||
// get the options specified for the platform
|
||||
const platformDefinition = getOptionsForPlatform(definition, targetPlatform);
|
||||
|
||||
// set up file input and output
|
||||
const { entry = './lib/index.js', outputPath = './dist', bundleName, noJSExtension, noPlatformSuffix } = platformDefinition;
|
||||
let out = path.join(outputPath, bundleName);
|
||||
if (!noPlatformSuffix) {
|
||||
out = `${out}.${targetPlatform}`;
|
||||
}
|
||||
|
||||
// get the config file, checking if there is a platform specific override
|
||||
let configName = `metro.config.${targetPlatform}.js`;
|
||||
configName = fs.existsSync(path.join(process.cwd(), configName)) ? configName : 'metro.config.js';
|
||||
const configBase = await Metro.loadConfig({ config: configName });
|
||||
|
||||
// add platform specific details for bundling this config
|
||||
const config = addPlatformMetroConfig(targetPlatform, configBase) as any;
|
||||
if (server) {
|
||||
config.server = config.server || {};
|
||||
config.server.port = port;
|
||||
}
|
||||
|
||||
// ensure the parent directory exists for the target output
|
||||
const parentDirectory = path.dirname(path.resolve(process.cwd(), out));
|
||||
if (!fs.existsSync(parentDirectory)) {
|
||||
fs.mkdirSync(parentDirectory);
|
||||
}
|
||||
|
||||
if (server) {
|
||||
// for server start up the server, note that this is for only one platform, at least by configuration
|
||||
logger.info(`Starting metro server for ${targetPlatform} platform on port ${port}.`);
|
||||
|
||||
await Metro.runServer(config, { port: port });
|
||||
|
||||
// break out of the loop, doesn't make sense to run servers for multiple platforms
|
||||
break;
|
||||
} else {
|
||||
// log out what is about to happen
|
||||
logger.info(`Starting metro bundling for ${targetPlatform}.`);
|
||||
logger.info(`Entry file ${entry}.`);
|
||||
logger.info(`Output file ${out}.`);
|
||||
|
||||
// now run the bundle task itself
|
||||
await Metro.runBuild(config, {
|
||||
platform: targetPlatform,
|
||||
entry,
|
||||
minify: !dev,
|
||||
out,
|
||||
optimize: !dev,
|
||||
sourceMap: dev
|
||||
});
|
||||
|
||||
// optionally rename the output to remove the JS extension if requested
|
||||
if (noJSExtension && !out.endsWith('.js')) {
|
||||
const metroBundlePath = out + '.js';
|
||||
if (fs.existsSync(metroBundlePath)) {
|
||||
if (fs.existsSync(out)) {
|
||||
logger.verbose(`Deleting existing output file at ${out}...`);
|
||||
fs.unlinkSync(out);
|
||||
}
|
||||
|
||||
logger.verbose(`Renaming ${metroBundlePath} to ${out}...`);
|
||||
fs.renameSync(metroBundlePath, out);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`Finished bundling ${out} for ${targetPlatform}.`);
|
||||
}
|
||||
}
|
||||
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
};
|
||||
}
|
||||
// @ts-check
|
||||
import Metro from 'metro';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { logger, TaskFunction } from 'just-task';
|
||||
import { AllPlatforms } from './platforms';
|
||||
import { addPlatformMetroConfig } from './configureMetro';
|
||||
|
||||
export interface BundleDetails {
|
||||
/**
|
||||
* entry file such as './src/index.ts'
|
||||
*/
|
||||
entry?: string;
|
||||
outputPath?: string;
|
||||
bundleName?: string;
|
||||
noPlatformSuffix?: boolean;
|
||||
noJSExtension?: boolean;
|
||||
}
|
||||
|
||||
export type BundleDefinition = BundleDetails & {
|
||||
name?: string;
|
||||
targets?: AllPlatforms[];
|
||||
platforms?: {
|
||||
[K in AllPlatforms]: BundleDetails;
|
||||
};
|
||||
};
|
||||
|
||||
export type MetroBundles = BundleDefinition | BundleDefinition[];
|
||||
|
||||
function asArray<T>(opt: T | T[]): T[] {
|
||||
return Array.isArray(opt) ? opt : [opt || ({} as T)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a bundle definition from package.json. The bundle definition should be of type BundleDefinition and would
|
||||
* typically look something like:
|
||||
* "metroBundles": {
|
||||
* "targets": ["win32", "windows"],
|
||||
* "entryFile": "./src/index.ts",
|
||||
* "outputPath": "./dist",
|
||||
* "outputFile": "myBundleName"
|
||||
* }
|
||||
*
|
||||
* Platform specific overrides can be specified by using a platforms which works as a selector. In this case
|
||||
* add:
|
||||
* "metroBundles": {
|
||||
* ...stuff
|
||||
* "platforms": {
|
||||
* "ios": {
|
||||
* "outputFile": "myIOSName"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @param bundleName - optional name of the bundle, use if there are multiple bundles defined in package JSON
|
||||
*/
|
||||
function loadBundleDefinition(bundleName?: string): BundleDefinition {
|
||||
const packageConfigPath = path.resolve(process.cwd(), 'package.json');
|
||||
const packageConfig = JSON.parse(fs.readFileSync(packageConfigPath, 'utf8'));
|
||||
|
||||
const metroBundles = asArray<BundleDefinition>(packageConfig.metroBundles);
|
||||
if (bundleName) {
|
||||
return metroBundles.find(bundle => bundle.name === bundleName) || {};
|
||||
}
|
||||
|
||||
if (metroBundles.length > 1) {
|
||||
logger.error('Multiple bundles are specified in the package, so bundle is ambiguous');
|
||||
} else if (metroBundles.length === 0) {
|
||||
logger.error('The package must contain a bundle definition');
|
||||
}
|
||||
return metroBundles[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the platform selector for each bundle target
|
||||
* @param bundle - bundle definition, potentially including a platform selector
|
||||
* @param platform - current platform target
|
||||
*/
|
||||
function getOptionsForPlatform(bundle: BundleDefinition, platform: AllPlatforms): BundleDefinition {
|
||||
const platformValues = bundle.platforms && bundle.platforms[platform];
|
||||
return platformValues ? { ...bundle, ...platformValues } : bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* options for the metro task
|
||||
*/
|
||||
export interface MetroTaskOptions {
|
||||
/**
|
||||
* name of the bundle to target, can be blank if the package.json only includes one bundle
|
||||
*/
|
||||
bundleName?: string;
|
||||
|
||||
/**
|
||||
* platform to bundle for, if blank will bundle for all platforms in this folder
|
||||
*/
|
||||
platform?: AllPlatforms;
|
||||
|
||||
/**
|
||||
* whether to bundle in development mode
|
||||
*/
|
||||
dev?: boolean;
|
||||
|
||||
/**
|
||||
* run metro in server mode
|
||||
*/
|
||||
server?: boolean;
|
||||
|
||||
/**
|
||||
* port override for server mode
|
||||
*/
|
||||
port?: number;
|
||||
}
|
||||
|
||||
export function metroTask(options: MetroTaskOptions = {}): TaskFunction {
|
||||
const { bundleName, platform, dev = false, server } = options;
|
||||
const port = options.port || (platform === 'windows' ? 8081 : 8080);
|
||||
|
||||
return async function metroPack(done) {
|
||||
logger.verbose(`Starting metropack task with platform ${bundleName}...`);
|
||||
|
||||
// get the bundle definition
|
||||
const definition = loadBundleDefinition(bundleName);
|
||||
const targets = (platform && [platform]) || definition.targets || [];
|
||||
|
||||
for (const targetPlatform of targets) {
|
||||
// get the options specified for the platform
|
||||
const platformDefinition = getOptionsForPlatform(definition, targetPlatform);
|
||||
|
||||
// set up file input and output
|
||||
const { entry = './lib/index.js', outputPath = './dist', bundleName, noJSExtension, noPlatformSuffix } = platformDefinition;
|
||||
let out = path.join(outputPath, bundleName);
|
||||
if (!noPlatformSuffix) {
|
||||
out = `${out}.${targetPlatform}`;
|
||||
}
|
||||
|
||||
// get the config file, checking if there is a platform specific override
|
||||
let configName = `metro.config.${targetPlatform}.js`;
|
||||
configName = fs.existsSync(path.join(process.cwd(), configName)) ? configName : 'metro.config.js';
|
||||
const configBase = await Metro.loadConfig({ config: configName });
|
||||
|
||||
// add platform specific details for bundling this config
|
||||
const config = addPlatformMetroConfig(targetPlatform, configBase) as any;
|
||||
if (server) {
|
||||
config.server = config.server || {};
|
||||
config.server.port = port;
|
||||
}
|
||||
|
||||
// ensure the parent directory exists for the target output
|
||||
const parentDirectory = path.dirname(path.resolve(process.cwd(), out));
|
||||
if (!fs.existsSync(parentDirectory)) {
|
||||
fs.mkdirSync(parentDirectory);
|
||||
}
|
||||
|
||||
if (server) {
|
||||
// for server start up the server, note that this is for only one platform, at least by configuration
|
||||
logger.info(`Starting metro server for ${targetPlatform} platform on port ${port}.`);
|
||||
|
||||
await Metro.runServer(config, { port: port });
|
||||
|
||||
// break out of the loop, doesn't make sense to run servers for multiple platforms
|
||||
break;
|
||||
} else {
|
||||
// log out what is about to happen
|
||||
logger.info(`Starting metro bundling for ${targetPlatform}.`);
|
||||
logger.info(`Entry file ${entry}.`);
|
||||
logger.info(`Output file ${out}.`);
|
||||
|
||||
// now run the bundle task itself
|
||||
await Metro.runBuild(config, {
|
||||
platform: targetPlatform,
|
||||
entry,
|
||||
minify: !dev,
|
||||
out,
|
||||
optimize: !dev,
|
||||
sourceMap: dev
|
||||
});
|
||||
|
||||
// optionally rename the output to remove the JS extension if requested
|
||||
if (noJSExtension && !out.endsWith('.js')) {
|
||||
const metroBundlePath = out + '.js';
|
||||
if (fs.existsSync(metroBundlePath)) {
|
||||
if (fs.existsSync(out)) {
|
||||
logger.verbose(`Deleting existing output file at ${out}...`);
|
||||
fs.unlinkSync(out);
|
||||
}
|
||||
|
||||
logger.verbose(`Renaming ${metroBundlePath} to ${out}...`);
|
||||
fs.renameSync(metroBundlePath, out);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`Finished bundling ${out} for ${targetPlatform}.`);
|
||||
}
|
||||
}
|
||||
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
import { ITheme, IThemeColorDefinition } from '@uifabricshared/theming-ramp';
|
||||
import { IOperationSet } from '@uifabricshared/foundation-tokens';
|
||||
|
||||
export interface IForegroundColorTokens {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export const getPaletteFromTheme = (theme: ITheme): IThemeColorDefinition => {
|
||||
return theme.colors;
|
||||
};
|
||||
|
||||
export const foregroundColorTokens: IOperationSet<IForegroundColorTokens, ITheme> = [{ source: 'color', lookup: getPaletteFromTheme }];
|
||||
|
||||
export interface IBackgroundColorTokens {
|
||||
backgroundColor?: string;
|
||||
}
|
||||
|
||||
export const backgroundColorTokens: IOperationSet<IBackgroundColorTokens, ITheme> = [
|
||||
{ source: 'backgroundColor', lookup: getPaletteFromTheme }
|
||||
];
|
||||
|
||||
export type IColorTokens = IForegroundColorTokens & IBackgroundColorTokens;
|
||||
export const colorTokens = [...foregroundColorTokens, ...backgroundColorTokens];
|
||||
import { ITheme, IThemeColorDefinition } from '@uifabricshared/theming-ramp';
|
||||
import { IOperationSet } from '@uifabricshared/foundation-tokens';
|
||||
|
||||
export interface IForegroundColorTokens {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export const getPaletteFromTheme = (theme: ITheme): IThemeColorDefinition => {
|
||||
return theme.colors;
|
||||
};
|
||||
|
||||
export const foregroundColorTokens: IOperationSet<IForegroundColorTokens, ITheme> = [{ source: 'color', lookup: getPaletteFromTheme }];
|
||||
|
||||
export interface IBackgroundColorTokens {
|
||||
backgroundColor?: string;
|
||||
}
|
||||
|
||||
export const backgroundColorTokens: IOperationSet<IBackgroundColorTokens, ITheme> = [
|
||||
{ source: 'backgroundColor', lookup: getPaletteFromTheme }
|
||||
];
|
||||
|
||||
export type IColorTokens = IForegroundColorTokens & IBackgroundColorTokens;
|
||||
export const colorTokens = [...foregroundColorTokens, ...backgroundColorTokens];
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
import { TextStyle, TextProps } from 'react-native';
|
||||
import { ITheme, ITypography } from '@uifabricshared/theming-ramp';
|
||||
import { styleFunction } from '@uifabricshared/foundation-tokens';
|
||||
|
||||
export interface ITextVariantTokens {
|
||||
variant?: keyof ITypography['variants'];
|
||||
}
|
||||
|
||||
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, variant }: ITextTokens, { typography }: ITheme): TextProps {
|
||||
const { families, sizes, weights, variants } = typography;
|
||||
if (fontFamily || fontSize || fontWeight || variant) {
|
||||
return {
|
||||
style: {
|
||||
fontFamily: families[fontFamily] || fontFamily || families[variants[variant].face] || variants[variant].face,
|
||||
fontSize: sizes[fontSize] || fontSize || sizes[variants[variant].size] || variants[variant].size,
|
||||
fontWeight: weights[fontWeight] || fontWeight || weights[variants[variant].weight] || variants[variant].weight
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
const _keyProps: (keyof ITextTokens)[] = ['fontFamily', 'fontSize', 'fontWeight', 'variant'];
|
||||
|
||||
export const textTokens = styleFunction<TextProps, ITextTokens, ITheme>(_buildTextStyles, _keyProps);
|
||||
import { TextStyle, TextProps } from 'react-native';
|
||||
import { ITheme, ITypography } from '@uifabricshared/theming-ramp';
|
||||
import { styleFunction } from '@uifabricshared/foundation-tokens';
|
||||
|
||||
export interface ITextVariantTokens {
|
||||
variant?: keyof ITypography['variants'];
|
||||
}
|
||||
|
||||
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, variant }: ITextTokens, { typography }: ITheme): TextProps {
|
||||
const { families, sizes, weights, variants } = typography;
|
||||
if (fontFamily || fontSize || fontWeight || variant) {
|
||||
return {
|
||||
style: {
|
||||
fontFamily: families[fontFamily] || fontFamily || families[variants[variant].face] || variants[variant].face,
|
||||
fontSize: sizes[fontSize] || fontSize || sizes[variants[variant].size] || variants[variant].size,
|
||||
fontWeight: weights[fontWeight] || fontWeight || weights[variants[variant].weight] || variants[variant].weight
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
const _keyProps: (keyof ITextTokens)[] = ['fontFamily', 'fontSize', 'fontWeight', 'variant'];
|
||||
|
||||
export const textTokens = styleFunction<TextProps, ITextTokens, ITheme>(_buildTextStyles, _keyProps);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const { metroPackTask } = require('./tasks/metro-pack');
|
||||
|
||||
const bundleName = process.argv[2];
|
||||
metroPackTask(bundleName)().then(() => console.log('Successful..'));
|
||||
const { metroPackTask } = require('./tasks/metro-pack');
|
||||
|
||||
const bundleName = process.argv[2];
|
||||
metroPackTask(bundleName)().then(() => console.log('Successful..'));
|
||||
|
|
Загрузка…
Ссылка в новой задаче