hs-uix 2.0.1 → 2.1.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/README.md CHANGED
@@ -15,26 +15,36 @@ npm install hs-uix
15
15
  import { DataTable } from "hs-uix/datatable";
16
16
  import { FormBuilder } from "hs-uix/form";
17
17
  import { Feed } from "hs-uix/feed";
18
- import { Icon, AutoStatusTag, AutoTag, CrmLookupSelect, KeyValueList, SectionHeader } from "hs-uix/common-components";
18
+ import { Calendar } from "hs-uix/calendar";
19
+ import {
20
+ Icon,
21
+ AutoStatusTag,
22
+ AutoTag,
23
+ CrmLookupSelect,
24
+ KeyValueList,
25
+ SectionHeader,
26
+ CollectionToolbar,
27
+ } from "hs-uix/common-components";
19
28
  import { CrmDataTable, CrmKanban, formatCurrency, formatDate } from "hs-uix/utils";
20
29
 
21
30
  // or import everything from the root
22
- import { DataTable, FormBuilder, Icon, AutoStatusTag, AutoTag } from "hs-uix";
31
+ import { DataTable, FormBuilder, Kanban, Feed, Calendar, Icon } from "hs-uix";
23
32
  ```
24
33
 
25
- Requires `react` >= 18.0.0 and `@hubspot/ui-extensions` >= 0.12.0 as peer dependencies (already present in any HubSpot UI Extensions project).
34
+ Requires `react` >= 18.0.0 and `@hubspot/ui-extensions` >= 0.14.0 as peer dependencies (already present in any HubSpot UI Extensions project).
26
35
 
27
36
  ## Components
28
37
 
29
38
  | Component | Description | Docs |
30
39
  |-----------|-------------|------|
31
- | **DataTable** | Filterable, sortable, paginated table with auto-sized columns, inline editing, row grouping, and more | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/packages/datatable/README.md) |
32
- | **FormBuilder** | Declarative, config-driven form with validation, multi-step wizards, and 20+ field types | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/packages/form/README.md) |
33
- | **Kanban** | Stage-based board with filters, sort, headline metrics, card action bars, and DataTable-parity card field config | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/packages/kanban/README.md) |
34
- | **Feed** | Activity feed / timeline with a standard item shape, date grouping, load-more pagination, and HubSpot-native item regions | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/packages/feed/README.md) |
35
- | **Common Components** | Thin visual wrappers over HubSpot primitives `Icon`, `AutoTag`, `AutoStatusTag`, `AvatarStack`, `CrmLookupSelect`, `SectionHeader`, `KeyValueList`, `StyledText` | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/src/common-components/README.md) |
40
+ | **DataTable** | Filterable, sortable, paginated table with auto-sized columns, inline editing, row grouping, and more | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/src/datatable/README.md) |
41
+ | **FormBuilder** | Declarative, config-driven form with validation, multi-step wizards, and 20+ field types | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/src/form/README.md) |
42
+ | **Kanban** | Stage-based board with filters, sort, headline metrics, card action bars, and DataTable-parity card field config | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/src/kanban/README.md) |
43
+ | **Feed** | Activity feed / timeline with a standard item shape, date grouping, load-more pagination, and HubSpot-native item regions | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/src/feed/README.md) |
44
+ | **Calendar** | Presentational month/week/day/agenda calendar with search, filters, date navigation, event overlays, and experimental Gantt view | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/src/calendar/README.md) |
45
+ | **Common Components** | Thin visual wrappers and shared collection primitives — `Icon`, `AutoTag`, `AutoStatusTag`, `AvatarStack`, `CrmLookupSelect`, `CollectionToolbar`, `CollectionFilterControl`, `CollectionSortSelect`, `CollectionCount`, and more | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/src/common-components/README.md) |
36
46
  | **CRM data** | `CrmDataTable` / `CrmKanban` — batch-fetching, client-side-paginating CRM table & board, plus the `useCrmSearch*` hooks behind them | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/src/utils/README.md) |
37
- | **Utils** | Pure helpers for formatting, options, HubSpot value guards, and tag-variant inference | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/src/utils/README.md) |
47
+ | **Utils** | Pure helpers for formatting, options, HubSpot value guards, tag-variant inference, collection filtering/searching, and active-filter chips | [Full documentation](https://github.com/05bmckay/hs-uix/blob/main/src/utils/README.md) |
38
48
 
39
49
  ---
40
50
 
@@ -42,7 +52,7 @@ Requires `react` >= 18.0.0 and `@hubspot/ui-extensions` >= 0.12.0 as peer depend
42
52
 
43
53
  A drop-in table component for HubSpot UI Extensions. Define your columns, pass your data, and you get search, filtering, sorting, pagination, inline editing, row grouping, and auto-sized columns out of the box.
44
54
 
45
- ![Full-Featured DataTable](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/datatable/assets/fully-featured-table.png)
55
+ ![Full-Featured DataTable](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/datatable/assets/fully-featured-table.png)
46
56
 
47
57
  ## Quick Start
48
58
 
@@ -95,29 +105,29 @@ That's a searchable, sortable, paginated table with auto-sized columns in 5 line
95
105
 
96
106
  ### Filters & Footer Totals
97
107
 
98
- ![Active Filters](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/datatable/assets/fully-featured-table-active-filters.png)
108
+ ![Active Filters](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/datatable/assets/fully-featured-table-active-filters.png)
99
109
 
100
110
  ### Row Selection & Bulk Actions
101
111
 
102
- ![Row Selection with Action Bar](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/datatable/assets/action-bar-per-row-actions.png)
112
+ ![Row Selection with Action Bar](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/datatable/assets/action-bar-per-row-actions.png)
103
113
 
104
114
  ### Inline Editing
105
115
 
106
- ![Discrete Editing](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/datatable/assets/inline-editing-discreet.png)
116
+ ![Discrete Editing](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/datatable/assets/inline-editing-discreet.png)
107
117
 
108
118
  Two edit modes: **discrete** (click-to-edit, default) and **inline** (always-visible inputs). Supports `text`, `textarea`, `number`, `currency`, `stepper`, `select`, `multiselect`, `date`, `time`, `datetime`, `toggle`, and `checkbox`.
109
119
 
110
120
  ### Row Grouping
111
121
 
112
- ![Row Grouping](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/datatable/assets/row-grouping.png)
122
+ ![Row Grouping](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/datatable/assets/row-grouping.png)
113
123
 
114
124
  ### Full-Row Editing
115
125
 
116
- ![Full-Row Editing](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/datatable/assets/full-row-editing.png)
126
+ ![Full-Row Editing](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/datatable/assets/full-row-editing.png)
117
127
 
118
128
  ### useAssociations
119
129
 
120
- ![useAssociations + DataTable](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/datatable/assets/useAssociations.png)
130
+ ![useAssociations + DataTable](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/datatable/assets/useAssociations.png)
121
131
 
122
132
  Connect live CRM data (contacts, deals, tickets, etc.) to a DataTable with `useAssociations` from `@hubspot/ui-extensions/crm`.
123
133
 
@@ -127,7 +137,7 @@ Connect live CRM data (contacts, deals, tickets, etc.) to a DataTable with `useA
127
137
 
128
138
  Declarative, config-driven forms for HubSpot UI Extensions. Define fields as data, get a complete form with validation, layout, multi-step wizards, and full HubSpot component integration.
129
139
 
130
- ![Basic Form](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/form/assets/basic-form.png)
140
+ ![Basic Form](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/form/assets/basic-form.png)
131
141
 
132
142
  ## Quick Start
133
143
 
@@ -166,35 +176,35 @@ const fields = [
166
176
 
167
177
  ### Layout
168
178
 
169
- ![Explicit Layout](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/form/assets/explicit-layout-weighted.png)
179
+ ![Explicit Layout](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/form/assets/explicit-layout-weighted.png)
170
180
 
171
181
  ### Conditional Visibility & Dependent Properties
172
182
 
173
- ![Dependent & Cascading](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/form/assets/dependent-cascading.gif)
183
+ ![Dependent & Cascading](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/form/assets/dependent-cascading.gif)
174
184
 
175
185
  ### Async Validation
176
186
 
177
- ![Async Validation](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/form/assets/async-validation-side-effects.png)
187
+ ![Async Validation](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/form/assets/async-validation-side-effects.png)
178
188
 
179
189
  ### Repeater Fields
180
190
 
181
- ![Repeater Fields](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/form/assets/repeater-fields.png)
191
+ ![Repeater Fields](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/form/assets/repeater-fields.png)
182
192
 
183
193
  ### Sections & Groups
184
194
 
185
- ![Sections & Groups](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/form/assets/section-and-groups.png)
195
+ ![Sections & Groups](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/form/assets/section-and-groups.png)
186
196
 
187
197
  ### Custom Field Types
188
198
 
189
- ![Custom Field Types](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/form/assets/custom-field-types.png)
199
+ ![Custom Field Types](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/form/assets/custom-field-types.png)
190
200
 
191
201
  ### Display Options
192
202
 
193
- ![Display Options](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/form/assets/display-options.png)
203
+ ![Display Options](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/form/assets/display-options.png)
194
204
 
195
205
  ### Read-Only Mode
196
206
 
197
- ![Read-Only Mode](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/form/assets/readonly-autosave-dirty.png)
207
+ ![Read-Only Mode](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/form/assets/readonly-autosave-dirty.png)
198
208
 
199
209
  ---
200
210
 
@@ -202,7 +212,7 @@ const fields = [
202
212
 
203
213
  A stage-based board view that shares DataTable's config vocabulary (`cardFields` ≈ `columns`, filters, sort, selection) so you can offer users a table-or-board toggle without rewriting the data layer. Drag-and-drop isn't available inside HubSpot UI Extensions, so stage changes happen through an inline `Select` (or menu) on each card.
204
214
 
205
- ![Kanban — HubSpot Deals preset with metrics](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/kanban/assets/hubspot-deals-preset-with-metrics.png)
215
+ ![Kanban — HubSpot Deals preset with metrics](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/kanban/assets/hubspot-deals-preset-with-metrics.png)
206
216
 
207
217
  ## Quick Start
208
218
 
@@ -251,21 +261,21 @@ const CARD_FIELDS = [
251
261
 
252
262
  ### HubSpot Deals preset
253
263
 
254
- ![Kanban — HubSpot Deals preset with metrics](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/kanban/assets/hubspot-deals-preset-with-metrics.png)
264
+ ![Kanban — HubSpot Deals preset with metrics](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/kanban/assets/hubspot-deals-preset-with-metrics.png)
255
265
 
256
266
  Drop-in preset shaped like HubSpot's native deals pipeline: stage-variant headers, per-stage amount totals in the header metric, and an avatar-stack footer row. Hide the summary row with `showMetrics={false}` for dashboards that already surface totals elsewhere.
257
267
 
258
- ![Kanban — HubSpot Deals preset without metrics](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/kanban/assets/hubspot-deals-preset-no-metrics.png)
268
+ ![Kanban — HubSpot Deals preset without metrics](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/kanban/assets/hubspot-deals-preset-no-metrics.png)
259
269
 
260
270
  ### Compact lead board
261
271
 
262
- ![Kanban — Compact lead board preset](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/kanban/assets/compact-lead-board-preset.png)
272
+ ![Kanban — Compact lead board preset](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/kanban/assets/compact-lead-board-preset.png)
263
273
 
264
274
  `cardDensity="compact"` with trimmed `cardFields` for high-volume boards (leads, tickets, tasks) where you want to fit 8-12 cards per column on a typical viewport without horizontal scrolling.
265
275
 
266
276
  ### Load-more & stage controls
267
277
 
268
- ![Kanban — Select + load more preset](https://raw.githubusercontent.com/05bmckay/hs-uix/main/packages/kanban/assets/select-load-more-preset.png)
278
+ ![Kanban — Select + load more preset](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/kanban/assets/select-load-more-preset.png)
269
279
 
270
280
  Per-stage pagination via an `onLoadMore` handler and `stageMeta.hasMore`, plus inline `Select` stage controls on each card (`stageControl="select"`). Switch to `"menu"` for action-menu style transitions, or `"none"` for read-only boards.
271
281
 
@@ -341,7 +351,7 @@ A superset of HubSpot's native `<Icon>`. When the request is natively expressibl
341
351
 
342
352
  ![CrmLookupSelect live search](https://raw.githubusercontent.com/05bmckay/hs-uix/main/src/common-components/assets/crmLookUp.gif)
343
353
 
344
- Point it at a CRM `objectType` + `properties` and get a debounced, paginated `Select` / `MultiSelect` that searches live as the user types. Picked options stay valid after results change, `loadingOption` shows during the debounce window, and `noResultsOption` only appears once a query settles — no "no results" flash mid-type.
354
+ Point it at a CRM `objectType` + `properties` and get a debounced `Select` / `MultiSelect` that searches the first `pageLength` CRM matches as the user types. Picked options stay valid after results change, `loadingOption` shows during the debounce window, and `noResultsOption` only appears once a query settles — no "no results" flash mid-type. For custom lookup UIs that need native cursor controls, `useCrmSearchOptions` exposes `pagination` / `hasMore`.
345
355
 
346
356
  ### SectionHeader & KeyValueList
347
357
 
package/calendar.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/calendar/index";
@@ -100,6 +100,139 @@ export interface AvatarStackProps {
100
100
  alt?: string;
101
101
  }
102
102
 
103
+ export interface CollectionFilterConfig {
104
+ name: string;
105
+ type?: "select" | "multiselect" | "dateRange" | string;
106
+ label?: string;
107
+ placeholder?: string;
108
+ options?: Array<{ label: ReactNode; value: unknown }>;
109
+ includeAll?: boolean;
110
+ allValue?: unknown;
111
+ emptyValue?: unknown;
112
+ allLabel?: string;
113
+ chipLabel?: string;
114
+ fromLabel?: string;
115
+ toLabel?: string;
116
+ }
117
+
118
+ export interface CollectionFilterLabels {
119
+ all?: string;
120
+ dateFrom?: string;
121
+ dateTo?: string;
122
+ }
123
+
124
+ export interface CollectionFilterControlProps {
125
+ filter?: CollectionFilterConfig;
126
+ value?: unknown;
127
+ onChange?: (name: string, value: unknown) => void;
128
+ namePrefix?: string;
129
+ labels?: CollectionFilterLabels;
130
+ selectVariant?: "transparent" | "input" | string;
131
+ includeAll?: boolean;
132
+ allValue?: unknown;
133
+ }
134
+
135
+ export interface ActiveFilterChip {
136
+ key: string;
137
+ label: ReactNode;
138
+ }
139
+
140
+ export interface ActiveFilterChipsProps {
141
+ chips?: ActiveFilterChip[];
142
+ showBadges?: boolean;
143
+ showClearAll?: boolean;
144
+ clearAllLabel?: ReactNode;
145
+ onRemove?: (key: string) => void;
146
+ gap?: string;
147
+ }
148
+
149
+ export interface CollectionToolbarSearchConfig {
150
+ visible?: boolean;
151
+ show?: boolean;
152
+ name?: string;
153
+ placeholder?: string;
154
+ value?: string;
155
+ clearable?: boolean;
156
+ onChange?: (value: string) => void;
157
+ onInput?: (value: string) => void;
158
+ }
159
+
160
+ export interface CollectionToolbarFiltersConfig {
161
+ items?: CollectionFilterConfig[];
162
+ values?: Record<string, unknown>;
163
+ inlineLimit?: number;
164
+ namePrefix?: string;
165
+ onChange?: (name: string, value: unknown) => void;
166
+ labels?: CollectionFilterLabels & Record<string, unknown>;
167
+ includeAll?: boolean;
168
+ allValue?: unknown;
169
+ selectVariant?: "transparent" | "input" | string;
170
+ overflowButtonSize?: string;
171
+ filtersButtonLabel?: ReactNode;
172
+ }
173
+
174
+ export interface CollectionToolbarChipsConfig {
175
+ items?: ActiveFilterChip[];
176
+ showBadges?: boolean;
177
+ showClearAll?: boolean;
178
+ clearAllLabel?: ReactNode;
179
+ onRemove?: (key: string) => void;
180
+ gap?: string;
181
+ }
182
+
183
+ export interface CollectionCountLabelObject {
184
+ singular: string;
185
+ plural: string;
186
+ }
187
+
188
+ export interface CollectionCountProps {
189
+ shown?: number;
190
+ total?: number;
191
+ label?: string | CollectionCountLabelObject | ((count: number) => string);
192
+ text?: ReactNode;
193
+ formatter?: (shown: number, total: number) => ReactNode;
194
+ bold?: boolean;
195
+ variant?: string;
196
+ format?: Record<string, unknown>;
197
+ }
198
+
199
+ export interface FormatCollectionCountParams {
200
+ shown?: number;
201
+ total?: number;
202
+ label?: string | CollectionCountLabelObject | ((count: number) => string);
203
+ formatter?: (shown: number, total: number) => ReactNode;
204
+ }
205
+
206
+ export interface CollectionSortSelectProps {
207
+ name?: string;
208
+ value?: string | null;
209
+ options?: Array<{ label: ReactNode; value: string }>;
210
+ placeholder?: string;
211
+ onChange?: (value: string) => void;
212
+ includeEmpty?: boolean;
213
+ emptyValue?: string;
214
+ variant?: "transparent" | "input" | string;
215
+ idPrefix?: string;
216
+ uniqueName?: boolean;
217
+ }
218
+
219
+ export interface CollectionToolbarProps {
220
+ search?: CollectionToolbarSearchConfig;
221
+ filters?: CollectionToolbarFiltersConfig;
222
+ chips?: CollectionToolbarChipsConfig;
223
+ right?: ReactNode;
224
+ footer?: ReactNode;
225
+ labels?: Record<string, unknown>;
226
+ leftFlex?: number;
227
+ rightFlex?: number;
228
+ rightAlignSelf?: string;
229
+ gap?: string;
230
+ /** Optional stable prefix used to generate unique child input/select names. */
231
+ idPrefix?: string;
232
+ /** Append a per-toolbar suffix to child input/select names. Default true. */
233
+ uniqueNames?: boolean;
234
+ }
235
+
103
236
  export interface CrmLookupSelectProps {
104
237
  objectType: "contact" | "contacts" | "company" | "companies" | "deal" | "deals" | string;
105
238
  properties?: string[];
@@ -267,6 +400,10 @@ export interface IconProps {
267
400
  size?: IconSize;
268
401
  /** Accessible label for screen readers. */
269
402
  screenReaderText?: string;
403
+ /** Passed through to native HubSpot Icon when possible; fallback Image also receives it. */
404
+ onClick?: (...args: unknown[]) => void;
405
+ /** Passed through to native HubSpot Icon when possible; fallback Image also receives it. */
406
+ href?: string | { url: string; external?: boolean };
270
407
  }
271
408
 
272
409
  export interface IconDataUriResult {
@@ -297,6 +434,12 @@ export declare function svgToIconEntry(raw: string): IconEntry;
297
434
 
298
435
  export declare function AutoTag(props: AutoTagProps): ReactNode;
299
436
  export declare function AutoStatusTag(props: AutoStatusTagProps): ReactNode;
437
+ export declare function ActiveFilterChips(props: ActiveFilterChipsProps): ReactNode;
438
+ export declare function CollectionCount(props: CollectionCountProps): ReactNode;
439
+ export declare function formatCollectionCount(params: FormatCollectionCountParams): ReactNode;
440
+ export declare function CollectionFilterControl(props: CollectionFilterControlProps): ReactNode;
441
+ export declare function CollectionSortSelect(props: CollectionSortSelectProps): ReactNode;
442
+ export declare function CollectionToolbar(props: CollectionToolbarProps): ReactNode;
300
443
  export declare function SectionHeader(props: SectionHeaderProps): ReactNode;
301
444
  export declare function KeyValueList(props: KeyValueListProps): ReactNode;
302
445
  export declare function AvatarStack(props: AvatarStackProps): ReactNode;
package/datatable.d.ts CHANGED
@@ -1,27 +1 @@
1
- export {
2
- DataTable,
3
- DataTableProps,
4
- DataTableColumn,
5
- DataTableFilterConfig,
6
- DataTableFilterType,
7
- DataTableGroupBy,
8
- DataTableSortDirection,
9
- DataTableSortObject,
10
- DataTableParams,
11
- DataTableOption,
12
- DataTableDateValue,
13
- DataTableTimeValue,
14
- DataTableDateRangeValue,
15
- DataTableWidth,
16
- DataTableColumnWidth,
17
- DataTableEditMode,
18
- DataTableEditType,
19
- DataTableSelectionAction,
20
- DataTableRowAction,
21
- DataTableSelectAllRequestPayload,
22
- DataTableLabels,
23
- DataTableSelectionBarRenderContext,
24
- DataTableEmptyStateRenderContext,
25
- DataTableLoadingStateRenderContext,
26
- DataTableErrorStateRenderContext,
27
- } from "./packages/datatable/index";
1
+ export * from "./src/datatable/index";