@bfrs/agentic-components 0.2.8 → 0.3.1

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.
Files changed (63) hide show
  1. package/BFRS_AGENTIC_COMPONENTS.md +346 -8
  2. package/README.md +34 -2
  3. package/dist/components/ui/feedback/InfoCard/InfoCard.d.ts +16 -0
  4. package/dist/components/ui/feedback/InfoCard/index.d.ts +2 -0
  5. package/dist/components/ui/feedback/Tip/Tip.d.ts +8 -0
  6. package/dist/components/ui/feedback/Tip/index.d.ts +2 -0
  7. package/dist/components/ui/forms/FileDropzone/FileDropzone.d.ts +21 -0
  8. package/dist/components/ui/forms/FileDropzone/index.d.ts +2 -0
  9. package/dist/components/ui/forms/MultiSelect/MultiSelect.d.ts +20 -0
  10. package/dist/components/ui/forms/MultiSelect/index.d.ts +1 -0
  11. package/dist/components/ui/forms/NumberStepper/NumberStepper.d.ts +21 -0
  12. package/dist/components/ui/forms/NumberStepper/index.d.ts +2 -0
  13. package/dist/components/ui/forms/OptionCardGroup/OptionCardGroup.d.ts +20 -0
  14. package/dist/components/ui/forms/OptionCardGroup/index.d.ts +2 -0
  15. package/dist/components/ui/forms/RevealField/RevealField.d.ts +16 -0
  16. package/dist/components/ui/forms/RevealField/index.d.ts +2 -0
  17. package/dist/components/ui/forms/SelectableChipGroup/SelectableChipGroup.d.ts +23 -0
  18. package/dist/components/ui/forms/SelectableChipGroup/index.d.ts +2 -0
  19. package/dist/components/ui/forms/SuggestInput/SuggestInput.d.ts +25 -0
  20. package/dist/components/ui/forms/SuggestInput/index.d.ts +2 -0
  21. package/dist/components/ui/index.d.ts +13 -0
  22. package/dist/components/ui/overlays/Tooltip/Tooltip.d.ts +3 -1
  23. package/dist/components/ui/patterns/Accordion/Accordion.d.ts +33 -0
  24. package/dist/components/ui/patterns/Accordion/index.d.ts +2 -0
  25. package/dist/components/ui/patterns/Collapsible/Collapsible.d.ts +15 -0
  26. package/dist/components/ui/patterns/Collapsible/index.d.ts +2 -0
  27. package/dist/components/ui/patterns/EntityDisplayCard/EntityDisplayCard.d.ts +33 -0
  28. package/dist/components/ui/patterns/EntityDisplayCard/index.d.ts +2 -0
  29. package/dist/components/ui/patterns/SummaryBar/SummaryBar.d.ts +17 -0
  30. package/dist/components/ui/patterns/SummaryBar/index.d.ts +2 -0
  31. package/dist/components/ui/patterns/WorkspaceHeader/WorkspaceHeader.d.ts +13 -3
  32. package/dist/components/ui/primitives/Grid/Grid.d.ts +6 -2
  33. package/dist/components/ui/primitives/Text/Text.d.ts +4 -2
  34. package/dist/custom-elements.d.ts +113 -0
  35. package/dist/custom-elements.js +20984 -19658
  36. package/dist/custom-elements.js.map +1 -1
  37. package/dist/font/sfprofonts/SF-Pro-Display-Black.otf +0 -0
  38. package/dist/font/sfprofonts/SF-Pro-Display-BlackItalic.otf +0 -0
  39. package/dist/font/sfprofonts/SF-Pro-Display-Bold.otf +0 -0
  40. package/dist/font/sfprofonts/SF-Pro-Display-BoldItalic.otf +0 -0
  41. package/dist/font/sfprofonts/SF-Pro-Display-Heavy.otf +0 -0
  42. package/dist/font/sfprofonts/SF-Pro-Display-HeavyItalic.otf +0 -0
  43. package/dist/font/sfprofonts/SF-Pro-Display-Light.otf +0 -0
  44. package/dist/font/sfprofonts/SF-Pro-Display-LightItalic.otf +0 -0
  45. package/dist/font/sfprofonts/SF-Pro-Display-Medium.otf +0 -0
  46. package/dist/font/sfprofonts/SF-Pro-Display-MediumItalic.otf +0 -0
  47. package/dist/font/sfprofonts/SF-Pro-Display-Regular.otf +0 -0
  48. package/dist/font/sfprofonts/SF-Pro-Display-RegularItalic.otf +0 -0
  49. package/dist/font/sfprofonts/SF-Pro-Display-Semibold.otf +0 -0
  50. package/dist/font/sfprofonts/SF-Pro-Display-SemiboldItalic.otf +0 -0
  51. package/dist/font/sfprofonts/SF-Pro-Display-Thin.otf +0 -0
  52. package/dist/font/sfprofonts/SF-Pro-Display-ThinItalic.otf +0 -0
  53. package/dist/font/sfprofonts/SF-Pro-Display-Ultralight.otf +0 -0
  54. package/dist/font/sfprofonts/SF-Pro-Display-UltralightItalic.otf +0 -0
  55. package/dist/fonts.css +152 -0
  56. package/dist/index.js +5681 -4980
  57. package/dist/index.js.map +1 -1
  58. package/dist/style.css +1 -1
  59. package/dist/theme/overrides.d.ts +10 -0
  60. package/dist/theme.js +62 -50
  61. package/dist/theme.js.map +1 -1
  62. package/dist/tokens/colors.d.ts +6 -1
  63. package/package.json +8 -2
@@ -24,10 +24,19 @@ import "@bfrs/agentic-components/styles";
24
24
 
25
25
  The stylesheet is safe to import globally. It does not ship Tailwind preflight, page-level resets, font-face declarations, unprefixed utilities, or generic keyframes.
26
26
 
27
+ The main stylesheet references the SF Pro family by name only (`--bfrs-font-sans`) and ships no font files. To have the library download and apply SF Pro across the **whole app**, additionally import the opt-in font stylesheet:
28
+
29
+ ```tsx
30
+ import "@bfrs/agentic-components/styles";
31
+ import "@bfrs/agentic-components/fonts.css";
32
+ ```
33
+
34
+ `fonts.css` bundles the SF Pro Display webfont (relative URLs, so any base path works), defines `--bfrs-font-sans` at the document root, and applies it to `html, body`. Angular consumers import it the same way (`@import "@bfrs/agentic-components/fonts.css";` in `styles.scss`, or add `dist/fonts.css` to the `angular.json` styles array). Skip it if the host app provides its own font.
35
+
27
36
  Import components by name:
28
37
 
29
38
  ```tsx
30
- import { BfrsProvider, Button, Input, Slider, ColorPicker, ColorSwatchGroup, RevealAndCopy, Modal, DataTable, DateRangePicker, ToastProvider, useToast } from "@bfrs/agentic-components";
39
+ import { BfrsProvider, Button, Input, Slider, ColorPicker, ColorSwatchGroup, OptionCardGroup, NumberStepper, SuggestInput, FileDropzone, RevealField, RevealAndCopy, Modal, DataTable, DateRangePicker, ToastProvider, useToast } from "@bfrs/agentic-components";
31
40
  ```
32
41
 
33
42
  React consumers should wrap BFRS surfaces in `BfrsProvider`; the provider owns `--bfrs-*` variables, color scheme, and portal inheritance.
@@ -106,11 +115,11 @@ Use native Angular DOM event bindings for interactions. Do not pass React-style
106
115
  <bfrs-paper (click)="openDetails()">Open details</bfrs-paper>
107
116
  ```
108
117
 
109
- Registered tags cover the documented component surface: `bfrs-box`, `bfrs-container`, `bfrs-paper`, `bfrs-stack`, `bfrs-grid`, `bfrs-text`, `bfrs-icon`, `bfrs-button`, `bfrs-icon-button`, `bfrs-form-field`, `bfrs-label`, `bfrs-input`, `bfrs-slider`, `bfrs-color-picker`, `bfrs-color-swatch-group`, `bfrs-textarea`, `bfrs-select`, `bfrs-date-range-picker`, `bfrs-searchable-select`, `bfrs-checkbox`, `bfrs-radio`, `bfrs-switch`, `bfrs-badge`, `bfrs-chip`, `bfrs-alert`, `bfrs-toast-manager`, `bfrs-spinner`, `bfrs-skeleton`, `bfrs-empty-state`, `bfrs-error-state`, `bfrs-loading-state`, `bfrs-modal`, `bfrs-drawer`, `bfrs-confirm-dialog`, `bfrs-dropdown`, `bfrs-tooltip`, `bfrs-popover`, `bfrs-avatar`, `bfrs-metric-card`, `bfrs-table-pagination`, `bfrs-data-table`, `bfrs-tabs`, `bfrs-breadcrumbs`, `bfrs-action-menu`, `bfrs-page-header`, `bfrs-section-header`, `bfrs-layout-shell`, `bfrs-form-section`, `bfrs-filter-bar`, `bfrs-filter-drawer`, `bfrs-chat-bubble`, `bfrs-chat-composer`, `bfrs-full-page-loader`, `bfrs-business-info-display-card`, `bfrs-reveal-and-copy`, and `bfrs-step-progress-card`.
118
+ Registered tags cover the documented component surface: `bfrs-box`, `bfrs-container`, `bfrs-paper`, `bfrs-stack`, `bfrs-grid`, `bfrs-text`, `bfrs-icon`, `bfrs-button`, `bfrs-icon-button`, `bfrs-form-field`, `bfrs-label`, `bfrs-input`, `bfrs-slider`, `bfrs-color-picker`, `bfrs-color-swatch-group`, `bfrs-textarea`, `bfrs-select`, `bfrs-date-range-picker`, `bfrs-searchable-select`, `bfrs-multi-select`, `bfrs-suggest-input`, `bfrs-option-card-group`, `bfrs-selectable-chip-group`, `bfrs-number-stepper`, `bfrs-file-dropzone`, `bfrs-reveal-field`, `bfrs-checkbox`, `bfrs-radio`, `bfrs-switch`, `bfrs-badge`, `bfrs-chip`, `bfrs-alert`, `bfrs-info-card`, `bfrs-tip`, `bfrs-toast-manager`, `bfrs-spinner`, `bfrs-skeleton`, `bfrs-empty-state`, `bfrs-error-state`, `bfrs-loading-state`, `bfrs-modal`, `bfrs-drawer`, `bfrs-confirm-dialog`, `bfrs-dropdown`, `bfrs-tooltip`, `bfrs-popover`, `bfrs-avatar`, `bfrs-metric-card`, `bfrs-table-pagination`, `bfrs-data-table`, `bfrs-tabs`, `bfrs-breadcrumbs`, `bfrs-action-menu`, `bfrs-page-header`, `bfrs-section-header`, `bfrs-layout-shell`, `bfrs-form-section`, `bfrs-filter-bar`, `bfrs-filter-drawer`, `bfrs-chat-bubble`, `bfrs-chat-composer`, `bfrs-full-page-loader`, `bfrs-business-info-display-card`, `bfrs-collapsible`, `bfrs-accordion`, `bfrs-summary-bar`, `bfrs-entity-display-card`, `bfrs-reveal-and-copy`, and `bfrs-step-progress-card`.
110
119
 
111
120
  Use attributes for simple props: `variant`, `size`, `tone`, `label`, `loading`, `disabled`, `required`, `error-message`, `error-text`, `helper-text`, `prefix`, `suffix`, `min`, `max`, `step`, and `value`. Use `[props]` or the `props` JSON attribute for structured props like `options`, palette arrays, `items`, `columns`, `data`, `sections`, `steps`, and `toasts`.
112
121
 
113
- Common component events: `(value-change)`, `(checked-change)`, `(open-change)`, `(reveal-change)`, `(copy)`, `(copy-error)`, `(close)`, `(confirm)`, `(cancel)`, `(row-click)`, `(sort-change)`, `(page-change)`, `(page-size-change)`, `(action-select)`, `(dropdown-select)`, `(date-range-change)`, `(search-change)`, `(open-filters)`, `(apply)`, `(reset)`, and `(submit)`. Payloads are available on `$event.detail`.
122
+ Common component events: `(value-change)`, `(checked-change)`, `(open-change)`, `(reveal-change)`, `(copy)`, `(copy-error)`, `(close)`, `(confirm)`, `(cancel)`, `(cell-action)`, `(row-click)`, `(sort-change)`, `(page-change)`, `(page-size-change)`, `(action-select)`, `(dropdown-select)`, `(date-range-change)`, `(search-change)`, `(open-filters)`, `(apply)`, `(reset)`, and `(submit)`. Payloads are available on `$event.detail`.
114
123
 
115
124
  For validated forms, keep client validation, API validation, and submit side effects in the consuming app. In React, pass field errors through `FormField errorText` and set `Input error`. In Angular, use `bfrs-input` with `[attr.error]` and `[attr.error-message]`, listen to `(value-change)`, and manage success/failure notifications with `bfrs-toast-manager`.
116
125
 
@@ -138,7 +147,7 @@ For validated forms, keep client validation, API validation, and submit side eff
138
147
  - All interactive components forward refs and spread native HTML props
139
148
  - Styling uses **Tailwind CSS** + **CVA** with the `bfrs-` utility prefix. Use classes such as `bfrs-flex`, `hover:bfrs-bg-primary`, and `bfrs-animate-shimmer` when you intentionally depend on library utilities. Unprefixed classes are treated as host-app classes.
140
149
  - Use the `cn()` utility from the library for conditional class merging; it merges prefixed BFRS utilities and preserves unprefixed host classes.
141
- - **Card surface standard** — all card-like components (`Card`, `MetricCard`, `FormSection`, `BusinessInfoDisplayCard`, and `StepProgressCard` when `surface="card"`) share the same surface style: `border-radius: 12px`, a faded green-grey gradient stroke (`bfrs-faded-card-border`), `background: linear-gradient(168deg, #FFF 8.6%, #FFFFFD 97.41%)`, `box-shadow: 0 0 21.7px 0 rgba(24, 240, 64, 0.03)`. Do not override these properties unless intentionally switching to a `muted` or `soft` variant.
150
+ - **Card surface standard** — default/elevated card-like components (`Card`, `MetricCard`, `FormSection`, `BusinessInfoDisplayCard`, and `StepProgressCard` when `surface="card"`) use the faded green-grey gradient stroke (`bfrs-faded-card-border`) and tokenized white surface. `Card variant="bordered"` and `Paper variant="outlined"` intentionally use the plain reference card spec: `border-radius: 12px`, `border: 1px solid hsl(var(--bfrs-color-border))`, `background: surface`, `box-shadow: none`, and default medium padding of `18px 22px`.
142
151
 
143
152
  ```tsx
144
153
  import { cn } from "@bfrs/agentic-components";
@@ -219,7 +228,7 @@ Flexbox layout. Use instead of writing flex utility classes directly.
219
228
 
220
229
  #### `Grid`
221
230
 
222
- Responsive CSS grid layout.
231
+ Responsive CSS grid layout. Use numeric shortcuts for common responsive grids or pass a custom CSS template/min column width for form layouts.
223
232
 
224
233
  ```tsx
225
234
  <Grid columns={3} gap="md">
@@ -227,11 +236,16 @@ Responsive CSS grid layout.
227
236
  <Card />
228
237
  <Card />
229
238
  </Grid>
239
+
240
+ <Grid templateColumns="2fr 1fr" />
241
+ <Grid minColumnWidth="220px" />
230
242
  ```
231
243
 
232
244
  | Prop | Type | Default |
233
245
  |------|------|---------|
234
- | `columns` | `1 \| 2 \| 3 \| 4` | `3` |
246
+ | `columns` | `1 \| 2 \| 3 \| 4 \| string` | `3` |
247
+ | `templateColumns` | `string` | — |
248
+ | `minColumnWidth` | `string` | — |
235
249
  | `gap` | `"sm" \| "md" \| "lg"` | `"md"` |
236
250
 
237
251
  ---
@@ -243,14 +257,19 @@ Semantic typography. Always use this instead of raw `<p>`, `<h1>`, `<span>` for
243
257
  ```tsx
244
258
  <Text variant="h2">Welcome back</Text>
245
259
  <Text variant="body" tone="muted">Last seen 2 hours ago</Text>
260
+ <Text variant="caption" weight="bold">Bold small label</Text>
261
+ <Text variant="h1" weight="normal">Light large heading</Text>
246
262
  ```
247
263
 
248
264
  | Prop | Type | Default |
249
265
  |------|------|---------|
250
- | `variant` | `"display" \| "h1" \| "h2" \| "h3" \| "title" \| "body" \| "body-sm" \| "caption" \| "label"` | `"body"` |
266
+ | `variant` | `"display" \| "h1" \| "h2" \| "h3" \| "title" \| "body" \| "body-sm" \| "body-xs" \| "caption" \| "label"` | `"body"` |
251
267
  | `tone` | `"primary" \| "secondary" \| "muted" \| "disabled" \| "danger" \| "success" \| "accent"` | `"primary"` |
268
+ | `weight` | `"normal" \| "medium" \| "semibold" \| "bold"` | per variant |
252
269
  | `as` | `ElementType` | inferred from variant |
253
270
 
271
+ Each variant ships a sensible default weight; pass `weight` to override it — e.g. make a small `caption`/`body-xs` bold, or a large `h1`/`display` normal.
272
+
254
273
  ---
255
274
 
256
275
  #### `Icon`
@@ -458,6 +477,8 @@ Single-value dropdown. Options are `{ value: string; label: string }`.
458
477
  | `disabled` | `boolean` | `false` |
459
478
  | `error` | `boolean` | `false` |
460
479
 
480
+ The selected value never wraps: it truncates with an ellipsis when it is too long for the trigger, and the full value appears in a tooltip on hover.
481
+
461
482
  ---
462
483
 
463
484
  #### `DateRangePicker`
@@ -519,6 +540,126 @@ Combobox with search. Use when options list is long (10+).
519
540
 
520
541
  ---
521
542
 
543
+ #### `MultiSelect`
544
+
545
+ Searchable multi-value select. Use for channel/category filters or any bounded list where more than one option can be selected.
546
+
547
+ ```tsx
548
+ <MultiSelect
549
+ options={channels}
550
+ value={selectedChannels}
551
+ onValueChange={setSelectedChannels}
552
+ placeholder="Select channels"
553
+ searchPlaceholder="Search channels..."
554
+ />
555
+ ```
556
+
557
+ Angular custom element:
558
+
559
+ ```html
560
+ <bfrs-multi-select
561
+ placeholder="Select channels"
562
+ [props]="{ options: channelOptions, value: channels }"
563
+ (value-change)="channels = $event.detail.value">
564
+ </bfrs-multi-select>
565
+ ```
566
+
567
+ | Prop | Type | Default |
568
+ |------|------|---------|
569
+ | `options` | `{ value: string; label: string; disabled?: boolean }[]` | **required** |
570
+ | `value` | `string[]` | — |
571
+ | `defaultValue` | `string[]` | `[]` |
572
+ | `onValueChange` | `(value: string[]) => void` | — |
573
+ | `placeholder` | `string` | `"Select"` |
574
+ | `searchPlaceholder` | `string` | `"Search..."` |
575
+ | `emptyText` | `string` | `"No results found"` |
576
+ | `loading` | `boolean` | `false` |
577
+ | `disabled` | `boolean` | `false` |
578
+ | `error` | `boolean` | `false` |
579
+ | `clearable` | `boolean` | `true` |
580
+ | `maxVisibleValues` | `number` | `2` |
581
+
582
+ ---
583
+
584
+ #### `OptionCardGroup`
585
+
586
+ Bordered selectable option cards for radio-style choices. Supports optional description, icon, disabled state, and help tooltip text.
587
+
588
+ ```tsx
589
+ <OptionCardGroup
590
+ value={mode}
591
+ onValueChange={setMode}
592
+ options={[
593
+ { value: "standard", label: "Standard", description: "Lowest cost option.", helpText: "Best for flexible delivery." },
594
+ { value: "express", label: "Express", description: "Prioritize faster pickup." }
595
+ ]}
596
+ />
597
+ ```
598
+
599
+ Angular: `<bfrs-option-card-group [props]="{ options, value }" (value-change)="value = $event.detail.value"></bfrs-option-card-group>`.
600
+
601
+ ---
602
+
603
+ #### `SelectableChipGroup`
604
+
605
+ Segmented icon/label chips with selected state and optional trailing add action. Use `multiple` for checkbox-like chip groups.
606
+
607
+ ```tsx
608
+ <SelectableChipGroup multiple value={channels} options={channelOptions} addAction={{ label: "Add" }} onValueChange={setChannels} />
609
+ ```
610
+
611
+ Angular: `<bfrs-selectable-chip-group multiple [props]="{ options, value }" (value-change)="value = $event.detail.value"></bfrs-selectable-chip-group>`.
612
+
613
+ ---
614
+
615
+ #### `NumberStepper`
616
+
617
+ Quantity input rendered as decrement, value, increment controls.
618
+
619
+ ```tsx
620
+ <NumberStepper value={quantity} min={1} max={10} onValueChange={setQuantity} />
621
+ ```
622
+
623
+ Angular: `<bfrs-number-stepper [value]="quantity" min="1" max="10" (value-change)="quantity = $event.detail.value"></bfrs-number-stepper>`.
624
+
625
+ ---
626
+
627
+ #### `SuggestInput`
628
+
629
+ Free-text input with async-friendly suggestions dropdown. Use when the user may type arbitrary text; use `SearchableSelect` when the final value must be from a bounded option list.
630
+
631
+ ```tsx
632
+ <SuggestInput value={city} suggestions={citySuggestions} onValueChange={setCity} onSuggestionSelect={setSelectedCity} />
633
+ ```
634
+
635
+ Angular: `<bfrs-suggest-input [props]="{ suggestions, value }" (value-change)="value = $event.detail.value"></bfrs-suggest-input>`.
636
+
637
+ ---
638
+
639
+ #### `FileDropzone`
640
+
641
+ Drag/drop file selection area. Uploading, validation, and API side effects remain app-owned.
642
+
643
+ ```tsx
644
+ <FileDropzone title="Upload invoice" accept="application/pdf,image/*" onFilesChange={setFiles} />
645
+ ```
646
+
647
+ Angular: `<bfrs-file-dropzone title="Upload invoice" (files-change)="files = $event.detail.files"></bfrs-file-dropzone>`.
648
+
649
+ ---
650
+
651
+ #### `RevealField`
652
+
653
+ Field-level masked value with reveal and optional copy action, built on `RevealAndCopy`.
654
+
655
+ ```tsx
656
+ <RevealField label="Phone" value="9876543210" allowCopy helperText="Only reveal when required." />
657
+ ```
658
+
659
+ Angular: `<bfrs-reveal-field label="Phone" value="9876543210"></bfrs-reveal-field>`.
660
+
661
+ ---
662
+
522
663
  #### `Slider`
523
664
 
524
665
  Controlled numeric range control. Use instead of raw `<input type="range">`.
@@ -794,6 +935,30 @@ Contextual message banner. Auto-selects an icon based on tone.
794
935
 
795
936
  ---
796
937
 
938
+ #### `InfoCard`
939
+
940
+ Flexible callout with leading colored icon, title, description, optional actions, and semantic tone.
941
+
942
+ ```tsx
943
+ <InfoCard tone="info" title="Courier allocation is ready" description="Review serviceability before assigning the shipment." />
944
+ ```
945
+
946
+ Angular: `<bfrs-info-card title="Courier allocation is ready" description="Review serviceability before assigning the shipment."></bfrs-info-card>`.
947
+
948
+ ---
949
+
950
+ #### `Tip`
951
+
952
+ Small subtle accent pill for hints such as recommended, verified, or review states.
953
+
954
+ ```tsx
955
+ <Tip tone="success">Verified</Tip>
956
+ ```
957
+
958
+ Angular: `<bfrs-tip tone="success">Verified</bfrs-tip>`.
959
+
960
+ ---
961
+
797
962
  #### `ToastProvider`, `useToast`, `ToastManager`
798
963
 
799
964
  App-wide transient feedback manager. Wrap the app once, then call toast helpers from event handlers.
@@ -1129,6 +1294,30 @@ Generic data table with sorting, loading skeleton, row actions, selection, pagin
1129
1294
 
1130
1295
  When `loading` is true, `DataTable` renders built-in table-row skeleton placeholders rather than a spinner. The consumer app only owns the loading boolean.
1131
1296
 
1297
+ Custom-element DataTable action cells must be declarative because Angular/HTML cannot pass React `cell` functions through JSON. Use `cellType: "button"` for one inline button, `cellType: "buttons"` for multiple inline buttons, or `cellType: "actions"` for an action menu. Action clicks emit `cell-action` with `{ actionId, columnId, row, rowId, rowIndex }` and do not trigger `row-click`.
1298
+
1299
+ ```html
1300
+ <bfrs-data-table
1301
+ [props]="{
1302
+ data: orders,
1303
+ columns: [
1304
+ { id: 'orderId', header: 'Order ID', accessorKey: 'orderId' },
1305
+ {
1306
+ id: 'actions',
1307
+ header: 'Actions',
1308
+ cellType: 'buttons',
1309
+ actions: [
1310
+ { id: 'view', label: 'View', variant: 'outline', size: 'sm', iconName: 'eye' },
1311
+ { id: 'ship', label: 'Ship now', variant: 'primary', size: 'sm', disabledKey: 'shipDisabled' }
1312
+ ]
1313
+ }
1314
+ ]
1315
+ }"
1316
+ (cell-action)="handleTableAction($event.detail)"
1317
+ (row-click)="openOrder($event.detail.row)">
1318
+ </bfrs-data-table>
1319
+ ```
1320
+
1132
1321
  ---
1133
1322
 
1134
1323
  ### Navigation
@@ -1244,6 +1433,80 @@ Full-page app shell with sticky header and collapsible sidebar.
1244
1433
 
1245
1434
  ---
1246
1435
 
1436
+ #### `WorkspaceHeader`
1437
+
1438
+ Slot-based top bar for Agentic Platform workspaces. It preserves the standalone prototype chrome by default: 52px header height, 216px brand rail, 380px chat/workspace rail, 300px search slot, strong dividers, and compact 26px sidebar toggle. Product-specific brand, tab title/collapse controls, search internals, wallet, launcher, and avatar remain app-owned slots.
1439
+
1440
+ ```tsx
1441
+ <WorkspaceHeader
1442
+ brand={<ShiprocketBrand />}
1443
+ onToggleSidebar={toggleSidebar}
1444
+ tabs={<ActiveWorkspaceTab />}
1445
+ search={<HeaderJumpSearch />}
1446
+ actions={<HeaderActions />}
1447
+ />
1448
+ ```
1449
+
1450
+ | Prop | Type | Default |
1451
+ |------|------|---------|
1452
+ | `brand` | `ReactNode` | — |
1453
+ | `brandWidth` | `number` | `216` |
1454
+ | `brandCollapsed` | `boolean` | `false` |
1455
+ | `collapsedBrandWidth` | `number` | `56` |
1456
+ | `onToggleSidebar` | `() => void` | — |
1457
+ | `toggleLabel` | `string` | `"Toggle sidebar"` |
1458
+ | `tabs` | `ReactNode` | — |
1459
+ | `tabsWidth` | `number` | `380` |
1460
+ | `tabsCollapsed` | `boolean` | `false` |
1461
+ | `collapsedTabsWidth` | `number` | `40` |
1462
+ | `search` | `ReactNode` | — |
1463
+ | `searchWidth` | `number` | `300` |
1464
+ | `actions` | `ReactNode` | — |
1465
+ | `children` | `ReactNode` | — |
1466
+ | `height` | `number` | `52` |
1467
+
1468
+ Use `brandCollapsed` and `tabsCollapsed` to mirror the standalone collapsed sidebar/chat rails. Use explicit widths only when the host app intentionally diverges from the prototype.
1469
+
1470
+ ---
1471
+
1472
+ #### `SideNav`
1473
+
1474
+ Collapsible application sidebar navigation. Renders grouped sections of items with active state, badges, and hover flyouts for nested items, plus `header`, `footer`, and `children` slots. All data (labels, icons, handlers) is passed in — the component owns layout and collapse behavior.
1475
+
1476
+ ```tsx
1477
+ <SideNav
1478
+ collapsed={collapsed}
1479
+ sections={[
1480
+ {
1481
+ id: "nav",
1482
+ items: [
1483
+ { id: "orders", label: "Orders", icon: <Icon icon={Package} />, active: true, onSelect: goOrders },
1484
+ { id: "finance", label: "Finance", icon: <Icon icon={Wallet} />, nested: [
1485
+ { id: "cod", label: "COD Remittance", onSelect: goCod },
1486
+ ] },
1487
+ ],
1488
+ },
1489
+ ]}
1490
+ footer={<UserMenu />}
1491
+ />
1492
+ ```
1493
+
1494
+ | Prop | Type | Default |
1495
+ |------|------|---------|
1496
+ | `sections` | `SideNavSection[]` | **required** |
1497
+ | `collapsed` | `boolean` | `false` |
1498
+ | `width` | `number` | `240` |
1499
+ | `collapsedWidth` | `number` | `56` |
1500
+ | `header` | `ReactNode` | — |
1501
+ | `children` | `ReactNode` | — |
1502
+ | `footer` | `ReactNode` | — |
1503
+
1504
+ - `SideNavSection`: `{ id?, title?, items, action? }` — `title` (uppercase) and `action` are hidden when collapsed.
1505
+ - `SideNavItem`: `{ id, label, icon?, active?, badge?, nested?, onSelect? }` — `badge` is hidden when collapsed; `nested` opens a hover flyout (expanded only).
1506
+ - When `collapsed`, each row hides its `label` and surfaces it as a right-side `Tooltip` on hover, so items stay identifiable by icon alone.
1507
+
1508
+ ---
1509
+
1247
1510
  #### `ChatBubble`
1248
1511
 
1249
1512
  Chat message bubble. Renders differently for `user`, `assistant`, and `system` senders. Assistant messages support a Figma-derived identity block with an uppercase eyebrow, title, and muted body copy.
@@ -1326,6 +1589,81 @@ Branded full-screen loading screen. Use during auth redirects and account setup.
1326
1589
 
1327
1590
  ---
1328
1591
 
1592
+ #### `Collapsible`
1593
+
1594
+ Inline expandable section with caret, title, optional description, controlled or uncontrolled open state, and `open-change` custom-element event.
1595
+
1596
+ ```tsx
1597
+ <Collapsible title="Courier rules" description="Expandable inline section">
1598
+ <Text variant="body-sm">Rules and restrictions.</Text>
1599
+ </Collapsible>
1600
+ ```
1601
+
1602
+ Angular: `<bfrs-collapsible title="Courier rules" (open-change)="open = $event.detail.open">Rules and restrictions</bfrs-collapsible>`.
1603
+
1604
+ ---
1605
+
1606
+ #### `Accordion`
1607
+
1608
+ Grouped expandable sections. Use `type="single"` (default) to keep one panel open at a time, or `type="multiple"` to allow several. Each item is `{ value, title, content, description?, disabled? }`. Use `Collapsible` instead for a single standalone disclosure.
1609
+
1610
+ ```tsx
1611
+ <Accordion
1612
+ type="single"
1613
+ defaultValue="pickup"
1614
+ items={[
1615
+ { value: "pickup", title: "Pickup details", description: "Warehouse and contact", content: <Text variant="body-sm">Plot 42, Sector 18, Gurugram.</Text> },
1616
+ { value: "shipping", title: "Shipping preferences", content: <Text variant="body-sm">Standard delivery.</Text> }
1617
+ ]}
1618
+ onValueChange={setOpenSection}
1619
+ />
1620
+ ```
1621
+
1622
+ | Prop | Type | Default |
1623
+ |------|------|---------|
1624
+ | `items` | `{ value: string; title: ReactNode; content: ReactNode; description?: ReactNode; disabled?: boolean }[]` | **required** |
1625
+ | `type` | `"single" \| "multiple"` | `"single"` |
1626
+ | `value` | `string \| string[]` | — |
1627
+ | `defaultValue` | `string \| string[]` | — |
1628
+ | `onValueChange` | `(value: string \| string[]) => void` | — |
1629
+ | `collapsible` | `boolean` | `true` |
1630
+
1631
+ For `type="single"`, `value`/`defaultValue`/`onValueChange` use a string; for `type="multiple"` they use a string array.
1632
+
1633
+ Angular: `<bfrs-accordion type="single" [props]="{ items: sections }" (value-change)="openSection = $event.detail.value"></bfrs-accordion>`. Pass each item's `content` as a string in custom-element usage.
1634
+
1635
+ ---
1636
+
1637
+ #### `SummaryBar`
1638
+
1639
+ Highlighted total/summary row for subtotal, charges, total, and optional note.
1640
+
1641
+ ```tsx
1642
+ <SummaryBar items={[{ label: "Subtotal", value: "₹840" }, { label: "Charges", value: "₹60" }]} totalLabel="Total" totalValue="₹900" />
1643
+ ```
1644
+
1645
+ Angular: `<bfrs-summary-bar total-label="Total" total-value="₹900" [props]="{ items }"></bfrs-summary-bar>`.
1646
+
1647
+ ---
1648
+
1649
+ #### `EntityDisplayCard`
1650
+
1651
+ Read-only selected address/entity card with status badge, metadata, and inline edit/action controls.
1652
+
1653
+ ```tsx
1654
+ <EntityDisplayCard
1655
+ title="Dee-doodles warehouse"
1656
+ description="Plot 42, Sector 18, Gurugram, Haryana"
1657
+ status="Verified"
1658
+ actions={[{ id: "edit", label: "Edit" }]}
1659
+ onAction={handleAction}
1660
+ />
1661
+ ```
1662
+
1663
+ Angular: `<bfrs-entity-display-card title="Dee-doodles warehouse" status="Verified" [props]="{ actions }" (entity-action)="handleEntityAction($event.detail.action)"></bfrs-entity-display-card>`.
1664
+
1665
+ ---
1666
+
1329
1667
  #### `RevealAndCopy`
1330
1668
 
1331
1669
  Masked sensitive-value display with a reveal action and optional clipboard copy. Use for phone numbers, email addresses, tokens, and other values that should not render as plaintext until the user asks to reveal them. The plaintext value is not placed in the DOM while masked.
@@ -1440,7 +1778,7 @@ Built-in loading behavior:
1440
1778
 
1441
1779
  #### `StepProgressCard`
1442
1780
 
1443
- Step-by-step progress indicator. Calculates `done` / `active` / `pending` state automatically from `currentStep` and preserves the animated completed-dot, active-star, and rail-fill transitions. Defaults to the Figma-derived plain progress block; pass `surface="card"` for the standard card wrapper.
1781
+ Step-by-step progress indicator. Calculates `done` / `active` / `pending` state automatically from `currentStep` and preserves the green completed-dot, active-star, and rail-fill transitions. Defaults to the Figma-derived plain progress block; pass `surface="card"` for the standard card wrapper.
1444
1782
 
1445
1783
  ```tsx
1446
1784
  <StepProgressCard
package/README.md CHANGED
@@ -42,6 +42,17 @@ export function Example() {
42
42
 
43
43
  The stylesheet is safe to import globally: it does not ship Tailwind preflight, page-level resets, global font-face declarations, unprefixed utilities, or generic keyframes. React surfaces should still render inside `BfrsProvider`; the provider owns `--bfrs-*` theme variables and passes the same scope to Radix portals.
44
44
 
45
+ ### Optional: bundled SF Pro font
46
+
47
+ The main stylesheet only references the SF Pro family by name (`--bfrs-font-sans`) — it ships no font files, so by default you supply the font. To have the library download and apply SF Pro across your **whole app**, additionally import the opt-in font stylesheet once at your entry point:
48
+
49
+ ```tsx
50
+ import "@bfrs/agentic-components/styles";
51
+ import "@bfrs/agentic-components/fonts.css";
52
+ ```
53
+
54
+ This bundles the SF Pro Display webfont (relative URLs, so any base path works), defines `--bfrs-font-sans` at the document root, and applies it to `html, body`. Keeping it separate means the main stylesheet stays free of global `@font-face`/`html`/`body` rules.
55
+
45
56
  Most DOM-backed components forward compatible React props such as `onClick`, `onKeyDown`, `aria-*`, `data-*`, `className`, `style`, and refs. Controlled components expose explicit callbacks such as `onValueChange`, `onOpenChange`, `onSort`, `onRowClick`, and `onPageChange`.
46
57
 
47
58
  Library-owned Tailwind utilities are prefixed with `bfrs-`, for example `bfrs-flex`, `hover:bfrs-bg-primary`, and `bfrs-animate-shimmer`. Unprefixed classes passed through `className` are treated as host-app classes.
@@ -60,14 +71,17 @@ import "@bfrs/agentic-components/custom-elements";
60
71
  ```scss
61
72
  /* styles.scss */
62
73
  @import "@bfrs/agentic-components/styles";
74
+ /* Optional — bundled SF Pro, applied to the whole app: */
75
+ @import "@bfrs/agentic-components/fonts.css";
63
76
  ```
64
77
 
65
- If Angular does not resolve the package style export, add the built CSS file in `angular.json`:
78
+ If Angular does not resolve the package style export, add the built CSS files in `angular.json`:
66
79
 
67
80
  ```json
68
81
  {
69
82
  "styles": [
70
83
  "node_modules/@bfrs/agentic-components/dist/style.css",
84
+ "node_modules/@bfrs/agentic-components/dist/fonts.css",
71
85
  "src/styles.scss"
72
86
  ]
73
87
  }
@@ -113,12 +127,30 @@ Use simple attributes for primitive values and `[props]` for structured values o
113
127
 
114
128
  <bfrs-data-table
115
129
  [props]="{ data: orders, columns: orderColumns, selection: true }"
130
+ (cell-action)="handleTableAction($event.detail)"
116
131
  (row-click)="openOrder($event.detail.row)"
117
132
  (sort-change)="sorting = $event.detail.sorting">
118
133
  </bfrs-data-table>
119
134
  ```
120
135
 
121
- Registered tags include `bfrs-box`, `bfrs-container`, `bfrs-paper`, `bfrs-stack`, `bfrs-grid`, `bfrs-text`, `bfrs-icon`, `bfrs-button`, `bfrs-icon-button`, `bfrs-form-field`, `bfrs-label`, `bfrs-input`, `bfrs-slider`, `bfrs-color-picker`, `bfrs-color-swatch-group`, `bfrs-textarea`, `bfrs-select`, `bfrs-date-range-picker`, `bfrs-searchable-select`, `bfrs-checkbox`, `bfrs-radio`, `bfrs-switch`, `bfrs-badge`, `bfrs-chip`, `bfrs-alert`, `bfrs-toast-manager`, `bfrs-spinner`, `bfrs-skeleton`, `bfrs-empty-state`, `bfrs-error-state`, `bfrs-loading-state`, `bfrs-modal`, `bfrs-drawer`, `bfrs-confirm-dialog`, `bfrs-dropdown`, `bfrs-tooltip`, `bfrs-popover`, `bfrs-avatar`, `bfrs-metric-card`, `bfrs-table-pagination`, `bfrs-data-table`, `bfrs-tabs`, `bfrs-breadcrumbs`, `bfrs-action-menu`, `bfrs-page-header`, `bfrs-section-header`, `bfrs-layout-shell`, `bfrs-form-section`, `bfrs-filter-bar`, `bfrs-filter-drawer`, `bfrs-chat-bubble`, `bfrs-chat-composer`, `bfrs-full-page-loader`, `bfrs-business-info-display-card`, `bfrs-reveal-and-copy`, and `bfrs-step-progress-card`.
136
+ For DataTable action cells in Angular, use serializable column configs instead of React `cell` functions:
137
+
138
+ ```ts
139
+ orderColumns = [
140
+ { id: "orderId", header: "Order ID", accessorKey: "orderId" },
141
+ {
142
+ id: "actions",
143
+ header: "Actions",
144
+ cellType: "buttons",
145
+ actions: [
146
+ { id: "view", label: "View", variant: "outline", size: "sm", iconName: "eye" },
147
+ { id: "ship", label: "Ship now", variant: "primary", size: "sm", disabledKey: "shipDisabled" }
148
+ ]
149
+ }
150
+ ];
151
+ ```
152
+
153
+ Registered tags include `bfrs-box`, `bfrs-container`, `bfrs-paper`, `bfrs-stack`, `bfrs-grid`, `bfrs-text`, `bfrs-icon`, `bfrs-button`, `bfrs-icon-button`, `bfrs-form-field`, `bfrs-label`, `bfrs-input`, `bfrs-slider`, `bfrs-color-picker`, `bfrs-color-swatch-group`, `bfrs-textarea`, `bfrs-select`, `bfrs-date-range-picker`, `bfrs-searchable-select`, `bfrs-multi-select`, `bfrs-suggest-input`, `bfrs-option-card-group`, `bfrs-selectable-chip-group`, `bfrs-number-stepper`, `bfrs-file-dropzone`, `bfrs-reveal-field`, `bfrs-checkbox`, `bfrs-radio`, `bfrs-switch`, `bfrs-badge`, `bfrs-chip`, `bfrs-alert`, `bfrs-info-card`, `bfrs-tip`, `bfrs-toast-manager`, `bfrs-spinner`, `bfrs-skeleton`, `bfrs-empty-state`, `bfrs-error-state`, `bfrs-loading-state`, `bfrs-modal`, `bfrs-drawer`, `bfrs-confirm-dialog`, `bfrs-dropdown`, `bfrs-tooltip`, `bfrs-popover`, `bfrs-avatar`, `bfrs-metric-card`, `bfrs-table-pagination`, `bfrs-data-table`, `bfrs-tabs`, `bfrs-breadcrumbs`, `bfrs-action-menu`, `bfrs-page-header`, `bfrs-section-header`, `bfrs-layout-shell`, `bfrs-form-section`, `bfrs-filter-bar`, `bfrs-filter-drawer`, `bfrs-chat-bubble`, `bfrs-chat-composer`, `bfrs-full-page-loader`, `bfrs-business-info-display-card`, `bfrs-collapsible`, `bfrs-accordion`, `bfrs-summary-bar`, `bfrs-entity-display-card`, `bfrs-reveal-and-copy`, and `bfrs-step-progress-card`.
122
154
 
123
155
  ## Theme Overrides
124
156
 
@@ -0,0 +1,16 @@
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
+ import { Tone } from '../../../../tokens';
3
+ export type InfoCardProps = Omit<HTMLAttributes<HTMLDivElement>, "title"> & {
4
+ tone?: Tone;
5
+ icon?: ReactNode;
6
+ title: ReactNode;
7
+ description?: ReactNode;
8
+ actions?: ReactNode;
9
+ };
10
+ export declare const InfoCard: import('react').ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "title"> & {
11
+ tone?: Tone;
12
+ icon?: ReactNode;
13
+ title: ReactNode;
14
+ description?: ReactNode;
15
+ actions?: ReactNode;
16
+ } & import('react').RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,2 @@
1
+ export { InfoCard } from './InfoCard';
2
+ export type { InfoCardProps } from './InfoCard';
@@ -0,0 +1,8 @@
1
+ import { HTMLAttributes } from 'react';
2
+ import { Tone } from '../../../../tokens';
3
+ export type TipProps = HTMLAttributes<HTMLSpanElement> & {
4
+ tone?: Tone;
5
+ };
6
+ export declare const Tip: import('react').ForwardRefExoticComponent<HTMLAttributes<HTMLSpanElement> & {
7
+ tone?: Tone;
8
+ } & import('react').RefAttributes<HTMLSpanElement>>;
@@ -0,0 +1,2 @@
1
+ export { Tip } from './Tip';
2
+ export type { TipProps } from './Tip';
@@ -0,0 +1,21 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export type FileDropzoneProps = Omit<HTMLAttributes<HTMLDivElement>, "onDrop"> & {
3
+ accept?: string;
4
+ multiple?: boolean;
5
+ disabled?: boolean;
6
+ error?: boolean;
7
+ title?: string;
8
+ description?: string;
9
+ browseLabel?: string;
10
+ onFilesChange?: (files: File[]) => void;
11
+ };
12
+ export declare const FileDropzone: import('react').ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "onDrop"> & {
13
+ accept?: string;
14
+ multiple?: boolean;
15
+ disabled?: boolean;
16
+ error?: boolean;
17
+ title?: string;
18
+ description?: string;
19
+ browseLabel?: string;
20
+ onFilesChange?: (files: File[]) => void;
21
+ } & import('react').RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,2 @@
1
+ export { FileDropzone } from './FileDropzone';
2
+ export type { FileDropzoneProps } from './FileDropzone';
@@ -0,0 +1,20 @@
1
+ import { SelectOption } from '../Select';
2
+ export type MultiSelectProps = {
3
+ options: SelectOption[];
4
+ value?: string[];
5
+ defaultValue?: string[];
6
+ onValueChange?: (value: string[]) => void;
7
+ placeholder?: string;
8
+ searchPlaceholder?: string;
9
+ emptyText?: string;
10
+ loading?: boolean;
11
+ disabled?: boolean;
12
+ error?: boolean;
13
+ clearable?: boolean;
14
+ maxVisibleValues?: number;
15
+ className?: string;
16
+ id?: string;
17
+ "aria-describedby"?: string;
18
+ "aria-invalid"?: boolean;
19
+ };
20
+ export declare const MultiSelect: import('react').ForwardRefExoticComponent<MultiSelectProps & import('react').RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ export * from './MultiSelect';
@@ -0,0 +1,21 @@
1
+ import { InputHTMLAttributes } from 'react';
2
+ export type NumberStepperProps = Omit<InputHTMLAttributes<HTMLInputElement>, "defaultValue" | "onChange" | "size" | "value"> & {
3
+ value?: number;
4
+ defaultValue?: number;
5
+ onValueChange?: (value: number) => void;
6
+ min?: number;
7
+ max?: number;
8
+ step?: number;
9
+ size?: "sm" | "md";
10
+ error?: boolean;
11
+ };
12
+ export declare const NumberStepper: import('react').ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "value" | "defaultValue" | "onChange"> & {
13
+ value?: number;
14
+ defaultValue?: number;
15
+ onValueChange?: (value: number) => void;
16
+ min?: number;
17
+ max?: number;
18
+ step?: number;
19
+ size?: "sm" | "md";
20
+ error?: boolean;
21
+ } & import('react').RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,2 @@
1
+ export { NumberStepper } from './NumberStepper';
2
+ export type { NumberStepperProps } from './NumberStepper';