Skip to main content

Shareholders Tab

Shareholders Tab

The Shareholders tab is a special component in the Company Form, as it handles a dynamic list of shareholders that users can add, update, or remove.

To build this functionality, we use the VisualSubDocument component from the SOKit UI library. This component provides a dual-pane layout:

  • A list of items (cards) on the left
  • A form for editing or creating items on the right

Step 1: Create the Shareholder Form

This form is used for inputting shareholder data and will be rendered on the right side of each card. Create it in:

src/pages/company/components/forms/ShareholdersForm.jsx
ShareholderForm.jsx
import { Input, Section, SectionContainer, SectionTitle } from 'so-kit-ui';

const ShareholdersForm = () => {
return (
<SectionContainer padded>
<Section>
<SectionTitle>title.sh.info</SectionTitle>
<Section.Elements>
<Input id='firstName' />
<Input id='lastName' />
<Input
id='shares'
type='number'
/>
<Input id='percentage' />
<Input id='email' />
<Input id='phone' />
</Section.Elements>
</Section>
</SectionContainer>
);
};

export default ShareholdersForm;


Step 2: Create the Shareholders Tab Component

Now create the actual tab component using the VisualSubDocument wrapper.

Save this in:

src/pages/company/components/tabs/Shareholders.jsx
Shareholders.jsx
import { VisualSubDocument, Tag } from "so-kit-ui";
import ShareholdersForm from "../forms/ShareholdersForm.jsx";

// Display first and last name on the card
const Line1 = ({ subDataTabsProps }) => {
const fn = subDataTabsProps?.subData?.firstName ?? '';
const ln = subDataTabsProps?.subData?.lastName ?? '';
return (
<div className='ps-2 max-w-full overflow-hidden'>
<Tag color='base'>{`${fn} ${ln}`}</Tag>
</div>
);
};

// Display shares and percentage below the name
const Line2 = ({ subDataTabsProps }) => {
const shares = subDataTabsProps?.subData?.shares ?? '';
const quote = subDataTabsProps?.subData?.percentage ?? '';
return (
<div className='max-w-full text-nowrap text-ellipsis overflow-hidden'>
{`Shares: ${shares} - ${quote} %`}
</div>
);
};

const Shareholders = () => {
return (
<VisualSubDocument
qpName='shareholder'
path='shareholders'
idAccessor='id'
autoNumber={true}
formComponent={<ShareholdersForm />}
buttonNew={true}
buttonNewId='btn.sh.new'
buttonClone={true}
buttonCloneId='btn.sh.clone'
buttonDelete={true}
buttonDeleteId='btn.sh.delete'
tabLine1={Line1}
tabLine2={Line2}
tabEmptyPlaceHolder='empty.shareholders'
formEmptyPlaceHolder='empty.shareholders'
maxVerticalItems={9}
/>
);
};

export default Shareholders;

How It Works

  • FormComponent: We pass ShareholdersForm to render in the form area for each list item.
  • Line1 / Line2: These define how each item (card) appears in the sidebar.
  • Buttons: The props buttonNew, buttonClone, and buttonDelete enable UI actions and hook into localized labels using translation keys.
  • Placeholders: Shown when the list is empty or when no item is selected.

The VisualSubDocument is highly customizable and integrates smoothly with your data schema and workflows.