Forum Discussion
john john
Nov 15, 2021Steel Contributor
Modify my SPFx web part to read css file instead of writing the css code inside the web part
I have built a web part which is similar to this web part from github @ https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-enhanced-list-formatting . The web part allow to embed custom css code inside modern pages. But is it possible to modify the web part, to referecne a css file instead of having to write the actual css code inside the web part? So instead of writing the css code as follow:-
to reference the css file as follow:-
Here is the EnhancedListFormattingWebPart.ts:-
import * as React from 'react'; import * as ReactDom from 'react-dom'; import { Version } from '@microsoft/sp-core-library'; import { IPropertyPaneConfiguration, } from '@microsoft/sp-property-pane'; import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base'; import * as strings from 'EnhancedListFormattingWebPartStrings'; import EnhancedListFormatting from './components/EnhancedListFormatting'; import { IEnhancedListFormattingProps } from './components/IEnhancedListFormattingProps'; import { PropertyPaneWebPartInformation } from '@pnp/spfx-property-controls/lib/PropertyPaneWebPartInformation'; import { PropertyFieldMonacoEditor } from '../../controls/PropertyFieldMonacoEditor'; export interface IEnhancedListFormattingWebPartProps { css: string; acceptedDisclaimer?: boolean; } export default class EnhancedListFormattingWebPart extends BaseClientSideWebPart <IEnhancedListFormattingWebPartProps> { public render(): void { const element: React.ReactElement<IEnhancedListFormattingProps> = React.createElement( EnhancedListFormatting, { css: this.properties.css, acceptedDisclaimer: this.properties.acceptedDisclaimer, displayMode: this.displayMode, context: this.context, onAcceptDisclaimer: ()=>this._handleAcceptDisclaimer() } ); ReactDom.render(element, this.domElement); } protected onDispose(): void { ReactDom.unmountComponentAtNode(this.domElement); } // protected get dataVersion(): Version { // return Version.parse('1.0'); // } protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { return { pages: [ { header: { description: strings.PropertyPaneDescription }, groups: [ { groupName: strings.BasicGroupName, groupFields: [ PropertyFieldMonacoEditor('css', { label: strings.CSSFieldLabel, key: "cssText", value: this.properties.css, defaultValue: this.properties.css, language: "css", theme: "vs-light", showLineNumbers: false, onPropertyChange: (_propertyPath: string, _oldValue: string, value: string) => this._handleSave(value), }), PropertyPaneWebPartInformation({ description: strings.CSSDisclaimer, key: 'cssDisclaimer' }) ] } ] } ] }; } private _handleAcceptDisclaimer = () => { this.properties.acceptedDisclaimer = true; this.render(); } private _handleSave = (value: string) => { this.properties.css = value; } }
here is the EnhancedListFormatting.tsx:-
import * as React from 'react'; import styles from './EnhancedListFormatting.module.scss'; import * as strings from 'EnhancedListFormattingWebPartStrings'; import { IEnhancedListFormattingProps } from './IEnhancedListFormattingProps'; import { MessageBarButton, MessageBar, MessageBarType } from 'office-ui-fabric-react'; import { DisplayMode } from '@microsoft/sp-core-library'; export default class EnhancedListFormatting extends React.Component<IEnhancedListFormattingProps, {}> { public render(): React.ReactElement<IEnhancedListFormattingProps> { const { css, displayMode, acceptedDisclaimer } = this.props; // If we accepted the disclaimer, let's work as expected // Determine if there is a CSS value const hasCSS: boolean = css !== undefined && css !== ""; // Create a style element const styleElem: JSX.Element = <style type="text/css">{css}</style>; // If we're not in Edit mode, hide this web part if (displayMode !== DisplayMode.Edit) { return styleElem; } // if we didn't accept the disclaimer, show a disclaimer and nothing else if (acceptedDisclaimer !== true) { return (<MessageBar onDismiss={()=>this._onAcceptDisclaimer()} dismissButtonAriaLabel={strings.DismissDisclaimerAriaLabel} messageBarType={MessageBarType.warning} actions={ <div> <MessageBarButton onClick={()=>this._onAcceptDisclaimer()}>{strings.AcceptDisclaimerButton}</MessageBarButton> </div> } > <div className={styles.disclaimerText} dangerouslySetInnerHTML={{__html: strings.DisclaimerText}}></div> </MessageBar>); } return ( <div className={styles.enhancedListFormatting}> {styleElem} <MessageBar messageBarType={hasCSS ? MessageBarType.success : null} isMultiline={false} actions={ <div> <MessageBarButton onClick={() => this._onConfigure()}>{hasCSS ? strings.PlaceholderButtonTitleHasStyles : strings.PlaceholderButtonTitleNoStyles}</MessageBarButton> </div> } > {hasCSS ? strings.PlaceholderDescriptionHasStyles : strings.PlaceholderDescriptionNoStyles} </MessageBar> </div> ); } private _onAcceptDisclaimer() { this.props.onAcceptDisclaimer(); } private _onConfigure() { this.props.context.propertyPane.open(); } }
any idea, how i can achieve this? I want to do so , as we are planing to create a lot of pages which have the custom css. And instead of having to modify all those pages in the future to change their css, we will only need to change the related css file, and the change will be applied automatically to all the pages at once.
Thanks
No RepliesBe the first to reply