如何使用基于 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 React -Basic Webpart 中的数据版本错误