如何使用基于 ts 的新样式方法在 spfx webpart 中获取当前主题

Posted

技术标签:

【中文标题】如何使用基于 ts 的新样式方法在 spfx webpart 中获取当前主题【英文标题】:How to get the current theme in a spfx webpart using the new ts based styling approach 【发布时间】:2019-07-13 01:44:18 【问题描述】:

我们正在使用 Office UI Fabric React 为 O365 通信站点开发现代 Web 部件。我想使用新的基于 ts 的方法来设置我的 components(see here) 的样式。一切都很好,除了它没有使用它部署到的 SharePoint 网站的当前主题。

我的 webpart 是使用 SharePoint webparts 的标准 Yeoman 脚手架创建的(选择 React 作为框架)。

我的样式代码如下所示:

import  getTheme, FontWeights, mergeStyleSets  from 'office-ui-fabric-react/lib/Styling';

export interface IComponentClassNames 
    locationBanner: string;
    locationLabel: string;
    locationValue: string;
    editLocationButton: string;
    findLocationButton: string;


const theme = getTheme();

export const getClassNames = (): IComponentClassNames => 
    return mergeStyleSets(
        locationBanner: 
            display: 'inline-flex',
            paddingLeft: '8px',
        ,
        locationLabel: [
            theme.fonts.large,
            
                color: theme.palette.neutralPrimary
            
        ],
        locationValue: 
            color: theme.palette.themeDark
        ,
        editLocationButton: 
            paddingLeft: '20px'
        ,
        findLocationButton: 
            paddingLeft: '10px'
        
    );
;

然后在我的组件的渲染部分我执行以下操作:

const locationBanner, editLocationButton, findLocationButton, locationLabel, locationValue = getClassNames();

然后在 className-attributes 中应用它。这可以正常工作并应用样式 - 但是:getTheme() 返回默认主题(即主要为蓝色),而不是 SharePoint 网站上当前设置的主题。我是否必须以某种方式将主题传递给我的组件(来自 webpart ts)或者这应该如何工作?

【问题讨论】:

【参考方案1】:

我的解决方案是从窗口对象中提取主题,构建一个主题对象,然后根据需要将其传递给组件

像这样:

在根 ts 文件中构建主题

const ThemeColorsFromWindow: any = (window as any).__themeState__.theme;
const siteTheme: ITheme = createTheme( //pass this object to your components
  palette: ThemeColorsFromWindow
);

然后我将主题传递给需要的组件。

<MyButton
    ButtonText=this.props.itemButtonText
    ButtonType='dark'
    ButtonURL=this.props.itemButtonURL
    siteTheme=siteTheme //site theme is passed to component
/>

构建我的 CSS-in-JS 对象

  const siteTheme: IReadonlyTheme = this.props.siteTheme; //shortening the path a little

  ButtonStyles: IButtonStyles =  //the interface here varies by component
    root:
      backgroundColor: siteTheme.palette.themeTertiary, //get theme colors like this
    ,
    label:
      color: siteTheme.palette.white,
    ,
    rootHovered:
      backgroundColor: siteTheme.palette.themePrimary,
    ,
    labelHovered:
      color: siteTheme.palette.white
    
  ;

然后我设置组件的样式属性

<PrimaryButton
    styles=ButtonStyles //pass the styles to the component here
    onClick=() => GoToPage(this.props.ButtonURL)
    text=this.props.ButtonText ? this.props.ButtonText : 'BUTTON TEXT'
/>

如果您想适应变体或部分背景,请查看此博文。 https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/guidance/supporting-section-backgrounds

使用 ThemeProvider 服务。

【讨论】:

【参考方案2】:

在我看来,您使用的是 office-ui-fabric-react 库。您导入的 getTheme 方法来自那里。我看不到 office-ui-fabric-react 如何查询 SharePoint 以获取当前主题。它可能正在跟踪自己。我会尝试通过 SharePoint 组件库获取主题。 https://docs.microsoft.com/en-us/javascript/api/sp-component-base/themeprovider

【讨论】:

是的,我们也对此进行了研究,但无法使其正常工作。奇怪的是,考虑到现在有些人应该已经将它用于他们的现代 Web 部件(通常应该是线程感知的),所以绝对没有示例代码存在 看起来“提供者”方法不适用于全屏 WebPart。

以上是关于如何使用基于 ts 的新样式方法在 spfx webpart 中获取当前主题的主要内容,如果未能解决你的问题,请参考以下文章

SPFx Webpart - node_modules/@types/ [prop types] 和 [react] index.d.ts:在 gulp 构建时加载“错误 TS1005”

如何更改SPFx中的页面导航链接?

如何在 SPFx 中使用本地化资源?

SPFX React -Basic Webpart 中的数据版本错误

在现代站点中添加 SPFx webpart 时的 Javascript

如何使用样式组件扩展(MUI)React 组件的 TS 接口?