Ribbon
Ribbon is a horizontal scrolling button list component. See the example code for usage. Ribbon operates like the Tab component where the activeButtonId
attribute is used to specify the selected button. The id
attribute of the button must match the activeButtonId
in order for the button to be selected.
Result
Loading...
Live Editor
function Demo() {const [activeButtonId, setActiveButtonId] = useState('5-year-cash-flow-overview');function onButtonClick(key) {setActiveButtonId(key);}return (<Ribbon activeButtonId={activeButtonId} onButtonClick={onButtonClick}><Ribbon.Buttonid="5-year-cash-flow-overview"title="5 Year Cash Flow Overview"iconName="5-year-cash-flow-overview"/><Ribbon.Button id="account-summary" title="Account Summary" iconName="account-summary" /><Ribbon.Separator /><Ribbon.Button id="asset-allocation" title="Asset Allocation" iconName="asset-allocation" /><Ribbon.Button id="asset-spread" title="Asset Apread" iconName="asset-spread" /><Ribbon.Button id="balance-sheet" title="Balance Sheet" iconName="balance-sheet" /><Ribbon.Buttonid="balance-sheet-at-death"title="Balance Sheet at Death"iconName="balance-sheet-at-death"/><Ribbon.Buttonid="cash-flow-details"title="Cash Flow Details"iconName="cash-flow-details"/><Ribbon.Buttonid="cash-flow-overview"title="Cash Flow Overview"iconName="cash-flow-overview"/><Ribbon.Buttonid="compare-distributions"title="Compare Distributions"iconName="compare-distributions"/><Ribbon.Buttonid="compare-survivor-income"title="Compare Survivor Income"iconName="compare-survivor-income"/><Ribbon.Buttonid="estate-flow-chart"title="Estate Flow Chart"iconName="estate-flow-chart"/><Ribbon.Button id="expenses" title="Expenses" iconName="expenses" /><Ribbon.Button id="goal-education" title="Goal Education" iconName="goal-education" /><Ribbon.Button id="goal-retirement" title="Goal Retirement" iconName="goal-retirement" /><Ribbon.Button id="goals" title="Goals" iconName="goals" /><Ribbon.Button id="goal-spending" title="Goal Spending" iconName="goal-spending" /><Ribbon.Button id="holdings-details" title="Holdings Details" iconName="holdings-details" /><Ribbon.Buttonid="holdings-gain-loss"title="Holdings Gain Loss"iconName="holdings-gain-loss"/><Ribbon.Button id="income" title="Income" iconName="income" /><Ribbon.Buttonid="insurance-premiums"title="Insurance Premiums"iconName="insurance-premiums"/><Ribbon.Buttonid="life-insurance-gap-analysis"title="Life Insurance Gap Analysis"iconName="life-insurance-gap-analysis"/><Ribbon.Buttonid="life-insurance-summary"title="Life Insurance Summary"iconName="life-insurance-summary"/><Ribbon.Buttonid="lifetime-portfolio-value"title="Lifetime Portfolio Value"iconName="lifetime-portfolio-value"/><Ribbon.Button id="longevity-risk" title="Longevity Risk" iconName="longevity-risk" /><Ribbon.Buttonid="monte-carlo-summary"title="Monte Carlo Summary"iconName="monte-carlo-summary"/><Ribbon.Button id="other-income" title="Other Income" iconName="other-income" /><Ribbon.Button id="plan-overview" title="Plan Overview" iconName="plan-overview" /><Ribbon.Button id="profile" title="Profile" iconName="profile" /><Ribbon.Button id="progress" title="Progress" iconName="progress" /><Ribbon.Buttonid="progress-to-goals"title="Progress to Goals"iconName="progress-to-goals"/><Ribbon.Buttonid="scenario-comparison"title="Scenario Comparison"iconName="scenario-comparison"/><Ribbon.Button id="secure-income" title="Secure Income" iconName="secure-income" /><Ribbon.Button id="tax-bracket" title="Tax Bracket" iconName="tax-bracket" /><Ribbon.Button id="total-taxes" title="Total Taxes" iconName="total-taxes" /></Ribbon>);}
Custom Icon
You can use the renderIcon
prop to provide a custom icon SVG.
Result
Loading...
Live Editor
function Demo() {const profileIcon = () => (<svg xmlns="http://www.w3.org/2000/svg" width="33" height="32" viewBox="0 0 33 32" fill="none"><pathd="M7.83872 25.9172C8.64982 24.0063 10.5436 22.666 12.7503 22.666H20.7503C22.9571 22.666 24.8508 24.0063 25.6619 25.9172M22.0837 12.666C22.0837 15.6115 19.6958 17.9993 16.7503 17.9993C13.8048 17.9993 11.417 15.6115 11.417 12.666C11.417 9.7205 13.8048 7.33268 16.7503 7.33268C19.6958 7.33268 22.0837 9.7205 22.0837 12.666ZM30.0837 15.9993C30.0837 23.3631 24.1141 29.3327 16.7503 29.3327C9.38653 29.3327 3.41699 23.3631 3.41699 15.9993C3.41699 8.63555 9.38653 2.66602 16.7503 2.66602C24.1141 2.66602 30.0837 8.63555 30.0837 15.9993Z"strokeWidth="2"strokeLinecap="round"strokeLinejoin="round"/></svg>);const summaryIcon = () => (<svg xmlns="http://www.w3.org/2000/svg" width="33" height="32" viewBox="0 0 33 32" fill="none"><pathd="M26.9163 13.9993V9.06602C26.9163 6.82581 26.9163 5.7057 26.4804 4.85005C26.0969 4.09741 25.4849 3.48548 24.7323 3.10199C23.8767 2.66602 22.7566 2.66602 20.5163 2.66602H11.983C9.7428 2.66602 8.62269 2.66602 7.76705 3.10199C7.0144 3.48548 6.40248 4.09741 6.01898 4.85005C5.58301 5.7057 5.58301 6.82581 5.58301 9.06602V22.9327C5.58301 25.1729 5.58301 26.293 6.01898 27.1486C6.40248 27.9013 7.0144 28.5132 7.76705 28.8967C8.62269 29.3327 9.7428 29.3327 11.983 29.3327H16.2497M18.9163 14.666H10.9163M13.583 19.9993H10.9163M21.583 9.33268H10.9163"strokeWidth="2"strokeLinecap="round"strokeLinejoin="round"/><pathd="M30.75 30.75L26.6833 26.6833M28.1722 22.9611C28.1722 25.8391 25.8391 28.1722 22.9611 28.1722C20.0831 28.1722 17.75 25.8391 17.75 22.9611C17.75 20.0831 20.0831 17.75 22.9611 17.75C25.8391 17.75 28.1722 20.0831 28.1722 22.9611Z"strokeWidth="2"strokeLinecap="round"strokeLinejoin="round"/></svg>);const [activeButtonId, setActiveButtonId] = React.useState('one');function onButtonClick(key) {setActiveButtonId(key);}return (<Ribbon activeButtonId={activeButtonId} onButtonClick={onButtonClick}><Ribbon.Button id="one" title="one" renderIcon={profileIcon} /><Ribbon.Button id="two" title="two" renderIcon={summaryIcon} /><Ribbon.Separator /><Ribbon.Button id="three" title="three" renderIcon={summaryIcon} /><Ribbon.Button id="four" title="four" renderIcon={summaryIcon} /><Ribbon.Button id="five" title="five" renderIcon={summaryIcon} /><Ribbon.Button id="six" title="six" renderIcon={summaryIcon} /><Ribbon.Button id="seven" title="seven" renderIcon={summaryIcon} /><Ribbon.Button id="eight" title="eight" renderIcon={summaryIcon} /><Ribbon.Button id="nine" title="nine" renderIcon={summaryIcon} /><Ribbon.Button id="ten" title="ten" renderIcon={summaryIcon} /><Ribbon.Button id="eleven" title="eleven" renderIcon={summaryIcon} /><Ribbon.Button id="twelve" title="twelve" renderIcon={summaryIcon} /><Ribbon.Button id="thirteen" title="thirteen" renderIcon={summaryIcon} /><Ribbon.Button id="fourteen" title="fourteen" renderIcon={summaryIcon} /><Ribbon.Button id="fifteen" title="fifteen" renderIcon={summaryIcon} /><Ribbon.Button id="sixteen" title="sixteen" renderIcon={summaryIcon} /><Ribbon.Button id="seventeen" title="seventeen" renderIcon={summaryIcon} /><Ribbon.Button id="eighteen" title="eighteen" renderIcon={summaryIcon} /></Ribbon>);}
Draggable and Edit Mode
The DragAndDropRibbon and DragAndDropRibbonButton can be used to create editable Ribbons when placed in Edit Mode. Tiles become sortable and removable and the onSort
prop is called with the new order of the tiles.
Note: The immediate children of the DragAndDropRibbon must be DragAndDropRibbonButtons. Using a wrapper around the child elements will break the component.
Result
Loading...
Live Editor
const defaultItems = [{id: '5-year-cash-flow-overview',title: '5 Year Cash Flow Overview',iconName: '5-year-cash-flow-overview',},{ id: 'account-summary', title: 'Account Summary', iconName: 'account-summary' },{ id: 'asset-allocation', title: 'Asset Allocation', iconName: 'asset-allocation' },{ id: 'asset-spread', title: 'Asset Apread', iconName: 'asset-spread' },{ id: 'balance-sheet', title: 'Balance Sheet', iconName: 'balance-sheet' },{id: 'balance-sheet-at-death',title: 'Balance Sheet at Death',iconName: 'balance-sheet-at-death',},{ id: 'cash-flow-details', title: 'Cash Flow Details', iconName: 'cash-flow-details' },{ id: 'cash-flow-overview', title: 'Cash Flow Overview', iconName: 'cash-flow-overview' },{id: 'compare-distributions',title: 'Compare Distributions',iconName: 'compare-distributions',},{id: 'compare-survivor-income',title: 'Compare Survivor Income',iconName: 'compare-survivor-income',},{ id: 'estate-flow-chart', title: 'Estate Flow Chart', iconName: 'estate-flow-chart' },{ id: 'expenses', title: 'Expenses', iconName: 'expenses' },{ id: 'goal-education', title: 'Goal Education', iconName: 'goal-education' },{ id: 'goal-retirement', title: 'Goal Retirement', iconName: 'goal-retirement' },{ id: 'goals', title: 'Goals', iconName: 'goals' },{ id: 'goal-spending', title: 'Goal Spending', iconName: 'goal-spending' },{ id: 'holdings-details', title: 'Holdings Details', iconName: 'holdings-details' },{ id: 'holdings-gain-loss', title: 'Holdings Gain Loss', iconName: 'holdings-gain-loss' },{ id: 'income', title: 'Income', iconName: 'income' },{ id: 'insurance-premiums', title: 'Insurance Premiums', iconName: 'insurance-premiums' },{id: 'life-insurance-gap-analysis',title: 'Life Insurance Gap Analysis',iconName: 'life-insurance-gap-analysis',},{id: 'life-insurance-summary',title: 'Life Insurance Summary',iconName: 'life-insurance-summary',},{id: 'lifetime-portfolio-value',title: 'Lifetime Portfolio Value',iconName: 'lifetime-portfolio-value',},{ id: 'longevity-risk', title: 'Longevity Risk', iconName: 'longevity-risk' },{id: 'monte-carlo-summary',title: 'Monte Carlo Summary',iconName: 'monte-carlo-summary',},{ id: 'other-income', title: 'Other Income', iconName: 'other-income' },{ id: 'plan-overview', title: 'Plan Overview', iconName: 'plan-overview' },{ id: 'profile', title: 'Profile', iconName: 'profile' },{ id: 'progress', title: 'Progress', iconName: 'progress' },{ id: 'progress-to-goals', title: 'Progress to Goals', iconName: 'progress-to-goals' },{id: 'scenario-comparison',title: 'Scenario Comparison',iconName: 'scenario-comparison',},{ id: 'secure-income', title: 'Secure Income', iconName: 'secure-income' },{ id: 'tax-bracket', title: 'Tax Bracket', iconName: 'tax-bracket' },{ id: 'total-taxes', title: 'Total Taxes', iconName: 'total-taxes' },];function Example() {const [items, setItems] = useState(defaultItems);const [activeButtonId, setActiveButtonId] = useState('one');const [editMode, setEditMode] = useState(false);const [showModal, setShowModal] = useState(false);function onButtonClick(key) {setActiveButtonId(key);}return (<><style>{`.scrollLeft,.scrollRight {--bs-horizontal-scrollleft-background: var(--ifm-pre-background);--bs-horizontal-scrollright-background: var(--ifm-pre-background);}`}</style><Button className="mb-4" onClick={() => setEditMode(!editMode)}>Toggle Edit Mode</Button><Ribbon.DragAndDropRibbonactiveButtonId={activeButtonId}onButtonClick={onButtonClick}editMode={editMode}addButtonTitle="Add Report"onAddButtonClick={() => {setShowModal(true);}}onRemoveButtonClick={(id) => {setItems(items.filter((item) => item.id !== id));}}onSort={(sortedItems) => {setItems(sortedItems.map((key) => items.find((i) => i.id === key)));}}>{items.map((item) => (<Ribbon.DragAndDropRibbonButtonkey={item.id}id={item.id}title={item.title}iconName={item.iconName}animateIn={item.isNew}/>))}</Ribbon.DragAndDropRibbon></>);}render(<Example />);