Component inside another component

Hello everybody,
I am a developer of a public website here in Brazil, where we use Plone + Volto, but recently I have the following problem:
I need to create a component that serves again has tabs to store contents of other components within this specific component but I don't know how to do that, below I will put some images to exemplify:

I have this component that has tabs, but so far the content of these tabs are fixed, I need to be able to have some way to add other components back to this component, can anyone help me?

Hey André!
There are some implementations of 'sub blocks' in volto addons. eea/volto-accordion-block and kitconcept/volto-blocks-grid are both good examples of implementing blocks inside of blocks. I also began implementing a similar pattern for the sidebar component for the New South Wales Design System for Volto that is smaller in scope than the other examples I just gave, but this is very much in a work-in-progress state and probably has numerous edge cases that aren't accounted for in the more complete implementations of the other examples.

While I haven't used eea/volto-tabs-block, this might also help.

I'm happy to help if you need some more specifics after looking through these! :slight_smile:

3 Likes

Thanks for the help, but I am a beginner and still don't understand even with the references that were sent to me.

My structure so far is something much simpler, I understood exactly how I put editable text, but blocks I am still confused.

My current code:

import React, {useState} from 'react';
import { Segment, Form } from 'semantic-ui-react';
import { SidebarPortal, Field, InlineForm } from '@plone/volto/components';
import { EditSchema } from './editSchema';
import TabNavigationView from './TabNavigationView.jsx';

const TabNavigationEdit = (props) => {
  const [selectedBlock, setSelectedBlock] = useState({});
  const { selected, data, onChangeBlock, block } = props;

  return (
    <div>
      <TabNavigationView {...props} />
      <SidebarPortal selected={selected}>
        <Segment.Group raised>
          <header className="header pulled">
            <h2>Calendário</h2>
          </header>
          <Form>
            <InlineForm
              schema={EditSchema}
              onChangeField={(id, value) => {
                onChangeBlock(block, {
                  ...data,
                  [id]: value,
                });
              }}
              formData={data}
            />
          </Form>
        </Segment.Group>
      </SidebarPortal>
    </div>
  );
};

export default TabNavigationEdit;

You first have to define your data structure, and for that you have to answer a few questions:

  • is the list of tabs fixed, always the same for your block?
  • inside each of these tabs, do you need to add multiple blocks, or a single block?

The volto-tabs-block provides a block where you can define tabs and create any number of "sub-blocks" inside each of these tabs. If you need a fixed set of tabs for each instance of your block you could try to see if you can import/reuse the tabs block and precook the initial tabs on your block creation, and there's even a way to make the tabs part "read only" volto-tabs-block/Edit.jsx at 8473f7b209df00939b3d9922e5be75c0dfb3d998 · eea/volto-tabs-block · GitHub