@telicent-oss/ds 4.2.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/llms.txt ADDED
@@ -0,0 +1,1009 @@
1
+ # Telicent DS Component Manifest
2
+
3
+ **VERSION:** This file documents @telicent-oss/ds v4.4.0. It shipped inside that package, so it matches the version installed in your project. If that package was built locally rather than installed from npm, the code may be newer than v4.4.0.
4
+
5
+ > `@telicent-oss/ds` is Telicent's MUI-based React component library. This file is the complete, self-contained reference: setup, theming, every exported component, and copy-paste recipes. An agent that fetches it has what it needs to build a Telicent app UI without reading the source.
6
+
7
+ **AGENT INSTRUCTION:** This is your source of truth for UI components. Before writing any custom JSX or Tailwind classes for a visual element, you MUST find the closest match in this document.
8
+ - All components are imported directly from `@telicent-oss/ds`. (e.g., `import { Button, Card } from "@telicent-oss/ds";`)
9
+ - **Do not** write raw HTML (`<button>`, `<div>` for cards, `<input>`) if a component exists here.
10
+ - **Do not** use Tailwind for colors, borders, or shadows on these components; the theme controls them. Set colour through the theme palette (see Setup & Theming). Use Tailwind primarily for spacing (`gap-X`, `mt-X`) and sizing.
11
+
12
+ > Component names, props, and demonstrated states are generated from the `@telicent-oss/ds` type surface and stories, so they track the source. Setup, theming, and usage guidance are maintained by hand: reviewed against the source for v3.0.0, but not auto-checked on every build.
13
+
14
+ ---
15
+
16
+ ## Setup & Theming
17
+
18
+ Install:
19
+ ```sh
20
+ npm install @telicent-oss/ds
21
+ ```
22
+
23
+ Peer dependencies the consuming app must also install: `react@^19`, `react-dom@^19`, `@tanstack/react-query`, `@telicent-oss/ontologyservice@^1`, `axios`.
24
+
25
+ Import the styles once at the app entry. FontAwesome icons render only if the second file is loaded:
26
+ ```ts
27
+ import "@telicent-oss/ds/dist/style.css";
28
+ import "@telicent-oss/ds/dist/fontawesome.css";
29
+ ```
30
+
31
+ Wrap the app in `UIThemeProvider`. It supplies the MUI theme and `CssBaseline` internally — do not add your own `ThemeProvider` or `CssBaseline`.
32
+ ```tsx
33
+ import { UIThemeProvider } from "@telicent-oss/ds";
34
+
35
+ <UIThemeProvider theme="DataNavy" dark={false}>
36
+ <App />
37
+ </UIThemeProvider>
38
+ ```
39
+ - `theme` (required): one of `"DataNavy"`, `"DocumentPink"`, `"GraphOrange"`, `"AdminBlue"`, `"Blank"`.
40
+ - `dark` (optional, default `false`): set it for the dark palette. Dark mode is this prop only — there is no runtime toggle or CSS class.
41
+
42
+ Read theme colours and tokens in app code with the `useExtendedTheme` hook. This is the sanctioned way to set a colour — use it instead of a Tailwind colour class:
43
+ ```tsx
44
+ import { useExtendedTheme } from "@telicent-oss/ds";
45
+
46
+ const theme = useExtendedTheme();
47
+ // theme.palette.primary.main, theme.palette.tertiary.main, theme.palette.background.default
48
+ ```
49
+ Palette keys include `primary`, `tertiary`, `text`, and `background`.
50
+
51
+ > Auth (`useAuth`, `AuthProvider`, `AuthContext`, `AuthRedirectUri`, `Callback`, and the `authorize-flow` utilities) is exported from `@telicent-oss/ds` and used by most Telicent apps, but it is out of scope for this UI component reference. See `src/utils/authorize-flow` in the source.
52
+
53
+ > Geospatial map components (`BasicMapV2`, `MapCanvasV2`, `LayerSelectorV2`, and the zoom and toggle controls) are exported from `@telicent-oss/ds` and used by telicent-search and telicent-graph, but they are out of scope for this general UI component reference. See `src/feature-components/Map/v2` in the source. The v1 components were removed in 4.0.0.
54
+
55
+ ---
56
+
57
+ ## 1. Buttons & Actions
58
+ *Use these instead of standard `<button>` tags. There is one `Button` component; the visual style is a `variant` prop, not a separate component per style.*
59
+ * **`Button`**: The standard button. Set emphasis with `variant`:
60
+ * `variant="primary"` — main call-to-action on a page or form.
61
+ * `variant="secondary"` — alternative actions (e.g. "Cancel", "Back").
62
+ * `variant="tertiary"` — low-emphasis, neutral-colour actions.
63
+ * `variant="text"` — text-only clickable actions (no background).
64
+ * `variant="base"` — unstyled button base.
65
+ * Size via `size="small" | "medium" | "large"` (default `medium`).
66
+ * `onClick`, `type`, `disabled`, `startIcon`, `endIcon` pass through to MUI Button. There is **no `loading` prop** — show a pending state with `disabled` plus a label change, or an inline `<Spinner size={16} />` (see Recipes).
67
+ ```yaml
68
+ Button:
69
+ variant: {type: '"base" | "text" | "primary" | "secondary" | "tertiary"', required: false}
70
+ ```
71
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/buttons-button--docs
72
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/buttons/Button/Button.stories.tsx
73
+ Default args: children="Button", variant="primary"
74
+
75
+ Demonstrated states:
76
+ - Primary — variant="primary"
77
+ - Secondary — variant="secondary"
78
+ - Tertiary — variant="tertiary"
79
+ - Text — variant="text"
80
+ - Base — variant="base"
81
+ - Sizes
82
+ - StartIcon
83
+ - EndIcon
84
+ - FullWidth
85
+ - SXOverrides
86
+ * **`IconButton`**: Use when a button only contains an Icon. Should include an `aria-label`.
87
+ * **`DropdownButton`**: Use for buttons that trigger a menu of options. (This is also the menu primitive — there is no standalone `Menu` export.)
88
+ ```yaml
89
+ DropdownButton:
90
+ ariaLabel: {type: 'string', required: true}
91
+ id: {type: 'string', required: true}
92
+ menuItems: {type: 'DropDownButtonMenuItemProps[]', required: true}
93
+ ```
94
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/navigation-menu--docs
95
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/Navigation/Menu/Menu.stories.tsx
96
+
97
+ Demonstrated states:
98
+ - Default — "aria-label"="menu", menuId="menu-default", options=[…]
99
+ - WithIconsAndDisabled — "aria-label"="menu with icons", menuId="menu-icons", options=[…]
100
+ - LinkNavigation — "aria-label"="navigation menu", menuId="menu-links", options=[…]
101
+ - WithDividerAndOnSelect — "aria-label"="menu with divider", menuId="menu-divider", options=[…]
102
+ - WithSelected — "aria-label"="menu with selected item", menuId="menu-selected", options=[…]
103
+ * **`TooltipToggleButton`**: Toggle actions that require hover context.
104
+ ```yaml
105
+ TooltipToggleButton:
106
+ tooltip: {type: 'string', required: false}
107
+ ```
108
+ * **`CopyToClipboard`**: Utility component specifically for copy-to-clipboard actions.
109
+ ```yaml
110
+ CopyToClipboard:
111
+ ariaLabel: {type: 'string', required: false}
112
+ style: {type: 'React.CSSProperties & String', required: false}
113
+ successMsg: {type: 'string', required: false}
114
+ testFailure: {type: 'boolean', required: false}
115
+ text: {type: 'string', required: true}
116
+ variant: {type: '"base" | "text" | "primary" | "secondary" | "tertiary"', required: false}
117
+ ```
118
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/buttons-copytoclipboard--docs
119
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/buttons/CopyToClipboard/CopyToClipboard.stories.tsx
120
+
121
+ Demonstrated states:
122
+ - Default — text="this is a default example string", ariaLabel="Copy to clipboard button"
123
+ - CustomSuccessMessage — text="Hooray!", successMsg="Hooray!!"
124
+ - CustomStyle — text="Text for clipboard via WithCustomStyle", ariaLabel="Copy to clipboard button with white color", sx={…}
125
+ - Error — testFailure=true, text="This will fail"
126
+ * **`Link`**: Use for navigation links. (There is no `LinkButton`; for a link that should read as a link, use `Link`; for a link-styled action, use `Button variant="text"`.)
127
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/buttons-link--docs
128
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/buttons/Link/Link.stories.tsx
129
+
130
+ Demonstrated states:
131
+ - Default
132
+ - Disabled
133
+
134
+ ## 2. Layout & Surfaces
135
+ *Use these to group content. Avoid writing custom `div` structures with manual padding/borders.*
136
+ * **`FlexBox`**: The main layout primitive (wraps MUI `Stack`), used more than any other component. Props: `direction="row" | "column"`, `spacing`, `gap` / `columnGap` / `rowGap`, `justifyContent`, `alignItems`, plus any MUI sx system prop.
137
+ * **`FlexGrid` / `FlexGridItem`**: 12-column grid (wrap MUI `Grid`). `FlexGrid` is the container, `FlexGridItem` the child slot; props pass through to MUI Grid (`spacing`, `columns`, breakpoint sizes).
138
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/component-library-flexgrid--docs
139
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/layout/FlexGrid.stories.tsx
140
+
141
+ Demonstrated states:
142
+ - BasicColumns
143
+ - Rows
144
+ - MainDetailLayout
145
+ * **`Container`**: Use to wrap page content and restrict maximum width.
146
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/layout-container--docs
147
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/layout/Container/Container.stories.tsx
148
+
149
+ Demonstrated states:
150
+ - Basic
151
+ * **`Brand`**: Telicent brand mark component for use in headers and identity contexts.
152
+ ```yaml
153
+ Brand:
154
+ appName: {type: 'string', required: false}
155
+ beta: {type: 'boolean', required: false}
156
+ size: {type: '"base" | "jumbo"', required: false}
157
+ ```
158
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/brand-brand--docs
159
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/Brand/Brand.stories.tsx
160
+ Default args: appName="Graph", beta=false, size="base"
161
+
162
+ Demonstrated states:
163
+ - Default
164
+ - WithBeta — beta=true
165
+ - Jumbo — size="jumbo", beta=true
166
+ - WithoutAppName
167
+ - AsLink — href="https://telicent.io", target="_blank", rel="noreferrer", beta=true
168
+ - OnDarkBackground — appName="Admin", beta=true
169
+ * **`Card`**: The primary container for distinct data entities.
170
+ * *Composition:* Usually composed with `CardContent` (for data) and `CardActions` (for buttons). A `CardHeader` export also exists (passes through to MUI CardHeader), though most apps omit it and put the title inside `CardContent`.
171
+ * *Props:* `maxWidth` is a DS-specific prop; other props pass through to MUI Card (e.g. `variant="outlined"`).
172
+ ```yaml
173
+ Card:
174
+ maxWidth: {type: 'Property.MaxWidth<string | number>', required: false}
175
+ ```
176
+ ```yaml
177
+ CardContent:
178
+ sx: {type: 'SxProps<Theme>', required: false}
179
+ ```
180
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/surfaces-card--docs
181
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/surfaces/Card/Card.stories.tsx
182
+
183
+ Demonstrated states:
184
+ - OutlinedCard — variant="outlined"
185
+ * **`Paper`**: A basic elevated surface background without the strict structure of a Card.
186
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/surfaces-paper--docs
187
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/surfaces/Paper/Paper.stories.tsx
188
+
189
+ Demonstrated states:
190
+ - Demo
191
+ * **`Accordion` / `AccordionSummary` / `AccordionDetails`**: Collapsible surface. DS bakes `elevation={0}`, `disableGutters`, transparent background, hidden top divider, and a default `expandIcon` on `AccordionSummary` — a plain `<Accordion><AccordionSummary>label</AccordionSummary><AccordionDetails>body</AccordionDetails></Accordion>` renders the DS shape with no `sx`. Padding on Summary/Details is deliberately left per-callsite. Prefer `Card` when the group is a distinct data entity with actions.
192
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/surfaces-accordion--docs
193
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/surfaces/Accordion/Accordion.stories.tsx
194
+
195
+ Demonstrated states:
196
+ - Default
197
+ - StartsExpanded
198
+ - CustomExpandIcon
199
+ - FlushLeftPadding
200
+ - AdjacentAccordions
201
+ - WithGutter
202
+ - OverriddenStyles
203
+ - Disabled
204
+ * **`PopOver`**: Use for tooltip-style overlays and contextual pop-up content.
205
+ ```yaml
206
+ PopOver:
207
+ anchorEl: {type: 'Element | (() => Element) | PopoverVirtualElement | (() => PopoverVirtualElement)', required: false}
208
+ anchorOrigin: {type: 'PopoverOrigin', required: false}
209
+ anchorPosition: {type: 'PopoverPosition', required: false}
210
+ anchorReference: {type: 'PopoverReference', required: false}
211
+ children: {type: 'React.ReactNode', required: false}
212
+ hideCloseButton: {type: 'boolean', required: false}
213
+ onClose: {type: '((event: {}, reason: "backdropClick" | "escapeKeyDown" | "closeButtonClick") => void)', required: true}
214
+ open: {type: 'boolean', required: true}
215
+ transformOrigin: {type: 'PopoverOrigin', required: false}
216
+ width: {type: 'number', required: false}
217
+ ```
218
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/surfaces-popover--docs
219
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/surfaces/PopOver/PopOver.stories.tsx
220
+
221
+ Demonstrated states:
222
+ - Default — open=false
223
+ - WithWidth — open=false, width=320
224
+ - AsUserMenu — open=false
225
+ - AnchorPosition — open=false
226
+ * **`FixedPanel` / `FloatingPanel`**: Use for sidebars, property panels, or tool windows.
227
+ * `FloatingPanel` exposes three sub-components: `FloatingPanel.DraggablePanel`, `FloatingPanel.Provider`, and `FloatingPanel.ToggleButton`.
228
+ * `DraggableFloatingPanel` is the same component as `FloatingPanel.DraggablePanel`, exported directly. Use the named export for a standalone draggable panel; use the `FloatingPanel.*` namespace when you also need `.Provider` / `.ToggleButton` (also exported flat as `FloatingPanelProvider` and `FloatingPanelToggleButton`).
229
+ ```yaml
230
+ DraggableFloatingPanel:
231
+ bounds: {type: 'string | Element', required: false}
232
+ children: {type: 'React.ReactNode', required: false}
233
+ count: {type: 'number', required: false}
234
+ defaultPosition: {type: '{ x: number; y: number; }', required: false}
235
+ dragHandleClassName: {type: 'string', required: false}
236
+ iconBeforeTitle: {type: 'React.ReactNode', required: false}
237
+ menu: {type: 'any', required: false}
238
+ targetId: {type: 'string', required: true}
239
+ title: {type: 'string', required: true}
240
+ ```
241
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/surfaces-fixedpanel--docs
242
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/surfaces/FixedPanel/FixedPanel.stories.tsx
243
+
244
+ Demonstrated states:
245
+ - Demo — count=3, iconBeforeTitle=<jsx>, title="Nodes with geo data", targetId="map"
246
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/surfaces-floatingpanel-floatingpanel-draggablepanel--docs
247
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/surfaces/FloatingPanel/DraggableFloatingPanel.stories.tsx
248
+
249
+ Demonstrated states:
250
+ - ResizeBaseline — bounds="parent", title="Resize baseline", targetId="map", iconBeforeTitle=<jsx>
251
+ * **`Drawer`**: Collapsible side panel with a built-in toggle tab. `children` is the panel content; `drawerWidth` sets its open width; `initialOpen` sets the starting state; `onVisibilityChange(open)` and `onToggle` report toggles. Style the surface with `PaperProps` / `PaperSx`.
252
+ ```yaml
253
+ Drawer:
254
+ children: {type: 'React.ReactNode', required: true}
255
+ drawerWidth: {type: 'number', required: false}
256
+ id: {type: 'string', required: false}
257
+ initialOpen: {type: 'boolean', required: false}
258
+ onToggle: {type: 'React.MouseEventHandler<HTMLButtonElement>', required: false}
259
+ onVisibilityChange: {type: '(open: boolean) => void', required: false}
260
+ PaperProps: {type: 'Partial<PaperProps<React.ElementType<any, keyof React.JSX.IntrinsicElements>>>', required: false}
261
+ PaperSx: {type: 'SxProps<Theme>', required: false}
262
+ ```
263
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/component-library-drawer--docs
264
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/feature-components/Drawer/composites/Drawer.stories.tsx
265
+
266
+ Demonstrated states:
267
+ - Default — children=<jsx>
268
+ - CustomWidth — drawerWidth=200, PaperSx={…}
269
+ - PresentationalAndHook
270
+ - ImperativeApi
271
+ * **`AppBar` / `Toolbar` / `AppChrome`**: Use strictly for top-level application navigation and headers. `AppChrome` is the app shell; pair it with `AppSwitch` for cross-app navigation.
272
+
273
+ Application header — blessed method. Render the top-level chrome of a standalone app with `AppBar` and fill every chrome slot; do not ship the title-only form. Canonical composition:
274
+
275
+ ```tsx
276
+ <AppBar
277
+ appName={config.appNameForHumans} // title, from config — never hardcode
278
+ isElevated // shadow under the bar
279
+ startChild={<AppSwitch apps={config.APP_SWITCH_LIBRARY} />} // cross-app switcher
280
+ endChild={<UserProfile />} // user menu + sign-out (common fill)
281
+ />
282
+ ```
283
+
284
+ Required: `appName` (read from config, never hardcoded), `isElevated`, and both chrome slots filled — `startChild` with `AppSwitch` for cross-app navigation, `endChild` with a user affordance. `endChild` accepts any `ReactNode` within reason; `<UserProfile />` (user menu + sign-out) is the common choice, demonstrated by the `UsageExample` story (Surfaces/AppBar). Optional: `href` / `target` make the centered brand a link to the app root (see the `ClickableBrand` story); `beta` / `version` annotate the title; `disableBrand` drops the Telicent logo only when an app supplies its own brand via `startChild`; `position` defaults to page flow, set `sticky` only when the bar must stay visible on scroll. Anti-pattern: `<AppBar appName="X" />` — a title-only bar has no app-switcher and no user affordance, renders flat, and makes the app feel detached from the suite (this is the `Default` story).
285
+ ```yaml
286
+ AppBar:
287
+ appName: {type: 'string', required: false}
288
+ beta: {type: 'boolean', required: false}
289
+ disableBrand: {type: 'boolean', required: false}
290
+ endChild: {type: 'React.ReactNode', required: false}
291
+ href: {type: 'string', required: false}
292
+ isElevated: {type: 'boolean', required: false}
293
+ position: {type: '"fixed" | "absolute" | "sticky" | "static" | "relative"', required: false}
294
+ startChild: {type: 'React.ReactNode', required: false}
295
+ target: {type: 'React.HTMLAttributeAnchorTarget', required: false}
296
+ version: {type: 'string', required: false}
297
+ ```
298
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/surfaces-appbar--docs
299
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/surfaces/AppBar/AppBar.stories.tsx
300
+
301
+ Demonstrated states:
302
+ - Default
303
+ - WithSignOutButton — appName="Catalogue"
304
+ - WithNoBrand — disableBrand=true, startChild=<jsx>, endChild=UserProfileExample
305
+ - ClickableBrand — appName="Catalogue", href="https://telicent.io", target="_blank"
306
+ - StandardHeader — appName="Catalogue", isElevated=true, startChild=<jsx>
307
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/surfaces-toolbar--docs
308
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/surfaces/Toolbar/Toolbar.stories.tsx
309
+
310
+ Demonstrated states:
311
+ - Example
312
+
313
+ * **`Tabs` / `Tab` / `TabPanel`**: Switch between views of the same region. Give `Tabs` an `idPrefix` and an accessible name (the type requires one of `aria-label` / `aria-labelledby`), give each `Tab` an explicit `value`, and repeat the same `idPrefix` on each `TabPanel` — the DS derives every `id`, `aria-controls`, and `aria-labelledby` from those two things, so there is no `a11yProps` helper to write. Panels unmount their children when hidden; pass `keepMounted` to preserve form state across switches. The divider under the tab bar comes from the theme — do not wrap `Tabs` in a bordered `Box`. Padding inside a panel is yours to set. Pass `pill` for the Telicent pill treatment (same shape as `ToggleButtonGroup`'s pill); the tablist role, roving tabindex and derived ids are unchanged.
314
+ ```yaml
315
+ Tabs:
316
+ 'aria-label': {type: 'string', required: false}
317
+ 'aria-labelledby': {type: 'string', required: false}
318
+ idPrefix: {type: 'string', required: true}
319
+ pill: {type: 'boolean', required: false}
320
+ ```
321
+ ```yaml
322
+ Tab:
323
+ value: {type: 'TabValue', required: true}
324
+ ```
325
+ ```yaml
326
+ TabPanel:
327
+ activeValue: {type: 'TabValue', required: true}
328
+ idPrefix: {type: 'string', required: true}
329
+ keepMounted: {type: 'boolean', required: false}
330
+ value: {type: 'TabValue', required: true}
331
+ ```
332
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/navigation-tabs--docs
333
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/Navigation/Tabs/Tabs.stories.tsx
334
+
335
+ Demonstrated states:
336
+ - Default
337
+ - WithLabelledBy
338
+ - Vertical
339
+ - Scrollable
340
+ - WithIcons
341
+ - KeepMounted
342
+ - Pill
343
+
344
+ ## 3. Inputs & Forms
345
+ *Use these instead of standard `<input>`, `<select>`, or `<textarea>` tags. Ensure accessibility labels are passed.*
346
+ * **`TextField`**: Standard text input (wraps MUI TextField). Set the caption with `label`; use `value`/`onChange` as usual; DS adds `errorText` for an inline error message. Other props pass through to MUI TextField.
347
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-textfield--docs
348
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/TextField/TextField.stories.tsx
349
+
350
+ Demonstrated states:
351
+ - Default — label="Full Name", placeholder="Enter your name", error=false, errorText="This field is required"
352
+ - MultiLine — label="Multiline Input", placeholder="type anything that needs a lot of space in here", error=false, multiline=true, rows=10
353
+ - HelperText
354
+ - ErrorMessage — label="Title", error=true, errorText="Something went wrong, please try again."
355
+ * **`EditableTextField`**: Use for inline-editing scenarios (e.g., clicking a title to rename it).
356
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-editable-textfield--docs
357
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/EditableTextField/EditableTextField.stories.tsx
358
+
359
+ Demonstrated states:
360
+ - Basic
361
+ - FullWidth
362
+ - CustomWidth
363
+ - WithErrorText
364
+ - NoInitialValue
365
+ * **`SearchBox` / `MiniSearchBox`**: Use specifically for search inputs.
366
+ ```yaml
367
+ SearchBox:
368
+ autoFocus: {type: 'boolean', required: false}
369
+ inputRef: {type: 'React.ForwardedRef<HTMLInputElement>', required: false}
370
+ name: {type: 'string', required: false}
371
+ onBlur: {type: '(event: React.FocusEvent<HTMLInputElement>) => void', required: false}
372
+ onChange: {type: '(event: React.ChangeEvent<HTMLInputElement>) => void', required: false}
373
+ onSearch: {type: '(event: React.SubmitEvent<HTMLFormElement>) => void', required: false}
374
+ placeholder: {type: 'string', required: false}
375
+ sx: {type: 'SxProps', required: false}
376
+ value: {type: 'Value', required: false}
377
+ width: {type: 'number', required: false}
378
+ ```
379
+ ```yaml
380
+ MiniSearchBox:
381
+ autoFocus: {type: 'boolean', required: false}
382
+ disabled: {type: 'boolean', required: false}
383
+ endIcon: {type: 'React.ReactNode', required: false}
384
+ error: {type: 'boolean', required: false}
385
+ fullWidth: {type: 'boolean', required: false}
386
+ helperText: {type: 'string', required: false}
387
+ id: {type: 'string', required: false}
388
+ inputRef: {type: 'React.Ref<any>', required: false}
389
+ loading: {type: 'boolean', required: false}
390
+ maxRows: {type: 'string | number', required: false}
391
+ minRows: {type: 'string | number', required: false}
392
+ multiline: {type: 'boolean', required: false}
393
+ name: {type: 'string', required: false}
394
+ onBlur: {type: 'React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>', required: false}
395
+ onChange: {type: 'React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement, Element>', required: false}
396
+ onFocus: {type: 'React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>', required: false}
397
+ onInvalid: {type: 'React.FormEventHandler<HTMLInputElement | HTMLTextAreaElement>', required: false}
398
+ onKeyDown: {type: 'React.KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>', required: false}
399
+ onKeyUp: {type: 'React.KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>', required: false}
400
+ onSearch: {type: 'React.MouseEventHandler<HTMLButtonElement>', required: false}
401
+ onTogglePopOver: {type: 'React.MouseEventHandler<HTMLButtonElement>', required: false}
402
+ placeholder: {type: 'string', required: false}
403
+ progressProps: {type: 'ProgressProps', required: false}
404
+ rows: {type: 'string | number', required: false}
405
+ value: {type: 'unknown', required: false}
406
+ ```
407
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-search-minisearchbox--docs
408
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/SearchBox/MiniSearchBox.stories.tsx
409
+
410
+ Demonstrated states:
411
+ - Demo — placeholder="Search"
412
+ - WithDownArrow — placeholder="Search"
413
+ - Loading — placeholder="Loading", loading=true
414
+ * **`Autocomplete` / `MiniSearchAutocomplete`**: Use when search requires type-ahead dropdown suggestions.
415
+ ```yaml
416
+ MiniSearchAutocomplete:
417
+ disabled: {type: 'boolean', required: false}
418
+ endIcon: {type: 'React.ReactNode', required: false}
419
+ error: {type: 'boolean', required: false}
420
+ id: {type: 'string', required: false}
421
+ loading: {type: 'boolean', required: false}
422
+ name: {type: 'string', required: false}
423
+ onKeyDown: {type: 'React.KeyboardEventHandler<HTMLInputElement>', required: false}
424
+ onSearch: {type: 'React.MouseEventHandler<HTMLElement>', required: false}
425
+ placeholder: {type: 'string', required: false}
426
+ progressProps: {type: 'ProgressProps', required: false}
427
+ renderOption: {type: '(props: React.HTMLAttributes<HTMLLIElement> & { key: any; }, option: Value) => React.ReactNode', required: false}
428
+ ```
429
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-autocomplete--docs
430
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/Autocomplete/Autocomplete.stories.tsx
431
+
432
+ Demonstrated states:
433
+ - Basic
434
+ - Preselected
435
+ - WithHelperText
436
+ - Disabled
437
+ - AsyncLoading
438
+ - StoresIdInFormState
439
+ - MultiSelectWithLimit
440
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-search-minisearchautocomplete--docs
441
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/SearchBox/MiniSearchAutocomplete.stories.tsx
442
+
443
+ Demonstrated states:
444
+ - RecentSearches — options=[…], placeholder="Search"
445
+ - SearchResults — options=[…]
446
+ * **`SearchAutocompleteDialog`**: Full-screen dialog combining search input with autocomplete. Composes with `RecentSearches` (renders recent search history) and `SearchResults` (renders the results list).
447
+ ```yaml
448
+ SearchAutocompleteDialog:
449
+ autoFocus: {type: 'boolean', required: false}
450
+ autoHighlight: {type: 'boolean', required: false}
451
+ children: {type: 'React.ReactNode', required: true}
452
+ error: {type: 'boolean', required: false}
453
+ getOptionKey: {type: '(option: string | SearchOption) => string | number', required: false}
454
+ getOptionLabel: {type: '(option: string | SearchOption) => string', required: false}
455
+ helperText: {type: 'string', required: false}
456
+ id: {type: 'string', required: false}
457
+ inputValue: {type: 'string', required: false}
458
+ isOptionEqualToValue: {type: '(option: SearchOption, value: SearchOption) => boolean', required: false}
459
+ label: {type: 'string', required: false}
460
+ loading: {type: 'boolean', required: false}
461
+ loadingText: {type: 'React.ReactNode', required: false}
462
+ name: {type: 'string', required: false}
463
+ onChange: {type: '(event: React.SyntheticEvent, value: string | SearchOption, reason: AutocompleteChangeReason, details?: ...', required: false}
464
+ onClose: {type: '(event: {}, reason: "backdropClick" | "escapeKeyDown") => void', required: false}
465
+ onInputChange: {type: '(event: React.SyntheticEvent, value: string, reason: AutocompleteInputChangeReason) => void', required: false}
466
+ open: {type: 'boolean', required: true}
467
+ openOnFocus: {type: 'boolean', required: false}
468
+ options: {type: 'readonly SearchOption[]', required: true}
469
+ placeholder: {type: 'string', required: false}
470
+ width: {type: 'number', required: false}
471
+ ```
472
+ * **`Select`**: Standard dropdown (wraps MUI Select). Supply choices via the `options` prop — an array of `{ value, label }`, **not** `<MenuItem>` children. Use `value`/`onChange`/`label` as usual; optional `width`, `helperText`.
473
+ ```yaml
474
+ Select:
475
+ footer: {type: 'React.ReactNode | ((args: SelectFooterArgs) => React.ReactNode)', required: false}
476
+ helperText: {type: 'React.ReactNode', required: false}
477
+ options: {type: 'Options[]', required: true}
478
+ renderOption: {type: '(option: Options) => React.ReactNode', required: false}
479
+ width: {type: 'string | number', required: false}
480
+ ```
481
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-select--docs
482
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/Select/Select.stories.tsx
483
+
484
+ Demonstrated states:
485
+ - Default — label="Select an option", value="option1", id="select-disabled", options=OPTIONS, width=300
486
+ - Disabled — label="Select an option", value="none", id="select-disabled", options=OPTIONS, width=300, disabled=true
487
+ - WithCustomWidth — label="Select an option", value="option2", id="select-disabled", options=OPTIONS, width=500
488
+ - WithNoLabel — value="option2", id="select-disabled", options=OPTIONS
489
+ - ExampleWithOnChange — width=250, disabled=false
490
+ - WithRenderOption — label="Resource type", value="dataset", width=320, options=RESOURCE_TYPE_OPTIONS
491
+ - WithFooter — label="Owner", value="mcga", width=300, options=OWNER_OPTIONS
492
+ * **`Checkbox`**: Boolean or multi-select input (wraps MUI Checkbox). `label` renders the caption; `checked`/`onChange` control state.
493
+ ```yaml
494
+ Checkbox:
495
+ label: {type: 'string', required: false}
496
+ required: {type: 'boolean', required: false}
497
+ ```
498
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-checkbox--docs
499
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/Checkbox/Checkbox.stories.tsx
500
+
501
+ Demonstrated states:
502
+ - Default — checked=true, id="checkbox-default"
503
+ - Disabled — checked=false, id="checkbox-disabled", disabled=true
504
+ - WithCustomLabel — checked=true, id="checkbox-custom-label", label="Custom Label"
505
+ - WithRequired — checked=false, id="checkbox-custom-label", label="Required", required=true
506
+ - WithNoLabel — checked=true, id="checkbox-custom-label", required=true
507
+ - ExampleWithOnChange — disabled=false
508
+ * **`Switch`**: On/Off toggle (wraps MUI Switch). `label`, `labelPlacement="end" | "start" | "top" | "bottom"` (default `end`), `checked`/`onChange`.
509
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-switch--docs
510
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/Switch/Switch.stories.tsx
511
+
512
+ Demonstrated states:
513
+ - Default — checked=true, id="switch-default"
514
+ - Disabled — checked=false, id="switch-disabled", disabled=true
515
+ - WithLabel — checked=true, id="switch-with-label", label="Enable feature"
516
+ - Required — checked=false, id="switch-required", label="Required setting", required=true
517
+ - NoLabel — checked=true, id="switch-no-label"
518
+ - ExampleWithOnChange — disabled=false
519
+ * **`Radio` / `RadioGroup`**: Mutually-exclusive choice between several options (wraps MUI Radio / RadioGroup). `label` on `Radio` collapses the `FormControlLabel` wrap; `color="primary"` is baked (not overridable). Use `RadioGroup` with `value`/`onChange` to own the selection; use standalone `Radio` only when a `Switch` would be semantically wrong.
520
+ ```yaml
521
+ Radio:
522
+ label: {type: 'React.ReactNode', required: false}
523
+ labelPlacement: {type: '"bottom" | "top" | "end" | "start"', required: false}
524
+ ```
525
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-radio--docs
526
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/Radio/Radio.stories.tsx
527
+
528
+ Demonstrated states:
529
+ - Default — id="radio-default", value="option-a"
530
+ - WithLabel — id="radio-with-label", value="option-a", label="Full backup", defaultChecked=true
531
+ - Disabled — id="radio-disabled", value="option-a", label="Not available", disabled=true
532
+ - InsideRadioGroup
533
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-radiogroup--docs
534
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/RadioGroup/RadioGroup.stories.tsx
535
+
536
+ Demonstrated states:
537
+ - Column
538
+ - Row
539
+ * **`ToggleButtonGroup`**: Use for a small set of mutually exclusive views or modes where both options should stay visible. Pass `pill` for the Telicent pill treatment. Reach for `Tabs` instead when the buttons select a panel.
540
+ ```yaml
541
+ ToggleButtonGroup:
542
+ 'aria-label': {type: 'string', required: false}
543
+ 'aria-labelledby': {type: 'string', required: false}
544
+ pill: {type: 'boolean', required: false}
545
+ ```
546
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-togglebuttongroup--docs
547
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/ToggleButtonGroup/ToggleButtonGroup.stories.tsx
548
+
549
+ Demonstrated states:
550
+ - Pill
551
+ - Default
552
+ - WithLabelledBy
553
+ - DeselectHazard
554
+ * **`DatePicker` / `DateTimePicker`**: Use for any temporal inputs.
555
+ ```yaml
556
+ DatePicker:
557
+ error: {type: 'boolean', required: false}
558
+ errorMsg: {type: 'String', required: false}
559
+ fullWidth: {type: 'boolean', required: false}
560
+ helperText: {type: 'string', required: false}
561
+ label: {type: 'ReactNode & string', required: false}
562
+ maxDate: {type: 'Dayjs', required: false}
563
+ minDate: {type: 'Dayjs', required: false}
564
+ textFieldProps: {type: 'TextFieldProps', required: false}
565
+ value: {type: 'Dayjs', required: true}
566
+ ```
567
+ ```yaml
568
+ DateTimePicker:
569
+ error: {type: 'boolean', required: false}
570
+ errorMsg: {type: 'string', required: false}
571
+ fullWidth: {type: 'boolean', required: false}
572
+ helperText: {type: 'string', required: false}
573
+ maxDateTime: {type: 'Dayjs', required: false}
574
+ minDateTime: {type: 'Dayjs', required: false}
575
+ textFieldProps: {type: 'TextFieldProps', required: false}
576
+ ```
577
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-datepicker--docs
578
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/DatePicker/DatePicker.stories.tsx
579
+
580
+ Demonstrated states:
581
+ - Default — label="Pick a date"
582
+ - ErrorState — label="Required", errorMsg="Oops, something went wrong with the validation", helperText="Please select a valid date"
583
+ - WithDateRestrictions — label="Restricted range", helperText="You can only select dates within ±5 days"
584
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-datetimepicker--docs
585
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/DateAndTimePicker/DayTimePicker.stories.tsx
586
+
587
+ Demonstrated states:
588
+ - Default — label="Pick date & time"
589
+ - ErrorState — label="Required field", error=true, errorMsg="Something went wrong", helperText="Date and time are required"
590
+ - WithDateRestrictions — label="Restricted time range", helperText="Only available within the next 48 hours"
591
+ * **`LocalizationProvider` / `AdapterDayjs`**: Root-level provider for `DatePicker` / `DateTimePicker`. Mount once at the app root — the dayjs adapter is pre-wired, so a bare `<LocalizationProvider>` is enough. `AdapterDayjs` is re-exported for apps that want to pass it explicitly or use it outside the provider.
592
+ ```yaml
593
+ LocalizationProvider:
594
+ dateAdapter: {type: 'new (...args: any) => MuiPickersAdapter<unknown>', required: false}
595
+ ```
596
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-localizationprovider--docs
597
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/LocalizationProvider/LocalizationProvider.stories.tsx
598
+
599
+ Demonstrated states:
600
+ - WrappingADatePicker
601
+
602
+ ## 4. Data Display & Typography
603
+ *Use these to render text and structured data.*
604
+ * **`Text`**: Use for all body typography instead of `<p>` or `<span>`. Style via `variant`: `body1` (default), `body2`, `subtitle1`, `subtitle2`, `caption`, `overline`, `h1`, `h2`, `h3`. (`h4`–`h6` are not valid `Text` variants — use the `H4`–`H6` components for those.)
605
+ ```yaml
606
+ Text:
607
+ paragraph: {type: 'boolean', required: false}
608
+ variant: {type: '"caption" | "h1" | "h2" | "h3" | "overline" | "body1" | "body2" | "subtitle1" | "subtitle2"', required: false}
609
+ ```
610
+ * **`H1` / `H2` / `H3` / `H4` / `H5` / `H6`**: Use for headings instead of `<h1>`–`<h6>`; each renders the matching semantic element. (There is no `Heading` component. `<Text variant="h2">` styles text as a heading but renders a `<p>` — use `H1`–`H6` when the semantic element matters.)
611
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-headings--docs
612
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/Text/Heading.stories.tsx
613
+ Default args: align="inherit"
614
+
615
+ Demonstrated states:
616
+ - Heading1 — children="Heading Style 1"
617
+ - Heading2 — variant="h2", children="Heading Style 2"
618
+ - Heading3 — variant="h3", children="Heading Style 3"
619
+ - Heading4 — variant="h4", children="Heading Style 4"
620
+ - Heading5 — variant="h5", children="Heading Style 5"
621
+ - Heading6 — variant="h6", children="Heading Style 6"
622
+ * **`TitleAndContent`**: Use for standard "Label: Value" data pairings.
623
+ ```yaml
624
+ TitleAndContent:
625
+ content: {type: 'string', required: false}
626
+ title: {type: 'string', required: false}
627
+ ```
628
+ * **`List`**: Standard list rendering.
629
+ * **`TreeView`**: Use for hierarchical or nested data structures.
630
+ ```yaml
631
+ TreeView:
632
+ alwaysExpandedIds: {type: 'string[]', required: false}
633
+ defaultExpandedItems: {type: 'string[]', required: false}
634
+ defaultSelectedItems: {type: 'string | string[]', required: false}
635
+ expandedItems: {type: 'string[]', required: false}
636
+ getItemId: {type: '(item: Item) => string', required: false}
637
+ getItemLabel: {type: '(item: Item) => string', required: false}
638
+ id: {type: 'string', required: false}
639
+ isItemDisabled: {type: '(item: Item) => boolean', required: false}
640
+ items: {type: 'Item[]', required: true}
641
+ multiSelect: {type: 'boolean', required: false}
642
+ onExpandedItemsChange: {type: '(event: React.SyntheticEvent, itemIds: string[]) => void', required: false}
643
+ onItemExpansionToggle: {type: '(event: React.SyntheticEvent, itemId: string, isExpanded: boolean) => void', required: false}
644
+ onItemFocus: {type: '(event: React.SyntheticEvent | null, itemId: string) => void', required: false}
645
+ onItemSelectionToggle: {type: '(event: React.SyntheticEvent, itemId: string, isSelected: boolean) => void', required: false}
646
+ onSelectedItemsChange: {type: '(event: React.SyntheticEvent, itemIds: string[] | string | null) => void', required: false}
647
+ selectedItems: {type: 'string | string[]', required: false}
648
+ sx: {type: 'SxProps', required: false}
649
+ ```
650
+ * **`Chip`**: Use for tags, statuses, or small attributes.
651
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-chip--docs
652
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/Chip/Chip.stories.tsx
653
+ Default args: label="Chip"
654
+
655
+ Demonstrated states:
656
+ - Filled
657
+ - Outlined — variant="outlined"
658
+ - ClickableChips
659
+ - DeletableChips
660
+ * **`DataGrid`**: Tabular data with pagination, sorting, and themed styling (wraps MUI X `DataGrid`). DS bakes `autoHeight`, `disableColumnResize`, `disableRowSelectionOnClick`, `disableColumnMenu`, `pagination`, `pageSizeOptions=[10, 25, 50]`, and initial `pageSize=10`. Row hover is suppressed by default; when `onRowClick` is set, the DS auto-opts `cursor: "pointer"` + `palette.action.hover` back in so interactive grids read as interactive with zero `sx` at the callsite. A nested `ThemeProvider` scopes the palette-driven grid overrides so Paper / MenuItem / IconButton / TablePagination styling inside the grid doesn't leak globally. DS re-exports `GridColDef`, `GridRenderCellParams`, `GridRowParams`, `GridSortModel`. `initialSort` is a DS convenience prop that maps to `initialState.sorting.sortModel`.
661
+ ```yaml
662
+ DataGrid:
663
+ initialSort: {type: 'GridSortModel', required: false}
664
+ ```
665
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-datagrid--docs
666
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/DataGrid/DataGrid.stories.tsx
667
+
668
+ Demonstrated states:
669
+ - Default — columns=basicColumns
670
+ - WithInitialSort — columns=basicColumns, initialSort=[…]
671
+ - WithCustomCellRenderer
672
+ - ClickableRows
673
+ - Loading — columns=basicColumns, loading=true
674
+ - Empty — rows=[…], columns=basicColumns
675
+ * **`Divider`**: Use to separate content sections instead of `<hr>`.
676
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-divider--docs
677
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/Divider/Divider.stories.tsx
678
+
679
+ Demonstrated states:
680
+ - Example
681
+ - Orientation — orientation="vertical", flexItem=true
682
+ - FlexItem
683
+ * **`UserProfile` / `UserProfileContent` / `UserStatus`**: Components for rendering user avatars, profile details, and active states. `UserProfileContent` renders the expanded profile detail; `UserStatus` renders the online/status indicator.
684
+ ```yaml
685
+ UserProfile:
686
+ ariaLabel: {type: 'string', required: false}
687
+ fullName: {type: 'string', required: false}
688
+ id: {type: 'string', required: false}
689
+ ```
690
+ ```yaml
691
+ UserStatus:
692
+ fullName: {type: 'string', required: true}
693
+ ```
694
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-user-profile--docs
695
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/UserProfile/UserProfile.stories.tsx
696
+
697
+ Demonstrated states:
698
+ - Default — fullName="Satoru Gojo", children=DropdownChildren
699
+ - IconOnly — children=DropdownChildren
700
+ - WithId — id="user-profile", fullName="Satoru Gojo", children=DropdownChildren
701
+ - LongName — fullName="Alexander Montgomery-Fitzpatrick III, Senior Principal Engineer", children=DropdownChildren
702
+ * **`AppSwitch`**: Specific component for switching between different applications.
703
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-app-switch--docs
704
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/AppSwitch/AppSwitch.stories.tsx
705
+ Default args: apps=appList
706
+
707
+ Demonstrated states:
708
+ - AppSwitchExample — apps=appList
709
+ * **`IESType`**: Specific component for rendering IES data types.
710
+ ```yaml
711
+ IESType:
712
+ backgroundColor: {type: 'string', required: true}
713
+ borderColor: {type: 'string', required: true}
714
+ color: {type: 'string', required: true}
715
+ iconClass: {type: 'string', required: true}
716
+ ```
717
+
718
+ ## 5. Feedback & States
719
+ *Use these to communicate system status to the user.*
720
+ * **`Spinner`**: Circular loading indicator (wraps MUI CircularProgress; props `size`, `color`). Use for localized loading — inside a button or a small card.
721
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/feedback-spinner--docs
722
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/feedback/Spinner/Spinner.stories.tsx
723
+ Default args: size=40, color="primary"
724
+
725
+ Demonstrated states:
726
+ - Default
727
+ - Small — size=24
728
+ - Large — size=64
729
+ - Determinate — variant="determinate", value=65
730
+ - InContainer
731
+ * **`LinearProgress`**: Horizontal loading bar for page-level or wide-component loading.
732
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/feedback-linear-progress--docs
733
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/feedback/LinearProgress/LinearProgress.stories.tsx
734
+
735
+ Demonstrated states:
736
+ - Basic
737
+ * **`Skeleton`**: Use to render placeholder UI while `useQuery` is in an `isLoading` state.
738
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/feedback-skeleton--docs
739
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/feedback/Skeleton/Skeleton.stories.tsx
740
+
741
+ Demonstrated states:
742
+ - Basic
743
+ * **`Dialog`**: Interrupt the user for confirmation or sub-forms (wraps MUI Dialog). Required `open` and `onClose`; compose with `DialogTitle` / `DialogContent` / `DialogActions`.
744
+ ```yaml
745
+ Dialog:
746
+ children: {type: 'React.ReactNode', required: true}
747
+ onClose: {type: '() => void', required: true}
748
+ open: {type: 'boolean', required: true}
749
+ ```
750
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/feedback-dialog--docs
751
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/feedback/Dialog/Dialog.stories.tsx
752
+
753
+ Demonstrated states:
754
+ - Basic
755
+ * **`Modal`**: Lower-level overlay with its own close button (`onClose(event, reason)`, optional `hideCloseButton`).
756
+ ```yaml
757
+ Modal:
758
+ hideCloseButton: {type: 'boolean', required: false}
759
+ onClose: {type: '((event: {}, reason: "backdropClick" | "escapeKeyDown" | "closeButtonClick") => void)', required: true}
760
+ ```
761
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/utils-modal--docs
762
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/utils/Modal/Modal.stories.tsx
763
+
764
+ Demonstrated states:
765
+ - Example
766
+ - WithNoCloseButton
767
+ * **`ErrorFallback`** (and `ErrorFallbackWrapper`, `ErrorFallbackText`): Render as the fallback of a React error boundary to display crash states gracefully. `ErrorFallbackText` is the text-only variant (no surrounding box). (The boundary itself is not a DS export; the DS provides the fallback UI.)
768
+ ```yaml
769
+ ErrorFallback:
770
+ height: {type: 'string | number', required: false}
771
+ message: {type: 'string', required: false}
772
+ name: {type: 'string', required: false}
773
+ sx: {type: 'SxProps<Theme>', required: false}
774
+ ```
775
+ ```yaml
776
+ ErrorFallbackWrapper:
777
+ children: {type: 'React.ReactNode', required: true}
778
+ height: {type: 'string | number', required: false}
779
+ sx: {type: 'SxProps<Theme>', required: false}
780
+ ```
781
+ ```yaml
782
+ ErrorFallbackText:
783
+ message: {type: 'string', required: false}
784
+ name: {type: 'string', required: false}
785
+ ```
786
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/utils-errorfallback--docs
787
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/utils/ErrorFallback/ErrorFallback.stories.tsx
788
+ Default args: name="ExampleComponent", height=256
789
+
790
+ Demonstrated states:
791
+ - DefaultError — name="ExampleComponent"
792
+ - CustomMessage — name="DataWidget", message="Unable to load user data."
793
+ - CustomNameAndStyle — name="ChartComponent", sx={…}
794
+ - ExplicitHeight — name="ProfileCard", height=150
795
+
796
+ ## 6. Icons
797
+ *The DS includes two icon sets. Import them directly from `@telicent-oss/ds`.*
798
+ * **SVG Icons** (custom Telicent icons): `BinIcon`, `CloseIcon`, `DataServiceIcon`, `DataSetIcon`, `DragHandleIcon`, `FloppyDiskIcon`, `GridIcon`, `ListIcon`, `LocationOnIcon`, `MapIcon`, `MinusCircleIcon`, `PlayIcon`, `PlusCircleIcon`, `TelicentMark`, `TelicentHorizontalSVG`, `UserIcon`, `XIcon`.
799
+ * **FontAwesome Icons** (wrapped FA icons): `ClockIcon`, `DownArrowIcon`, `DownloadIcon`, `SearchIcon`.
800
+ * **`TeliTypeIcon`**: Renders a type indicator icon for IES/ontology types.
801
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-icons--docs
802
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/Icons/index.stories.tsx
803
+ Default args: color="inherit", fontSize="large", background="surface", filter=""
804
+
805
+ Demonstrated states:
806
+ - AllIcons
807
+ - ColorMatrixStory — fontSize="large", background="surface"
808
+ - SizeMatrixStory — color="inherit", background="surface"
809
+ - ColorOverridesStory
810
+
811
+ ---
812
+
813
+ ## Recipes
814
+
815
+ *Real shapes from Telicent apps. Copy and adapt.*
816
+
817
+ **Themed app root** — styles, then the provider (which supplies the MUI theme + CssBaseline):
818
+ ```tsx
819
+ import "@telicent-oss/ds/dist/style.css";
820
+ import "@telicent-oss/ds/dist/fontawesome.css";
821
+ import { UIThemeProvider } from "@telicent-oss/ds";
822
+
823
+ export function Root() {
824
+ return (
825
+ <UIThemeProvider theme="DataNavy" dark={false}>
826
+ <App />
827
+ </UIThemeProvider>
828
+ );
829
+ }
830
+ ```
831
+
832
+ **A form** — note `Select` takes an `options` array, not `<MenuItem>` children:
833
+ ```tsx
834
+ import { FlexBox, TextField, Select, Checkbox, Button } from "@telicent-oss/ds";
835
+
836
+ <FlexBox direction="column" gap={2}>
837
+ <TextField label="Name" value={name} onChange={(e) => setName(e.target.value)} />
838
+ <Select
839
+ label="Colour"
840
+ value={colour}
841
+ onChange={(e) => setColour(e.target.value)}
842
+ options={[{ value: "r", label: "Red" }, { value: "b", label: "Blue" }]}
843
+ />
844
+ <Checkbox label="I agree" checked={agreed} onChange={(e) => setAgreed(e.target.checked)} />
845
+ <Button variant="primary" onClick={submit}>Save</Button>
846
+ </FlexBox>
847
+ ```
848
+
849
+ **A react-hook-form form** — the common shape in Telicent apps: uncontrolled inputs (`TextField`) take `register`; controlled inputs (`Select`, `Autocomplete`) go through `Controller` and spread `field`:
850
+ ```tsx
851
+ import { useForm, Controller } from "react-hook-form";
852
+ import { FlexBox, TextField, Select, Autocomplete, Button } from "@telicent-oss/ds";
853
+
854
+ const { register, control, handleSubmit, formState: { isValid } } = useForm<FormValues>();
855
+
856
+ <FlexBox direction="column" gap={2} component="form" onSubmit={handleSubmit(onSave)}>
857
+ <TextField label="Name" {...register("name")} />
858
+ <Controller
859
+ name="classification"
860
+ control={control}
861
+ render={({ field }) => (
862
+ <Select label="Classification" options={CLASSIFICATION_OPTIONS} {...field} fullWidth />
863
+ )}
864
+ />
865
+ <Controller
866
+ name="nationality"
867
+ control={control}
868
+ render={({ field }) => <Autocomplete label="Nationality" options={countryOptions} {...field} />}
869
+ />
870
+ <Button variant="primary" type="submit" disabled={!isValid}>Save</Button>
871
+ </FlexBox>
872
+ ```
873
+
874
+ **A loading button** — there is no `loading` prop; gate on `disabled` and swap the label:
875
+ ```tsx
876
+ import { Button, Spinner } from "@telicent-oss/ds";
877
+
878
+ <Button
879
+ variant="primary"
880
+ disabled={isPending}
881
+ startIcon={isPending ? <Spinner size={16} color="inherit" /> : undefined}
882
+ >
883
+ {isPending ? "Saving..." : "Save"}
884
+ </Button>
885
+ ```
886
+
887
+ **A card with content and actions** — compose `CardContent` and `CardActions`:
888
+ ```tsx
889
+ import { Card, CardContent, CardActions, Text, Button } from "@telicent-oss/ds";
890
+
891
+ <Card maxWidth={400}>
892
+ <CardContent>
893
+ <Text variant="h3">Dataset</Text>
894
+ <Text>1,240 records</Text>
895
+ </CardContent>
896
+ <CardActions>
897
+ <Button variant="secondary">Cancel</Button>
898
+ <Button variant="primary">Open</Button>
899
+ </CardActions>
900
+ </Card>
901
+ ```
902
+
903
+ ---
904
+ **Agent Rule Checklist Before Generating JSX:**
905
+ 1. Did I import `style.css` + `fontawesome.css` and wrap the app in `UIThemeProvider`?
906
+ 2. Did I use `Card` instead of a custom styled `div`?
907
+ 3. Are all texts wrapped in `H1`–`H6` or `Text`?
908
+ 4. Did I use `Button` with the right `variant` instead of styling a raw `<button>`?
909
+ 5. Are loading states handled by `Skeleton`, `Spinner`, or a `disabled` button?
910
+ 6. Did I set colours via the theme palette (`useExtendedTheme`) rather than Tailwind colour classes?
911
+
912
+ ---
913
+
914
+ ## Other exports
915
+
916
+ Exported by `@telicent-oss/ds` but not yet given a section above. Auto-listed from the type surface (props only); a maintainer should fold these into the manifest.
917
+
918
+ * `AppInfo`:
919
+ ```yaml
920
+ AppInfo:
921
+ ariaLabel: {type: 'string', required: false}
922
+ id: {type: 'string', required: false}
923
+ ```
924
+
925
+ * `AppInfoRow`:
926
+ ```yaml
927
+ AppInfoRow:
928
+ id: {type: 'string', required: false}
929
+ label: {type: 'string', required: true}
930
+ value: {type: 'React.ReactNode', required: true}
931
+ ```
932
+
933
+ * `AppSettings`:
934
+ ```yaml
935
+ AppSettings:
936
+ ariaLabel: {type: 'string', required: false}
937
+ id: {type: 'string', required: false}
938
+ ```
939
+
940
+ * `ConfirmDialog`:
941
+ ```yaml
942
+ ConfirmDialog:
943
+ alert: {type: 'ConfirmDialogAlert', required: false}
944
+ ariaLabel: {type: 'string', required: false}
945
+ body: {type: 'React.ReactNode', required: true}
946
+ cancelLabel: {type: 'string', required: false}
947
+ confirmLabel: {type: 'string', required: false}
948
+ icon: {type: 'React.ReactNode', required: false}
949
+ id: {type: 'string', required: false}
950
+ isPending: {type: 'boolean', required: false}
951
+ onClose: {type: '() => void', required: true}
952
+ onConfirm: {type: '() => void', required: true}
953
+ open: {type: 'boolean', required: true}
954
+ pendingLabel: {type: 'string', required: false}
955
+ title: {type: 'string', required: true}
956
+ variant: {type: 'ConfirmDialogVariant', required: false}
957
+ ```
958
+
959
+ * `LabeledSwitch`:
960
+ ```yaml
961
+ LabeledSwitch:
962
+ checked: {type: 'boolean', required: false}
963
+ disabled: {type: 'boolean', required: false}
964
+ error: {type: 'boolean', required: false}
965
+ helperText: {type: 'string', required: false}
966
+ inputProps: {type: 'React.InputHTMLAttributes<HTMLInputElement>', required: false}
967
+ onChange: {type: '(checked: boolean) => void', required: true}
968
+ ref: {type: 'React.Ref<HTMLButtonElement>', required: false}
969
+ subtext: {type: 'string', required: false}
970
+ text: {type: 'string', required: true}
971
+ ```
972
+
973
+ * `SnackbarProvider`:
974
+ ```yaml
975
+ SnackbarProvider: {} # no own props; all inherited from the underlying MUI/DOM element
976
+ ```
977
+
978
+ * `ThemeSwitch`:
979
+ ```yaml
980
+ ThemeSwitch:
981
+ checked: {type: 'boolean', required: true}
982
+ className: {type: 'string', required: false}
983
+ disabled: {type: 'boolean', required: false}
984
+ label: {type: 'string', required: false}
985
+ labelId: {type: 'string', required: false}
986
+ onChange: {type: '(checked: boolean) => void', required: true}
987
+ ```
988
+
989
+ * `ThemeSwitchRow`:
990
+ ```yaml
991
+ ThemeSwitchRow:
992
+ checked: {type: 'boolean', required: true}
993
+ className: {type: 'string', required: false}
994
+ disabled: {type: 'boolean', required: false}
995
+ hint: {type: 'string', required: false}
996
+ label: {type: 'string', required: false}
997
+ onChange: {type: '(checked: boolean) => void', required: true}
998
+ ```
999
+
1000
+ ---
1001
+
1002
+ ## Package and install
1003
+
1004
+ - Install with `yarn add @telicent-oss/ds`
1005
+ - npm: https://www.npmjs.com/package/@telicent-oss/ds
1006
+ - Live examples (Storybook): https://telicent-oss.github.io/telicent-ds/
1007
+ - Source and issues: https://github.com/telicent-oss/telicent-ds
1008
+
1009
+ This reference documents @telicent-oss/ds v4.4.0.