Intentwise Primitives
Controls
Interactive filter, selector, and toggle components for dashboard toolbars and settings panels.
FilterSelect
Multi-Select Mode
Select multiple options from a dropdown list. Supports search, select all, and clear.
Selected: None
Show code
<FilterSelect
data={{ label: 'Campaign Type', options: [...], value: [], mode: 'multi' }}
onChange={(value) => setSelected(value)}
searchable
/>Single-Select Mode
Select a single option from a dropdown. Useful for status or category filters.
Selected: active
Show code
<FilterSelect
data={{ label: 'Status', options: [...], value: 'active', mode: 'single' }}
onChange={(value) => setStatus(value)}
/>Loading & Disabled States
FilterSelect supports loading spinners and disabled state.
Show code
<FilterSelect data={...} onChange={...} loading />
<FilterSelect data={...} onChange={...} disabled />FilterBar
FilterBar Layout
Responsive grid container that arranges filter controls in a consistent row. Adapts from 1 column on mobile to 4 on large screens.
Show code
<FilterBar>
<FilterSelect data={campaignType} onChange={...} />
<FilterSelect data={status} onChange={...} />
<FilterSelect data={brand} onChange={...} />
</FilterBar>SegmentedControl
Default Size
Radio-group style toggle for switching between options. Commonly used for time range, view mode, or metric selectors.
Time Range
View Mode
Show code
<SegmentedControl
data={{ options: [{ value: '7d', label: '7D' }, ...], value: '30d' }}
onChange={(value) => setTimeRange(value)}
/>Size Variants
Available in sm and md (default) sizes.
sm
md
Show code
<SegmentedControl data={...} onChange={...} size="sm" />OrgAccountSelector
Organization & Account Selector
Cascading dropdown pair for selecting organization and account. The account dropdown is disabled until an organization is selected. Changing org resets the account.
Org: org-1 | Account: acc-1
Show code
<OrgAccountSelector
data={{ organizations: [...], accounts: [...], selectedOrgId, selectedAccountId }}
onOrgChange={(id) => setOrgId(id)}
onAccountChange={(id) => setAccountId(id)}
/>Loading States
Loading spinners display while data is being fetched from the server.
Show code
<OrgAccountSelector data={...} orgsLoading accountsLoading />Disabled State
Both dropdowns disabled when the component is in disabled state.
Show code
<OrgAccountSelector data={...} disabled />FilterChipBar
FilterChipBar
Chips for applied filters with reset/save. Pass filters, onChange, and filterMenuItems. Returns null when filters.length === 0.
Show code
<FilterChipBar
filters={filters}
onChange={setFilters}
filterMenuItems={[{ value: 'campaign', label: 'Campaign', filterType: 'name' }, ...]}
/>NameFilterDialog
NameFilterDialog
Modal for name-type filters with configurable operator modes: full, select-only, or non-select operators only.
Select-only uses list selection only. Operator-only hides Select and shows text operators.
Show code
<NameFilterDialog
open={open}
onClose={() => setOpen(false)}
onApply={(result) => { ...; setOpen(false); }}
title="Campaign(s)"
options={[{ id, label }, ...]}
showSelectOperator={true}
showNonSelectOperators={true}
/>StatusFilterDialog
StatusFilterDialog
Status selector dialog with configurable single-select (radio) and multi-select (checkbox) modes.
Show code
<StatusFilterDialog
open={open}
onClose={() => setOpen(false)}
onApply={(result) => { ...; setOpen(false); }}
selectionMode="single"
options={[{ id: 'enabled', label: 'Enabled' }]}
/>TableColumnSelector
TableColumnSelector
Panel to show/hide and reorder table columns. open, onOpenChange, onApply(state), columns.
Show code
<TableColumnSelector
columns={[{ id, label, visible }, ...]}
open={open}
onOpenChange={setOpen}
onApply={(state) => setState(state)}
/>FullscreenToggle
FullscreenToggle
Button that fullscreens the element at targetRef. Add FULLSCREEN_TARGET_CLASS to the target for viewport styling.
Show code
<div ref={targetRef} className={FULLSCREEN_TARGET_CLASS}>...</div>
<FullscreenToggle targetRef={targetRef} />DarkModeToggle
DarkModeToggle
Button that toggles light/dark mode. Requires DarkModeProvider from @primitives/context. showLabel, size: sm | md.
Show code
<DarkModeProvider><DarkModeToggle showLabel size="md" /></DarkModeProvider>DateRangePicker
DateRangePicker
Calendar popover for selecting a date range. value, onChange, label, comparison.
Show code
<DateRangePicker value={range} onChange={setRange} label="Date range" />MetricChip
MetricChip
Compact chip for selected metrics with color dot, chart type toggles, and remove action.
Show code
<MetricChip
label="Spend"
color="#4573D2"
type="line"
onTypeChange={(type) => {}}
onRemove={() => {}}
/>MetricsSelector
MetricsSelector
Multi-select for which metrics to show. metrics, value, onChange, max, min.
Show code
<MetricsSelector metrics={[...]} value={value} onChange={setValue} />ExportToolbar
ExportToolbar
Dropdown with PNG and Excel export. containerRef for PNG, onExportExcel for spreadsheet.
Chart or content area for PNG export
Show code
<ExportToolbar containerRef={ref} filename="chart" onExportExcel={() => {}} />Toggle
Toggle
Switch control. checked, onChange, label, disabled.
Show code
<Toggle checked={checked} onChange={setChecked} label="Enable feature" />TimeAggregation
TimeAggregation
Selector for Daily / Weekly / Monthly. value, onChange.
Show code
<TimeAggregation value={value} onChange={setValue} />RollUpSelector
RollUpSelector
Grouping selector. options, value, onChange.
Show code
<RollUpSelector options={[...]} value={value} onChange={setValue} />FrequencySelector
FrequencySelector
Frequency of tracking with Save. title, options, value, onChange, onSave.
Frequency Of Tracking
Show code
<FrequencySelector title="Frequency" options={[...]} value={value} onChange={setValue} onSave={() => {}} />EntitySelector
EntitySelector
Campaign and Ad Group tree selector. campaigns, selectedCampaignIds, selectedAdGroupIds, onChange.
Show code
<EntitySelector campaigns={[...]} onChange={(c, a) => {}} />ViewModeToggle
Chart / Table Switch
Icon toggle for switching between chart and table views. value, onChange, size.
Show code
<ViewModeToggle value={mode} onChange={setMode} />Size Variants & Disabled
Available in sm and md sizes. Can be disabled.
Show code
<ViewModeToggle value="chart" onChange={...} size="sm" />LayoutSelector
Dashboard Layout Picker
Popover with grid thumbnails for choosing dashboard layout. options, value, onChange.
Show code
<LayoutSelector options={layouts} value={layout} onChange={setLayout} />DataLabelsToggle
Data Labels Toggle
Toggle button to show/hide data labels on charts. pressed, onPressedChange, size, disabled.
Show code
<DataLabelsToggle pressed={on} onPressedChange={setOn} />DataExportButton
Data Export Button
Downloads table data as CSV. getData (async), columns, fileName, visibleColumnIds.
Show code
<DataExportButton getData={async () => rows} columns={columns} fileName="export" />TableToolbar
TableToolbar
Generic table toolbar composing column-selector, export, fullscreen, and chart-toggle actions. All slots are optional. Pass exportSlot for custom export buttons with toasts.
Show code
<TableToolbar
featureToolbar={<span className="text-sm text-iw-text-secondary">Custom actions here</span>}
chartToggle={{ showChart, onToggleChart: () => setShowChart(v => !v) }}
showColumnSelector
onColumnSelectorOpen={() => alert('Open column selector')}
showExport
exportProps={{ getData: async () => rows, columns, fileName: 'export' }}
showFullscreen
fullscreenExpanded={fullscreenExpanded}
onFullscreenChange={setFullscreenExpanded}
targetRef={containerRef}
/>Card
Basic Card
Generic surface container with optional header slot.
Simple card content
Card with header slot
Show code
<Card>Content goes here</Card>
<Card header={<span>Header</span>}>With header slot</Card>InputField
Sizes & States
InputField supports sm, md, lg sizes with error, disabled, and readOnly states.
This field is required
Show code
<InputField label="Name" size="md" value={value} onChange={setValue} />
<InputField label="Error" error="Required" value="" onChange={() => {}} />
<InputField label="Disabled" disabled value="Cannot edit" onChange={() => {}} />Button
Primary, Secondary, and Tertiary Buttons
Primary and secondary buttons support optional icons. Tertiary is text-forward for low-emphasis actions.
Show code
<Button variant="primary" startIcon={<Plus />}>New Rule</Button>
<Button variant="secondary">View History</Button>
<Button variant="tertiary">Cancel</Button>SelectField
Select Field
Native select with boxed and underline variants using primitives theme tokens.
Show code
<SelectField value={value} onChange={setValue} label="Target">
<option value="line_items">Line Items</option>
<option value="ad_groups">Ad Groups</option>
</SelectField>CheckboxField
Checkbox Field
Checkbox states aligned to the primitive visual system.
Show code
<CheckboxField checked={checked} onChange={setChecked} label="Enable undo schedule" />RadioField
Radio Field
Radio states aligned to primitive tokens with selected and disabled visuals.
Show code
<RadioField checked={value === 'a'} onChange={(checked) => checked && setValue('a')} />TimeField
Time Field
Time input control with the same primitive visual system as other form controls.
Show code
<TimeField value={value} onChange={setValue} label="Execution Time" />Toast
Toast Notifications
ToastContainer and useToast for success, error, warning, and info messages with primitive theming.
Show code
const { toasts, addToast, removeToast } = useToast();
<ToastContainer toasts={toasts} onRemove={removeToast} />DateTimePicker
Date & Time Picker
Single date-time picker and date-only mode (time disabled), including underline variant.
Datetime: 2026-04-07T14:30:00Z
Date only: 2026-04-07
Show code
<DateTimePicker value={dateTime} onChange={setDateTime} label="Start Date" />
<DateTimePicker value={dateOnly} onChange={setDateOnly} showTime={false} variant="underline" label="Execution Date" />CalendarRangeModal
Calendar Range Modal
Modal calendar for selecting a date range.
Show code
<CalendarRangeModal
isOpen={open}
onClose={() => setOpen(false)}
initialStartDate={start}
initialEndDate={end}
onApply={(s, e) => { setStart(s); setEnd(e); setOpen(false); }}
/>DateRangeSelector
Date Range Selector
Preset dropdown with optional custom range support.
Preset: last7 | Range: 2026-03-31 to 2026-04-07
Show code
<DateRangeSelector
selectedPreset={preset}
onPresetChange={setPreset}
customRange={{ startDate: start, endDate: end }}
onCustomRangeChange={(s, e) => { setStart(s); setEnd(e); }}
/>Accordion
Single Expand
Only one item can be open at a time. Supports badges and disabled items.
Expanded: none
Show code
<Accordion items={items} expanded={expanded} onExpandedChange={setExpanded} />Multiple Expand
Multiple items can be expanded simultaneously.
Show code
<Accordion items={items} allowMultiple />Checkbox
Checkbox States & Sizes
Standalone checkbox with sizes, indeterminate state, and optional label.
sm
md
lg
indeterminate
disabled
Show code
<Checkbox checked={checked} onCheckedChange={setChecked} label="Enable" size="md" />FilterConditionCell
With Conditions
Toggle to show/hide filter criteria. Designed for use inside table cells.
Show code
<FilterConditionCell conditions={[{ fieldLabel: 'Campaign', opLabel: 'is', valueStr: 'SP' }]} />Empty State
Renders an em-dash when no conditions are present.
Show code
<FilterConditionCell conditions={[]} />SearchInput
Search Input
Text input with search icon, optional clear button, and debounce support.
Value: (empty)
Show code
<SearchInput value={value} onChange={setValue} onSearch={handleSearch} debounceMs={300} />SelectableTable
Interactive Selection
Table with checkbox column, header select-all, and sortable columns.
| Campaign | Status | Spend | ROAS | |
|---|---|---|---|---|
| Brand Defence – SP | Active | $1,240.50 | 4.2x | |
| Category Conquest – SB | Active | $890.30 | 3.1x | |
| Retargeting – SD | Paused | $320.00 | 2.8x | |
| New Launch – SP | Active | $2,100.75 | 5.6x | |
| Competitor ASIN – SP | Ended | $450.20 | 1.9x |
0 of 5 selected
Show code
<SelectableTable columns={cols} rows={rows} rowIdField="id"
selectedIds={selectedIds} onSelectionChange={setSelectedIds} />Loading State
Shows loading overlay while data is being fetched.
| Campaign | Status | Spend | ROAS | |
|---|---|---|---|---|
| Loading... | ||||
Show code
<SelectableTable loading columns={cols} rows={[]} ... />TransparentCard
Transparent vs Regular Card
TransparentCard removes border, background, and shadow from the base Card component.
Has border, background, and shadow.
No border, no background, no shadow.
Show code
<Card header="Regular">content</Card>
<TransparentCard header="Transparent">content</TransparentCard>TreeSelect
Basic Tree
Two-level checkbox tree with parent indeterminate states and selection counts.
Selected: none
Show code
<TreeSelect items={items} selectedIds={selectedIds} onSelectionChange={setSelectedIds} />With Search
Searchable mode filters both parent and child labels.
Show code
<TreeSelect items={items} selectedIds={selectedIds} onSelectionChange={setSelectedIds} searchable />RadioGroup
Horizontal Orientation
Inline radio group for simple binary or small-set choices (e.g. Include/Exclude targeting).
Selected: include
Show code
<RadioGroup
options={[{ value: 'include', label: 'Include' }, { value: 'exclude', label: 'Exclude' }]}
value={value}
onChange={setValue}
orientation="horizontal"
/>Vertical Orientation
Stacked radio group for longer option lists (e.g. bid edit type selector).
Selected: new-bid
Show code
<RadioGroup
options={[{ value: 'new-bid', label: 'Set New Bid' }, ...]}
value={value}
onChange={setValue}
orientation="vertical"
/>Disabled States
Individual options or the entire group can be disabled.
Single option disabled
Entire group disabled
Show code
<RadioGroup options={[...]} value="active" disabled />IWDialog
Default Dialog
Modal dialog with header (auto close button), scrollable body, and footer with action buttons.
Show code
<IWDialog isOpen={open} onClose={() => setOpen(false)}>
<IWDialogHeader title="Edit Line Item" />
<IWDialogBody>...</IWDialogBody>
<IWDialogFooter>
<Button variant="secondary" onClick={onClose}>Cancel</Button>
<Button variant="primary" onClick={onSave}>Save</Button>
</IWDialogFooter>
</IWDialog>Branded Header
Use variant='branded' for a primary-colored header (e.g. bulk edit confirmation).
Show code
<IWDialogHeader title="Bulk Update" variant="branded" />Size Variants
Sizes: sm (400px), md (560px), lg (760px), xl (960px), full (95vw).
Show code
<IWDialog isOpen={open} onClose={onClose} size="xl">...</IWDialog>IWDrawer
Right Drawer (default)
Slide-in panel from the right edge. Supports header, scrollable body, and footer.
Show code
<IWDrawer isOpen={open} onClose={() => setOpen(false)}>
<IWDrawerHeader title="Settings" />
<IWDrawerBody>...</IWDrawerBody>
<IWDrawerFooter>
<Button variant="primary" onClick={onClose}>Apply</Button>
</IWDrawerFooter>
</IWDrawer>Left Drawer
Slides in from the left edge. Useful for navigation or filter panels.
Show code
<IWDrawer isOpen={open} onClose={onClose} position="left" width="20rem">...</IWDrawer>MetricFilterDialog
Number Filter
Filter by numeric metrics with operators: equal, less than, greater than, between, etc.
Show code
<MetricFilterDialog
open={open}
onClose={() => setOpen(false)}
title="Filter by Impressions"
filterType="number"
onApply={(result) => console.log(result)}
/>Text Filter
Filter by text with operators: equals, contains, does not contain, not equals.
Show code
<MetricFilterDialog
open={open}
onClose={() => setOpen(false)}
title="Filter by Campaign Name"
filterType="text"
onApply={(result) => console.log(result)}
/>