@hubspot/ui-extensions 0.8.16 → 0.8.17

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
@@ -2,2230 +2,4 @@
2
2
 
3
3
  React components and utilities for extending HubSpot's UI.
4
4
 
5
- ## TOC
6
-
7
- - [Accordion](#accordion)
8
- - [Alert](#alert)
9
- - [Box](#box)
10
- - [Button](#button)
11
- - [ButtonRow](#buttonrow)
12
- - [Card](#card)
13
- - [DateInput](#dateinput)
14
- - [DescriptionList](#descriptionlist)
15
- - [DescriptionListItem](#descriptionlistitem)
16
- - [Divider](#divider)
17
- - [Flex](#flex)
18
- - [Form](#form)
19
- - [EmptyState](#emptystate)
20
- - [ErrorState](#errorstate)
21
- - [Heading](#heading)
22
- - [Image](#image)
23
- - [Input](#input)
24
- - [Link](#link)
25
- - [LoadingSpinner](#loadingspinner)
26
- - [MultiSelect](#multiselect)
27
- - [NumberInput](#numberInput)
28
- - [ProgressBar](#progressbar)
29
- - [Select](#select)
30
- - [Stack](#stack)
31
- - [Statistics](#statistics)
32
- - [StatisticsItem](#statisticsitem)
33
- - [StatisticsTrend](#statisticstrend)
34
- - [StepIndicator](#StepIndicator)
35
- - [Table](#table)
36
- - [TableBody](#tablebody)
37
- - [TableCell](#tablecell)
38
- - [TableFooter](#tablefooter)
39
- - [TableHead](#tablehead)
40
- - [TableHeader](#tableheader)
41
- - [TableRow](#tablerow)
42
- - [Tag](#tag)
43
- - [Text](#text)
44
- - [TextArea](#textarea)
45
- - [Tile](#tile)
46
- - [ToggleGroup](#togglegroup)
47
-
48
- ## Components
49
-
50
- ### Accordion
51
-
52
- ##### Import
53
-
54
- ```javascript
55
- import { Accordion } from '@hubspot/ui-extensions';
56
- ```
57
-
58
- ##### Props
59
-
60
- The Accordion component accepts the following props:
61
-
62
- ```typescript
63
- export interface AccordionProps {
64
- title: string;
65
- children: ReactNode;
66
- defaultOpen?: boolean;
67
- disabled?: boolean;
68
- open?: boolean;
69
- onClick?: () => void;
70
- size?:
71
- | 'small'
72
- | 'extra-small'
73
- | 'medium'
74
- | 'xs'
75
- | 'sm'
76
- | 'md';
77
- }
78
- ```
79
-
80
- | Prop | Type | Default | Description |
81
- | --- | --- | --- | --- |
82
- | `title` | `string` | `N/A` | The title text for the accordion. |
83
- | `children` | `ReactNode(optional)` | `N/A` | The main content of the accordion when it opens. |
84
- | `defaultOpen` | `boolean(optional)` | `false` | If `true`, the accordion will be open by default. |
85
- | `disabled` | `boolean(optional)` | `false` | If `true`, users cannot change the open state of the accordion. |
86
- | `open` | `boolean(optional)` | `N/A` | Use it when you want to control the open state programatically. If true, the accordion will open. |
87
- | `onClick` | `() => void` `(optional)` | `N/A` | A function that will be invoked when the title is clicked. It receives no arguments and it's return value is ignored. |
88
- | `size` | `'extra-small' \| 'small' \| 'medium' \| 'xs' \| 'sm' \| 'md'` | `'small'` | The size of the accordion title.|
89
-
90
-
91
- ##### Usage
92
-
93
- ```javascript
94
- function Extension() {
95
- return (
96
- <>
97
- <Accordion title="Item One">
98
- <Text>first inner text</Text>
99
- </Accordion>
100
- <Accordion title="Item Two">
101
- <Text>second inner text</Text>
102
- </Accordion>
103
- </>
104
- );
105
- }
106
- ```
107
-
108
- ### Alert
109
-
110
- ##### Import
111
-
112
- ```javascript
113
- import { Alert } from '@hubspot/ui-extensions';
114
- ```
115
-
116
- ##### Props
117
-
118
- The Alert component accepts the following props:
119
-
120
- ```typescript
121
- export interface AlertProps {
122
- title: string;
123
- children?: ReactNode;
124
- variant?: 'info' | 'warning' | 'success' | 'error' | 'danger';
125
- }
126
- ```
127
-
128
- | Prop | Type | Default | Description |
129
- | --- | --- | --- | --- |
130
- | `title` | `string` | `N/A` | The title text for the alert message. |
131
- | `children` | `ReactNode(optional)` | `N/A` | The main content of the alert message when the body prop is not provided. |
132
- | `variant` | `'info' \| 'warning' \| 'success' \|'error' \| 'danger'` `(optional)` | `'info'` | Sets the color variation of the alert |
133
-
134
- ##### Usage
135
-
136
- ```javascript
137
- const Extension = () => {
138
- return (
139
- <>
140
- <Alert title="Important Info" variant="info">
141
- This is an informative message.
142
- </Alert>
143
- <Alert title="Success"variant="success">
144
- Operation completed successfully.
145
- </Alert>
146
- <Alert title="Warning" variant="warning" >
147
- Proceed with caution.
148
- </Alert>
149
- <Alert title="Error" variant="error" >
150
- Something went wrong. Please try again.
151
- </Alert>
152
- <Alert title="Danger" variant="danger" >
153
- This action cannot be undone. Be careful.
154
- </Alert>
155
- </>
156
- );
157
- };
158
- ```
159
-
160
- ### Box
161
-
162
- ##### Import
163
-
164
- ```javascript
165
- import { Box } from '@hubspot/ui-extensions';
166
- ```
167
-
168
- ##### Props
169
-
170
- ```typescript
171
- export interface BoxProps {
172
- children: ReactNode;
173
- alignSelf?: 'start' | 'center' | 'baseline' | 'end' | 'stretch' | 'auto';
174
- flex?: 'initial' | 'auto' | 'none' | number;
175
- }
176
- ```
177
-
178
- | Prop | Type | Default | Description |
179
- | --- | --- | --- | --- |
180
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
181
- | `alignSelf` | `'start' \| 'center' \| 'baseline' \| 'end' \| 'stretch' \| 'auto'` `(optional)` | `'auto'` | Overrides flex's align item value for this element. |
182
- | `flex` | `'initial' \| 'auto' \| 'none' \| number` `(optional)` | `'initial'` | Sets how the item will grow or shrink when it's a direct ancestor of the Flex component. |
183
-
184
-
185
- #### flex prop Options
186
-
187
- - `initial`: The item is sized according to its width and height properties. It shrinks to its minimum size to fit the container, but does not grow to absorb any extra free space in the flex container.
188
- - `auto`: The item is sized according to its width and height properties, but grows to absorb any extra free space in the flex container, and shrinks to its minimum size to fit the container.
189
- - `none`: The item is sized according to its width and height properties. It is fully inflexible: it neither shrinks nor grows in relation to the flex container.
190
- - `number`: Tells a component to fill all available space, shared evenly amongst other components with the same parent. The larger the flex given, the higher the ratio of space a component will take compared to its siblings.
191
-
192
- ##### Usage
193
-
194
- ```javascript
195
- const Extension = () => {
196
- return (
197
- <Box>
198
- <Text>Hello</Text>
199
- </Box>
200
- );
201
- };
202
- ```
203
-
204
-
205
- ### Button
206
-
207
- ##### Import
208
-
209
- ```javascript
210
- import { Button } from '@hubspot/ui-extensions';
211
- ```
212
-
213
- ##### Props
214
-
215
- ```typescript
216
- interface ButtonProps {
217
- children: string;
218
- onClick?: () => void;
219
- href?: string;
220
- disabled?: boolean;
221
- variant?: 'primary' | 'secondary' | 'destructive';
222
- type?: 'button' | 'reset' | 'submit';
223
- }
224
- ```
225
-
226
- | Prop | Type | Default | Description |
227
- | --- | --- | --- | --- |
228
- | `children` | `string` | `N/A` | The displayable text for the Button |
229
- | `onClick` | `() => void` `(optional)` | `N/A` | A function that will be invoked when the button is clicked. It receives no arguments and it's return value is ignored |
230
- | `href` | `string(optional)` | `N/A` | A URL that will be opened when the button is clicked. If the value is a URL external to HubSpot it will be opened in a new tab. |
231
- | `disabled` | `boolean(optional)` | `N/A` | Determines if the button should be disabled or not. |
232
- | `variant` | `'primary' \| 'secondary' \| 'destructive'` `(optional)` | `'secondary'` | Sets the color variation of the button |
233
- | `type` | `'button' \| 'reset' \| 'submit'` `(optional)` | `'button'` | Sets the HTML attribute "role" of the button |
234
-
235
- ##### Usage
236
-
237
- ```javascript
238
- const Extension = () => {
239
- return (
240
- <Button
241
- onClick={() => {
242
- console.log('Someone clicked on the button!');
243
- }}
244
- href="https://hubspot.com"
245
- variant="destructive"
246
- type="button"
247
- >
248
- Click me!
249
- </Button>
250
- );
251
- };
252
- ```
253
-
254
- ### ButtonRow
255
-
256
- ##### Import
257
-
258
- ```javascript
259
- import { ButtonRow } from '@hubspot/ui-extensions';
260
- ```
261
-
262
- ##### Props
263
-
264
- ```typescript
265
- interface ButtonRowProps {
266
- children: ReactNode;
267
- disableDropdown?: boolean;
268
- }
269
- ```
270
-
271
- | Prop | Type | Default | Description |
272
- | --- | --- | --- | --- |
273
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
274
- | `disableDropdown` | `boolean(optional)` | `false` | Disables the dropdown list of buttons that appears the the children expand beyond the horizontal space |
275
-
276
- ##### Usage
277
-
278
- ```javascript
279
- const Extension = () => {
280
- return (
281
- <ButtonRow disableDropdown={false}>
282
- <Button
283
- onClick={() => {
284
- console.log('Regular button clicked');
285
- }}
286
- >
287
- Regular Button
288
- </Button>
289
- <Button
290
- onClick={() => {
291
- console.log('Reset button clicked');
292
- }}
293
- variant="destructive"
294
- type="reset"
295
- >
296
- Reset
297
- </Button>
298
- <Button
299
- onClick={() => {
300
- console.log('Submit button clicked');
301
- }}
302
- variant="primary"
303
- type="submit"
304
- >
305
- Submit
306
- </Button>
307
- </ButtonRow>
308
- );
309
- };
310
- ```
311
-
312
- ### Card
313
-
314
- ##### Import
315
-
316
- ```javascript
317
- import { Card } from '@hubspot/ui-extensions';
318
- ```
319
-
320
- ##### Props
321
-
322
- ```typescript
323
- interface CardProps {
324
- children: ReactNode;
325
- }
326
- ```
327
-
328
- | Prop | Type | Default | Description |
329
- | --- | --- | --- | --- |
330
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
331
-
332
- ##### Usage
333
-
334
- ```javascript
335
- const Extension = () => {
336
- return (
337
- <Card>
338
- <Button
339
- onClick={() => {
340
- console.log('Regular button clicked');
341
- }}
342
- >
343
- Regular Button
344
- </Button>
345
- </Card>
346
- );
347
- };
348
- ```
349
-
350
- ### DateInput
351
-
352
- ##### Import
353
-
354
- ```javascript
355
- import { DateInput } from '@hubspot/ui-extensions';
356
- ```
357
-
358
- ##### Props
359
-
360
- ```typescript
361
- interface DateInputProps {
362
- label: string;
363
- name: string;
364
- value?: { year: number; month: number; date: number };
365
- required?: boolean;
366
- readOnly?: boolean;
367
- description?: string;
368
- tooltip?: string;
369
- error?: boolean;
370
- defaultValue?: { year: number; month: number; date: number };
371
- validationMessage?: string;
372
- onChange?: (value: {
373
- year: number;
374
- month: number;
375
- date: number;
376
- formattedDate?: string;
377
- }) => void;
378
- onBlur?: (value: {
379
- year: number;
380
- month: number;
381
- date: number;
382
- formattedDate?: string;
383
- }) => void;
384
- onFocus?: (value: {
385
- year: number;
386
- month: number;
387
- date: number;
388
- formattedDate?: string;
389
- }) => void;
390
- min?: { year: number; month: number; date: number };
391
- max?: { year: number; month: number; date: number };
392
- minValidationMessage?: string;
393
- maxValidationMessage?: string;
394
- format?:
395
- | 'YYYY-MM-DD'
396
- | 'L'
397
- | 'LL'
398
- | 'll'
399
- | 'short'
400
- | 'long'
401
- | 'medium'
402
- | 'standard';
403
- timezone?: 'userTz' | 'portalTz';
404
- clearButtonLabel?: string;
405
- todayButtonLabel?: string;
406
- }
407
- ```
408
-
409
- | Prop | Type | Default | Description |
410
- | --- | --- | --- | --- |
411
- | `label` | `string` | `N/A` | The label text to display for the form input element. |
412
- | `name` | `string` | `N/A` | The unique identifier for the input element, this could be thought of as the HTML5 [Input element's name attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#name) |
413
- | `value` | `{ year: number; month: number; date: number }(optional)` | `N/A` | The value of the input |
414
- | `required` | `boolean(optional)` | `false` | Determines if the required indicator should be displayed |
415
- | `readOnly` | `boolean(optional)` | `false` | Determines if the field is editable or not. |
416
- | `description` | `string(optional)` | `N/A` | Instructional message to display to the user to help understand the purpose of the input. |
417
- | `tooltip` | `string(optional)` | `N/A` | Text that will appear in a tooltip next to the input label. |
418
- | `error` | `boolean(optional)` | `false` | If set to true, `validationMessage` is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, `validationMessage` is displayed as a success message. |
419
- | `validationMessage` | `string(optional)` | `''` | The text to show if the input has an error. |
420
- | `onChange` | `(value: {year: number; month: number; date: number; formattedDate?: string;}) => void(optional)` | `N/A` | A callback function that is invoked when the user selects or types a valid date. It won't get called on invalid inputs. |
421
- | `onBlur` | `(value: {year: number; month: number; date: number; formattedDate?: string;}) => void(optional)` | `N/A` | A function that is called and passed the value every time the field loses focus. |
422
- | `onFocus` | `(value: {year: number; month: number; date: number; formattedDate?: string;}) => void(optional)` | `N/A` | A function that is called and passed the value every time the field gets focused. |
423
- | `min` | `{ year: number; month: number; date: number }(optional)` | `N/A` | Sets the earliest date that will be valid. |
424
- | `max` | `{ year: number; month: number; date: number }(optional)` | `N/A` | Sets the latest date that will be valid|
425
- | `minValidationMessage` | `string` | `"You must choose an older date"` | Sets the message that users will see when the hover over dates that are older than the min date. |
426
- | `maxValidationMessage` | `string` | `"You must choose a newer date"` | Sets the message that users will see when the hover over dates that are newer than the max date. |
427
- | `format` | `'short' \| 'long' \| 'medium' \| 'standard' \| 'YYYY-MM-DD' \| 'L' \| 'LL' \| 'll'` | `short` | Sets the date format that input will display to users. |
428
- | `timezone` | `'userTz' \| 'portalTz'` | `userTz` | Sets the timezone that the component will user to calculate valid dates. |
429
- | `clearButtonLabel` | `string` | `Clear` | Sets the label of the clear button. |
430
- | `todayButtonLabel` | `string` | `Today` | Sets the label of the today button.|
431
-
432
-
433
- #### Format Options
434
-
435
- - short: `09/04/1986`
436
- - long: `September 4, 1986`
437
- - medium : `Sep 4, 1986`
438
- - standard: `1986-09-04`
439
- - L: `09/04/1986`
440
- - LL: `September 4, 1986`
441
- - ll : `Sep 4, 1986`
442
- - YYYY-MM-DD: `1986-09-04`
443
-
444
- ##### Usage
445
-
446
- ```javascript
447
- const Extension = () => {
448
- return (
449
- <DateInput
450
- label="Appointment Date"
451
- name="appointment-date"
452
- format="LL"
453
- />
454
- );
455
- };
456
- ```
457
-
458
- ### DescriptionList
459
-
460
- ##### Import
461
-
462
- ```javascript
463
- import { DescriptionList } from '@hubspot/ui-extensions';
464
- ```
465
-
466
- ##### Props
467
-
468
- ```typescript
469
- interface DescriptionListProps {
470
- children: ReactNode;
471
- direction?: 'row' | 'column';
472
- }
473
- ```
474
-
475
- | Prop | Type | Default | Description |
476
- | --- | --- | --- | --- |
477
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. The children should be [DescriptionListItem](#descriptionlistitem) |
478
- | `direction` | `'row' \| 'column'` `(optional)` | `'column'` | The direction the label/value pairs are placed in the description list container. |
479
-
480
- ##### Usage
481
-
482
- ```javascript
483
- const Extension = () => {
484
- return (
485
- <DescriptionList direction="row">
486
- <DescriptionListItem label={'First Name'}>
487
- <Text>Alan</Text>
488
- </DescriptionListItem>
489
- <DescriptionListItem label={'Last Name'}>
490
- <Text>Turing</Text>
491
- </DescriptionListItem>
492
- </DescriptionList>
493
- );
494
- };
495
- ```
496
-
497
- #### DescriptionListItem
498
-
499
- ##### Import
500
-
501
- ```javascript
502
- import { DescriptionListItem } from '@hubspot/ui-extensions';
503
- ```
504
-
505
- ##### Props
506
-
507
- ```typescript
508
- interface DescriptionListItemProps {
509
- children: ReactNode;
510
- label: string;
511
- }
512
- ```
513
-
514
- | Prop | Type | Default | Description |
515
- | --- | --- | --- | --- |
516
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
517
- | `label` | `string` | `N/A` | Text to be displayed as the label |
518
-
519
- ##### Usage
520
-
521
- ```javascript
522
- const Extension = () => {
523
- return (
524
- <DescriptionList direction="row">
525
- <DescriptionListItem label={'First Name'}>
526
- <Text>Alan</Text>
527
- </DescriptionListItem>
528
- <DescriptionListItem label={'Last Name'}>
529
- <Text>Turing</Text>
530
- </DescriptionListItem>
531
- </DescriptionList>
532
- );
533
- };
534
- ```
535
-
536
- ### Divider
537
-
538
- ##### Import
539
-
540
- ```javascript
541
- import { Divider } from '@hubspot/ui-extensions';
542
- ```
543
-
544
- ##### Props
545
-
546
- ```typescript
547
- interface DividerProps {
548
- distance?:
549
- | 'flush'
550
- | 'extra-small'
551
- | 'small'
552
- | 'medium'
553
- | 'large'
554
- | 'extra-large';
555
- }
556
- ```
557
-
558
- | Prop | Type | Default | Description |
559
- | --- | --- | --- | --- |
560
- | `distance` | `'flush'\| 'extra-small' \| 'small' \| 'medium' \| 'large'\| 'extra-large'` `(optional)` | `'small'` | The size of the padding above and below the divider. |
561
-
562
- ##### Usage
563
-
564
- ```javascript
565
- const Extension = () => {
566
- return <Divider distance="extra-large" />;
567
- };
568
- ```
569
-
570
- ### Flex
571
-
572
- ##### Import
573
-
574
- ```javascript
575
- import { Flex } from '@hubspot/ui-extensions';
576
- ```
577
-
578
- ##### Props
579
-
580
- ```typescript
581
- export interface FlexProps {
582
- children?: React.ReactNode;
583
- direction?: 'row' | 'column';
584
- justify?: 'center' | 'end' | 'start' | 'around' | 'between';
585
- align?: 'start' | 'center' | 'baseline' | 'end' | 'stretch';
586
- alignSelf?: 'start' | 'center' | 'baseline' | 'end' | 'stretch';
587
- wrap?: 'wrap' | 'nowrap';
588
- gap?:
589
- | 'flush'
590
- | 'small'
591
- | 'extra-small'
592
- | 'medium'
593
- | 'large'
594
- | 'extra-large'
595
- | 'xs'
596
- | 'sm'
597
- | 'md'
598
- | 'lg'
599
- | 'xl';
600
- }
601
- ```
602
-
603
- | Prop | Type | Default | Description |
604
- | --- | --- | --- | --- |
605
- | `direction` | `'row' \| 'column'` | `'column'` | Sets the direction in which elements are placed. |
606
- | `justify` | `'start' \| 'center' \|'end' \|'around' \| 'between'` | `'start'` | Defines how to distribute space between and around children on main axis. |
607
- | `align` | `'start' \| 'center' \|'baseline' \| 'end' \| 'stretch' \|'between'` | `'start'` | Controls the aligment of children in the cross axis. |
608
- | `alignSelf` | `'start' \| 'center' \| 'baseline' \| 'end' \| 'stretch' \| 'auto'` `(optional)` | `'auto'` | Overrides flex's align item value for this element. Useful when `Flex` is the child of another `Flex` component. |
609
- | `wrap` | `'wrap' \| 'nowrap'` | `'nowrap'` | If set to `nowrap`, children are forced onto one line. If set to `wrap`, they can wrap into multiple lines. |
610
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
611
- | `gap` | `'flush' \| 'extra-small' \| 'small' \| 'medium' \| 'large' \| 'extra-large' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'small'` | Amount of space between each child component passed as children. |
612
-
613
- ##### Usage
614
-
615
- ```javascript
616
- const Extension = () => {
617
- return (
618
- <Flex direction="column" distance="large">
619
- <Tile>Tile 1</Tile>
620
- <Tile>Tile 2</Tile>
621
- <Tile>Tile 3</Tile>
622
- </Flex>
623
- );
624
- };
625
- ```
626
-
627
- ### Form
628
-
629
- ##### Import
630
-
631
- ```javascript
632
- import { Form } from '@hubspot/ui-extensions';
633
- ```
634
-
635
- ##### Props
636
-
637
- ```typescript
638
- interface FormProps {
639
- children: ReactNode;
640
- onSubmit?: (event: RemoteEvent<FormInputValues>) => void;
641
- preventDefault?: boolean;
642
- }
643
- ```
644
-
645
- | Prop | Type | Default | Description |
646
- | --- | --- | --- | --- |
647
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
648
- | `onSubmit` | `function(optional)` | `N/A` | A function that will be called when the form is submitted. It will receive a `RemoteEvent` as argument and it's return value will be ignored. |
649
- | `preventDefault` | `boolean(optional)` | `false` | If set to `true` `event.preventDefault()` will be invoked before your `onSubmit` function is called, preventing the default html form behavior. |
650
-
651
- ##### Usage
652
-
653
- ```javascript
654
- const Extension = () => {
655
- return (
656
- <Form onSubmit={() => { console.log('Form submitted!')}} preventDefault={true}>
657
- <Input {...} />
658
- <Select {...} />
659
- <Button
660
- onClick={() => {
661
- console.log('Submit button clicked');
662
- }}
663
- variant="primary"
664
- type="submit"
665
- >
666
- Submit
667
- </Button>
668
- </Form>
669
- );
670
- }
671
- ```
672
-
673
- ### EmptyState
674
-
675
- ##### Import
676
-
677
- ```javascript
678
- import { EmptyState } from '@hubspot/ui-extensions';
679
- ```
680
-
681
- ##### Props
682
-
683
- ```typescript
684
- interface EmptyStateProps {
685
- children: ReactNode;
686
- flush?: boolean;
687
- imageWidth?: number;
688
- layout?: 'horizontal' | 'vertical';
689
- reverseOrder?: boolean;
690
- title?: string;
691
- }
692
- ```
693
-
694
- | Prop | Type | Default | Description |
695
- | --- | --- | --- | --- |
696
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
697
- | `flush` | `boolean(optional)` | `false` | Removes the default vertical margins for the component. |
698
- | `imageWidth` | `number(optional)` | `250` | The max-width for the image container. |
699
- | `layout` | `'horizontal' \| 'vertical'` `(optional)` | `'horizontal'` | Sets the layout direction for the content. |
700
- | `reverseOrder` | `boolean(optional)` | `false` | Swaps the visual order of the text (primary) and image (secondary) content. This ensures the primary content is still presented first to assistive technology. |
701
- | `title` | `string(optional)` | `Intl('All is not lost.')` | The text for the title header rendered above the `children`. |
702
-
703
- ##### Usage
704
-
705
- ```javascript
706
- const Extension = ({ data }) => {
707
- if (!data || !data.length) {
708
- return (
709
- <EmptyState title="Nothing here yet" layout="vertical" reverseOrder={true}>
710
- <Text>Go out there and get some leads!</Text>
711
- </EmptyState>
712
- )
713
- }
714
-
715
- return (
716
- <Stack>
717
- {data.map(...)}
718
- </Stack>
719
- );
720
- }
721
- ```
722
-
723
- ### ErrorState
724
-
725
- ##### Import
726
-
727
- ```javascript
728
- import { ErrorState } from '@hubspot/ui-extensions';
729
- ```
730
-
731
- ##### Props
732
-
733
- ```typescript
734
- interface ErrorStateProps {
735
- children: ReactNode;
736
- title?: string;
737
- type?: 'error' | 'support' | 'lock';
738
- }
739
- ```
740
-
741
- | Prop | Type | Default | Description |
742
- | --- | --- | --- | --- |
743
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
744
- | `title` | `string(optional)` | `Intl('All is not lost.')` | The text for the title header rendered above the `children`. |
745
- | `type` | `'error' \| 'support' \| 'lock'` `(optional)` | `'error'` | Sets the type of error image that will be shown. |
746
-
747
- ##### Usage
748
-
749
- ```javascript
750
- const Extension = ({ data, error, fetchData }) => {
751
- if (error) {
752
- return (
753
- <ErrorState title="Trouble fetching properties." layout="vertical" reverseOrder={true}>
754
- <Stack>
755
- <Text>
756
- Please try again in a few moments.
757
- </Text>
758
- <Button onClick={fetchData}>
759
- Try again
760
- </Button>
761
- </Stack>
762
- </ErrorState>
763
- )
764
- }
765
-
766
- return (
767
- <Stack>
768
- {data.map(...)}
769
- </Stack>
770
- );
771
- }
772
- ```
773
-
774
- ### Heading
775
-
776
- ##### Import
777
-
778
- ```javascript
779
- import { Heading } from '@hubspot/ui-extensions';
780
- ```
781
-
782
- ##### Props
783
-
784
- ```typescript
785
- interface HeadingProps {
786
- children: ReactNode;
787
- inline?: boolean;
788
- }
789
- ```
790
-
791
- | Prop | Type | Default | Description |
792
- | --- | --- | --- | --- |
793
- | `children` | `string` | `N/A` | Text to be displayed as heading text. |
794
- | `inline` | `boolean(optional)` | `false` | Determines if the text will break line or share the space. |
795
-
796
- ##### Usage
797
-
798
- ```javascript
799
- const Extension = () => {
800
- return <Heading>Plain text, nothing special here</Heading>;
801
- };
802
- ```
803
-
804
- ### Image
805
-
806
- ##### Import
807
-
808
- ```javascript
809
- import { Image } from '@hubspot/ui-extensions';
810
- ```
811
-
812
- ##### Props
813
-
814
- ```typescript
815
- interface ImageProps {
816
- alt?: string;
817
- href?: string;
818
- onClick?: () => void;
819
- src: string;
820
- width?: number;
821
- height?: number;
822
- }
823
- ```
824
-
825
- | Prop | Type | Description |
826
- | --- | --- | --- |
827
- | `alt` | `string(optional)` | The alt text for the image, similar to the `alt` attribute for the html [img tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attributes) |
828
- | `href` | `string(optional)` | If provided, it will be used as a href that will be opened in a new tag when the image is clicked |
829
- | `onClick` | `function(optional)` | A function that will be called when the image is clicked on. This function will receive no arguments any returned values will be ignored. |
830
- | `src` | `string` | The url to the image to display, similar to [img tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attributes) |
831
- | `width` | `number(optional)` | The pixel width of the image |
832
- | `height` | `number(optional)` | The pixel height of the image |
833
-
834
- ##### Usage
835
-
836
- ```javascript
837
- const Extension = () => {
838
- return (
839
- <Image
840
- alt="A picture of an adorable black lab puppy, click on me to see in a new tab"
841
- src="https://picsum.photos/id/237/200/300"
842
- href="https://picsum.photos/id/237"
843
- onClick={() => {
844
- console.log('Someone clicked on the image!');
845
- }}
846
- width={200}
847
- />
848
- );
849
- };
850
- ```
851
-
852
- ### Input
853
-
854
- ##### Import
855
-
856
- ```javascript
857
- import { Input } from '@hubspot/ui-extensions';
858
- ```
859
-
860
- ##### Props
861
-
862
- ```typescript
863
- interface InputProps {
864
- label: string;
865
- name: string;
866
- value?: string;
867
- required?: boolean;
868
- readOnly?: boolean;
869
- description?: string;
870
- tooltip?: string;
871
- placeholder?: string;
872
- error?: boolean;
873
- validationMessage?: string;
874
- onChange?: (value: string) => void;
875
- onInput?: (value: string) => void;
876
- onBlur?: (value: string) => void;
877
- onFocus?: (value: string) => void;
878
- }
879
- ```
880
-
881
- | Prop | Type | Default | Description |
882
- | --- | --- | --- | --- |
883
- | `label` | `string` | `N/A` | The label text to display for the form input element |
884
- | `name` | `string` | `N/A` | The unique identifier for the input element, this could be thought of as the HTML5 [Input element's name attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#name) |
885
- | `value` | `string(optional)` | `''` | The value of the input |
886
- | `required` | `boolean(optional)` | `false` | Determines if the required indicator should be displayed |
887
- | `readOnly` | `boolean(optional)` | `false` | Determines if the field is editable or not. |
888
- | `description` | `string(optional)` | `N/A` | Instructional message to display to the user to help understand the purpose of the input. |
889
- | `tooltip` | `string(optional)` | `N/A` | Text that will appear in a tooltip next to the input label. |
890
- | `placeholder` | `string(optional)` | `N/A` | Text that appears in the input when it has no value set. |
891
- | `error` | `boolean(optional)` | `false` | If set to true, `validationMessage` is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, `validationMessage` is displayed as a success message. |
892
- | `validationMessage` | `string(optional)` | `''` | The text to show if the input has an error. |
893
- | `onChange` | `(value: string) => void(optional)` | `N/A` | A callback function that is invoked when the value is committed. Currently these times are `onBlur` of the input and when the user submits the form. |
894
- | `onInput` | `(value: string) => void(optional)` | `N/A` | A function that is called and passed the value every time the field is edited by the user. It is recommended that you do not use this value to update state, that is what `onChange` should be used for. Instead this should be used for validation. |
895
- | `onBlur` | `(value: string) => void(optional)` | `N/A` | A function that is called and passed the value every time the field loses focus. |
896
- | `onFocus` | `(value: string) => void(optional)` | `N/A` | A function that is called and passed the value every time the field gets focused. |
897
-
898
- ##### Usage
899
-
900
- ```javascript
901
- import { useState } from 'react';
902
-
903
- const Extension = () => {
904
- const [name, setName] = useState('');
905
- const [validationMessage, setValidationMessage] = useState('');
906
- const [isValid, setIsValid] = useState(true);
907
-
908
- return (
909
- <Form>
910
- <Input
911
- label="First Name"
912
- name="first-name"
913
- tooltip="Please enter your first name"
914
- description="Please enter your first name"
915
- placeholder="First name"
916
- required={true}
917
- error={!isValid}
918
- validationMessage={validationMessage}
919
- onChange={value => {
920
- setName(value);
921
- }}
922
- onInput={value => {
923
- if (value !== 'Bill') {
924
- setValidationMessage('This form only works for people named Bill');
925
- setIsValid(false);
926
- } else if (value === '') {
927
- setValidationMessage('First name is required');
928
- setIsValid(false);
929
- } else {
930
- setValidationMessage('Valid first name!');
931
- setIsValid(true);
932
- }
933
- }}
934
- />
935
- </Form>
936
- );
937
- };
938
- ```
939
-
940
- ### Link
941
-
942
- ##### Import
943
-
944
- ```javascript
945
- import { Link } from '@hubspot/ui-extensions';
946
- ```
947
-
948
- ##### Props
949
-
950
- ```typescript
951
- export interface LinkProps {
952
- href: string;
953
- variant?: 'primary' | 'destructive' | 'light' | 'dark';
954
- children: ReactNode;
955
- onClick?: () => void;
956
- preventDefault?: boolean;
957
- }
958
- ```
959
-
960
- | Prop | Type | Default | Description |
961
- | --- | --- | --- | --- |
962
- | `href` | `string` | `N/A` | A URL that will be opened when the link is clicked. If the value is a URL external to HubSpot it will be opened in a new tab. |
963
- | `variant` | `'primary' \| 'light' \| 'dark' \| 'destructive'` `(optional)` | `'primary'` | Sets the color variation of the link |
964
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. |
965
- | `onClick` | `() => void` `(optional)` | `N/A` | A function that will be invoked when the link is clicked. It receives no arguments and it's return value is ignored |
966
- | `preventDefault` | `boolean(optional)` | `false` | If set to `true` `event.preventDefault()` will be invoked before your `onClick` function is called, preventing automatic navigation to the anchor's href url. |
967
-
968
- ##### Usage
969
-
970
- ```javascript
971
- const Extension = () => {
972
- return <Link href="https://app.hubspot.com/">HubSpot</Link>;
973
- };
974
- ```
975
-
976
- ### LoadingSpinner
977
-
978
- ##### Import
979
-
980
- ```javascript
981
- import { LoadingSpinner } from '@hubspot/ui-extensions';
982
- ```
983
-
984
- ##### Props
985
-
986
- ```typescript
987
- export interface LoadingSpinnerProps {
988
- label: string;
989
- showLabel?: boolean;
990
- size?: 'xs' | 'extra-small' | 'sm' | 'small' | 'md' | 'medium';
991
- layout?: 'inline' | 'centered';
992
- }
993
- ```
994
-
995
- | Prop | Type | Default | Description |
996
- | --- | --- | --- | --- |
997
- | `label` | `string` | `N/A` | The companion text for the loading spinner. |
998
- | `showLabel` | `boolean(optional)` | `false` | if `true`, the label will be visible alongside the loading spinner. |
999
- | `size` | `'xs' \| 'sm' \| 'md' \| 'extra-small' \| 'small' \| 'medium'` `(optional)` | `'sm'` | The size of the loading spinner icon. |
1000
- | `layout` | `'inline'\| 'centered'` `(optional)` | `N/A` | Use the `centered` option for layout as a convenience for the common pattern of filling the space of its parent. |
1001
-
1002
- ##### Usage
1003
-
1004
- ```javascript
1005
- const Extension = () => {
1006
- return <LoadingSpinner label="Loading..." />;
1007
- };
1008
- ```
1009
- ### MultiSelect
1010
-
1011
- ```javascript
1012
- import { MultiSelect } from '@hubspot/ui-extensions';
1013
- ```
1014
-
1015
- ### Props
1016
-
1017
- ```typescript
1018
- interface MultiSelectProps {
1019
- label: string;
1020
- name: string;
1021
- value?: (string | number)[];
1022
- required?: boolean;
1023
- readOnly?: boolean;
1024
- description?: string;
1025
- tooltip?: string;
1026
- placeholder?: string;
1027
- error?: boolean;
1028
- errorMessage?: string;
1029
- onChange: (value: (string | number)[]) => void;
1030
- options: {
1031
- label: string;
1032
- value: string | number;
1033
- }[];
1034
- variant?: 'transparent' | 'input';
1035
- }
1036
- ```
1037
-
1038
- | Prop | Type | Default | Description |
1039
- | --- | --- | --- | --- |
1040
- | `label` | `string(optional)` | `N/A` | The label text to display for the select element. |
1041
- | `name` | `string(optional)` | `N/A` | The unique identifier for the select element. |
1042
- | `value` | `Array<string \| number>` | `N/A` | The value of the select input. |
1043
- | `required` | `boolean` | `false` | Determines if the required indicator should be displayed. |
1044
- | `readOnly` | `boolean` | `false` | Determines if the field is editable or not. |
1045
- | `description` | `string` | `N/A` | Instructional message to display to the user to help understand the purpose of the input. |
1046
- | `tooltip` | `string` | `N/A` | Text that will appear in a tooltip next to the input label. |
1047
- | `placeholder` | `string` | `N/A` | Text that appears in the input when it has no value set. |
1048
- | `error` | `boolean(optional)` | `false` | If set to true, `validationMessage` is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, `validationMessage` is displayed as a success message. |
1049
- | `validationMessage` | `string(optional)` | `''` | The text to show if the input has an error. |
1050
- | `onChange` | `(value: Array<string \| number>) => void` | `N/A` | Function that is called with the new value when it is updated. |
1051
- | `options` | `Array<{label: string; value: string \| number}>` | `N/A` | Array of options to be displayed in the select. `label` will be used as the display text in the dropdown list and `value` should be a **unique** identifier. `value` is the data that will be submitted with the form. |
1052
- | `variant` | `'transparent' \| 'input' `| `input` | Sets the visual styles of the button used for the anchor of the component. |
1053
-
1054
- ##### Usage
1055
-
1056
- ```javascript
1057
- const Extension = () => {
1058
- const options = [
1059
- { label: 'Ice cream', value: 'ice-cream' },
1060
- { label: 'Pizza', value: 'pizza' },
1061
- { label: 'Burger', value: 'burger' },
1062
- { label: 'Soda', value: 'soda' },
1063
- ];
1064
-
1065
- return (
1066
- <MultiSelect
1067
- name="favorite-food"
1068
- label="Favorite Food"
1069
- options={options}
1070
- />
1071
- );
1072
- };
1073
- ```
1074
-
1075
- ### NumberInput
1076
-
1077
- ##### Import
1078
-
1079
- ```javascript
1080
- import { NumberInput } from '@hubspot/ui-extensions';
1081
- ```
1082
-
1083
- ##### Props
1084
-
1085
- ```typescript
1086
- export interface NumberInputProps {
1087
- label: string;
1088
- name: string;
1089
- value?: number;
1090
- required?: boolean;
1091
- readOnly?: boolean;
1092
- description?: string;
1093
- tooltip?: string;
1094
- placeholder?: string;
1095
- error?: boolean;
1096
- defaultValue?: number;
1097
- validationMessage?: string;
1098
- onChange?: (value: number) => void;
1099
- onBlur?: (value: number) => void;
1100
- onFocus?: (value: number) => void;
1101
- min?: number;
1102
- max?: number;
1103
- precision?: number;
1104
- formatStyle?: 'decimal' | 'percentage';
1105
- }
1106
- ```
1107
-
1108
- | Prop | Type | Default | Description |
1109
- | --- | --- | --- | --- |
1110
- | `label` | `string` | `N/A` | The label text to display for the form input element |
1111
- | `name` | `string` | `N/A` | The unique identifier for the input element, this could be thought of as the HTML5 [Input element's name attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#name) |
1112
- | `value` | `number(optional)` | `''` | The value of the input |
1113
- | `required` | `boolean(optional)` | `false` | Determines if the required indicator should be displayed |
1114
- | `readOnly` | `boolean(optional)` | `false` | Determines if the field is editable or not. |
1115
- | `description` | `string(optional)` | `N/A` | Instructional message to display to the user to help understand the purpose of the input. |
1116
- | `tooltip` | `string(optional)` | `N/A` | Text that will appear in a tooltip next to the input label. |
1117
- | `placeholder` | `string(optional)` | `N/A` | Text that appears in the input when it has no value set. |
1118
- | `error` | `boolean(optional)` | `false` | If set to true, `validationMessage` is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, `validationMessage` is displayed as a success message. |
1119
- | `validationMessage` | `string(optional)` | `''` | The text to show if the input has an error. |
1120
- | `onChange` | `(value: number) => void(optional)` | `N/A` | A callback function that is invoked when the user types a valid number. It won't get called on invalid inputs. |
1121
- | `onBlur` | `(value: number) => void(optional)` | `N/A` | A function that is called and passed the value every time the field loses focus. |
1122
- | `onFocus` | `(value: number) => void(optional)` | `N/A` | A function that is called and passed the value every time the field gets focused. |
1123
- | `min` | `number(optional)` | `N/A` | Sets the lower bound of your input. |
1124
- | `max` | `number(optional)` | `N/A` | Sets the upper bound of your input. |
1125
- | `precision` | `number(optional)` | `N/A` | Represents the number of digits to the right of the decimal point. |
1126
- | `precision` | `number(optional)` | `N/A` | Represents the number of digits to the right of the decimal point. |
1127
- | `formatStyle` | `'decimal' \| 'percentage'` | `'decimal'` | Formats the input as a decimal point number or a percentage. |
1128
-
1129
- ##### Usage
1130
-
1131
- ```javascript
1132
- const Extension = () => {
1133
- const [portalCount, setPortalCount] = useState(0);
1134
- return (
1135
- <NumberInput
1136
- label={'HubSpot Portal Count'}
1137
- name="portalsNumber"
1138
- description={'Number of active portals'}
1139
- placeholder={'number of portals'}
1140
- value={portalCount}
1141
- onChange={value => setPortalCount(value)}
1142
- />
1143
- );
1144
- };
1145
- ```
1146
-
1147
- ### ProgressBar
1148
-
1149
- ##### Import
1150
-
1151
- ```javascript
1152
- import { ProgressBar } from '@hubspot/ui-extensions';
1153
- ```
1154
-
1155
- ##### Props
1156
-
1157
- ```typescript
1158
- export interface ProgressBarProps {
1159
- title?: string;
1160
- aria-label?: string;
1161
- showPercentage?: boolean;
1162
- value?: number;
1163
- maxValue?: number;
1164
- valueDescription?: string;
1165
- variant?: 'success' | 'danger' | 'warning';
1166
- }
1167
- ```
1168
-
1169
- | Prop | Type | Default | Description |
1170
- | --- | --- | --- | --- |
1171
- | `title` | `string(optional)` | `N/A` | Text to be displayed in the progressbar title. |
1172
- | `showPercentage` | `boolean(optional)` | `false` | Toggles the display of the completion percentage. |
1173
- | `value` | `number(optional)` | `0` | The value of the progress indicator. |
1174
- | `maxValue` | `number(optional)` | `100` | The maximum value of the progress bar. |
1175
- | `valueDescription` | `string(optional)` | `N/A` | Text that explains the current state of the `value` prop. Renders to the right of `title`. **Example: "10,000 of 7,500"** |
1176
- | `variant` | `'success' \| 'danger' \| 'warning'` | `'success'` | The type of progressbar to display. Defaults to success. |
1177
- | `aria-label` | `string(optional)` | `N/A` | Indicates the content of the ProgressBar to screen readers. Should be used if there's no title. |
1178
-
1179
- ##### Usage
1180
-
1181
- ```javascript
1182
- const Extension = () => {
1183
- return (
1184
- <ProgressBar
1185
- variant="warning"
1186
- value={50}
1187
- maxValue={200}
1188
- showPercentage={true}
1189
- />
1190
- );
1191
- };
1192
- ```
1193
-
1194
- ### Select
1195
-
1196
- ##### Import
1197
-
1198
- ```javascript
1199
- import { Select } from '@hubspot/ui-extensions';
1200
- ```
1201
-
1202
- ##### Props
1203
-
1204
- ```typescript
1205
- interface SelectProps {
1206
- label?: string;
1207
- name?: string;
1208
- value?: string | number | boolean;
1209
- variant?: 'transparent' | 'input'
1210
- required?: boolean;
1211
- readOnly?: boolean;
1212
- description?: string;
1213
- tooltip?: string;
1214
- placeholder?: string;
1215
- error?: boolean;
1216
- errorMessage?: string;
1217
- onChange: (value: string) => void;
1218
- options: {
1219
- label: string;
1220
- value: string | number | boolean;
1221
- }[];
1222
- }
1223
- ```
1224
-
1225
- | Prop | Type | Default | Description |
1226
- | --- | --- | --- | --- |
1227
- | `label` | `string(optional)` | `N/A` | The label text to display for the select element. |
1228
- | `name` | `string(optional)` | `N/A` | The unique identifier for the select element. |
1229
- | `value` | `string \| number \| boolean` | `''` | The value of the select input. |
1230
- | `required` | `boolean` | `false` | Determines if the required indicator should be displayed |
1231
- | `readOnly` | `boolean` | `false` | Determines if the field is editable or not. |
1232
- | `description` | `string` | `N/A` | Instructional message to display to the user to help understand the purpose of the input. |
1233
- | `tooltip` | `string` | `N/A` | Text that will appear in a tooltip next to the input label. |
1234
- | `placeholder` | `string` | `N/A` | Text that appears in the input when it has no value set. |
1235
- | `error` | `boolean(optional)` | `false` | If set to true, `validationMessage` is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, `validationMessage` is displayed as a success message. |
1236
- | `validationMessage` | `string(optional)` | `''` | The text to show if the input has an error. |
1237
- | `onChange` | `(value: string) => void` | `N/A` | Function that is called with the new value when it is updated. |
1238
- | `options` | `Array<{label: string; value: string \| number \| boolean}>` | `N/A` | Array of options to be displayed in the select. `label` will be used as the display text in the dropdown list and `value` should be a **unique** identifier. `value` is the data that will be submitted with the form. |
1239
- | `variant` | `'transparent' \| 'input' `| `input` | Sets the visual styles of the button used for the anchor of the component. |
1240
-
1241
- ##### Usage
1242
-
1243
- ```javascript
1244
- const Extension = () => {
1245
- const [name, setName] = useState(null);
1246
- const [validationMessage, setValidationMessage] = useState('');
1247
- const [isValid, setIsValid] = useState(true);
1248
-
1249
- const options = [
1250
- { label: 'Bill', value: 42 },
1251
- { label: 'Ted', value: 43 },
1252
- ];
1253
-
1254
- return (
1255
- <Form>
1256
- <Select
1257
- label="Best Bill & Ted Character?"
1258
- name="best-char"
1259
- tooltip="Please choose"
1260
- description="Please choose"
1261
- placeholder="Bill or Ted?"
1262
- required={true}
1263
- error={!isValid}
1264
- validationMessage={validationMessage}
1265
- onChange={value => {
1266
- setName(value);
1267
- if (!value) {
1268
- setValidationMessage('This is required');
1269
- setIsValid(false);
1270
- } else {
1271
- setValidationMessage('Excellent!');
1272
- setIsValid(true);
1273
- }
1274
- }}
1275
- options={options}
1276
- />
1277
- </Form>
1278
- );
1279
- };
1280
- ```
1281
-
1282
- ### Stack
1283
-
1284
- ##### Import
1285
-
1286
- ```javascript
1287
- import { Stack } from '@hubspot/ui-extensions';
1288
- ```
1289
-
1290
- ##### Props
1291
-
1292
- ```typescript
1293
- interface StackProps {
1294
- distance?:
1295
- | 'flush'
1296
- | 'small'
1297
- | 'extra-small'
1298
- | 'medium'
1299
- | 'large'
1300
- | 'extra-large'
1301
- | 'xs'
1302
- | 'sm'
1303
- | 'md'
1304
- | 'lg'
1305
- | 'xl';
1306
- direction?: 'row' | 'column';
1307
- children?: ReactNode;
1308
- }
1309
- ```
1310
-
1311
- | Prop | Type | Default | Description |
1312
- | --- | --- | --- | --- |
1313
- | `distance` | `'flush' \| 'extra-small' \| 'small' \| 'medium' \| 'large' \| 'extra-large' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'small'` | Amount of space between each child component passed as children |
1314
- | `direction` | `'row' \| 'column'` | `'column'` | Stacks elements in the vertical or horizontal direction. |
1315
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
1316
-
1317
- ##### Usage
1318
-
1319
- ```javascript
1320
- const Extension = () => {
1321
- return (
1322
- <Stack>
1323
- <Image {...} />
1324
- <Text {...} />
1325
- </Stack>
1326
- );
1327
- }
1328
- ```
1329
-
1330
- ### Statistics
1331
-
1332
- ##### Import
1333
-
1334
- ```javascript
1335
- import { Statistics } from '@hubspot/ui-extensions';
1336
- ```
1337
-
1338
- ##### Props
1339
-
1340
- ```typescript
1341
- interface StatisticsProps {
1342
- children: ReactNode;
1343
- }
1344
- ```
1345
-
1346
- | Prop | Type | Default | Description |
1347
- | --- | --- | --- | --- |
1348
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be [StatisticsItem](#statisticsitem) or [StatisticsTrend](#statisticstrend) |
1349
-
1350
- ##### Usage
1351
-
1352
- ```javascript
1353
- const Extension = () => {
1354
- return (
1355
- <Statistics>
1356
- <StatisticsItem {...} />
1357
- <StatisticsTrend {...} />
1358
- </Statistics>
1359
- );
1360
- }
1361
- ```
1362
-
1363
- #### StatisticsItem
1364
-
1365
- ##### Import
1366
-
1367
- ```javascript
1368
- import { StatisticsItem } from '@hubspot/ui-extensions';
1369
- ```
1370
-
1371
- ##### Props
1372
-
1373
- ```typescript
1374
- interface StatisticsItemProps {
1375
- id?: string;
1376
- label: string;
1377
- number: string;
1378
- children: ReactNode;
1379
- }
1380
- ```
1381
-
1382
- | Prop | Type | Default | Description |
1383
- | --- | --- | --- | --- |
1384
- | `id` | `string(optional)` | `N/A` | The unique identifier |
1385
- | `label` | `string` | `N/A` | The text to be used as a label |
1386
- | `number` | `string` | `N/A` | Fully formatted string to be displayed as the item's primary number |
1387
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be [Text](#text) or [StatisticsTrend](#statisticstrend) |
1388
-
1389
- ##### Usage
1390
-
1391
- ```javascript
1392
- const Extension = () => {
1393
- return (
1394
- <Statistics>
1395
- <StatisticsItem label="Sales" number={'30000'}>
1396
- <Text>Big Numbers</Text>
1397
- </StatisticsItem>
1398
- </Statistics>
1399
- );
1400
- };
1401
- ```
1402
-
1403
- #### StatisticsTrend
1404
-
1405
- ##### Import
1406
-
1407
- ```javascript
1408
- import { StatisticsTrend } from '@hubspot/ui-extensions';
1409
- ```
1410
-
1411
- ##### Props
1412
-
1413
- ```typescript
1414
- interface StatisticsTrendProps {
1415
- value: string;
1416
- direction: 'increase' | 'decrease';
1417
- }
1418
- ```
1419
-
1420
- | Prop | Type | Default | Description |
1421
- | --- | --- | --- | --- |
1422
- | `value` | `string` | `N/A` | Formatted string to be displayed as trend value |
1423
- | `direction` | `'increase' \| 'decrease'` | `N/A` | Direction in which the trend arrow should be displayed |
1424
-
1425
- ##### Usage
1426
-
1427
- ```javascript
1428
- const Extension = () => {
1429
- return (
1430
- <Statistics>
1431
- <StatisticsItem label="Item A Sales" number="10000">
1432
- <StatisticsTrend direction="decrease" value="200%" />
1433
- </StatisticsItem>
1434
- <StatisticsItem label="Item B Sales" number="100000">
1435
- <StatisticsTrend direction="increase" value="100%" />
1436
- </StatisticsItem>
1437
- </Statistics>
1438
- );
1439
- };
1440
- ```
1441
-
1442
-
1443
- ### StepIndicator
1444
-
1445
- ##### Import
1446
-
1447
- ```javascript
1448
- import { StepIndicator } from '@hubspot/ui-extensions';
1449
- ```
1450
-
1451
- ##### Props
1452
-
1453
- ```typescript
1454
- export interface StepIndicatorProps {
1455
- stepNames: string[];
1456
- direction?: 'horizontal' | 'vertical';
1457
- onClick?: (stepIndex: number) => void;
1458
- circleSize?: AllSizes;
1459
- currentStep?: number;
1460
- variant?: 'default' | 'compact' | 'flush';
1461
- }
1462
- ```
1463
-
1464
- | Prop | Type | Default | Description |
1465
- | --- | --- | --- | --- |
1466
- | `stepNames` | `Array<string>` | `N/A` | Sets the name of the available steps. |
1467
- | `direction` | `'horizontal' \| 'vertical'` `(optional)` | `N/A` | Determines whether the step indicator is laid out on a horizontal or vertical axis. |
1468
- | `onClick` | `() => void` `(optional)` | `N/A` | A function that will be invoked when a step is clicked. It receives the current step index as an argument(zero based). Use this to update the active step.|
1469
- | `circleSize` | `'extra-small' \| 'small' \| 'medium' \| 'large'\| 'extra-large'` `(optional)` | `'small'` | Determines the size of the circle of an individual step. |
1470
- | `currentStep` | `number(optional)` | `N/A` | Determines which step is visually active in the step indicator. |
1471
- | `variant` | `'default' \| 'compact' \| 'flush'` `(optional)` | `'default'` | Changes the visual styling of the component. compact only shows the title of the active step. flush does the same thing, but also removes the left and right margins. |
1472
-
1473
- ##### Usage
1474
-
1475
- ```javascript
1476
- function Extension() {
1477
- const [currentStep, setCurrentStep] = useState(0);
1478
-
1479
- return (
1480
- <Stack>
1481
- <StepIndicator
1482
- currentStep={currentStep}
1483
- stepNames={['First', 'Second', 'Third']}
1484
- />
1485
- <Stack>
1486
- <Button onClick={() => setCurrentStep(currentStep - 1)}>
1487
- Previous
1488
- </Button>
1489
- <Button onClick={() => setCurrentStep(currentStep + 1)}>
1490
- Next
1491
- </Button>
1492
- </Stack>
1493
- </Stack>
1494
- );
1495
- }
1496
- ```
1497
-
1498
-
1499
- ### Table
1500
-
1501
- ##### Import
1502
-
1503
- ```javascript
1504
- import { Table } from '@hubspot/ui-extensions';
1505
- ```
1506
-
1507
- ##### Props
1508
-
1509
- ```typescript
1510
- interface TableProps {
1511
- children: ReactNode;
1512
- flush?: boolean;
1513
- bordered?: boolean;
1514
- paginated?: boolean;
1515
- // if paginated=true
1516
- pageCount: number;
1517
- onPageChange: (pageNumber: number) => void;
1518
- showButtonLabels?: boolean;
1519
- showFirstLastButtons?: boolean;
1520
- maxVisiblePageButtons?: number;
1521
- page?: number;
1522
- }
1523
- ```
1524
-
1525
- | Prop | Type | Default | Description |
1526
- | --- | --- | --- | --- |
1527
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be [TableHead](#tablehead), [TableFooter](#tablefooter), or [TableBody](#tablebody) |
1528
- | `flush` | `boolean(optional)` | `false` | If true the table will not have bottom margin. |
1529
- | `bordered` | `boolean(optional)` | `true` | If false the table will not haver borders around its content. |
1530
- | `paginated` | `boolean(optional)` | `false` | If true, the table will display the paginator component and consumer will have to provide extra pagination props. |
1531
-
1532
- **Props for paginated=true**
1533
-
1534
- | Prop | Type | Default | Description |
1535
- | --- | --- | --- | --- |
1536
- | `pageCount` | `number` | `N/A` | The total number of pages available |
1537
- | `onPageChange` | `onPageChange: (pageNumber: number) => void` | `N/A` | A function that will be invoked when the pagination button is clicked. It receives the new page number as argument. |
1538
- | `showButtonLabels` | `boolean(optional)` | `true` | if `false`, it hides the text labels for the First/Prev/Next/Last buttons. The button labels will still be accessible for screen readers. |
1539
- | `showFirstLastButtons` | `boolean(optional)` | `false` | if `true`, it displays the First page and Last page buttons. |
1540
- | `maxVisiblePageButtons` | `number(optional)` | `5` | Changes how many page buttons are shown. |
1541
- | `page` | `number(optional)` | `N/A` | Denotes the current page. |
1542
-
1543
- ##### Usage
1544
-
1545
- ```javascript
1546
- const Extension = () => {
1547
- return (
1548
- <Table bordered={true}>
1549
- <TableHead>
1550
- <TableRow>
1551
- <TableHeader>Name</TableHeader>
1552
- <TableHeader>Phone</TableHeader>
1553
- </TableRow>
1554
- </TableHead>
1555
- <TableBody>
1556
- <TableRow>
1557
- <TableCell>Roger Federer</TableCell>
1558
- <TableCell>555-555-7866</TableCell>
1559
- </TableRow>
1560
- </TableBody>
1561
- </Table>
1562
- );
1563
- };
1564
-
1565
- // Paginated example
1566
-
1567
- function generateData(count = 15) {
1568
- const result = [];
1569
-
1570
- for (let index = 0; index < count; index++) {
1571
- result.push({
1572
- name: `Jane Doe ${index}`,
1573
- email: `janedoemail${index}@hubspot.com`,
1574
- });
1575
- }
1576
-
1577
- return result;
1578
- }
1579
-
1580
- function PaginatedTable() {
1581
- const ITEMS_PER_PAGE = 10;
1582
- const data = generateData(30);
1583
-
1584
- const [currentPage, setCurrentPage] = useState(1);
1585
- const pageCount = data.length / ITEMS_PER_PAGE;
1586
-
1587
- const dataToDisplay = data.slice(
1588
- (currentPage - 1) * ITEMS_PER_PAGE,
1589
- currentPage * ITEMS_PER_PAGE
1590
- );
1591
-
1592
- return (
1593
- <Table
1594
- paginated={true}
1595
- pageCount={pageCount}
1596
- page={currentPage}
1597
- onPageChange={(nextPageNumber: number) => {
1598
- setCurrentPage(nextPageNumber);
1599
- }}
1600
- >
1601
- <TableHead>
1602
- <TableRow>
1603
- <TableHeader>Name</TableHeader>
1604
- <TableHeader>Email</TableHeader>
1605
- </TableRow>
1606
- </TableHead>
1607
- <TableBody>
1608
- {dataToDisplay.map(({ name, email }) => {
1609
- console.log(name, email);
1610
- return (
1611
- <TableRow key={email}>
1612
- <TableCell>{name}</TableCell>
1613
- <TableCell>{email}</TableCell>
1614
- </TableRow>
1615
- );
1616
- })}
1617
- </TableBody>
1618
- </Table>
1619
- );
1620
- }
1621
- ```
1622
-
1623
- ### TableBody
1624
-
1625
- ##### Import
1626
-
1627
- ```javascript
1628
- import { TableBody } from '@hubspot/ui-extensions';
1629
- ```
1630
-
1631
- ##### Props
1632
-
1633
- ```typescript
1634
- interface TableBodyProps {
1635
- children: ReactNode;
1636
- }
1637
- ```
1638
-
1639
- | Prop | Type | Default | Description |
1640
- | --- | --- | --- | --- |
1641
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be [TableRow](#tablerow). |
1642
-
1643
- ##### Usage
1644
-
1645
- ```javascript
1646
- const Extension = () => {
1647
- return (
1648
- <Table bordered={true}>
1649
- <TableHead>
1650
- <TableRow>
1651
- <TableHeader>Name</TableHeader>
1652
- <TableHeader>Phone</TableHeader>
1653
- </TableRow>
1654
- </TableHead>
1655
- <TableBody>
1656
- <TableRow>
1657
- <TableCell>Roger Federer</TableCell>
1658
- <TableCell>555-555-7866</TableCell>
1659
- </TableRow>
1660
- </TableBody>
1661
- </Table>
1662
- );
1663
- };
1664
- ```
1665
-
1666
- ### TableCell
1667
-
1668
- ##### Import
1669
-
1670
- ```javascript
1671
- import { TableCell } from '@hubspot/ui-extensions';
1672
- ```
1673
-
1674
- ##### Props
1675
-
1676
- ```typescript
1677
- interface TableCellProps {
1678
- children: ReactNode;
1679
- width?: 'min' | 'max' | 'auto' | number;
1680
- align?: 'left' | 'center' | 'right';
1681
- }
1682
- ```
1683
-
1684
- | Prop | Type | Default | Description |
1685
- | --- | --- | --- | --- |
1686
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
1687
- | `width` | `'min' \| 'max' \| 'auto' \| number` | `'auto'` | Sets the width of a table cell |
1688
- | `align` | `'left' \| 'center' \| 'right'` | `'left'` | Sets the alignment of a table cell |
1689
-
1690
- ##### Usage
1691
-
1692
- ```javascript
1693
- const Extension = () => {
1694
- return (
1695
- <Table bordered={true}>
1696
- <TableHead>
1697
- <TableRow>
1698
- <TableHeader>Name</TableHeader>
1699
- <TableHeader>Phone</TableHeader>
1700
- </TableRow>
1701
- </TableHead>
1702
- <TableBody>
1703
- <TableRow>
1704
- <TableCell>Roger Federer</TableCell>
1705
- <TableCell>555-555-7866</TableCell>
1706
- </TableRow>
1707
- </TableBody>
1708
- </Table>
1709
- );
1710
- };
1711
- ```
1712
-
1713
- ### TableFooter
1714
-
1715
- ##### Import
1716
-
1717
- ```javascript
1718
- import { TableFooter } from '@hubspot/ui-extensions';
1719
- ```
1720
-
1721
- ##### Props
1722
-
1723
- ```typescript
1724
- interface TableFooterProps {
1725
- children: ReactNode;
1726
- }
1727
- ```
1728
-
1729
- | Prop | Type | Default | Description |
1730
- | --- | --- | --- | --- |
1731
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be [TableRow](#tablerow). |
1732
-
1733
- ##### Usage
1734
-
1735
- ```javascript
1736
- const Extension = () => {
1737
- return (
1738
- <Table>
1739
- <TableHead>
1740
- <TableRow>
1741
- <TableHeader>Series</TableHeader>
1742
- <TableHeader>Years on air</TableHeader>
1743
- <TableHeader>Emmys</TableHeader>
1744
- </TableRow>
1745
- </TableHead>
1746
- <TableFooter>
1747
- <TableRow>
1748
- <TableHeader>Totals</TableHeader>
1749
- <TableHeader>43</TableHeader>
1750
- <TableHeader>50</TableHeader>
1751
- </TableRow>
1752
- </TableFooter>
1753
- <TableBody>
1754
- <TableRow>
1755
- <TableCell>The Simpsons</TableCell>
1756
- <TableCell>28</TableCell>
1757
- <TableCell>31</TableCell>
1758
- </TableRow>
1759
- <TableRow>
1760
- <TableCell>M*A*S*H</TableCell>
1761
- <TableCell>11</TableCell>
1762
- <TableCell>14</TableCell>
1763
- </TableRow>
1764
- <TableRow>
1765
- <TableCell>Arrested Development</TableCell>
1766
- <TableCell>4</TableCell>
1767
- <TableCell>5</TableCell>
1768
- </TableRow>
1769
- </TableBody>
1770
- </Table>
1771
- );
1772
- };
1773
- ```
1774
-
1775
- ### TableHead
1776
-
1777
- ##### Import
1778
-
1779
- ```javascript
1780
- import { TableHead } from '@hubspot/ui-extensions';
1781
- ```
1782
-
1783
- ##### Props
1784
-
1785
- ```typescript
1786
- interface TableHeadProps {
1787
- children: ReactNode;
1788
- }
1789
- ```
1790
-
1791
- | Prop | Type | Default | Description |
1792
- | --- | --- | --- | --- |
1793
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. These children should be [TableHeader](#tableheader). |
1794
-
1795
- ##### Usage
1796
-
1797
- ```javascript
1798
- const Extension = () => {
1799
- return (
1800
- <Table bordered={true}>
1801
- <TableHead>
1802
- <TableRow>
1803
- <TableHeader>Name</TableHeader>
1804
- <TableHeader>Phone</TableHeader>
1805
- </TableRow>
1806
- </TableHead>
1807
- <TableBody>
1808
- <TableRow>
1809
- <TableCell>Roger Federer</TableCell>
1810
- <TableCell>555-555-7866</TableCell>
1811
- </TableRow>
1812
- </TableBody>
1813
- </Table>
1814
- );
1815
- };
1816
- ```
1817
-
1818
- ### TableHeader
1819
-
1820
- ##### Import
1821
-
1822
- ```javascript
1823
- import { TableHeader } from '@hubspot/ui-extensions';
1824
- ```
1825
-
1826
- ##### Props
1827
-
1828
- ```typescript
1829
- interface TableHeaderProps {
1830
- children: ReactNode;
1831
- width?: 'min' | 'max' | 'auto' | number;
1832
- align?: 'left' | 'center' | 'right';
1833
- sortDirection?: 'ascending' | 'descending' | 'none';
1834
- onSortChange?: (value: 'ascending' | 'descending') => void;
1835
- disabled?: boolean;
1836
- }
1837
- ```
1838
-
1839
- | Prop | Type | Default | Description |
1840
- | --- | --- | --- | --- |
1841
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
1842
- | `width` | `'min' \| 'max' \| 'auto' \| 'large'` | `'auto'` | Sets the width of a table header. |
1843
- | `align` | `'left' \| 'center' \| 'right'` | `'left'` | Sets the alignment of a table header |
1844
- | `sortDirection` | `'ascending' \| 'descending' \| 'none'` | `'N/A'` | Sets the current direction in which the column is sorted (if any). It's a visual indicator, it doesn't modify the data. |
1845
- | `disabled` | `boolean(optional)` | `false` | If `true`, users cannot change the sort ordering. It has no effect if sort=`never` or `undefined`. |
1846
- | `onSortChange` | `(value: 'ascending' | 'descending') => void(optional)` | `N/A` | A callback function that is invoked when the header is clicked. It recieves the new sort direction as an argument. It's required when sort = `ascending`, `descending` or `none`. |
1847
-
1848
- ##### Usage
1849
-
1850
- ```javascript
1851
- const Extension = () => {
1852
- return (
1853
- <Table bordered={true}>
1854
- <TableHead>
1855
- <TableRow>
1856
- <TableHeader width={150} align="left">Name</TableHeader>
1857
- <TableHeader>Price</TableHeader>
1858
- </TableRow>
1859
- </TableHead>
1860
- <TableBody>
1861
- <TableRow>
1862
- <TableCell>Roger Federer</TableCell>
1863
- <TableCell align="right">$1.50</TableCell>
1864
- </TableRow>
1865
- </TableBody>
1866
- </Table>
1867
- );
1868
- };
1869
- ```
1870
-
1871
- ### TableRow
1872
-
1873
- ##### Import
1874
-
1875
- ```javascript
1876
- import { TableRow } from '@hubspot/ui-extensions';
1877
- ```
1878
-
1879
- ##### Props
1880
-
1881
- ```typescript
1882
- interface TableRowProps {
1883
- children: ReactNode;
1884
- }
1885
- ```
1886
-
1887
- | Prop | Type | Default | Description |
1888
- | --- | --- | --- | --- |
1889
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
1890
-
1891
- ##### Usage
1892
-
1893
- ```javascript
1894
- const Extension = () => {
1895
- return (
1896
- <Table bordered={true}>
1897
- <TableHead>
1898
- <TableRow>
1899
- <TableHeader>Name</TableHeader>
1900
- <TableHeader>Phone</TableHeader>
1901
- </TableRow>
1902
- </TableHead>
1903
- <TableBody>
1904
- <TableRow>
1905
- <TableCell>Roger Federer</TableCell>
1906
- <TableCell>555-555-7866</TableCell>
1907
- </TableRow>
1908
- </TableBody>
1909
- </Table>
1910
- );
1911
- };
1912
- ```
1913
-
1914
- ### Tag
1915
-
1916
- ##### Import
1917
-
1918
- ```javascript
1919
- import { Tag } from '@hubspot/ui-extensions';
1920
- ```
1921
-
1922
- ##### Props
1923
-
1924
- ```typescript
1925
- interface TagProps {
1926
- children: ReactNode;
1927
- onClick?: () => void;
1928
- variant?: 'default' | 'warning' | 'success' | 'error';
1929
- }
1930
- ```
1931
-
1932
- | Prop | Type | Default | Description |
1933
- | --- | --- | --- | --- |
1934
- | `children` | `string` | `N/A` | Text to be displayed in the tag. |
1935
- | `onClick` | `() => void` `(optional)` | `N/A` | A function that will be invoked when the `Tag` is clicked. It receives no arguments and it's return value is ignored. |
1936
- | `variant` | `'default' \| 'warning' \| 'success' \| 'error'` `(optional)` | `'default'` | The color variation of the tag to display |
1937
-
1938
- ##### Usage
1939
-
1940
- ```javascript
1941
- const Extension = () => {
1942
- return (
1943
- <Tag
1944
- variant="success"
1945
- onClick={() => {
1946
- console.log('Tag clicked!');
1947
- }}
1948
- >
1949
- Success
1950
- </Tag>
1951
- );
1952
- };
1953
- ```
1954
-
1955
- ### Text
1956
-
1957
- ##### Import
1958
-
1959
- ```javascript
1960
- import { Text } from '@hubspot/ui-extensions';
1961
- ```
1962
-
1963
- ##### Props
1964
-
1965
- ```typescript
1966
- export interface TextFormatOptions {
1967
- fontWeight?: 'regular' | 'bold' | 'demibold';
1968
- italic?: boolean;
1969
- lineDecoration?: 'none' | 'underline' | 'strikethrough';
1970
- }
1971
-
1972
- export type TextProps = {
1973
- variant?: 'bodytext' | 'microcopy';
1974
- inline?: boolean;
1975
- children: ReactNode;
1976
- format?: TextFormatOptions;
1977
- };
1978
- ```
1979
-
1980
- | Prop | Type | Default | Description |
1981
- | --- | --- | --- | --- |
1982
- | `format` | `'TextFormatOptions'` `(optional)` | `N/A` | Type of formatting options for the text. |
1983
- | `children` | `string` | `N/A` | Text to be displayed as body text. |
1984
- | `variant` | `'bodytext' \| 'microcopy'` | `'bodytext'` | Type of text to display |
1985
- | `inline` | `boolean(optional)` | `false` | If `false` the text component will not insert a line break. |
1986
-
1987
- #### Format Options
1988
-
1989
- - bold text: `{ fontWeight: 'bold' }`
1990
- - semibold text: `{ fontWeight: 'demibold' }`
1991
- - italicized text: `{ italic: true }`
1992
- - strikethrough text: `{ lineDecoration: 'strikethrough' }`
1993
- - underlined text: `{ lineDecoration: 'underline' }`
1994
- - inline text: `<Text inline={true}/>`
1995
-
1996
-
1997
- ##### Usage
1998
-
1999
- ```javascript
2000
- const Extension = () => {
2001
- return (
2002
- <>
2003
- <Text>Plain text</Text>
2004
- <Text format={{ fontWeight: 'bold' }}>Bold</Text>
2005
- <Text format={{ italic: true }}>Italics</Text>
2006
- <Text format={{ fontWeight: 'bold', italic: true }}>
2007
- Bold and Italic text
2008
- </Text>
2009
- <Text format={{ lineDecoration: 'strikethrough' }}>
2010
- Strikethrough Text
2011
- </Text>
2012
- <Text variant="microcopy">
2013
- Microcopy text
2014
- <Text inline={true} format={{ fontWeight: 'bold' }}>
2015
- with inner bold
2016
- </Text>
2017
- </Text>
2018
- </>
2019
- );
2020
- };
2021
- ```
2022
-
2023
- ### TextArea
2024
-
2025
- ##### Import
2026
-
2027
- ```javascript
2028
- import { TextArea } from '@hubspot/ui-extensions';
2029
- ```
2030
-
2031
- ##### Props
2032
-
2033
- ```typescript
2034
- interface TextareaProps {
2035
- label: string;
2036
- name: string;
2037
- value?: string;
2038
- required?: boolean;
2039
- readOnly?: boolean;
2040
- description?: string;
2041
- tooltip?: string;
2042
- placeholder?: string;
2043
- error?: boolean;
2044
- validationMessage?: string;
2045
- onChange?: (value: string) => void;
2046
- onInput?: (value: string) => void;
2047
- onBlur?: (value: string) => void;
2048
- onFocus?: (value: string) => void;
2049
- cols?: number;
2050
- maxLength?: number;
2051
- rows?: number;
2052
- resize?: 'vertical' | 'horizontal' | 'both' | 'none';
2053
- }
2054
- ```
2055
-
2056
- | Prop | Type | Default | Description |
2057
- | --- | --- | --- | --- |
2058
- | `label` | `string` | `N/A` | The label text to display for the textarea element |
2059
- | `name` | `string` | `N/A` | The unique identifier for the textarea element, this could be thought of as the HTML5 [textarea element's name attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#name) |
2060
- | `value` | `string(optional)` | `''` | The value of the textarea |
2061
- | `required` | `boolean(optional)` | `false` | Determines if the required indicator should be displayed |
2062
- | `readOnly` | `boolean(optional)` | `false` | Determines if the field is editable or not. |
2063
- | `description` | `string(optional)` | `N/A` | Instructional message to display to the user to help understand the purpose of the textarea. |
2064
- | `tooltip` | `string(optional)` | `N/A` | Text that will appear in a tooltip next to the textarea label. |
2065
- | `placeholder` | `string(optional)` | `N/A` | Text that appears in the textarea when it has no value set. |
2066
- | `error` | `boolean(optional)` | `false` | If set to true, `validationMessage` is displayed as an error message, if it was provided. The textarea will also render it's error state to let the user know there is an error. If false, `validationMessage` is displayed as a success message. |
2067
- | `validationMessage` | `string(optional)` | `''` | The text to show if the textarea has an error. |
2068
- | `onChange` | `(value: string) => void(optional)` | `N/A` | A callback function that is invoked when the value is committed. Currently these times are `onBlur` of the textarea and when the user submits the form. |
2069
- | `onInput` | `(value: string) => void(optional)` | `N/A` | A function that is called and passed the value every time the field is edited by the user. It is recommended that you do not use this value to update state, that is what `onChange` should be used for. Instead this should be used for validation. |
2070
- | `onBlur` | `(value: string) => void(optional)` | `N/A` | A function that is called and passed the value every time the field loses focus. |
2071
- | `onFocus` | `(value: string) => void(optional)` | `N/A` | A function that is called and passed the value every time the field gets focused. |
2072
- | `cols` | `number(optional)` | `N/A` | The visible width of the text control, in average character widths. |
2073
- | `rows` | `number(optional)` | `N/A` | The number of visible text lines for the control. |
2074
- | `maxLength` | `number(optional)` | `N/A` | The maximum number of characters (UTF-16 code units) that the user can enter. If this value isn't specified, the user can enter an unlimited number of characters. |
2075
- | `resize` | `'vertical' \| 'horizontal' \| 'both' \| 'none'` `(optional)` | `'vertical'` | Sets whether an element is resizable, and if so, in which directions. |
2076
-
2077
- ##### Usage
2078
-
2079
- ```javascript
2080
- import { useState } from 'react';
2081
-
2082
- const Extension = () => {
2083
- const [desciptiption, setDescription] = useState('');
2084
- const [validationMessage, setValidationMessage] = useState('');
2085
- const [isValid, setIsValid] = useState(true);
2086
-
2087
- return (
2088
- <Form>
2089
- <TextArea
2090
- label="Description"
2091
- name="description"
2092
- tooltip="Provide as much detail as possible"
2093
- description="Please include a link"
2094
- placeholder="My desription"
2095
- required={true}
2096
- error={!isValid}
2097
- validationMessage={validationMessage}
2098
- onChange={value => {
2099
- setDescription(value);
2100
- }}
2101
- onInput={value => {
2102
- if (!value.includes('http')) {
2103
- setValidationMessage('A link must be included.');
2104
- setIsValid(false);
2105
- } else {
2106
- setValidationMessage('Valid description!');
2107
- setIsValid(true);
2108
- }
2109
- }}
2110
- />
2111
- </Form>
2112
- );
2113
- };
2114
- ```
2115
-
2116
- ### Tile
2117
-
2118
- ##### Import
2119
-
2120
- ```javascript
2121
- import { Tile } from '@hubspot/ui-extensions';
2122
- ```
2123
-
2124
- ##### Props
2125
-
2126
- ```typescript
2127
- interface TileProps {
2128
- children: ReactNode;
2129
- flush?: boolean;
2130
- }
2131
- ```
2132
-
2133
- | Prop | Type | Default | Description |
2134
- | --- | --- | --- | --- |
2135
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
2136
- | `flush` | `boolean(optional)` | `false` | If true the content of the Tile will have no left or right padding. |
2137
-
2138
- ##### Usage
2139
-
2140
- ```javascript
2141
- const Extension = () => {
2142
- return (
2143
- <>
2144
- <Tile flush={true}>
2145
- <Text>No left padding</Text>
2146
- </Tile>
2147
- <Tile>
2148
- <Text>Small amount of left padding</Text>
2149
- </Tile>
2150
- </>
2151
- );
2152
- };
2153
- ```
2154
-
2155
- ### ToggleGroup
2156
-
2157
- ##### Import
2158
-
2159
- ```javascript
2160
- import { ToggleGroup } from '@hubspot/ui-extensions';
2161
- ```
2162
-
2163
- ##### Props
2164
-
2165
- ```typescript
2166
- type ToggleGroupProps = {
2167
- toggleType: 'checkboxList' | 'radioButtonList';
2168
- name: string;
2169
- label: string;
2170
- value?: string | string[];
2171
- onChange?: (value: string) => void | (value: string[]) => void;
2172
- validationMessage?: string;
2173
- required?: boolean;
2174
- tooltip?: string;
2175
- error?: boolean;
2176
- options: {
2177
- label: string;
2178
- value: string;
2179
- initialIsChecked?: boolean;
2180
- readonly?: boolean;
2181
- description?: string;
2182
- }[];
2183
- inline?: boolean;
2184
- variant?: 'default' | 'small';
2185
- };
2186
-
2187
- ```
2188
-
2189
- | Prop | Type | Default | Description |
2190
- | --- | --- | --- | --- | --- |
2191
- | `toggleType` | `'radioButtonList' \| 'checkboxList'` | `N/A` | The type of toggles that will be shown. `'checkboxList'` is a multi-select and `'radioButtonList'` is a single select | ; |
2192
- | `name` | `string` | `N/A` | The unique identifier for the toggle group element. |
2193
- | `label` | `string` | `N/A` | The label text to display for the toggle group element. |
2194
- | `options` | `Array<{ label: string; value: string; initialIsChecked?: boolean; readonly?: boolean; description?: string }>` | `N/A` | |
2195
- | `value` | `string \| string[]` `(optional)` | `N/A` | The value of the toggle group. If `toggleType` is `'radioButtonList'`, this should be a `string`. If `toggleType` is `'checkboxList'` this should be an array of `string`s. |
2196
- | `onChange` | `(value: string) => void \| (value: string[]) => void` `(optional)` | `N/A` | A function that is called with the new value or values when it is updated. If `toggleType` is `'radioButtonList'`, the function will be called with the `value` that is a `string`. If `toggleType` is `'checkboxList'` the function will be called with the `value` that is an array of `string`s. |
2197
- | `required` | `boolean(optional)` | `false` | Determines if the required indicator should be displayed |
2198
- | `tooltip` | `string` | `N/A` | Text that will appear in a tooltip next to the toggle group label. |
2199
- | `error` | `boolean(optional)` | `false` | If set to true, `validationMessage` is displayed as an error message, if it was provided. The input will also render it's error state to let the user know there is an error. If false, `validationMessage` is displayed as a success message. |
2200
- | `validationMessage` | `string(optional)` | `''` | The text to show if the input has an error. |
2201
- | `inline` | `boolean(optional)` | `false` | Determines of the options are stacked vertically or share a line horizontally. |
2202
- | `variant` | `'default' \| 'small'` `(optional)` | `default` | The size variation of the individual options. |
2203
-
2204
- ##### Usage
2205
-
2206
- ```javascript
2207
- const options = [1, 2, 3, 4].map(n => ({
2208
- label: `Option ${n}`,
2209
- value: `${n}`,
2210
- initialIsChecked: n === 2,
2211
- readonly: false,
2212
- description: `This is option ${n}`,
2213
- }));
2214
-
2215
- const Extension = () => {
2216
- return (
2217
- <ToggleGroup
2218
- name="toggle-checkboxes"
2219
- label="Toggle these things"
2220
- error={false}
2221
- options={options}
2222
- tooltip="Here's a secret tip."
2223
- validationMessage="Make sure you do the thing correctly."
2224
- required={false}
2225
- inline={false}
2226
- toggleType="checkboxList"
2227
- variant="default"
2228
- />
2229
- );
2230
- };
2231
- ```
5
+ [Documentation](https://developers.hubspot.com/docs/platform/ui-components)