Merge pull request #5283 from petkir/react-organization-chart

This commit is contained in:
Hugo Bernier 2024-10-12 11:57:49 -07:00 committed by GitHub
commit 48d50e3d79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 9658 additions and 9264 deletions

View File

@ -1,6 +1,6 @@
{
"name": "SPFx 1.18.2",
"image": "docker.io/m365pnp/spfx:1.18.2",
"name": "SPFx 1.20.2",
"image": "docker.io/m365pnp/spfx:1.20.2",
"customizations": {
"vscode": {
"extensions": [

View File

@ -20,39 +20,6 @@ module.exports = {
'@rushstack/security/no-unsafe-regexp': 1,
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
'@typescript-eslint/adjacent-overload-signatures': 1,
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
//
// CONFIGURATION: By default, these are banned: String, Boolean, Number, Object, Symbol
'@typescript-eslint/ban-types': [
1,
{
'extendDefaults': false,
'types': {
'String': {
'message': 'Use \'string\' instead',
'fixWith': 'string'
},
'Boolean': {
'message': 'Use \'boolean\' instead',
'fixWith': 'boolean'
},
'Number': {
'message': 'Use \'number\' instead',
'fixWith': 'number'
},
'Object': {
'message': 'Use \'object\' instead, or else define a proper TypeScript type:'
},
'Symbol': {
'message': 'Use \'symbol\' instead',
'fixWith': 'symbol'
},
'Function': {
'message': 'The \'Function\' type accepts any function-like value.\nIt provides no type safety when calling the function, which can be a common source of bugs.\nIt also accepts things like class declarations, which will throw at runtime as they will not be called with \'new\'.\nIf you are expecting the function to accept certain arguments, you should explicitly define the function shape.'
}
}
}
],
// RATIONALE: Code is more readable when the type of every variable is immediately obvious.
// Even if the compiler may be able to infer a type, this inference will be unavailable
// to a person who is reviewing a GitHub diff. This rule makes writing code harder,

View File

@ -1 +1 @@
v18.19.1
v18.20.3

View File

@ -2,12 +2,13 @@
"@microsoft/generator-sharepoint": {
"plusBeta": false,
"isCreatingSolution": true,
"nodeVersion": "18.19.1",
"nodeVersion": "18.20.3",
"sdksVersions": {
"@microsoft/microsoft-graph-client": "3.0.2",
"@microsoft/teams-js": "2.12.0"
"@microsoft/teams-js": "2.24.0"
},
"version": "1.18.2",
"isDomainIsolated": false,
"version": "1.20.0",
"libraryName": "react-organization-chart",
"libraryId": "0b4a3e5d-123f-41ea-96c4-538c6a19932b",
"environment": "onprem19",

View File

@ -19,8 +19,8 @@ This web part shows an organization chart based on specified user, and user can
This sample is optimally compatible with the following environment configuration:
![SPFx 1.18.2](https://img.shields.io/badge/SPFx-1.18.2-green.svg)
![Node.js v16 | v18](https://img.shields.io/badge/Node.js-v16%20%7C%20v18-green.svg)
![SPFx 1.20.0](https://img.shields.io/badge/SPFx-1.20.0-green.svg)
![Node.js v18](https://img.shields.io/badge/Node.js-v18-green.svg)
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
@ -34,13 +34,16 @@ This sample is optimally compatible with the following environment configuration
## Contributors
- [João Mendes](https://github.com/joaojmendes)
- [Passoli Mirko](https://github.com/Paxol)
- [Peter Paul Kirschner](https://github.com/petkir)
## Version history
|Version|Date|Comments|
|-------|----|--------|
|1.2|Oct, 2024|SPFx 1.20.0|
|1.1|Feb, 2024|Guest user filter + update to SPFx 1.18.2|
|1.0|May, 2021|Initial release|

View File

@ -2,15 +2,15 @@
{
"name": "pnp-sp-dev-spfx-web-parts-react-organization-chart",
"source": "pnp",
"title": "Organization Chart Web Part (SP2019 and Online)",
"title": "Organization Chart Web Part",
"shortDescription": "Shows an organization chart based on specified user, and user can navigate to show company organization",
"url": "https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-organization-chart",
"longDescription": [
"This web part shows an organization chart based on specified user, and user can navigate to show company organization.",
"Can be installed on SharePoint Server 2019, and SharePoint Online."
"Can be installed on SharePoint Online."
],
"creationDateTime": "2021-05-03",
"updateDateTime": "2024-02-25",
"updateDateTime": "2024-10-04",
"products": [
"SharePoint"
],
@ -21,7 +21,7 @@
},
{
"key": "SPFX-VERSION",
"value": "1.18.2"
"value": "1.20.0"
}
],
"thumbnails": [
@ -55,6 +55,13 @@
{
"gitHubAccount": "Paxol",
"pictureUrl": "https://github.com/Paxol.png"
},
{
"gitHubAccount": "petkir",
"company": "ACP CUBIDO Digital Solutions GmbH",
"pictureUrl": "https://github.com/petkir.png",
"name": "Peter Paul Kirschner",
"twitter": "petkir_at"
}
],
"references": [

View File

@ -1,4 +0,0 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
"deployCdnPath": "temp/deploy"
}

View File

@ -1,7 +1,8 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
"workingDir": "./temp/deploy/",
"account": "<!-- STORAGE ACCOUNT NAME -->",
"container": "react-organization-chart",
"accessKey": "<!-- ACCESS KEY -->"
"accessKey": "<!-- ACCESS KEY -->",
"workingDir": "./release/assets/"
}

View File

@ -3,9 +3,40 @@
"solution": {
"name": "react-organization-chart",
"id": "0b4a3e5d-123f-41ea-96c4-538c6a19932b",
"version": "1.1.0.0",
"version": "1.2.0.0",
"includeClientSideAssets": true,
"skipFeatureDeployment": true
"skipFeatureDeployment": true,
"isDomainIsolated": false,
"developer": {
"name": "",
"privacyUrl": "",
"termsOfUseUrl": "",
"websiteUrl": "",
"mpnId": "Undefined-1.20.0"
},
"metadata": {
"shortDescription": {
"default": "react-organization-chart description"
},
"longDescription": {
"default": "react-organization-chart description"
},
"screenshotPaths": [],
"videoUrl": "",
"categories": []
},
"features": [
{
"title": "react-organization-chart OrganizationChartWebPart Feature",
"description": "The feature that activates OrganizationChartWebPart from the react-organization-chart solution.",
"id": "0338da15-07f9-4a53-b267-d790fb495cca",
"version": "1.2.0.0",
"componentIds": [
"0338da15-07f9-4a53-b267-d790fb495cca"
]
}
]
},
"paths": {
"zippedPackage": "solution/react-organization-chart.sppkg"

View File

@ -1,6 +1,6 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/spfx-serve.schema.json",
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
"port": 4321,
"https": true,
"initialPage": "https://{tenantDomain}/_layouts/workbench.aspx"
"initialPage": "https://enter-your-SharePoint-site/_layouts/workbench.aspx"
}

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
{
"name": "react-organization-chart",
"version": "0.0.1",
"version": "1.2.0.0",
"private": true,
"engines": {
"node": ">=16.13.0 <17.0.0 || >=18.17.1 <19.0.0"
"node": ">=18.17.1 <19.0.0"
},
"main": "lib/index.js",
"scripts": {
@ -29,19 +29,26 @@
"tslib": "2.3.1"
},
"devDependencies": {
"@microsoft/eslint-config-spfx": "1.18.2",
"@microsoft/eslint-plugin-spfx": "1.18.2",
"@microsoft/eslint-config-spfx": "1.20.2",
"@microsoft/eslint-plugin-spfx": "1.20.2",
"@microsoft/rush-stack-compiler-4.5": "0.5.0",
"@microsoft/rush-stack-compiler-4.7": "0.1.0",
"@microsoft/sp-build-web": "1.18.2",
"@microsoft/sp-module-interfaces": "1.18.2",
"@rushstack/eslint-config": "2.5.1",
"@microsoft/sp-build-web": "1.20.2",
"@microsoft/sp-module-interfaces": "1.20.2",
"@microsoft/sp-tslint-rules": "1.14.0",
"@microsoft/sp-webpart-workbench": "1.12.1",
"@rushstack/eslint-config": "4.0.1",
"@types/chai": "3.4.34",
"@types/es6-promise": "0.0.33",
"@types/mocha": "2.2.38",
"@types/react": "17.0.45",
"@types/react-dom": "17.0.17",
"@types/webpack-env": "~1.15.2",
"ajv": "^6.12.5",
"eslint": "8.7.0",
"@types/webpack-env": "1.15.2",
"ajv": "6.12.5",
"eslint": "8.57.0",
"eslint-plugin-react-hooks": "4.3.0",
"gulp": "4.0.2",
"tslint-microsoft-contrib": "5.0.0",
"typescript": "4.7.4"
}
}

View File

@ -48,6 +48,7 @@ export const getMd5HashForUrl = async (url: string): Promise<Maybe<string>> => {
return convertedHash;
}
} catch (error) {
console.error(error);
return url;
}
};
@ -73,14 +74,15 @@ export const getImageBase64 = async (pictureUrl: string): Promise<string> => {
const image = new Image();
image.addEventListener("load", () => {
const tempCanvas = document.createElement("canvas");
// eslint-disable-next-line no-unused-expressions, no-sequences
// eslint-disable-next-line no-unused-expressions, no-sequences, @typescript-eslint/no-unused-expressions
(tempCanvas.width = image.width),
(tempCanvas.height = image.height),
tempCanvas.getContext("2d")?.drawImage(image, 0, 0);
let base64Str;
try {
base64Str = tempCanvas.toDataURL("image/png");
} catch (e) {
} catch (error) {
console.error(error);
return "";
}
base64Str = base64Str.replace(/^data:image\/png;base64,/, "");

View File

@ -1,4 +1,4 @@
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
@import '~@fluentui/react/dist/sass/References.scss';
.OrgChart {
.container {

View File

@ -19,12 +19,14 @@ import {
Text,
} from "@fluentui/react";
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
import { getGUID } from "@pnp/common";
import { useOrgChartStyles } from "./useOrgChartStyles";
import "./OrgChart.module.scss";
import { Placeholder } from "../Placeholder/PlaceholderComponent";
const initialState: IOrgChartState = {
isLoading: true,
@ -236,15 +238,17 @@ export const OrgChart: React.FunctionComponent<IOrgChartProps> = (
if (!startFromUser) {
return (
<Placeholder
iconName="Edit"
iconText="Configure your Organization Chart Web Part"
description={"Please configure web part"}
buttonLabel="Configure"
onConfigure={context.propertyPane.open}
/>
iconName="Edit"
iconText="Configure your Organization Chart Web Part"
description={"Please configure web part"}
buttonLabel="Configure"
onConfigure={context.propertyPane.open}
/>
);
}
if (isLoading) {
return (
<Overlay style={{ height: "100%", position: "fixed" }}>

View File

@ -0,0 +1,67 @@
import { mergeStyleSets } from '@fluentui/merge-styles';
import { FontSizes, IPartialTheme, ITheme } from '@fluentui/react/lib/Styling';
export interface IPlaceholderComponentClassNames {
placeholder: string;
placeholderContainer: string;
placeholderHead: string;
placeholderHeadContainer: string;
placeholderIcon: string;
placeholderText: string;
hide: string;
placeholderDescription: string;
placeholderDescriptionText: string;
}
export const getClassNames = (theme: IPartialTheme | ITheme): IPlaceholderComponentClassNames => {
return mergeStyleSets({
placeholder: {
display: "flex"
},
placeholderContainer: {
alignItems: "center",
color: theme.palette.neutralSecondary,
backgroundColor: theme.palette.neutralLighter,
width: "100%",
padding: "80px 0"
},
placeholderHead: {
color: theme.palette.neutralPrimary
},
placeholderHeadContainer: {
height: "100%",
whiteSpace: "nowrap",
textAlign: "center"
},
placeholderIcon: {
display: "inline-block",
verticalAlign: "middle",
whiteSpace: "normal",
fontSize: FontSizes.size42
},
placeholderText: {
display: "inline",
verticalAlign: "middle",
whiteSpace: "normal",
fontWeight: 100,
fontSize: FontSizes.size28,
paddingLeft: "20px"
},
hide: {
display: "none"
},
placeholderDescription: {
width: "65%",
verticalAlign: "middle",
margin: "0 auto",
textAlign: "center"
},
placeholderDescriptionText: {
color: theme.palette.neutralSecondary,
fontSize: "17px",
display: "inline-block",
margin: "24px 0",
fontWeight: "100"
}
});
};

View File

@ -0,0 +1,199 @@
import { IPartialTheme, ITheme } from '@fluentui/react/lib/Styling';
/**
* Used to display a placeholder in case of no or temporary content. Button is optional.
*
*/
export interface IPlaceholderProps {
/**
* Text description or component for the placeholder. Appears bellow the Icon and IconText.
*/
description: string | ((defaultClassNames: string) => React.ReactElement);
/**
* Icon name used for the className from the MDL2 set. Example: 'Add'.
*/
iconName: string;
/**
* Heading displayed against the Icon.
*/
iconText: string | ((defaultClassNames: string) => React.ReactElement);
/**
* Text label to be displayed on button below the description.
* Optional: As the button is optional.
*/
buttonLabel?: string;
/**
* This className is applied to the root element of content. Use this to
* apply custom styles to the placeholder.
*/
contentClassName?: string;
/**
* Specify if you want to hide the config button
*/
hideButton?: boolean;
/**
* onConfigure handler for the button.
* Optional: As the button is optional.
*/
onConfigure?: () => void;
/**
* Set Fluent UI Theme.
* If not set or set to null or not defined, the theme passed through context will be used, or the default theme of the page will be loaded.
*/
theme?: IPartialTheme | ITheme;
}
export interface IPlaceholderState {
width: number;
}
import { ThemeContext } from '@fluentui/react-theme-provider/lib/ThemeContext';
import { Theme } from '@fluentui/react-theme-provider/lib/types';
import { PrimaryButton } from '@fluentui/react/lib/Button';
import { Icon } from '@fluentui/react/lib/Icon';
import * as React from 'react';
import { getFluentUIThemeOrDefault } from './ThemeUtility';
import { getClassNames } from './PlaceholderComponent.styles';
/**
* Placeholder component
*/
export class Placeholder extends React.Component<IPlaceholderProps, IPlaceholderState> {
private _crntElm: HTMLDivElement = null;
/**
* Constructor
*/
constructor(props: IPlaceholderProps) {
super(props);
this.state = {
width: null
};
}
/**
* componentDidMount lifecycle hook
*/
public componentDidMount(): void {
this._setZoneWidth();
}
/**
* componentDidUpdate lifecycle hook
* @param prevProps
* @param prevState
*/
public componentDidUpdate(prevProps: IPlaceholderProps, prevState: IPlaceholderState): void {
this._setZoneWidth();
}
/**
* shouldComponentUpdate lifecycle hook
* @param nextProps
* @param nextState
*/
public shouldComponentUpdate(nextProps: IPlaceholderProps, nextState: IPlaceholderState): boolean {
/*
* compare the props object for changes in primative values
* Return/re-render, bexeting the function, if the props change
*/
for (const property in nextProps) {
if (property !== '_onConfigure') {
if (nextProps[property as keyof IPlaceholderProps] !== this.props[property as keyof IPlaceholderProps]) {
return true;
}
}
}
return this.state.width !== nextState.width || this.props.hideButton !== nextProps.hideButton;
}
/**
* Execute the onConfigure function
*/
private _handleBtnClick = (event?: React.MouseEvent<HTMLButtonElement>): void => {
this.props.onConfigure();
}
/**
* Set the current zone width
*/
private _setZoneWidth = (): void => {
this.setState({
width: this._crntElm.clientWidth
});
}
/**
* Stores the current element
*/
private _linkElm = (e: HTMLDivElement): void => {
this._crntElm = e;
}
/**
* Default React component render method
*/
public render(): React.ReactElement<IPlaceholderProps> {
const {
iconName,
iconText,
description,
children,
buttonLabel,
hideButton,
theme
} = this.props;
return (
<ThemeContext.Consumer>
{(contextTheme: Theme | undefined) => {
const themeToApply = getFluentUIThemeOrDefault((theme) ? theme : contextTheme);
const styles = getClassNames(themeToApply);
const iconTextClassNames = `${styles.placeholderText} ${(this.state.width && this.state.width <= 380) ? styles.hide : ""}`;
const iconTextEl = typeof iconText === 'string' ? <span className={iconTextClassNames}>{this.props.iconText}</span> : iconText(iconTextClassNames);
const descriptionEl = typeof description === 'string' ? <span className={styles.placeholderDescriptionText}>{this.props.description}</span> : description(styles.placeholderDescriptionText);
return (
<div className={`${styles.placeholder} ${this.props.contentClassName ? this.props.contentClassName : ''}`} ref={this._linkElm}>
<div className={styles.placeholderContainer}>
<div className={styles.placeholderHead}>
<div className={styles.placeholderHeadContainer}>
{
iconName && <Icon iconName={iconName} className={styles.placeholderIcon} />
}
{iconTextEl}
</div>
</div>
<div className={styles.placeholderDescription}>
{descriptionEl}
</div>
{children}
<div className={styles.placeholderDescription}>
{
(buttonLabel && !hideButton) &&
<PrimaryButton
text={buttonLabel}
ariaLabel={buttonLabel}
ariaDescription={typeof description === 'string' ? description : ''}
onClick={this._handleBtnClick}
theme={themeToApply} />
}
</div>
</div>
</div>);
}}
</ThemeContext.Consumer>
);
}
}

View File

@ -0,0 +1,448 @@
import {
mergeThemes,
ThemeInput,
teamsTheme,
teamsDarkTheme,
teamsHighContrastTheme
} from "@fluentui/react-northstar";
import { createTheme, getTheme, IPalette, IPartialTheme, ITheme } from "@fluentui/react/lib/Styling";
import { ComponentVariablesObject } from "@fluentui/styles";
import { getVariant, VariantThemeType } from "@fluentui/scheme-utilities";
const colorPaletteV2 = {
black: "#000",
white: "#fff",
grey: {
25: "#fafafa",
50: "#f5f5f5",
100: "#f0f0f0",
150: "#ebebeb",
200: "#e0e0e0",
220: "#d6d6d6",
230: "#d1d1d1",
250: "#c7c7c7",
270: "#bdbdbd",
300: "#b3b3b3",
310: "#adadad",
350: "#949494",
400: "#8a8a8a",
430: "#707070",
440: "#666",
450: "#616161",
460: "#5c5c5c",
500: "#424242",
550: "#3d3d3d",
600: "#333",
650: "#2e2e2e",
700: "#292929",
750: "#242424",
800: "#1f1f1f",
850: "#1a1a1a",
870: "#141414",
900: "#0f0f0f",
910: "#0a0a0a",
},
brand: {
50: "#e9eaf6",
100: "#dbdcf0",
200: "#c7c9ff",
300: "#b2b5ff",
400: "#a6a7dc",
450: "#9ea2ff",
500: "#7479dc",
600: "#6264a7",
700: "#494b83",
800: "#464775",
900: "#3d3e66",
1000: "#323348",
},
};
const teamsNextThemeSiteVariables = {
teamsTheme: {
theme: "teamsTheme",
colors: colorPaletteV2,
colorScheme: {
elevations: {
4: "0px 0.3px 0.9px rgba(0, 0, 0, 0.07), 0px 1.6px 3.6px rgba(0, 0, 0, 0.11)",
8: "0px 3.2px 7.2px rgba(0, 0, 0, 0.13), 0px 0.6px 1.8px rgba(0, 0, 0, 0.11)",
16: "0px 6.4px 14.4px rgba(0, 0, 0, 0.07), 0px 1.2px 3.6px rgba(0, 0, 0, 0.03)",
},
default: {
foreground: colorPaletteV2.grey["750"],
foreground1: colorPaletteV2.grey["500"],
foreground2: colorPaletteV2.grey["450"],
foreground3: colorPaletteV2.white,
foreground4: colorPaletteV2.white,
background: colorPaletteV2.white,
background1: colorPaletteV2.grey["25"],
background2: colorPaletteV2.grey["50"],
background3: colorPaletteV2.grey["100"],
background4: colorPaletteV2.grey["150"],
background5: colorPaletteV2.grey["200"],
border: colorPaletteV2.grey["230"],
border1: colorPaletteV2.grey["100"],
border2: colorPaletteV2.grey["200"],
border3: colorPaletteV2.grey["100"],
foregroundHover: colorPaletteV2.grey["750"],
foregroundHover1: colorPaletteV2.white,
foregroundHover2: colorPaletteV2.white,
backgroundHover: colorPaletteV2.grey["50"],
backgroundHover1: colorPaletteV2.grey["25"],
backgroundHover2: "transparent",
backgroundHover3: colorPaletteV2.grey["150"],
backgroundHover4: colorPaletteV2.grey["25"],
borderHover: colorPaletteV2.grey["250"],
foregroundPressed: colorPaletteV2.grey["750"],
backgroundPressed: colorPaletteV2.grey["200"],
foregroundActive: colorPaletteV2.grey["750"],
foregroundActive1: colorPaletteV2.white,
backgroundActive: colorPaletteV2.grey["150"],
backgroundActive1: colorPaletteV2.white,
borderActive: colorPaletteV2.grey["270"],
// foregroundFocus: not specified,
// backgroundFocus: not specified,
borderFocus: colorPaletteV2.black,
borderFocusWithin: colorPaletteV2.white,
foregroundDisabled: colorPaletteV2.grey["250"],
foregroundDisabled1: colorPaletteV2.grey["250"],
borderDisabled: colorPaletteV2.grey["200"],
backgroundDisabled: colorPaletteV2.grey["100"],
backgroundDisabled1: colorPaletteV2.grey["100"],
},
brand: {
background: colorPaletteV2.brand["600"],
background1: colorPaletteV2.brand["50"],
background2: colorPaletteV2.brand["900"],
background3: colorPaletteV2.brand["1000"],
background4: colorPaletteV2.brand["800"],
foreground: colorPaletteV2.brand["600"],
foreground1: colorPaletteV2.brand["600"],
foreground2: colorPaletteV2.brand["700"],
foreground3: colorPaletteV2.brand["200"],
foreground4: colorPaletteV2.white,
border: colorPaletteV2.grey["200"],
border1: colorPaletteV2.brand["300"],
border2: colorPaletteV2.brand["200"],
foregroundHover: colorPaletteV2.brand["600"],
foregroundHover1: colorPaletteV2.white,
foregroundHover2: colorPaletteV2.brand["200"],
borderHover: colorPaletteV2.brand["300"],
backgroundHover: colorPaletteV2.brand["700"],
backgroundHover1: colorPaletteV2.brand["50"],
foregroundPressed: colorPaletteV2.brand["700"],
foregroundPressed1: colorPaletteV2.white,
backgroundPressed: colorPaletteV2.brand["800"],
borderPressed: colorPaletteV2.brand["300"],
foregroundActive: colorPaletteV2.brand["600"],
foregroundActive1: colorPaletteV2.brand["600"],
foregroundActive2: colorPaletteV2.brand["50"],
backgroundActive: colorPaletteV2.brand["600"],
backgroundActive1: colorPaletteV2.brand["600"],
borderActive: colorPaletteV2.grey["200"],
borderActive1: colorPaletteV2.brand["50"],
borderActive2: colorPaletteV2.brand["300"],
foregroundFocus: colorPaletteV2.brand["600"],
foregroundFocus1: colorPaletteV2.brand["600"],
foregroundFocus2: colorPaletteV2.brand["700"],
foregroundFocus3: colorPaletteV2.brand["50"],
foregroundFocus4: colorPaletteV2.white,
backgroundFocus: colorPaletteV2.brand["600"],
backgroundFocus1: colorPaletteV2.brand["50"],
backgroundFocus2: colorPaletteV2.brand["900"],
backgroundFocus3: colorPaletteV2.brand["1000"],
borderFocus: colorPaletteV2.black,
borderFocus1: colorPaletteV2.brand["600"],
borderFocusWithin: colorPaletteV2.white,
foregroundDisabled: colorPaletteV2.grey["250"],
foregroundDisabled1: colorPaletteV2.grey["250"],
borderDisabled: colorPaletteV2.grey["550"],
backgroundDisabled: colorPaletteV2.grey["100"],
backgroundDisabled1: colorPaletteV2.grey["100"],
},
},
},
teamsDarkTheme: {
theme: "teamsDarkTheme",
colors: colorPaletteV2,
colorScheme: {
elevations: {
8: "0px 3.2px 7.2px rgba(0, 0, 0, 0.13), 0px 0.6px 1.8px rgba(0, 0, 0, 0.11)",
16: "0px 6.4px 14.4px rgba(0, 0, 0, 0.32), 0px 1.2px 3.6px rgba(0, 0, 0, 0.28)",
},
default: {
foreground: colorPaletteV2.white,
foreground1: colorPaletteV2.grey["220"],
foreground2: colorPaletteV2.grey["310"],
foreground3: colorPaletteV2.white,
foreground4: colorPaletteV2.white,
background: colorPaletteV2.grey["700"],
background1: colorPaletteV2.grey["750"],
background2: colorPaletteV2.grey["800"],
background3: colorPaletteV2.grey["870"],
background4: colorPaletteV2.grey["550"],
background5: colorPaletteV2.grey["600"],
border: colorPaletteV2.grey["450"],
border1: colorPaletteV2.grey["850"],
border2: colorPaletteV2.grey["900"],
border3: colorPaletteV2.grey["550"],
foregroundHover: colorPaletteV2.white,
foregroundHover1: colorPaletteV2.white,
foregroundHover2: colorPaletteV2.white,
backgroundHover: colorPaletteV2.grey["550"],
backgroundHover1: colorPaletteV2.grey["750"],
backgroundHover2: "transparent",
backgroundHover3: colorPaletteV2.grey["650"],
backgroundHover4: colorPaletteV2.grey["750"],
borderHover: colorPaletteV2.grey["430"],
foregroundPressed: colorPaletteV2.white,
backgroundPressed: colorPaletteV2.grey["650"],
foregroundActive: colorPaletteV2.white,
foregroundActive1: colorPaletteV2.white,
backgroundActive: colorPaletteV2.grey["600"],
backgroundActive1: colorPaletteV2.grey["800"],
borderActive: colorPaletteV2.grey["440"],
// foregroundFocus: not specified,
// backgroundFocus: not specified,
borderFocus: colorPaletteV2.white,
borderFocusWithin: colorPaletteV2.black,
foregroundDisabled: colorPaletteV2.grey["460"],
foregroundDisabled1: colorPaletteV2.grey["460"],
borderDisabled: colorPaletteV2.grey["500"],
backgroundDisabled: colorPaletteV2.grey["800"],
backgroundDisabled1: colorPaletteV2.grey["800"],
},
brand: {
background: colorPaletteV2.brand["600"],
background1: colorPaletteV2.brand["1000"],
background2: colorPaletteV2.brand["900"],
background3: colorPaletteV2.brand["1000"],
background4: colorPaletteV2.grey["910"],
foreground: colorPaletteV2.brand["450"],
foreground1: colorPaletteV2.brand["450"],
foreground2: colorPaletteV2.brand["450"],
foreground3: colorPaletteV2.brand["200"],
foreground4: colorPaletteV2.white,
border: colorPaletteV2.grey["450"],
border1: colorPaletteV2.brand["800"],
border2: colorPaletteV2.brand["800"],
foregroundHover: colorPaletteV2.brand["450"],
foregroundHover1: colorPaletteV2.white,
foregroundHover2: colorPaletteV2.brand["200"],
borderHover: colorPaletteV2.brand["600"],
backgroundHover: colorPaletteV2.brand["700"],
backgroundHover1: colorPaletteV2.brand["900"],
foregroundPressed: colorPaletteV2.brand["200"],
foregroundPressed1: colorPaletteV2.white,
backgroundPressed: colorPaletteV2.brand["800"],
borderPressed: colorPaletteV2.brand["800"],
foregroundActive: colorPaletteV2.brand["450"],
foregroundActive1: colorPaletteV2.brand["450"],
foregroundActive2: colorPaletteV2.brand["50"],
backgroundActive: colorPaletteV2.brand["450"],
backgroundActive1: colorPaletteV2.brand["450"],
borderActive: colorPaletteV2.grey["450"],
borderActive1: colorPaletteV2.brand["800"],
borderActive2: colorPaletteV2.brand["800"],
foregroundFocus: colorPaletteV2.brand["450"],
foregroundFocus1: colorPaletteV2.brand["450"],
foregroundFocus2: colorPaletteV2.brand["450"],
foregroundFocus3: colorPaletteV2.brand["50"],
foregroundFocus4: colorPaletteV2.white,
backgroundFocus: colorPaletteV2.brand["450"],
backgroundFocus1: colorPaletteV2.brand["1000"],
backgroundFocus2: colorPaletteV2.brand["900"],
backgroundFocus3: colorPaletteV2.brand["1000"],
borderFocus: colorPaletteV2.white,
borderFocus1: colorPaletteV2.brand["450"],
borderFocusWithin: colorPaletteV2.black,
foregroundDisabled: colorPaletteV2.grey["460"],
foregroundDisabled1: colorPaletteV2.grey["460"],
borderDisabled: colorPaletteV2.grey["500"],
backgroundDisabled: colorPaletteV2.grey["800"],
backgroundDisabled1: colorPaletteV2.grey["800"],
},
},
},
teamsHighContrastTheme: {
theme: "teamsHighContrastTheme",
colorScheme: {
elevations: {
8: "none",
16: "none",
},
},
},
};
export const themes: { [themeKey: string]: ThemeInput<any> } = { // eslint-disable-line @typescript-eslint/no-explicit-any
teamsTheme: mergeThemes(teamsTheme, {
siteVariables: teamsNextThemeSiteVariables.teamsTheme,
}),
teamsDarkTheme: mergeThemes(teamsDarkTheme, {
siteVariables: teamsNextThemeSiteVariables.teamsDarkTheme,
}),
teamsHighContrastTheme: mergeThemes(teamsHighContrastTheme, {
siteVariables: teamsNextThemeSiteVariables.teamsHighContrastTheme,
}),
};
export const teamsNextVariableAssignments = {
componentStyles: {
Box: {
root: ({ variables }: ComponentVariablesObject) => ({
backgroundColor: variables.backgroundColor,
boxShadow: variables.elevation,
}),
},
Button: {
root: ({ variables }: ComponentVariablesObject) => ({
color: variables.color,
}),
},
ButtonContent: {
root: ({ variables }: ComponentVariablesObject) => ({
fontWeight: variables.fontWeight,
}),
},
Card: {
root: ({ variables }: ComponentVariablesObject) => ({
boxShadow: variables.elevation,
"&:hover": { boxShadow: variables.hoverElevation },
"&:focus": { boxShadow: variables.elevation },
}),
},
Flex: {
root: ({ variables }: ComponentVariablesObject) => ({
color: variables.color,
backgroundColor: variables.backgroundColor,
boxShadow: variables.elevation,
}),
},
ToolbarItem: {
root: ({ variables }: ComponentVariablesObject) => ({
color: variables.color,
fontWeight: variables.fontWeight,
}),
},
PopupContent: {
content: ({ variables }: ComponentVariablesObject) => ({
boxShadow: variables.elevation,
borderWidth: variables.borderWidth,
}),
},
PopupButton: {
root: ({ variables }: ComponentVariablesObject) => ({
color: variables.color,
}),
},
TableRow: {
root: ({ variables }: ComponentVariablesObject) => ({
height: variables.compactRow
? variables.compactRowHeight
: variables.defaultRowHeight,
minHeight: variables.compactRow
? variables.compactRowMinHeight
: variables.defaultRowMinHeight,
alignItems: variables.cellVerticalAlignment,
}),
},
TableCell: {
root: ({ variables }: ComponentVariablesObject) => ({
paddingTop: variables.compactRow
? variables.compactRowVerticalPadding
: variables.defaultRowVerticalPadding,
paddingBottom: variables.compactRow
? variables.compactRowVerticalPadding
: variables.defaultRowVerticalPadding,
}),
},
TreeItem: {
root: ({ variables }: ComponentVariablesObject) => ({
color: variables.color,
}),
},
},
};
export const getFluentUIThemeOrDefault = (theme?: IPartialTheme | ITheme): ITheme => {
let currentTheme;
if (theme) {
currentTheme = getVariant(theme, VariantThemeType.None);
} else {
const themeColorsFromWindow: Partial<IPalette> = window.__themeState__?.theme;
if (themeColorsFromWindow) {
currentTheme = createTheme({
palette: themeColorsFromWindow
});
}
else {
currentTheme = getTheme();
}
}
return currentTheme;
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 B

View File

@ -1,5 +1,5 @@
{
"extends": "./node_modules/@microsoft/rush-stack-compiler-4.7/includes/tsconfig-web.json",
"extends": "./node_modules/@microsoft/rush-stack-compiler-4.5/includes/tsconfig-web.json",
"compilerOptions": {
"target": "es5",
"forceConsistentCasingInFileNames": true,
@ -13,6 +13,8 @@
"outDir": "lib",
"inlineSources": false,
"noImplicitAny": true,
"strictNullChecks": false,
"noUnusedLocals": false,
"typeRoots": [
"./node_modules/@types",
@ -31,5 +33,9 @@
"include": [
"src/**/*.ts",
"src/**/*.tsx"
],
"exclude": [
"node_modules",
"lib"
]
}