@telicent-oss/ds 4.2.0 → 4.3.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,947 @@
1
+ # Telicent DS Component Manifest
2
+
3
+ **VERSION:** This file documents @telicent-oss/ds v4.3.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.3.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.
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
+ ```
320
+ ```yaml
321
+ Tab:
322
+ value: {type: 'TabValue', required: true}
323
+ ```
324
+ ```yaml
325
+ TabPanel:
326
+ activeValue: {type: 'TabValue', required: true}
327
+ idPrefix: {type: 'string', required: true}
328
+ keepMounted: {type: 'boolean', required: false}
329
+ value: {type: 'TabValue', required: true}
330
+ ```
331
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/navigation-tabs--docs
332
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/Navigation/Tabs/Tabs.stories.tsx
333
+
334
+ Demonstrated states:
335
+ - Default
336
+ - WithLabelledBy
337
+ - Vertical
338
+ - Scrollable
339
+ - WithIcons
340
+ - KeepMounted
341
+
342
+ ## 3. Inputs & Forms
343
+ *Use these instead of standard `<input>`, `<select>`, or `<textarea>` tags. Ensure accessibility labels are passed.*
344
+ * **`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.
345
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-textfield--docs
346
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/TextField/TextField.stories.tsx
347
+
348
+ Demonstrated states:
349
+ - Default — label="Full Name", placeholder="Enter your name", error=false, errorText="This field is required"
350
+ - MultiLine — label="Multiline Input", placeholder="type anything that needs a lot of space in here", error=false, multiline=true, rows=10
351
+ - HelperText
352
+ - ErrorMessage — label="Title", error=true, errorText="Something went wrong, please try again."
353
+ * **`EditableTextField`**: Use for inline-editing scenarios (e.g., clicking a title to rename it).
354
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-editable-textfield--docs
355
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/EditableTextField/EditableTextField.stories.tsx
356
+
357
+ Demonstrated states:
358
+ - Basic
359
+ - FullWidth
360
+ - CustomWidth
361
+ - WithErrorText
362
+ - NoInitialValue
363
+ * **`SearchBox` / `MiniSearchBox`**: Use specifically for search inputs.
364
+ ```yaml
365
+ SearchBox:
366
+ autoFocus: {type: 'boolean', required: false}
367
+ inputRef: {type: 'React.ForwardedRef<HTMLInputElement>', required: false}
368
+ name: {type: 'string', required: false}
369
+ onBlur: {type: '(event: React.FocusEvent<HTMLInputElement>) => void', required: false}
370
+ onChange: {type: '(event: React.ChangeEvent<HTMLInputElement>) => void', required: false}
371
+ onSearch: {type: '(event: React.SubmitEvent<HTMLFormElement>) => void', required: false}
372
+ placeholder: {type: 'string', required: false}
373
+ sx: {type: 'SxProps', required: false}
374
+ value: {type: 'Value', required: false}
375
+ width: {type: 'number', required: false}
376
+ ```
377
+ ```yaml
378
+ MiniSearchBox:
379
+ autoFocus: {type: 'boolean', required: false}
380
+ disabled: {type: 'boolean', required: false}
381
+ endIcon: {type: 'React.ReactNode', required: false}
382
+ error: {type: 'boolean', required: false}
383
+ fullWidth: {type: 'boolean', required: false}
384
+ helperText: {type: 'string', required: false}
385
+ id: {type: 'string', required: false}
386
+ inputRef: {type: 'React.Ref<any>', required: false}
387
+ loading: {type: 'boolean', required: false}
388
+ maxRows: {type: 'string | number', required: false}
389
+ minRows: {type: 'string | number', required: false}
390
+ multiline: {type: 'boolean', required: false}
391
+ name: {type: 'string', required: false}
392
+ onBlur: {type: 'React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>', required: false}
393
+ onChange: {type: 'React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement, Element>', required: false}
394
+ onFocus: {type: 'React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>', required: false}
395
+ onInvalid: {type: 'React.FormEventHandler<HTMLInputElement | HTMLTextAreaElement>', required: false}
396
+ onKeyDown: {type: 'React.KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>', required: false}
397
+ onKeyUp: {type: 'React.KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>', required: false}
398
+ onSearch: {type: 'React.MouseEventHandler<HTMLButtonElement>', required: false}
399
+ onTogglePopOver: {type: 'React.MouseEventHandler<HTMLButtonElement>', required: false}
400
+ placeholder: {type: 'string', required: false}
401
+ progressProps: {type: 'ProgressProps', required: false}
402
+ rows: {type: 'string | number', required: false}
403
+ value: {type: 'unknown', required: false}
404
+ ```
405
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-search-minisearchbox--docs
406
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/SearchBox/MiniSearchBox.stories.tsx
407
+
408
+ Demonstrated states:
409
+ - Demo — placeholder="Search"
410
+ - WithDownArrow — placeholder="Search"
411
+ - Loading — placeholder="Loading", loading=true
412
+ * **`Autocomplete` / `MiniSearchAutocomplete`**: Use when search requires type-ahead dropdown suggestions.
413
+ ```yaml
414
+ MiniSearchAutocomplete:
415
+ disabled: {type: 'boolean', required: false}
416
+ endIcon: {type: 'React.ReactNode', required: false}
417
+ error: {type: 'boolean', required: false}
418
+ id: {type: 'string', required: false}
419
+ loading: {type: 'boolean', required: false}
420
+ name: {type: 'string', required: false}
421
+ onKeyDown: {type: 'React.KeyboardEventHandler<HTMLInputElement>', required: false}
422
+ onSearch: {type: 'React.MouseEventHandler<HTMLElement>', required: false}
423
+ placeholder: {type: 'string', required: false}
424
+ progressProps: {type: 'ProgressProps', required: false}
425
+ renderOption: {type: '(props: React.HTMLAttributes<HTMLLIElement> & { key: any; }, option: Value) => React.ReactNode', required: false}
426
+ ```
427
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-autocomplete--docs
428
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/Autocomplete/Autocomplete.stories.tsx
429
+
430
+ Demonstrated states:
431
+ - Basic
432
+ - Preselected
433
+ - WithHelperText
434
+ - Disabled
435
+ - AsyncLoading
436
+ - StoresIdInFormState
437
+ - MultiSelectWithLimit
438
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-search-minisearchautocomplete--docs
439
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/SearchBox/MiniSearchAutocomplete.stories.tsx
440
+
441
+ Demonstrated states:
442
+ - RecentSearches — options=[…], placeholder="Search"
443
+ - SearchResults — options=[…]
444
+ * **`SearchAutocompleteDialog`**: Full-screen dialog combining search input with autocomplete. Composes with `RecentSearches` (renders recent search history) and `SearchResults` (renders the results list).
445
+ ```yaml
446
+ SearchAutocompleteDialog:
447
+ autoFocus: {type: 'boolean', required: false}
448
+ autoHighlight: {type: 'boolean', required: false}
449
+ children: {type: 'React.ReactNode', required: true}
450
+ error: {type: 'boolean', required: false}
451
+ getOptionKey: {type: '(option: string | SearchOption) => string | number', required: false}
452
+ getOptionLabel: {type: '(option: string | SearchOption) => string', required: false}
453
+ helperText: {type: 'string', required: false}
454
+ id: {type: 'string', required: false}
455
+ inputValue: {type: 'string', required: false}
456
+ isOptionEqualToValue: {type: '(option: SearchOption, value: SearchOption) => boolean', required: false}
457
+ label: {type: 'string', required: false}
458
+ loading: {type: 'boolean', required: false}
459
+ loadingText: {type: 'React.ReactNode', required: false}
460
+ name: {type: 'string', required: false}
461
+ onChange: {type: '(event: React.SyntheticEvent, value: string | SearchOption, reason: AutocompleteChangeReason, details?: ...', required: false}
462
+ onClose: {type: '(event: {}, reason: "backdropClick" | "escapeKeyDown") => void', required: false}
463
+ onInputChange: {type: '(event: React.SyntheticEvent, value: string, reason: AutocompleteInputChangeReason) => void', required: false}
464
+ open: {type: 'boolean', required: true}
465
+ openOnFocus: {type: 'boolean', required: false}
466
+ options: {type: 'readonly SearchOption[]', required: true}
467
+ placeholder: {type: 'string', required: false}
468
+ width: {type: 'number', required: false}
469
+ ```
470
+ * **`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`.
471
+ ```yaml
472
+ Select:
473
+ footer: {type: 'React.ReactNode | ((args: SelectFooterArgs) => React.ReactNode)', required: false}
474
+ helperText: {type: 'React.ReactNode', required: false}
475
+ options: {type: 'Options[]', required: true}
476
+ renderOption: {type: '(option: Options) => React.ReactNode', required: false}
477
+ width: {type: 'string | number', required: false}
478
+ ```
479
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-select--docs
480
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/Select/Select.stories.tsx
481
+
482
+ Demonstrated states:
483
+ - Default — label="Select an option", value="option1", id="select-disabled", options=OPTIONS, width=300
484
+ - Disabled — label="Select an option", value="none", id="select-disabled", options=OPTIONS, width=300, disabled=true
485
+ - WithCustomWidth — label="Select an option", value="option2", id="select-disabled", options=OPTIONS, width=500
486
+ - WithNoLabel — value="option2", id="select-disabled", options=OPTIONS
487
+ - ExampleWithOnChange — width=250, disabled=false
488
+ - WithRenderOption — label="Resource type", value="dataset", width=320, options=RESOURCE_TYPE_OPTIONS
489
+ - WithFooter — label="Owner", value="mcga", width=300, options=OWNER_OPTIONS
490
+ * **`Checkbox`**: Boolean or multi-select input (wraps MUI Checkbox). `label` renders the caption; `checked`/`onChange` control state.
491
+ ```yaml
492
+ Checkbox:
493
+ label: {type: 'string', required: false}
494
+ required: {type: 'boolean', required: false}
495
+ ```
496
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-checkbox--docs
497
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/Checkbox/Checkbox.stories.tsx
498
+
499
+ Demonstrated states:
500
+ - Default — checked=true, id="checkbox-default"
501
+ - Disabled — checked=false, id="checkbox-disabled", disabled=true
502
+ - WithCustomLabel — checked=true, id="checkbox-custom-label", label="Custom Label"
503
+ - WithRequired — checked=false, id="checkbox-custom-label", label="Required", required=true
504
+ - WithNoLabel — checked=true, id="checkbox-custom-label", required=true
505
+ - ExampleWithOnChange — disabled=false
506
+ * **`Switch`**: On/Off toggle (wraps MUI Switch). `label`, `labelPlacement="end" | "start" | "top" | "bottom"` (default `end`), `checked`/`onChange`.
507
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-switch--docs
508
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/Switch/Switch.stories.tsx
509
+
510
+ Demonstrated states:
511
+ - Default — checked=true, id="switch-default"
512
+ - Disabled — checked=false, id="switch-disabled", disabled=true
513
+ - WithLabel — checked=true, id="switch-with-label", label="Enable feature"
514
+ - Required — checked=false, id="switch-required", label="Required setting", required=true
515
+ - NoLabel — checked=true, id="switch-no-label"
516
+ - ExampleWithOnChange — disabled=false
517
+ * **`DatePicker` / `DateTimePicker`**: Use for any temporal inputs.
518
+ ```yaml
519
+ DatePicker:
520
+ error: {type: 'boolean', required: false}
521
+ errorMsg: {type: 'String', required: false}
522
+ fullWidth: {type: 'boolean', required: false}
523
+ helperText: {type: 'string', required: false}
524
+ label: {type: 'ReactNode & string', required: false}
525
+ maxDate: {type: 'PickerValidDate', required: false}
526
+ minDate: {type: 'PickerValidDate', required: false}
527
+ textFieldProps: {type: 'TextFieldProps', required: false}
528
+ value: {type: 'Dayjs | null', required: true}
529
+ ```
530
+ ```yaml
531
+ DateTimePicker:
532
+ error: {type: 'boolean', required: false}
533
+ errorMsg: {type: 'string', required: false}
534
+ fullWidth: {type: 'boolean', required: false}
535
+ helperText: {type: 'string', required: false}
536
+ maxDateTime: {type: 'PickerValidDate', required: false}
537
+ minDateTime: {type: 'PickerValidDate', required: false}
538
+ textFieldProps: {type: 'TextFieldProps', required: false}
539
+ ```
540
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-datepicker--docs
541
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/DatePicker/DatePicker.stories.tsx
542
+
543
+ Demonstrated states:
544
+ - Default — label="Pick a date"
545
+ - ErrorState — label="Required", errorMsg="Oops, something went wrong with the validation", helperText="Please select a valid date"
546
+ - WithDateRestrictions — label="Restricted range", helperText="You can only select dates within ±5 days"
547
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/inputs-datetimepicker--docs
548
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/inputs/DateAndTimePicker/DayTimePicker.stories.tsx
549
+
550
+ Demonstrated states:
551
+ - Default — label="Pick date & time"
552
+ - ErrorState — label="Required field", error=true, errorMsg="Something went wrong", helperText="Date and time are required"
553
+ - WithDateRestrictions — label="Restricted time range", helperText="Only available within the next 48 hours"
554
+
555
+ ## 4. Data Display & Typography
556
+ *Use these to render text and structured data.*
557
+ * **`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.)
558
+ ```yaml
559
+ Text:
560
+ paragraph: {type: 'boolean', required: false}
561
+ variant: {type: '"caption" | "h1" | "h2" | "h3" | "overline" | "body1" | "body2" | "subtitle1" | "subtitle2"', required: false}
562
+ ```
563
+ * **`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.)
564
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-headings--docs
565
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/Text/Heading.stories.tsx
566
+ Default args: align="inherit"
567
+
568
+ Demonstrated states:
569
+ - Heading1 — children="Heading Style 1"
570
+ - Heading2 — variant="h2", children="Heading Style 2"
571
+ - Heading3 — variant="h3", children="Heading Style 3"
572
+ - Heading4 — variant="h4", children="Heading Style 4"
573
+ - Heading5 — variant="h5", children="Heading Style 5"
574
+ - Heading6 — variant="h6", children="Heading Style 6"
575
+ * **`TitleAndContent`**: Use for standard "Label: Value" data pairings.
576
+ ```yaml
577
+ TitleAndContent:
578
+ content: {type: 'string', required: false}
579
+ title: {type: 'string', required: false}
580
+ ```
581
+ * **`List`**: Standard list rendering.
582
+ * **`TreeView`**: Use for hierarchical or nested data structures.
583
+ ```yaml
584
+ TreeView:
585
+ alwaysExpandedIds: {type: 'string[]', required: false}
586
+ defaultExpandedItems: {type: 'string[]', required: false}
587
+ defaultSelectedItems: {type: 'string | string[]', required: false}
588
+ expandedItems: {type: 'string[]', required: false}
589
+ getItemId: {type: '(item: Item) => string', required: false}
590
+ getItemLabel: {type: '(item: Item) => string', required: false}
591
+ id: {type: 'string', required: false}
592
+ isItemDisabled: {type: '(item: Item) => boolean', required: false}
593
+ items: {type: 'Item[]', required: true}
594
+ multiSelect: {type: 'boolean', required: false}
595
+ onExpandedItemsChange: {type: '(event: React.SyntheticEvent, itemIds: string[]) => void', required: false}
596
+ onItemExpansionToggle: {type: '(event: React.SyntheticEvent, itemId: string, isExpanded: boolean) => void', required: false}
597
+ onItemFocus: {type: '(event: React.SyntheticEvent | null, itemId: string) => void', required: false}
598
+ onItemSelectionToggle: {type: '(event: React.SyntheticEvent, itemId: string, isSelected: boolean) => void', required: false}
599
+ onSelectedItemsChange: {type: '(event: React.SyntheticEvent, itemIds: string[] | string | null) => void', required: false}
600
+ selectedItems: {type: 'string | string[]', required: false}
601
+ sx: {type: 'SxProps', required: false}
602
+ ```
603
+ * **`Chip`**: Use for tags, statuses, or small attributes.
604
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-chip--docs
605
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/Chip/Chip.stories.tsx
606
+ Default args: label="Chip"
607
+
608
+ Demonstrated states:
609
+ - Filled
610
+ - Outlined — variant="outlined"
611
+ - ClickableChips
612
+ - DeletableChips
613
+ * **`Divider`**: Use to separate content sections instead of `<hr>`.
614
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-divider--docs
615
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/Divider/Divider.stories.tsx
616
+
617
+ Demonstrated states:
618
+ - Example
619
+ - Orientation — orientation="vertical", flexItem=true
620
+ - FlexItem
621
+ * **`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.
622
+ ```yaml
623
+ UserProfile:
624
+ ariaLabel: {type: 'string', required: false}
625
+ fullName: {type: 'string', required: false}
626
+ id: {type: 'string', required: false}
627
+ ```
628
+ ```yaml
629
+ UserStatus:
630
+ fullName: {type: 'string', required: true}
631
+ ```
632
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-user-profile--docs
633
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/UserProfile/UserProfile.stories.tsx
634
+
635
+ Demonstrated states:
636
+ - Default — fullName="Satoru Gojo", children=DropdownChildren
637
+ - IconOnly — children=DropdownChildren
638
+ - WithId — id="user-profile", fullName="Satoru Gojo", children=DropdownChildren
639
+ - LongName — fullName="Alexander Montgomery-Fitzpatrick III, Senior Principal Engineer", children=DropdownChildren
640
+ * **`AppSwitch`**: Specific component for switching between different applications.
641
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-app-switch--docs
642
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/AppSwitch/AppSwitch.stories.tsx
643
+ Default args: apps=appList
644
+
645
+ Demonstrated states:
646
+ - AppSwitchExample — apps=appList
647
+ * **`IESType`**: Specific component for rendering IES data types.
648
+ ```yaml
649
+ IESType:
650
+ backgroundColor: {type: 'string', required: true}
651
+ borderColor: {type: 'string', required: true}
652
+ color: {type: 'string', required: true}
653
+ iconClass: {type: 'string', required: true}
654
+ ```
655
+
656
+ ## 5. Feedback & States
657
+ *Use these to communicate system status to the user.*
658
+ * **`Spinner`**: Circular loading indicator (wraps MUI CircularProgress; props `size`, `color`). Use for localized loading — inside a button or a small card.
659
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/feedback-spinner--docs
660
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/feedback/Spinner/Spinner.stories.tsx
661
+ Default args: size=40, color="primary"
662
+
663
+ Demonstrated states:
664
+ - Default
665
+ - Small — size=24
666
+ - Large — size=64
667
+ - Determinate — variant="determinate", value=65
668
+ - InContainer
669
+ * **`LinearProgress`**: Horizontal loading bar for page-level or wide-component loading.
670
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/feedback-linear-progress--docs
671
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/feedback/LinearProgress/LinearProgress.stories.tsx
672
+
673
+ Demonstrated states:
674
+ - Basic
675
+ * **`Skeleton`**: Use to render placeholder UI while `useQuery` is in an `isLoading` state.
676
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/feedback-skeleton--docs
677
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/feedback/Skeleton/Skeleton.stories.tsx
678
+
679
+ Demonstrated states:
680
+ - Basic
681
+ * **`Dialog`**: Interrupt the user for confirmation or sub-forms (wraps MUI Dialog). Required `open` and `onClose`; compose with `DialogTitle` / `DialogContent` / `DialogActions`.
682
+ ```yaml
683
+ Dialog:
684
+ children: {type: 'React.ReactNode', required: true}
685
+ onClose: {type: '() => void', required: true}
686
+ open: {type: 'boolean', required: true}
687
+ ```
688
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/feedback-dialog--docs
689
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/feedback/Dialog/Dialog.stories.tsx
690
+
691
+ Demonstrated states:
692
+ - Basic
693
+ * **`Modal`**: Lower-level overlay with its own close button (`onClose(event, reason)`, optional `hideCloseButton`).
694
+ ```yaml
695
+ Modal:
696
+ hideCloseButton: {type: 'boolean', required: false}
697
+ onClose: {type: '((event: {}, reason: "backdropClick" | "escapeKeyDown" | "closeButtonClick") => void)', required: true}
698
+ ```
699
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/utils-modal--docs
700
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/utils/Modal/Modal.stories.tsx
701
+
702
+ Demonstrated states:
703
+ - Example
704
+ - WithNoCloseButton
705
+ * **`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.)
706
+ ```yaml
707
+ ErrorFallback:
708
+ height: {type: 'string | number', required: false}
709
+ message: {type: 'string', required: false}
710
+ name: {type: 'string', required: false}
711
+ sx: {type: 'SxProps<Theme>', required: false}
712
+ ```
713
+ ```yaml
714
+ ErrorFallbackWrapper:
715
+ children: {type: 'React.ReactNode', required: true}
716
+ height: {type: 'string | number', required: false}
717
+ sx: {type: 'SxProps<Theme>', required: false}
718
+ ```
719
+ ```yaml
720
+ ErrorFallbackText:
721
+ message: {type: 'string', required: false}
722
+ name: {type: 'string', required: false}
723
+ ```
724
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/utils-errorfallback--docs
725
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/utils/ErrorFallback/ErrorFallback.stories.tsx
726
+ Default args: name="ExampleComponent", height=256
727
+
728
+ Demonstrated states:
729
+ - DefaultError — name="ExampleComponent"
730
+ - CustomMessage — name="DataWidget", message="Unable to load user data."
731
+ - CustomNameAndStyle — name="ChartComponent", sx={…}
732
+ - ExplicitHeight — name="ProfileCard", height=150
733
+
734
+ ## 6. Icons
735
+ *The DS includes two icon sets. Import them directly from `@telicent-oss/ds`.*
736
+ * **SVG Icons** (custom Telicent icons): `BinIcon`, `CloseIcon`, `DataServiceIcon`, `DataSetIcon`, `DragHandleIcon`, `FloppyDiskIcon`, `GridIcon`, `ListIcon`, `LocationOnIcon`, `MapIcon`, `MinusCircleIcon`, `PlayIcon`, `PlusCircleIcon`, `TelicentMark`, `TelicentHorizontalSVG`, `UserIcon`, `XIcon`.
737
+ * **FontAwesome Icons** (wrapped FA icons): `ClockIcon`, `DownArrowIcon`, `DownloadIcon`, `SearchIcon`.
738
+ * **`TeliTypeIcon`**: Renders a type indicator icon for IES/ontology types.
739
+ Live: https://telicent-oss.github.io/telicent-ds/?path=/docs/data-display-icons--docs
740
+ Usage: https://github.com/telicent-oss/telicent-ds/blob/main/src/components/data-display/Icons/index.stories.tsx
741
+ Default args: color="inherit", fontSize="large", background="surface", filter=""
742
+
743
+ Demonstrated states:
744
+ - AllIcons
745
+ - ColorMatrixStory — fontSize="large", background="surface"
746
+ - SizeMatrixStory — color="inherit", background="surface"
747
+ - ColorOverridesStory
748
+
749
+ ---
750
+
751
+ ## Recipes
752
+
753
+ *Real shapes from Telicent apps. Copy and adapt.*
754
+
755
+ **Themed app root** — styles, then the provider (which supplies the MUI theme + CssBaseline):
756
+ ```tsx
757
+ import "@telicent-oss/ds/dist/style.css";
758
+ import "@telicent-oss/ds/dist/fontawesome.css";
759
+ import { UIThemeProvider } from "@telicent-oss/ds";
760
+
761
+ export function Root() {
762
+ return (
763
+ <UIThemeProvider theme="DataNavy" dark={false}>
764
+ <App />
765
+ </UIThemeProvider>
766
+ );
767
+ }
768
+ ```
769
+
770
+ **A form** — note `Select` takes an `options` array, not `<MenuItem>` children:
771
+ ```tsx
772
+ import { FlexBox, TextField, Select, Checkbox, Button } from "@telicent-oss/ds";
773
+
774
+ <FlexBox direction="column" gap={2}>
775
+ <TextField label="Name" value={name} onChange={(e) => setName(e.target.value)} />
776
+ <Select
777
+ label="Colour"
778
+ value={colour}
779
+ onChange={(e) => setColour(e.target.value)}
780
+ options={[{ value: "r", label: "Red" }, { value: "b", label: "Blue" }]}
781
+ />
782
+ <Checkbox label="I agree" checked={agreed} onChange={(e) => setAgreed(e.target.checked)} />
783
+ <Button variant="primary" onClick={submit}>Save</Button>
784
+ </FlexBox>
785
+ ```
786
+
787
+ **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`:
788
+ ```tsx
789
+ import { useForm, Controller } from "react-hook-form";
790
+ import { FlexBox, TextField, Select, Autocomplete, Button } from "@telicent-oss/ds";
791
+
792
+ const { register, control, handleSubmit, formState: { isValid } } = useForm<FormValues>();
793
+
794
+ <FlexBox direction="column" gap={2} component="form" onSubmit={handleSubmit(onSave)}>
795
+ <TextField label="Name" {...register("name")} />
796
+ <Controller
797
+ name="classification"
798
+ control={control}
799
+ render={({ field }) => (
800
+ <Select label="Classification" options={CLASSIFICATION_OPTIONS} {...field} fullWidth />
801
+ )}
802
+ />
803
+ <Controller
804
+ name="nationality"
805
+ control={control}
806
+ render={({ field }) => <Autocomplete label="Nationality" options={countryOptions} {...field} />}
807
+ />
808
+ <Button variant="primary" type="submit" disabled={!isValid}>Save</Button>
809
+ </FlexBox>
810
+ ```
811
+
812
+ **A loading button** — there is no `loading` prop; gate on `disabled` and swap the label:
813
+ ```tsx
814
+ import { Button, Spinner } from "@telicent-oss/ds";
815
+
816
+ <Button
817
+ variant="primary"
818
+ disabled={isPending}
819
+ startIcon={isPending ? <Spinner size={16} color="inherit" /> : undefined}
820
+ >
821
+ {isPending ? "Saving..." : "Save"}
822
+ </Button>
823
+ ```
824
+
825
+ **A card with content and actions** — compose `CardContent` and `CardActions`:
826
+ ```tsx
827
+ import { Card, CardContent, CardActions, Text, Button } from "@telicent-oss/ds";
828
+
829
+ <Card maxWidth={400}>
830
+ <CardContent>
831
+ <Text variant="h3">Dataset</Text>
832
+ <Text>1,240 records</Text>
833
+ </CardContent>
834
+ <CardActions>
835
+ <Button variant="secondary">Cancel</Button>
836
+ <Button variant="primary">Open</Button>
837
+ </CardActions>
838
+ </Card>
839
+ ```
840
+
841
+ ---
842
+ **Agent Rule Checklist Before Generating JSX:**
843
+ 1. Did I import `style.css` + `fontawesome.css` and wrap the app in `UIThemeProvider`?
844
+ 2. Did I use `Card` instead of a custom styled `div`?
845
+ 3. Are all texts wrapped in `H1`–`H6` or `Text`?
846
+ 4. Did I use `Button` with the right `variant` instead of styling a raw `<button>`?
847
+ 5. Are loading states handled by `Skeleton`, `Spinner`, or a `disabled` button?
848
+ 6. Did I set colours via the theme palette (`useExtendedTheme`) rather than Tailwind colour classes?
849
+
850
+ ---
851
+
852
+ ## Other exports
853
+
854
+ 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.
855
+
856
+ * `AppInfo`:
857
+ ```yaml
858
+ AppInfo:
859
+ ariaLabel: {type: 'string', required: false}
860
+ id: {type: 'string', required: false}
861
+ ```
862
+
863
+ * `AppInfoRow`:
864
+ ```yaml
865
+ AppInfoRow:
866
+ id: {type: 'string', required: false}
867
+ label: {type: 'string', required: true}
868
+ value: {type: 'React.ReactNode', required: true}
869
+ ```
870
+
871
+ * `AppSettings`:
872
+ ```yaml
873
+ AppSettings:
874
+ ariaLabel: {type: 'string', required: false}
875
+ id: {type: 'string', required: false}
876
+ ```
877
+
878
+ * `ConfirmDialog`:
879
+ ```yaml
880
+ ConfirmDialog:
881
+ alert: {type: 'ConfirmDialogAlert', required: false}
882
+ ariaLabel: {type: 'string', required: false}
883
+ body: {type: 'React.ReactNode', required: true}
884
+ cancelLabel: {type: 'string', required: false}
885
+ confirmLabel: {type: 'string', required: false}
886
+ icon: {type: 'React.ReactNode', required: false}
887
+ id: {type: 'string', required: false}
888
+ isPending: {type: 'boolean', required: false}
889
+ onClose: {type: '() => void', required: true}
890
+ onConfirm: {type: '() => void', required: true}
891
+ open: {type: 'boolean', required: true}
892
+ pendingLabel: {type: 'string', required: false}
893
+ title: {type: 'string', required: true}
894
+ variant: {type: 'ConfirmDialogVariant', required: false}
895
+ ```
896
+
897
+ * `LabeledSwitch`:
898
+ ```yaml
899
+ LabeledSwitch:
900
+ checked: {type: 'boolean', required: false}
901
+ disabled: {type: 'boolean', required: false}
902
+ error: {type: 'boolean', required: false}
903
+ helperText: {type: 'string', required: false}
904
+ inputProps: {type: 'React.InputHTMLAttributes<HTMLInputElement>', required: false}
905
+ onChange: {type: '(checked: boolean) => void', required: true}
906
+ ref: {type: 'React.Ref<HTMLButtonElement>', required: false}
907
+ subtext: {type: 'string', required: false}
908
+ text: {type: 'string', required: true}
909
+ ```
910
+
911
+ * `SnackbarProvider`:
912
+ ```yaml
913
+ SnackbarProvider: {} # no own props; all inherited from the underlying MUI/DOM element
914
+ ```
915
+
916
+ * `ThemeSwitch`:
917
+ ```yaml
918
+ ThemeSwitch:
919
+ checked: {type: 'boolean', required: true}
920
+ className: {type: 'string', required: false}
921
+ disabled: {type: 'boolean', required: false}
922
+ label: {type: 'string', required: false}
923
+ labelId: {type: 'string', required: false}
924
+ onChange: {type: '(checked: boolean) => void', required: true}
925
+ ```
926
+
927
+ * `ThemeSwitchRow`:
928
+ ```yaml
929
+ ThemeSwitchRow:
930
+ checked: {type: 'boolean', required: true}
931
+ className: {type: 'string', required: false}
932
+ disabled: {type: 'boolean', required: false}
933
+ hint: {type: 'string', required: false}
934
+ label: {type: 'string', required: false}
935
+ onChange: {type: '(checked: boolean) => void', required: true}
936
+ ```
937
+
938
+ ---
939
+
940
+ ## Package and install
941
+
942
+ - Install with `yarn add @telicent-oss/ds`
943
+ - npm: https://www.npmjs.com/package/@telicent-oss/ds
944
+ - Live examples (Storybook): https://telicent-oss.github.io/telicent-ds/
945
+ - Source and issues: https://github.com/telicent-oss/telicent-ds
946
+
947
+ This reference documents @telicent-oss/ds v4.3.0.