Wrapping components
The tag
property
Intergalactic components are built with polymorphic typings, that means that you can provide tag
property that will redefine allowed properties list.
import Button from 'intergalactic/button';
<Button
href="">
// Error: Property 'href' does not exist on type...
Hello world
</Button>
<Button
tag="a"
href="">
Hello world
</Button>
tag
property also accepts React components and other Intergalactic components what allows you to easley combine logic of visual appearance of both components.
import React from 'react';
import Select from 'intergalactic/select';
import { LinkTrigger } from 'intergalactic/base-trigger';
const options = Array(6)
.fill('')
.map((_, index) => ({ value: index, children: `Label ${index}` }));
const Demo = () => <Select tag={LinkTrigger} options={options} placeholder='Select' />;
export default Demo;
The tag
property is not included in the component's props, so you can't make wrappers by simple using that.
import Select, { SelectProps } from 'intergalactic/select'
const WrappedSelect = ({
tag, // Property tag does not exist on type SelectProps.
...other
}: SelectProps) => (
<Select {...other} />
)
Making wrappers
Use the special utility wrapIntergalacticComponent
to wrap components. It does nothing in runtime but ensures correct typings in TypeScript.
import React from 'react';
import { wrapIntergalacticComponent } from 'intergalactic/core';
import Button from 'intergalactic/button';
const AlertButton = wrapIntergalacticComponent<
typeof Button,
{
handle: ('click' | 'hover')[];
message: string;
}
>(({ handle, message, ...restProps }) => {
const handleClick = () => {
if (handle.includes('click')) {
alert(message);
}
};
const handleMouseOver = () => {
if (handle.includes('hover')) {
alert(message);
}
};
return <Button {...restProps} onClick={handleClick} onMouseOver={handleMouseOver} />;
});
const Demo = () => (
<AlertButton handle={['click']} message='Hello world'>
Click me
</AlertButton>
);
export default Demo;
Complex components wrappers
Some components props are generic, for example Select
component has generic value
and DataTable
has generic data
. For such components, special wrapping utilities are provided.
It available for the following components:
wrapDataTable
,wrapDataTableRow
,wrapDataTableCell
for DataTable.wrapAccordion
for Accordion.wrapPills
for Pills.wrapRadioGroup
for Radio.wrapSelect
for Select.wrapSlider
for Slider.wrapTabLine
for TabLine.wrapTabPanel
for TabPanel.wrapWizardStepper
for Wizard.
import React from 'react';
import DataTable, { wrapDataTable } from 'intergalactic/data-table';
import Card from 'intergalactic/card';
const CardDataTable = wrapDataTable<{ title: string }>(({ title, ...restProps }) => {
return (
<Card>
<Card.Header>
<Card.Title>{title}</Card.Title>
</Card.Header>
<Card.Body px={0}>
<DataTable {...restProps} aria-label={'Table title'} />
</Card.Body>
</Card>
);
});
const Demo = () => {
return (
<CardDataTable data={data} title='A table combined with card'>
<DataTable.Head>
<DataTable.Column name='keyword' children='Keyword' />
<DataTable.Column name='kd' children='KD,%' />
<DataTable.Column name='cpc' children='CPC' />
<DataTable.Column name='vol' children='Vol.' />
</DataTable.Head>
<DataTable.Body />
</CardDataTable>
);
};
const data = [
{
keyword: 'ebay buy',
kd: '77.8',
cpc: '$1.25',
vol: '32,500,000',
},
{
keyword: 'www.ebay.com',
kd: '11.2',
cpc: '$3.4',
vol: '65,457,920',
},
{
keyword: 'www.ebay.com',
kd: '10',
cpc: '$0.65',
vol: '47,354,640',
},
];
export default Demo;