Skip to content

Creation of Multi-Accordion Block #1185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 27, 2025
Merged

Conversation

Gowrishankar-Palanisamy
Copy link
Contributor

This PR contains the following changes

--> Enhancement of accordion
-->Creation of multi accordion block

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
…nhance-multi-accordion
Copy link

@CodiumAI-Agent /describe

@CodiumAI-Agent
Copy link

Title

Creation of Multi-Accordion Block


User description

This PR contains the following changes

--> Enhancement of accordion
-->Creation of multi accordion block


PR Type

Enhancement


Description

  • Replace accordion expand icon and styling

  • Add Multi-Accordion Block menu entry

  • Define default multi-accordion JSON configuration


Changes walkthrough 📝

Relevant files
Enhancement
AccordionBlock.tsx
Update accordion icon and style                                                   

libs/renderer/src/components/block-defaults/accordion-block/AccordionBlock.tsx

  • Swap ExpandMore for ArrowDropDown icon
  • Add borderRadius to accordion styling
  • Simplify expandIcon prop usage
  • +3/-2     
    Configuration changes
    default-menu.ts
    Add Multi-Accordion Block menu entry                                         

    packages/client/src/components/blocks-workspace/menus/default-menu.ts

  • Insert Multi-Accordion Block menu section
  • Configure default JSON structure with three accordions
  • Add helper text and images for new block
  • +320/-0 

    Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • Copy link

    @CodiumAI-Agent /review

    @CodiumAI-Agent
    Copy link

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Icon Behavior

    The new ArrowDropDown icon may not rotate on expand/collapse like ExpandMore. Verify expand icon animation and alignment.

    import { ArrowDropDown } from "@mui/icons-material";
    
    import { Accordion, Stack, styled } from "@semoss/ui";
    
    import { Slot } from "../../blocks";
    import { useBlock } from "../../../hooks";
    import { BlockDef, BlockComponent, ListenerActions } from "../../../store";
    
    const StyledAccordion = styled(Accordion)(({ theme }) => ({
        padding: 0,
        margin: 0,
        borderRadius: "12px",
        "&.MuiAccordion-root:before": {
            backgroundColor: "white",
        },
    }));
    
    const AccordionTrigger = styled(Accordion.Trigger)(({ theme }) => ({
        "& .MuiAccordionSummary-content": {
            margin: 0,
        },
        minHeight: "fit-content",
        margin: 0,
        padding: 0,
        borderRadius: "inherit",
        //if accordion is expanded, then remove the border radius from bottom left and right side of the trigger element
        "&.MuiButtonBase-root.Mui-expanded": {
            borderBottomLeftRadius: 0,
            borderBottomRightRadius: 0,
        },
    }));
    
    const AccordionContent = styled(Accordion.Content)(({ theme }) => ({
        margin: 0,
        padding: 0,
        borderRadius: "inherit",
        borderTopLeftRadius: 0,
        borderTopRightRadius: 0,
    }));
    
    export interface AccordionBlockDef extends BlockDef<"accordion"> {
        widget: "accordion";
        data: {
            style: CSSProperties;
            triggerBgColor: string;
            contentBgColor: string;
            showExpandIcon: boolean;
            show: string;
        };
        slots: {
            header: true;
            content: true;
        };
        listeners: {
            preProcess: {
                type: "sync" | "async";
                order: ListenerActions[];
            };
        };
    }
    
    export const AccordionBlock: BlockComponent = observer(({ id }) => {
        const { attrs, data, slots, listeners } = useBlock<AccordionBlockDef>(id);
    
        useEffect(() => {
            if (listeners.preProcess) {
                listeners.preProcess();
            }
        }, []);
    
        return (
            <StyledAccordion
                {...attrs}
                sx={{ ...data.style, overflow: "hidden" }}
                square={true}
                disableGutters={true}
            >
                <AccordionTrigger
                    sx={{
                        backgroundColor: data.triggerBgColor,
                    }}
                    expandIcon={<ArrowDropDown />}
                >
    Unused Property

    The showExpandIcon prop is still present in defaults but no longer honored. Consider removing it or reintroducing conditional logic.

    import { ArrowDropDown } from "@mui/icons-material";
    
    import { Accordion, Stack, styled } from "@semoss/ui";
    
    import { Slot } from "../../blocks";
    import { useBlock } from "../../../hooks";
    import { BlockDef, BlockComponent, ListenerActions } from "../../../store";
    
    const StyledAccordion = styled(Accordion)(({ theme }) => ({
        padding: 0,
        margin: 0,
        borderRadius: "12px",
        "&.MuiAccordion-root:before": {
            backgroundColor: "white",
        },
    }));
    
    const AccordionTrigger = styled(Accordion.Trigger)(({ theme }) => ({
        "& .MuiAccordionSummary-content": {
            margin: 0,
        },
        minHeight: "fit-content",
        margin: 0,
        padding: 0,
        borderRadius: "inherit",
        //if accordion is expanded, then remove the border radius from bottom left and right side of the trigger element
        "&.MuiButtonBase-root.Mui-expanded": {
            borderBottomLeftRadius: 0,
            borderBottomRightRadius: 0,
        },
    }));
    
    const AccordionContent = styled(Accordion.Content)(({ theme }) => ({
        margin: 0,
        padding: 0,
        borderRadius: "inherit",
        borderTopLeftRadius: 0,
        borderTopRightRadius: 0,
    }));
    
    export interface AccordionBlockDef extends BlockDef<"accordion"> {
        widget: "accordion";
        data: {
            style: CSSProperties;
            triggerBgColor: string;
            contentBgColor: string;
            showExpandIcon: boolean;
            show: string;
        };
        slots: {
            header: true;
            content: true;
        };
        listeners: {
            preProcess: {
                type: "sync" | "async";
                order: ListenerActions[];
            };
        };
    }
    
    export const AccordionBlock: BlockComponent = observer(({ id }) => {
        const { attrs, data, slots, listeners } = useBlock<AccordionBlockDef>(id);
    
        useEffect(() => {
            if (listeners.preProcess) {
                listeners.preProcess();
            }
        }, []);
    
        return (
            <StyledAccordion
                {...attrs}
                sx={{ ...data.style, overflow: "hidden" }}
                square={true}
                disableGutters={true}
            >
                <AccordionTrigger
                    sx={{
                        backgroundColor: data.triggerBgColor,
                    }}
                    expandIcon={<ArrowDropDown />}
                >
    Config Maintainability

    The JSON for the multi-accordion block is very large and duplicated. Consider abstracting repeated structures to improve readability and reduce risks of inconsistencies.

    {
        section: SECTION_LAYOUT,
        name: 'Multi-Accordion Block',
        activeImage: BLOCK_IMAGES['ACCORDION_ACTIVE'],
        hoverImage: BLOCK_IMAGES['ACCORDION_HOVER'],
        helperText: 'Click to expand and collapse sections for more details',
        json: {
            widget: 'container',
            data: {
                style: {
                    display: 'flex',
                    flexDirection: 'column',
                },
            },
            listeners: {},
            slots: {
                children: [
                    {
                        widget: 'accordion',
                        data: {
                            style: {
                                borderBottom: '1px solid #ccc',
                                borderRadius: '0',
                            },
                            triggerBgColor: '',
                            contentBgColor: '',
                            showExpandIcon: false,
                            show: 'true',
                        },
                        listeners: {},
                        slots: {
                            header: [
                                {
                                    widget: 'container',
                                    data: {
                                        style: {
                                            display: 'flex',
                                            flexDirection: 'row',
                                            alignItems: 'center',
                                            gap: '30%',
                                        },
                                    },
                                    listeners: {},
                                    slots: {
                                        children: [
                                            {
                                                widget: 'text',
                                                data: {
                                                    style: {
                                                        padding: '20px',
                                                        whiteSpace: 'pre-line',
                                                        textOverflow:
                                                            'ellipsis',
                                                    },
                                                    text: 'Accordion 1',
                                                    variant: 'p',
                                                    show: 'true',
                                                },
                                                listeners: {},
                                                slots: {},
                                            },
                                            {
                                                widget: 'text',
                                                data: {
                                                    style: {
                                                        whiteSpace: 'pre-line',
                                                        textOverflow:
                                                            'ellipsis',
                                                        color: '#9c9696',
                                                        fontWeight: 'normal',
                                                    },
                                                    text: 'I am an accordion',
                                                    variant: 'h4',
                                                    show: 'true',
                                                },
                                                listeners: {},
                                                slots: {},
                                            },
                                        ],
                                    },
                                },
                            ],
                            content: [
                                {
                                    widget: 'container',
                                    data: {
                                        style: {
                                            display: 'flex',
                                            flexDirection: 'row',
                                            gap: '18px',
                                        },
                                    },
                                    listeners: {},
                                    slots: {
                                        children: [
                                            {
                                                widget: 'text',
                                                data: {
                                                    style: {
                                                        padding: '20px',
                                                        whiteSpace: 'pre-line',
                                                        textOverflow:
                                                            'ellipsis',
                                                    },
                                                    text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.',
                                                    variant: 'p',
                                                    show: 'true',
                                                },
                                                listeners: {},
                                                slots: {},
                                            },
                                        ],
                                    },
                                },
                            ],
                        },
                    },
                    {
                        widget: 'accordion',
                        data: {
                            style: {
                                borderBottom: '1px solid #ccc',
                            },
                            triggerBgColor: '',
                            contentBgColor: '',
                            showExpandIcon: false,
                            show: 'true',
                        },
                        listeners: {},
                        slots: {
                            header: [
                                {
                                    widget: 'container',
                                    data: {
                                        style: {
                                            display: 'flex',
                                            flexDirection: 'row',
                                            alignItems: 'center',
                                            gap: '30%',
                                        },
                                    },
                                    listeners: {},
                                    slots: {
                                        children: [
                                            {
                                                widget: 'text',
                                                data: {
                                                    style: {
                                                        padding: '20px',
                                                        whiteSpace: 'pre-line',
                                                        textOverflow:
                                                            'ellipsis',
                                                    },
                                                    text: 'Accordion 2',
                                                    variant: 'p',
                                                    show: 'true',
                                                },
                                                listeners: {},
                                                slots: {},
                                            },
                                            {
                                                widget: 'text',
                                                data: {
                                                    style: {
                                                        whiteSpace: 'pre-line',
                                                        textOverflow:
                                                            'ellipsis',
                                                        color: '#9c9696',
                                                        fontWeight: 'normal',
                                                    },
                                                    text: 'I am an accordion',
                                                    variant: 'h4',
                                                    show: 'true',
                                                },
                                                listeners: {},
                                                slots: {},
                                            },
                                        ],
                                    },
                                },
                            ],
                            content: [
                                {
                                    widget: 'container',
                                    data: {
                                        style: {
                                            display: 'flex',
                                            flexDirection: 'row',
                                            gap: '18px',
                                        },
                                    },
                                    listeners: {},
                                    slots: {
                                        children: [
                                            {
                                                widget: 'text',
                                                data: {
                                                    style: {
                                                        padding: '20px',
                                                        whiteSpace: 'pre-line',
                                                        textOverflow:
                                                            'ellipsis',
                                                    },
                                                    text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.',
                                                    variant: 'p',
                                                    show: 'true',
                                                },
                                                listeners: {},
                                                slots: {},
                                            },
                                        ],
                                    },
                                },
                            ],
                        },
                    },
                    {
                        widget: 'accordion',
                        data: {
                            style: {
                                borderBottom: '1px solid #ccc',
                            },
                            triggerBgColor: '',
                            contentBgColor: '',
                            showExpandIcon: false,
                            show: 'true',
                        },
                        listeners: {},
                        slots: {
                            header: [
                                {
                                    widget: 'container',
                                    data: {
                                        style: {
                                            display: 'flex',
                                            flexDirection: 'row',
                                            alignItems: 'center',
                                            gap: '30%',
                                        },
                                    },
                                    listeners: {},
                                    slots: {
                                        children: [
                                            {
                                                widget: 'text',
                                                data: {
                                                    style: {
                                                        padding: '20px',
                                                        whiteSpace: 'pre-line',
                                                        textOverflow:
                                                            'ellipsis',
                                                    },
                                                    text: 'Accordion 3',
                                                    variant: 'p',
                                                    show: 'true',
                                                },
                                                listeners: {},
                                                slots: {},
                                            },
                                            {
                                                widget: 'text',
                                                data: {
                                                    style: {
                                                        whiteSpace: 'pre-line',
                                                        textOverflow:
                                                            'ellipsis',
                                                        color: '#9c9696',
                                                        fontWeight: 'normal',
                                                    },
                                                    text: 'I am an accordion',
                                                    variant: 'h4',
                                                    show: 'true',
                                                },
                                                listeners: {},
                                                slots: {},
                                            },
                                        ],
                                    },
                                },
                            ],
                            content: [
                                {
                                    widget: 'container',
                                    data: {
                                        style: {
                                            display: 'flex',
                                            flexDirection: 'row',
                                            gap: '18px',
                                        },
                                    },
                                    listeners: {},
                                    slots: {
                                        children: [
                                            {
                                                widget: 'text',
                                                data: {
                                                    style: {
                                                        padding: '20px',
                                                        whiteSpace: 'pre-line',
                                                        textOverflow:
                                                            'ellipsis',
                                                    },
                                                    text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.',
                                                    variant: 'p',
                                                    show: 'true',
                                                },
                                                listeners: {},
                                                slots: {},
                                            },
                                        ],
                                    },
                                },
                            ],
                        },
                    },
                ],
            },
        },
    },

    Copy link

    @CodiumAI-Agent /improve

    @CodiumAI-Agent
    Copy link

    CodiumAI-Agent commented May 20, 2025

    PR Code Suggestions ✨

    Latest suggestions up to f828c84

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Conditionally render expand icon

    Respect the data.showExpandIcon flag when rendering the icon, so toggling visibility
    actually works. Render the icon only if showExpandIcon is true, otherwise pass
    undefined.

    libs/renderer/src/components/block-defaults/accordion-block/AccordionBlock.tsx [84]

    -expandIcon={<ArrowDropDown />}
    +expandIcon={data.showExpandIcon ? <ArrowDropDown /> : undefined}
    Suggestion importance[1-10]: 8

    __

    Why: The icon is currently always rendered, ignoring data.showExpandIcon, so adding this condition fixes a functional regression.

    Medium
    Use boolean instead of string

    Use boolean literals instead of strings for show (and similar) properties to avoid
    type mismatches at runtime. Replace 'true'/'false' with true/false.

    packages/client/src/components/blocks-workspace/menus/default-menu.ts [111]

    -show: 'true',
    +show: true,
    Suggestion importance[1-10]: 6

    __

    Why: The show property is defined as a string but should be a boolean to match expected types and prevent runtime issues.

    Low
    General
    Abstract repeated definitions

    Reduce the three nearly identical accordion definitions by mapping over a
    configuration array, improving maintainability and reducing duplication. Generate
    each accordion entry dynamically instead of hardcoding.

    packages/client/src/components/blocks-workspace/menus/default-menu.ts [100-224]

    -{
    +const defaultAccordions = [
    +  { title: 'Accordion 1', subtitle: 'I am an accordion', content: 'Lorem ipsum…' },
    +  { title: 'Accordion 2', subtitle: 'I am an accordion', content: 'Lorem ipsum…' },
    +  { title: 'Accordion 3', subtitle: 'I am an accordion', content: 'Lorem ipsum…' },
    +];
    +
    +slots: {
    +  children: defaultAccordions.map(({ title, subtitle, content }) => ({
         widget: 'accordion',
    -    data: {
    -        style: { borderBottom: '1px solid #ccc', borderRadius: '0', padding: '16px' },
    -        triggerBgColor: '',
    -        contentBgColor: '',
    -        showExpandIcon: false,
    -        show: 'true',
    -    },
    -
    -},
    +    data: { style: { borderBottom: '1px solid #ccc', padding: '16px' }, showExpandIcon: false, show: true },
    +    slots: {
    +      header: [ /* build header from title/subtitle */ ],
    +      content: [ /* build content from content */ ]
    +    }
    +  }))
    +}
    Suggestion importance[1-10]: 4

    __

    Why: Consolidating the repeated accordion entries into a mapping improves maintainability but is a broad refactoring outside the PR scope.

    Low

    Previous suggestions

    Suggestions up to commit fd6a5f8
    CategorySuggestion                                                                                                                                    Impact
    General
    Conditionally render expand icon

    Render the expand icon only when data.showExpandIcon is true to respect the
    configuration flag and avoid always displaying it.

    libs/renderer/src/components/block-defaults/accordion-block/AccordionBlock.tsx [84]

    -expandIcon={<ArrowDropDown />}
    +expandIcon={data.showExpandIcon ? <ArrowDropDown /> : undefined}
    Suggestion importance[1-10]: 8

    __

    Why: Without the data.showExpandIcon check the icon always renders, ignoring the original flag; this restores the intended conditional display.

    Medium
    Remove redundant borderRadius override

    Remove the explicit borderRadius override so that the styled Accordion’s default
    12px radius is applied consistently.

    packages/client/src/components/blocks-workspace/menus/default-menu.ts [100-103]

     style: {
         borderBottom: '1px solid #ccc',
    -    borderRadius: '0',
     },
    Suggestion importance[1-10]: 5

    __

    Why: Overriding borderRadius: '0' conflicts with the default 12px radius defined in the styled Accordion and is unnecessary for consistency.

    Low
    Possible issue
    Use boolean for show flag

    Change the show property from a string to a boolean to avoid type mismatches when
    evaluating visibility flags.

    packages/client/src/components/blocks-workspace/menus/default-menu.ts [107]

    -show: 'true',
    +show: true,
    Suggestion importance[1-10]: 7

    __

    Why: The JSON show property is defined as a string here, but consumers likely expect a boolean, so using show: true prevents type mismatches.

    Medium

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    …nhance-multi-accordion

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    @johbaxter
    Copy link
    Contributor

    @Gowrishankar-Palanisamy Thank you Gowri

    @bfekadu21 @ehynd
    This is cool for now will have design audit and fix please create follow up ticket on audits

    @johbaxter johbaxter merged commit 231f9d2 into dev May 27, 2025
    3 checks passed
    @johbaxter johbaxter deleted the feat/enhance-multi-accordion branch May 27, 2025 15:10
    Copy link

    @CodiumAI-Agent /update_changelog

    @CodiumAI-Agent
    Copy link

    Changelog updates: 🔄

    2025-05-27 #1185

    Added

    • Multi-Accordion Block for grouping multiple accordion sections
    • Enhanced Accordion component with updated drop-down icon and padding

    to commit the new content to the CHANGELOG.md file, please type:
    '/update_changelog --pr_update_changelog.push_changelog_changes=true'

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    None yet
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    Update current Accordion Block and Create New Multi-Accordion Block
    3 participants