The process of building custom applications and tools that interact with Microsoft SharePoint, including SharePoint Online in Microsoft 365.
Using Accordion from @pnp/spfx-controls-react and it is not styled as expected
Hi Everyone,
I am facing this issue where the Accordion is not rendering as expected
expected:
What I am getting is
I am using spfx 1.21.1, node v22.15.0, react@17.0., typescript@5.3.3
What could be the possible reasons, I am atttaching my component code and scss style below,
Please help me to understand the issue here. Thanks in advance.
Microsoft 365 and Office | SharePoint | Development
-
Chiara Carbone • 365 Reputation points2025-07-29T17:08:34.6666667+00:00 Hi
Is this:
className={styles.itemCell}Being applied in the rendered HTML?
You can confirm this by inspecting the element in the browser (right-click the accordion title and choose Inspect).
-
Dhilip Kumar • 45 Reputation points
2025-07-29T18:44:03.7466667+00:00 You see the computed class name is added here but not appplying the styles.
<head> tag has <style> tag in the end with all the styling from scss file which includes below class style.
.itemCell_8cdb066a_a85c335d:after{content:"\25B8";float:right;transition:transform .3s ease}
.itemCell_8cdb066a_a85c335d.active_8cdb066a_a85c335d:after{transform:rotate(90deg)}
Please let me know if you need anything else.
Even if I am not applying any custom style, it should display the content as block right? since it is in <div> tag but it is displaying it has inline.
-
Chiara Carbone • 365 Reputation points2025-07-30T10:15:31.38+00:00 What happens if you remove the itemCell class? Why do you need that custom class?
The Accordion component already includes built-in Fluent UI styling.
Can you try and let me know? -
Dhilip Kumar • 45 Reputation points
2025-07-31T02:56:17.15+00:00 It is still the same,
The style is not applying now,
is it due to any missing modules?
-
Dhilip Kumar • 45 Reputation points
2025-07-31T09:18:46.21+00:00 It is still the same,
The style is not applying now,
is it due to any missing modules?
-
Dhilip Kumar • 45 Reputation points
2025-07-31T14:48:53.08+00:00 missing info: i am using Accordion from pnp controls
-
Chiara Carbone • 365 Reputation points2025-07-31T15:53:32.12+00:00 What version of PnP? I tried it with the same setup and it works fine. Are there any other overwriting CSS classes?
-
Dhilip Kumar • 45 Reputation points
2025-07-31T16:58:58.9466667+00:00 @pnp/sp@4.14.0
@pnp/spfx-controls-react@3.21.0
these are the versions.
There are no styling I am using.
Component:
import * as React from 'react'; import styles from './Learn.module.scss'; import type { ILearnProps } from './ILearnProps'; import "@pnp/sp/lists"; import "@pnp/sp/webs"; //import { useState, useEffect } from 'react'; //import { getSP } from '../pnpjsConfig'; import { Accordion } from "@pnp/spfx-controls-react/lib/Accordion"; export interface Ilist{ Title:string, BaseTemplate:number, Description:string } const Learn = (props:ILearnProps): React.ReactElement<ILearnProps>=>{ const { hasTeamsContext, isDarkTheme } =props; const lists : any= [ {Title: "Displays an element as an inline element (like <span>). Any height and width properties will have no effect. This is default.", Desc: "Displays an element as an inline element (like <span>). Any height and width properties will have no effect. This is default." }, {Title: "House details", Desc: " Displays an element as a block element (like <p>). It starts on a new line, and takes up the whole width" }, {Title: "Certificates", Desc: "Displays an element as an inline-level block container. The element itself is formatted as an inline element, but you can apply height and width values" }, {Title: "Goods", Desc: "Makes the container disappear, making the child elements children of the element the next level up in the DOM" } ] //const [lists, setLists] = useState<Ilist[]>([]); /*const sp = getSP(context); const fetchLists = async (): Promise<void>=> { try { const allLists = await sp.web.lists.filter("Hidden eq false").select("Title", "BaseTemplate", "Description")(); const visibleLists = allLists.filter(list => list.BaseTemplate !== 544); // Exclude libraries if needed setLists(visibleLists); } catch (error) { console.error("Error fetching lists:", error); } }; useEffect(() => { fetchLists(); }, []);*/ return ( <section className={`${styles.learn} ${hasTeamsContext ? styles.teams : ''}`}> <div className={styles.welcome}> <img alt="" src={isDarkTheme ? require('../assets/welcome-dark.png') : require('../assets/welcome-light.png')} className={styles.welcomeImage} /> </div> <div > { lists.map((item:any, index:number) => ( <Accordion title={item.Title} defaultCollapsed={true} key={index} collapsedIcon={"ChevronRight"} expandedIcon={"ChevronDown"}> <p >{ item.Desc }</p> </Accordion> )) } </div> </section> ); } export default Learn;class component:
import * as React from 'react'; import * as ReactDom from 'react-dom'; import { Version } from '@microsoft/sp-core-library'; import { type IPropertyPaneConfiguration, PropertyPaneTextField } from '@microsoft/sp-property-pane'; import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base'; import { IReadonlyTheme } from '@microsoft/sp-component-base'; import * as strings from 'LearnWebPartStrings'; import Learn from './components/Learn'; import { ILearnProps } from './components/ILearnProps'; //import { IReadonlyTheme } from '@microsoft/sp-component-base'; export interface ILearnWebPartProps { description: string; name: string; } export default class LearnWebPart extends BaseClientSideWebPart<ILearnWebPartProps> { private _isDarkTheme: boolean = false; public render(): void { const element: React.ReactElement<ILearnProps> = React.createElement( Learn, { hasTeamsContext:!!this.context.sdks.microsoftTeams, isDarkTheme : this._isDarkTheme } ); ReactDom.render(element, this.domElement); } public async onInit(): Promise<void> { await super.onInit(); } protected onThemeChanged(currentTheme: IReadonlyTheme | undefined): void { if (!currentTheme) { return; } this._isDarkTheme = !!currentTheme.isInverted; const { semanticColors } = currentTheme; if (semanticColors) { this.domElement.style.setProperty('--bodyText', semanticColors.bodyText || null); this.domElement.style.setProperty('--link', semanticColors.link || null); this.domElement.style.setProperty('--linkHovered', semanticColors.linkHovered || null); } } /*protected onThemeChanged(currentTheme: IReadonlyTheme | undefined): void { if (!currentTheme) { return; } this._isDarkTheme = !!currentTheme.isInverted; const { semanticColors } = currentTheme; if (semanticColors) { this.domElement.style.setProperty('--bodyText', semanticColors.bodyText || null); this.domElement.style.setProperty('--link', semanticColors.link || null); this.domElement.style.setProperty('--linkHovered', semanticColors.linkHovered || null); } }*/ 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: [ PropertyPaneTextField('description', { label: strings.DescriptionFieldLabel }), PropertyPaneTextField('name',{label : "User Name"}) ] } ] } ] }; } }Styling:
@import '~@fluentui/react/dist/sass/References.scss'; .learn { overflow: hidden; padding: 1em; color: "[theme:bodyText, default: #323130]"; color: var(--bodyText); &.teams { font-family: $ms-font-family-fallbacks; } } .welcome { text-align: center; } .welcomeImage { width: 100%; max-width: 420px; } .links { a { text-decoration: none; color: "[theme:link, default:#03787c]"; color: var(--link); // note: CSS Custom Properties support is limited to modern browsers only &:hover { text-decoration: underline; color: "[theme:linkHovered, default: #014446]"; color: var(--linkHovered); // note: CSS Custom Properties support is limited to modern browsers only } } } .itemCell { background-color: #f5f5f5; padding: 12px 16px; display: block; border: 1px solid #ddd; cursor: pointer; font-weight: 500; font-size: 14px; transition: background-color 0.3s ease; &:hover { background-color: #e8e8e8; } &::after { content: '▸'; float: right; transition: transform 0.3s ease; } &.active::after { transform: rotate(90deg); } button{ display: block; } } .itemContent { margin-bottom: 10px; } .itemResponse { border: 2px burlywood; } -
Dhilip Kumar • 45 Reputation points
2025-07-31T17:14:20.88+00:00 @pnp/sp@4.14.0
@pnp/spfx-controls-react@3.21.0
These are the versions and i am not using any other custom styling for the Accordion.
-
Chiara Carbone • 365 Reputation points2025-08-03T13:22:06.27+00:00 It seems Accordion.module.scss is missing. Can you check this?
-
Dhilip Kumar • 45 Reputation points
2025-08-03T14:16:50.03+00:00 Hi Chiara,
I have started a new Project again to check. But mean while I have run another prjet from online which runs on 20.11.0 and it rendered as expected.
I will check again and I will let you know, thanks for Guidance so far.
Sign in to comment