Widget
Widget component
A widget is a quick summary view of data from the product. It gives users quick access to a product area and the most recent content in use there, as well as key actions. Widgets are mainly used on the Home page.
Example:
function WidgetExpample() {const [value, setValue] = useState('allreports');const options = [{ value: 'allreports', label: 'All reports' },{ value: 'myreports', label: 'My reports' }];const Filters = () => {return (<SegmentedButtonitems={options}value={value}onChange={(event) => setValue(event.target.value)}/>);};const cta = {label: 'New Report',iconName: 'Plus',onClick: () => console.log(''),id: 'widget-secondary-action-data-testid'};const footerAction = {label: 'Go to reports',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};// WIDGET CONTENTconst columns = [{Header: 'Name',accessor: 'name'},{Header: 'Last modified',accessor: 'lastModified',minWidth: 115,width: 115,align: 'right'}];const data = [{name: 'omatest',lastModified: '01/18/2024'},{name: 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.',lastModified: '12/19/2023'},{name: 'Aydin Hinton',lastModified: '12/19/2023'},{name: 'Raegan Hickman',lastModified: '12/19/2023'},{name: 'Ashley Page',lastModified: '12/19/2023'}];const rowOnClickHandler = (rowData) => {console.log(rowData);};return (<Widgettitle="Reports"cta={cta}secondaryAction={footerAction}filters={<Filters />}data={data}columns={columns}isHoverablerowOnClickHandler={rowOnClickHandler}actionMenu={[{ label: 'Edit', onClick: () => {}, iconName: 'Edit' },{ label: 'Delete', onClick: () => {}, iconName: 'Cross' }]}/>);}
Header
The header part accepts a title, primary action button, and filters.
Title:
You can provide title value with the title
prop. It accepts a string
value.
Cta:
You can provide the call-to-action button using a cta prop. This part uses the Atlas Button component with the primary button
kind.
You can use the following props from the Button in cta prop object:
label
, id (used for providing the custom data-testid)
, iconName
,
onClick
, onMouseEnter
, onMouseLeave
, onFocus
, onBlur
, onKeyDown
, and disabled
Filters:
You can provide a filter set using the filters prop. This part uses the type of ReactNode
that accepts Atlas components like Combobox
, SegmentedButton
etc.
Content
The content part of the Widget uses Atlas Table with limited features. resizing
, header actions
, header groups
, header menu
, nested table
, editable
, sticky
, and dnd
features are disabled here.
You can use the data and columns props as its used in Atlas Table.
Action Menu:
The Action Menu adds the menu for all the rows to the table as a last column item. You can use the actionMenu prop to provide the action menu for the table, as in the examples.
EmptyState:
You can provide an EmptyState instead of the table within the "emptyState" prop used in the example.
Secondary Action
You can provide the secondary-call-to-action button to footer part of the Widget using a secondaryAction prop. This part uses the Atlas Button component with the secondary button
kind.
Examples:
Apps
function WidgetExpample() {const cta = {label: 'New App',iconName: 'Plus',onClick: () => console.log(''),id: 'widget-secondary-action-data-testid'};const footerAction = {label: 'Go to Apps',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};// WIDGET CONTENTconst columns = [{Header: 'Apps',accessor: 'apps',width: 175,minWidth: 100,Cell: () => (<div style={{ display: 'flex', alignItems: 'center' }}><AppIconappId="com.adjust-demo.leardroid"appName="Education - Learn Droid"size="small"/><div style={{marginLeft: Spacing10}}><Icon name="PlatformIosFilled" /><Icon name="PlatformAndroidFilled" /><Icon name="PlatformWindowsFilled" /></div></div>)},{Header: 'Name',accessor: 'name',width: 165}];const data = [{name: 'Pettaculars',lastModified: 'Pettaculars'},{name: 'Get out',lastModified: '12/19/2023'},{name: 'Bottle up',lastModified: '12/19/2023'},{name: 'Bee Garden',lastModified: '12/19/2023'},{name: 'Fly me up',lastModified: '12/19/2023'}];const rowOnClickHandler = (rowData) => {console.log(rowData);};return (<Container><Row><Column xs={12} lg={12}><Widgettitle="Apps"cta={cta}secondaryAction={footerAction}data={data}columns={columns}isHoverablerowOnClickHandler={rowOnClickHandler}actionMenu={[{ label: 'Edit', onClick: () => {}, iconName: 'Edit' },{ label: 'Delete', onClick: () => {}, iconName: 'Cross' }]}/></Column></Row></Container>);}
Pulse
function WidgetExpample() {const cta = {label: 'New Pulse',iconName: 'Plus',onClick: () => console.log(''),id: 'widget-secondary-action-data-testid'};const footerAction = {label: 'Go to Pulse',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};// WIDGET CONTENTconst columns = [{Header: 'Name',accessor: 'name'},{Header: 'Type',accessor: 'type',minWidth: 64,width: 64,Cell: ({ value }) => <Badge color="positive" iconName="Key" />},{Header: 'Frequency',accessor: 'frequency'}];const data = [{name: 'Pettaculars',lastModified: 'Pettaculars',frequency: 'Weekly - Wednesday, 06:00 UTC'},{name: 'Get out',lastModified: '12/19/2023',frequency: 'Weekly - Wednesday, 06:00 UTC'},{name: 'Bottle up',lastModified: '12/19/2023',frequency: 'Weekly - Wednesday, 06:00 UTC'},{name: 'Bee Garden',lastModified: '12/19/2023',frequency: 'Weekly - Wednesday, 06:00 UTC'},{name: 'Fly me up',lastModified: '12/19/2023',frequency: 'Weekly - Wednesday, 06:00 UTC'}];const rowOnClickHandler = (rowData) => {console.log(rowData);};return (<Container><Row><Column xs={12} lg={12}><Widgettitle="Pulse"cta={cta}secondaryAction={footerAction}data={data}columns={columns}isHoverablerowOnClickHandler={rowOnClickHandler}actionMenu={[{ label: 'Edit', onClick: () => {}, iconName: 'Edit' },{ label: 'Delete', onClick: () => {}, iconName: 'Cross' }]}/></Column></Row></Container>);}
Connections
function WidgetExpample() {const cta = {label: 'New Connection',iconName: 'Plus',onClick: () => console.log(''),id: 'widget-secondary-action-data-testid'};const footerAction = {label: 'Go to connections',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};// WIDGET CONTENTconst columns = [{Header: 'Partner',accessor: 'name'},{Header: 'Status',accessor: 'type',minWidth: 64,width: 64,Cell: ({ value }) => <Badge color="positive" iconName="Check" />},{Header: 'Accounts',accessor: 'accounts'}];const data = [{name: 'Facebook',accounts: '3'},{name: 'Twitter',accounts: '3'},{name: 'Apple / Apple Ads',accounts: '3'},{name: 'Google / Google Ads',accounts: '3'},{name: 'Snapchat',accounts: '3'}];const rowOnClickHandler = (rowData) => {console.log(rowData);};return (<Widgettitle="Connections"cta={cta}secondaryAction={footerAction}data={data}columns={columns}isHoverablerowOnClickHandler={rowOnClickHandler}/>);}
Account users
function WidgetExpample() {const cta = {label: 'New user',iconName: 'Plus',onClick: () => console.log(''),id: 'widget-secondary-action-data-testid'};const footerAction = {label: 'Go to account users',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};// WIDGET CONTENTconst columns = [{Header: 'User',accessor: 'name',maxWidth: 200},{Header: 'Role',accessor: 'role',minWidth: 98,width: 98,Cell: ({ value }) => (<Badgecolor={value === 'Admin' ? 'negative' : 'primary'}label={value}/>)}];const data = [{name: 'John Doe',role: 'Admin'},{name: 'Peter Brown',role: 'Admin'},{name: 'Raegan Hickman',role: 'Admin'},{name: 'Mark Spencer',role: 'Admin'},{name: 'Aydin Hinton',role: 'Editor'}];const rowOnClickHandler = (rowData) => {console.log(rowData);};return (<Container><Row><Column xs={12} lg={12}><Widgettitle="Account users"cta={cta}secondaryAction={footerAction}data={data}columns={columns}isHoverablerowOnClickHandler={rowOnClickHandler}actionMenu={[{ label: 'Edit', onClick: () => {}, iconName: 'Edit' },{ label: 'Delete', onClick: () => {}, iconName: 'Cross' }]}/></Column></Row></Container>);}
Action center
function WidgetExpample() {const options = [{ value: 'last30days', label: 'Last 30 days' },{ value: 'lastMonth', label: 'Last Month' }];const footerAction = {label: 'Go to account users',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};// WIDGET CONTENTconst columns = [{Header: 'Action created',accessor: 'date',width: 250},{Header: 'Status',accessor: 'status',maxWidth: 170,Cell: ({ value }) => <Badge color="warning" label={value} size="small" />},{Header: '',accessor: 'actions',maxWidth: 120,align: 'right',Cell: ({ value }) => (<><IconButton iconName="Check" kind="light" aria-label="Approve" /><IconButtoniconName="Cross"kind="light"aria-label="Cancel"css={{ marginLeft: '8px' }}/></>)}];const data = [{date: '01/18/2024',status: 'Pending'},{date: '01/18/2024',status: 'Pending'},{date: '01/18/2024',status: 'Pending'},{date: '01/18/2024',status: 'Pending'},{date: '01/18/2024',status: 'Pending'}];const items = [{label: 'Pending',value: 'pending'},{label: 'Approved',value: 'approved'}];const initialSelectedItems = [{label: 'Pending',value: 'pending'}];const [selectedItems, setSelectedItems] = useState(initialSelectedItems);const rowOnClickHandler = (rowData) => {console.log(rowData);};return (<Container><Row><Column xs={12} lg={12}><Widgettitle="Action center"subTitle="24 pending changes"secondaryAction={footerAction}data={data}columns={columns}isHoverablerowOnClickHandler={rowOnClickHandler}filters={<div style={{ display: 'flex', flexDirection: 'row' }}><ComboBoxoptions={options}placeholder="Last 30 days"css={{ marginRight: '16px' }}/><FilterButtonname="Status"items={items}selectedItems={selectedItems}onApply={setSelectedItems}/></div>}/></Column></Row></Container>);}
Empty State
function WidgetExpample() {const cta = {label: 'New App',iconName: 'Plus',onClick: () => console.log(''),id: 'widget-secondary-action-data-testid'};const footerAction = {label: 'Go to Apps',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};// WIDGET CONTENTconst columns = [{Header: 'Apps',accessor: 'apps',width: 175},{Header: 'Name',accessor: 'name',width: 165}];const data = [{name: 'Pettaculars',lastModified: 'Pettaculars'},{name: 'Get out',lastModified: '12/19/2023'},{name: 'Bottle up',lastModified: '12/19/2023'},{name: 'Bee Garden',lastModified: '12/19/2023'},{name: 'Fly me up',lastModified: '12/19/2023'}];const emptyStateProps = {headLine: 'No apps yet',bodyText: 'When apps are added, you’ll see them here.',background: 'apps',iconKey: 'noData'};const emptyStatePropsAdmin = {headLine: 'Add your first app',bodyText:'Connect a platform, add some events, and integrate the Adjust SDK.',background: 'apps',iconKey: 'noData'};return (<Container><Row><Column xs={12} lg={6}><Widgettitle="Apps"cta={cta}secondaryAction={footerAction}data={[]}columns={[]}emptyState={emptyStatePropsAdmin}/></Column><Column xs={12} lg={6}><Widgettitle="Apps"secondaryAction={footerAction}emptyState={emptyStateProps}/></Column></Row></Container>);}
Grid examples
function WidgetExpample() {const options = [{ value: 'last30days', label: 'Last 30 days' },{ value: 'lastMonth', label: 'Last Month' }];const footerAction = {label: 'Go to account users',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};// WIDGET CONTENTconst columns = [{Header: 'Action created',accessor: 'date'},{Header: 'Status',accessor: 'status',Cell: ({ value }) => <Badge color="warning" label={value} size="small" />},{Header: '',accessor: 'actions',align: 'right',Cell: ({ value }) => (<><IconButton iconName="Check" kind="light" aria-label="Approve" /><IconButton iconName="Cross" kind="light" aria-label="Cancel" /></>)}];const data = [{date: '01/18/2024',status: 'Pending'},{date: '01/18/2024',status: 'Pending'},{date: '01/18/2024',status: 'Pending'},{date: '01/18/2024',status: 'Pending'},{date: '01/18/2024',status: 'Pending'}];const items = [{label: 'Pending',value: 'pending'},{label: 'Approved',value: 'approved'}];const initialSelectedItems = [{label: 'Pending',value: 'pending'}];const [selectedItems, setSelectedItems] = useState(initialSelectedItems);const [value, setValue] = useState('allreports');const optionsReports = [{ value: 'allreports', label: 'All reports' },{ value: 'myreports', label: 'My reports' }];const Filters = () => {return (<SegmentedButtonitems={optionsReports}value={value}onChange={(event) => setValue(event.target.value)}/>);};const ctaReports = {label: 'New Report',iconName: 'Plus',onClick: () => console.log(''),id: 'widget-secondary-action-data-testid'};const footerActionReports = {label: 'Go to reports',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};const columnsReports = [{Header: 'Name',accessor: 'name'},{Header: 'Last modified',accessor: 'lastModified',minWidth: 115,width: 115,align: 'right'}];const dataReports = [{name: 'omatest',lastModified: '01/18/2024'},{name: 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.',lastModified: '12/19/2023'},{name: 'Aydin Hinton',lastModified: '12/19/2023'},{name: 'Raegan Hickman',lastModified: '12/19/2023'},{name: 'Ashley Page',lastModified: '12/19/2023'}];const ctaPulse = {label: 'New Pulse',iconName: 'Plus',onClick: () => console.log(''),id: 'widget-secondary-action-data-testid'};const footerActionPulse = {label: 'Go to Pulse',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};const rowOnClickHandler = (rowData) => {console.log(rowData);};// WIDGET CONTENTconst columnsPulse = [{Header: 'Name',accessor: 'name'},{Header: 'Type',accessor: 'type',minWidth: 64,width: 64,Cell: ({ value }) => <Badge color="positive" iconName="Key" />},{Header: 'Frequency',accessor: 'frequency'}];const dataPulse = [{name: 'Pettaculars',lastModified: 'Pettaculars',frequency: 'Weekly - Wednesday, 06:00 UTC'},{name: 'Get out',lastModified: '12/19/2023',frequency: 'Weekly - Wednesday, 06:00 UTC'},{name: 'Bottle up',lastModified: '12/19/2023',frequency: 'Weekly - Wednesday, 06:00 UTC'},{name: 'Bee Garden',lastModified: '12/19/2023',frequency: 'Weekly - Wednesday, 06:00 UTC'},{name: 'Fly me up',lastModified: '12/19/2023',frequency: 'Weekly - Wednesday, 06:00 UTC'}];const ctaAccount = {label: 'New user',iconName: 'Plus',onClick: () => console.log(''),id: 'widget-secondary-action-data-testid'};const footerActionAccount = {label: 'Go to account users',onClick: () => console.log('secondary action click'),id: 'widget-secondary-action-data-testid'};// WIDGET CONTENTconst columnsAccount = [{Header: 'User',accessor: 'name',maxWidth: 200},{Header: 'Role',accessor: 'role',minWidth: 98,width: 98,Cell: ({ value }) => (<Badgecolor={value === 'Admin' ? 'negative' : 'primary'}iconName="Key"label={value}/>)}];const dataAccount = [{name: 'John Doe',role: 'Admin'},{name: 'Peter Brown',role: 'Admin'},{name: 'Raegan Hickman',role: 'Admin'},{name: 'Mark Spencer',role: 'Admin'},{name: 'Aydin Hinton',role: 'Editor'}];return (<Container><Row><Column xs={12} lg={6}><Widgettitle="Reports"cta={ctaReports}secondaryAction={footerActionReports}filters={<Filters />}data={dataReports}columns={columnsReports}isHoverablerowOnClickHandler={rowOnClickHandler}actionMenu={[{ label: 'Edit', onClick: () => {}, iconName: 'Edit' },{ label: 'Delete', onClick: () => {}, iconName: 'Cross' }]}/></Column><Column xs={12} lg={6}><Widgettitle="Action center"subTitle="24 pending changes"secondaryAction={footerAction}data={data}columns={columns}isHoverablerowOnClickHandler={rowOnClickHandler}filters={<div style={{ display: 'flex', flexDirection: 'row' }}><ComboBoxoptions={options}placeholder="Last 30 days"css={{ marginRight: '16px' }}/><FilterButtonname="Status"items={items}selectedItems={selectedItems}onApply={setSelectedItems}/></div>}/></Column></Row><Row><Column xs={12} lg={12}><Widgettitle="Action center"subTitle="24 pending changes"secondaryAction={footerAction}data={data}columns={columns}isHoverablerowOnClickHandler={rowOnClickHandler}filters={<div style={{ display: 'flex', flexDirection: 'row' }}><ComboBoxoptions={options}placeholder="Last 30 days"css={{ marginRight: '16px' }}/><FilterButtonname="Status"items={items}selectedItems={selectedItems}onApply={setSelectedItems}/></div>}/></Column></Row><Row><Column xs={12} lg={6}><Widgettitle="Account users"cta={ctaAccount}secondaryAction={footerActionAccount}data={dataAccount}columns={columnsAccount}isHoverablerowOnClickHandler={rowOnClickHandler}actionMenu={[{ label: 'Edit', onClick: () => {}, iconName: 'Edit' },{ label: 'Delete', onClick: () => {}, iconName: 'Cross' }]}/></Column><Column xs={12} lg={6}><Widgettitle="Pulse"cta={ctaPulse}secondaryAction={footerActionPulse}data={dataPulse}columns={columnsPulse}isHoverablerowOnClickHandler={rowOnClickHandler}actionMenu={[{ label: 'Edit', onClick: () => {}, iconName: 'Edit' },{ label: 'Delete', onClick: () => {}, iconName: 'Cross' }]}/></Column></Row></Container>);}
Props
Name | Type | Default |
---|---|---|
type * type of accordion |
| — |
data * accordion data |
| — |
bordered makes accordion headers bordered - for list type only |
| — |
disabled makes all accordion items disabled |
| — |
onItemUpdate callback for getting clicked item id, expand status and type (clicked item is custom checkbox or accordion header) |
| — |
selectable makes all items selectable |
| — |
togglePosition toggle button position - for list type only |
| — |
backgroundColor background color of headline |
| — |
data-{foo} Data attributes can be used by testing libraries to retrieve components or assert their existence |
| — |
* - the prop is required. |