@hubspot/ui-extensions 0.0.1-prealpha.2 → 0.0.1-prealpha.4

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 ADDED
@@ -0,0 +1,1228 @@
1
+ # ui-extensions-components
2
+
3
+ ## TOC
4
+
5
+ - [Alert](#alert)
6
+ - [Button](#button)
7
+ - [ButtonRow](#buttonrow)
8
+ - [Card](#card)
9
+ - [DescriptionList](#descriptionlist)
10
+ - [DescriptionListItem](#descriptionlistitem)
11
+ - [Divider](#divider)
12
+ - [Form](#form)
13
+ - [Heading](#heading)
14
+ - [Image](#image)
15
+ - [Input](#input)
16
+ - [LoadingSpinner](#loadingspinner)
17
+ - [ProgressBar](#progressbar)
18
+ - [Select](#select)
19
+ - [Stack](#stack)
20
+ - [Statistics](#statistics)
21
+ - [StatisticsItem](#statisticsitem)
22
+ - [StatisticsTrend](#statisticstrend)
23
+ - [Table](#table)
24
+ - [TableBody](#tablebody)
25
+ - [TableCell](#tablecell)
26
+ - [TableFooter](#tablefooter)
27
+ - [TableHead](#tablehead)
28
+ - [TableHeader](#tableheader)
29
+ - [TableRow](#tablerow)
30
+ - [Tag](#tag)
31
+ - [Text](#text)
32
+ - [Tile](#tile)
33
+
34
+ ## Components
35
+
36
+ ### Alert
37
+
38
+ ##### Import
39
+
40
+ ```javascript
41
+ import { Alert } from '@hubspot/ui-extensions';
42
+ ```
43
+
44
+ ##### Props
45
+
46
+ The Alert component accepts the following props:
47
+
48
+ ```typescript
49
+ export interface AlertProps {
50
+ title: string;
51
+ body?: string;
52
+ children?: ReactNode;
53
+ variant?: 'info' | 'warning' | 'success' | 'error' | 'danger';
54
+ }
55
+ ```
56
+
57
+ | Prop | Type | Default | Description |
58
+ | --- | --- | --- | --- |
59
+ | `title` | `string` | `N/A` | The title text for the alert message. |
60
+ | `body` | `string(optional)` | `N/A` | The main content of the alert message. If not provided, the children prop is used. |
61
+ | `children` | `ReactNode(optional)` | `N/A` | The main content of the alert message when the body prop is not provided. |
62
+ | `variant` | `'info' \| 'warning' \| 'success' \|'error' \| 'danger'` `(optional)` | `'info'` | Sets the color variation of the alert |
63
+
64
+ ##### Usage
65
+
66
+ ```javascript
67
+ const Extension = () => {
68
+ return (
69
+ <>
70
+ <Alert title="Important Info" variant="info">
71
+ This is an informative message.
72
+ </Alert>
73
+ <Alert
74
+ title="Success"
75
+ body="Operation completed successfully."
76
+ variant="success"
77
+ />
78
+ <Alert title="Warning" body="Proceed with caution." variant="warning" />
79
+ <Alert
80
+ title="Error"
81
+ body="Something went wrong. Please try again."
82
+ variant="error"
83
+ />
84
+ <Alert
85
+ title="Danger"
86
+ body="This action cannot be undone. Be careful."
87
+ variant="danger"
88
+ />
89
+ </>
90
+ );
91
+ };
92
+ ```
93
+
94
+ ### Button
95
+
96
+ ##### Import
97
+ ```javascript
98
+ import { Button } from '@hubspot/ui-extensions';
99
+ ```
100
+
101
+ ##### Props
102
+ ```typescript
103
+ interface ButtonProps {
104
+ text: string;
105
+ onClick?: () => void;
106
+ href?: string;
107
+ disabled?: boolean;
108
+ variant?: 'primary' | 'secondary' | 'destructive';
109
+ type?: 'button' | 'reset' | 'submit';
110
+ }
111
+ ```
112
+ | Prop | Type | Default | Description |
113
+ | - | - | - | - |
114
+ | `text` | `string` | `N/A` | The displayable text for the Button |
115
+ | `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|
116
+ | `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. |
117
+ | `disabled` | `boolean(optional)` | `N/A` | Determines if the button should be disabled or not.|
118
+ | `variant` | ` 'primary' | 'secondary' | 'destructive'` `(optional)` |`'secondary'`| Sets the color variation of the button |
119
+ | `type` | `'button' \| 'reset' \| 'submit'` `(optional)` | `'button'`| Sets the HTML attribute "role" of the button |
120
+
121
+ ##### Usage
122
+ ```javascript
123
+ const Extension = () => {
124
+ return (
125
+ <Button
126
+ text="Click me!"
127
+ onClick={() => {
128
+ console.log('Someone clicked on the button!');
129
+ }}
130
+ href="https://hubspot.com"
131
+ variant="destructive"
132
+ type="button"
133
+ />
134
+ );
135
+ }
136
+ ```
137
+
138
+ ### ButtonRow
139
+
140
+ ##### Import
141
+ ```javascript
142
+ import { ButtonRow } from '@hubspot/ui-extensions';
143
+ ```
144
+
145
+ ##### Props
146
+ ```typescript
147
+ interface ButtonRowProps {
148
+ children: ReactNode;
149
+ disableDropdown?: boolean;
150
+ }
151
+ ```
152
+ | Prop | Type | Default | Description |
153
+ | - | - | - | - |
154
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
155
+ | `disableDropdown` | `boolean(optional)` | `false` | Disables the dropdown list of buttons that appears the the children expand beyond the horizontal space |
156
+
157
+ ##### Usage
158
+ ```javascript
159
+ const Extension = () => {
160
+ return (
161
+ <ButtonRow disableDropdown={false}>
162
+ <Button
163
+ text="Regular Button"
164
+ onClick={() => {
165
+ console.log('Regular button clicked');
166
+ }}
167
+ />
168
+ <Button
169
+ text="Reset"
170
+ onClick={() => {
171
+ console.log('Reset button clicked');
172
+ }}
173
+ variant="destructive"
174
+ type="reset"
175
+ />
176
+ <Button
177
+ text="Submit"
178
+ onClick={() => {
179
+ console.log('Submit button clicked');
180
+ }}
181
+ variant="primary"
182
+ type="submit"
183
+ />
184
+ </ButtonRow>
185
+ );
186
+ }
187
+ ```
188
+
189
+ ### Card
190
+
191
+ ##### Import
192
+ ```javascript
193
+ import { Card } from '@hubspot/ui-extensions';
194
+ ```
195
+
196
+ ##### Props
197
+ ```typescript
198
+ interface CardProps {
199
+ children: ReactNode;
200
+ }
201
+ ```
202
+ | Prop | Type | Default | Description |
203
+ | - | - | - | - |
204
+ | `children` | `ReactNode`| `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
205
+
206
+ ##### Usage
207
+ ```javascript
208
+ const Extension = () => {
209
+ return (
210
+ <Card>
211
+ <Button
212
+ text="Regular Button"
213
+ onClick={() => {
214
+ console.log('Regular button clicked');
215
+ }}
216
+ />
217
+ </Card>
218
+ );
219
+ }
220
+ ```
221
+
222
+ ### DescriptionList
223
+
224
+ ##### Import
225
+ ```javascript
226
+ import { DescriptionList } from '@hubspot/ui-extensions';
227
+ ```
228
+
229
+ ##### Props
230
+ ```typescript
231
+ interface DescriptionListProps {
232
+ children: ReactNode;
233
+ direction?: 'row' | 'column';
234
+ }
235
+ ```
236
+ | Prop | Type | Default | Description |
237
+ | - | - | - | - |
238
+ | `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) |
239
+ | `direction` | `'row' \| 'column'` `(optional)` | `'column'`| The direction the label/value pairs are placed in the description list container. |
240
+
241
+ ##### Usage
242
+ ```javascript
243
+ const Extension = () => {
244
+ return (
245
+ <DescriptionList direction="row">
246
+ <DescriptionListItem label={"First Name"}>
247
+ <Text text="Alan" />
248
+ </DescriptionListItem>
249
+ <DescriptionListItem label={"Last Name"}>
250
+ <Text text="Turing" />
251
+ </DescriptionListItem>
252
+ </DescriptionList>
253
+ );
254
+ }
255
+ ```
256
+
257
+ #### DescriptionListItem
258
+
259
+ ##### Import
260
+ ```javascript
261
+ import { DescriptionListItem } from '@hubspot/ui-extensions';
262
+ ```
263
+
264
+ ##### Props
265
+ ```typescript
266
+ interface DescriptionListItemProps {
267
+ children: ReactNode;
268
+ label: string;
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
+ | `label` | `string` | `N/A` | Text to be displayed as the label |
275
+
276
+ ##### Usage
277
+ ```javascript
278
+ const Extension = () => {
279
+ return (
280
+ <DescriptionList direction="row">
281
+ <DescriptionListItem label={"First Name"}>
282
+ <Text text="Alan" />
283
+ </DescriptionListItem>
284
+ <DescriptionListItem label={"Last Name"}>
285
+ <Text text="Turing" />
286
+ </DescriptionListItem>
287
+ </DescriptionList>
288
+ );
289
+ }
290
+ ```
291
+
292
+ ### Divider
293
+
294
+ ##### Import
295
+ ```javascript
296
+ import { Divider } from '@hubspot/ui-extensions';
297
+ ```
298
+
299
+ ##### Props
300
+ ```typescript
301
+ interface DividerProps {
302
+ distance?:
303
+ | 'flush'
304
+ | 'extra-small'
305
+ | 'small'
306
+ | 'medium'
307
+ | 'large'
308
+ | 'extra-large';
309
+ }
310
+ ```
311
+ | Prop | Type | Default | Description |
312
+ | - | - | - | - |
313
+ | `distance` | `'flush'\| 'extra-small' \| 'small' \| 'medium' \| 'large'\| 'extra-large'` `(optional)`| `'small'` | The size of the padding above and below the divider. |
314
+
315
+ ##### Usage
316
+ ```javascript
317
+ const Extension = () => {
318
+ return (
319
+ <Divider distance="extra-large"/>
320
+ );
321
+ }
322
+ ```
323
+
324
+ ### Form
325
+
326
+ ##### Import
327
+ ```javascript
328
+ import { Form } from '@hubspot/ui-extensions';
329
+ ```
330
+
331
+ ##### Props
332
+ ```typescript
333
+ interface FormProps {
334
+ children: ReactNode;
335
+ onSubmit?: () => void;
336
+ preventDefault?: boolean;
337
+ }
338
+ ```
339
+ | Prop | Type | Default | Description |
340
+ | - | - | - | - |
341
+ | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
342
+ | `onSubmit` | `function(optional)` | `N/A`| A function that will be called when the form is submitted. It will receive no arguments and it's return value will be ignored. |
343
+ | `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. |
344
+
345
+ ##### Usage
346
+ ```javascript
347
+ const Extension = () => {
348
+ return (
349
+ <Form onSubmit={() => { console.log('Form submitted!')}} preventDefault={true}>
350
+ <Input {...} />
351
+ <Select {...} />
352
+ <Button
353
+ text="Submit"
354
+ onClick={() => {
355
+ console.log('Submit button clicked');
356
+ }}
357
+ variant="primary"
358
+ type="submit"
359
+ />
360
+ </Form>
361
+ );
362
+ }
363
+ ```
364
+
365
+ ### Heading
366
+
367
+ ##### Import
368
+ ```javascript
369
+ import { Heading } from '@hubspot/ui-extensions';
370
+ ```
371
+
372
+ ##### Props
373
+ ```typescript
374
+ interface HeadingProps {
375
+ text: string;
376
+ format?: 'plaintext' | 'markdown';
377
+ }
378
+ ```
379
+ | Prop | Type | Default | Description |
380
+ | - | - | - | - |
381
+ | `text` | `string` | `N/A`| Text to be displayed as heading text. If format is `"markdown"`, inline markdown elements (i.e. bold, italics, code, links) are supported|
382
+ | `format` | `'plaintext' \| 'markdown'` `(optional)` | `'plaintext'`| Type of formatting for the display text. |
383
+
384
+ #### Markdown
385
+ Markdown syntax supported in the component:
386
+
387
+ - bold text: `**like this**` or `__like this__`
388
+ - italicized text: `*like this*` or `_like this_`
389
+ - inline code: `` `like this` ``
390
+ - links: `[visible anchor text](https://www.hubspot.com/)`
391
+
392
+ ##### Usage
393
+ ```javascript
394
+ const Extension = () => {
395
+ return (
396
+ <>
397
+ <Heading text="Plain text, nothing special here"/>
398
+ <Heading text="**It's a Bold Strategy Cotton, lets see if it pays off for them.**" format="markdown"/>
399
+ </>
400
+ );
401
+ }
402
+ ```
403
+
404
+ ### Image
405
+ ##### Import
406
+
407
+
408
+ ```javascript
409
+ import { Image } from '@hubspot/ui-extensions';
410
+ ```
411
+
412
+ ##### Props
413
+ ```typescript
414
+ interface ImageProps {
415
+ alt?: string;
416
+ href?: string;
417
+ onClick?: () => void;
418
+ src: string;
419
+ width?: number;
420
+ }
421
+ ```
422
+
423
+ | Prop | Type | Description |
424
+ | - | - | - |
425
+ | `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) |
426
+ | `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 |
427
+ | `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. |
428
+ | `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)|
429
+ | `width` | `number(optional)` | The pixel width of the image |
430
+
431
+ | Prop | Type | Description |
432
+ | - | - | - |
433
+ | `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) |
434
+ | `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 |
435
+ | `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. |
436
+ | `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)|
437
+ | `width` | `number(optional)` | The pixel width of the image |
438
+
439
+ ##### Usage
440
+ ```javascript
441
+ const Extension = () => {
442
+ return (
443
+ <Image
444
+ alt="A picture of an adorable black lab puppy, click on me to see in a new tab"
445
+ src="https://picsum.photos/id/237/200/300"
446
+ href="https://picsum.photos/id/237"
447
+ onClick={() => {
448
+ console.log('Someone clicked on the image!')
449
+ }}
450
+ width={200}
451
+ />
452
+ );
453
+ }
454
+ ```
455
+
456
+ ### Input
457
+
458
+ ##### Import
459
+ ```javascript
460
+ import { Input } from '@hubspot/ui-extensions';
461
+ ```
462
+
463
+ ##### Props
464
+ ```typescript
465
+ interface InputProps {
466
+ label: string;
467
+ name: string;
468
+ value?: string;
469
+ required?: boolean;
470
+ readonly?: boolean;
471
+ description?: string;
472
+ tooltip?: string;
473
+ placeholder?: string;
474
+ error?: boolean;
475
+ errorMessage?: string;
476
+ onChange: (value: string) => void;
477
+ onInput: (value: string) => void;
478
+ }
479
+ ```
480
+ | Prop | Type | Default | Description |
481
+ | - | - | - | - |
482
+ | `label` | `string` | `N/A`| The label text to display for the form input element |
483
+ | `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) |
484
+ | `value` | `string(optional)` | `''`| The value of the input |
485
+ | `required` | `boolean(optional)` | `false`| Determines if the required indicator should be displayed |
486
+ | `readonly` | `boolean(optional)` | `false`| Determines if the field is editable or not. |
487
+ | `description` | `string(optional)` | `N/A`| Instructional message to display to the user to help understand the purpose of the input. |
488
+ | `tooltip` | `string(optional)` | `N/A`| Text that will appear in a tooltip next to the input label. |
489
+ | `placeholder` | `string(optional)` | `N/A`| Text that appears in the input when it has no value set. |
490
+ | `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. |
491
+ | `validationMessage` | `string(optional)` | `''`| The text to show if the input has an error. |
492
+ | `onChange` | `(value: string) => void` | `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 stops typing. |
493
+ | `onInput` | `(value: string) => void` | `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. |
494
+
495
+ ##### Usage
496
+ ```javascript
497
+ import { useState } from 'react';
498
+
499
+ const Extension = () => {
500
+ const [ name, setName ] = useState('');
501
+ const [ validationMessage, setValidationMessage ] = useState('');
502
+ const [ isValid, setIsValid ] = useState(true);
503
+
504
+ return (
505
+ <Form>
506
+ <Input
507
+ label="First Name"
508
+ name="first-name"
509
+ tooltip="Please enter your first name"
510
+ description="Please enter your first name"
511
+ placeholder="First name"
512
+ required={true}
513
+ error={!isValid}
514
+ validationMessage={validationMessage}
515
+ onChange={(value) => {
516
+ setName(value)
517
+ }}
518
+ onInput={(value) => {
519
+ if(value !== 'Bill') {
520
+ setValidationMessage('This form only works for people named Bill');
521
+ setIsValid(false);
522
+ } else if (value === '') {
523
+ setValidationMessage('First name is required')
524
+ setIsValid(false);
525
+ } else {
526
+ setValidationMessage('Valid first name!')
527
+ setIsValid(true);
528
+ }
529
+ }}
530
+ />
531
+ </Form>
532
+ );
533
+ }
534
+ ```
535
+
536
+ ### LoadingSpinner
537
+
538
+ ##### Import
539
+ ```javascript
540
+ import { LoadingSpinner } from '@hubspot/ui-extensions';
541
+ ```
542
+
543
+ ##### Props
544
+ ```typescript
545
+ export interface LoadingSpinnerProps {
546
+ label: string;
547
+ showLabel?: boolean;
548
+ size?: 'xs' | 'sm' | 'md';
549
+ layout?: 'inline' | 'centered';
550
+ grow?: boolean;
551
+ }
552
+ ```
553
+ | Prop | Type | Default | Description |
554
+ | --- | --- | --- | --- |
555
+ | `label` | `string` | `N/A`| The companion text for the loading spinner. |
556
+ | `showLabel` | `boolean(optional)` | `false` | if `true`, the label will be visible alongside the loading spinner. |
557
+ | `size` | `'xs'\| 'sm' \| 'md'` `(optional)`| `'sm'` | The size of the loading spinner icon. |
558
+ | `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. |
559
+ | `grow` | `boolean(optional)` | `false` | if `true`, sets the height and width of the loading spinner to 100%.|
560
+
561
+ ##### Usage
562
+ ```javascript
563
+ const Extension = () => {
564
+ return <LoadingSpinner label="Loading..." />;
565
+ }
566
+ ```
567
+ ### ProgressBar
568
+
569
+ ##### Import
570
+ ```javascript
571
+ import { ProgressBar } from '@hubspot/ui-extensions';
572
+ ```
573
+
574
+ ##### Props
575
+ ```typescript
576
+ export interface ProgressBarProps {
577
+ title?: string;
578
+ showPercentage?: boolean;
579
+ value?: number;
580
+ valueMax?: number;
581
+ valueDescription?: string;
582
+ variant?: 'success' | 'danger' | 'warning';
583
+ }
584
+ ```
585
+ | Prop | Type | Default | Description |
586
+ | --- | --- | --- | --- |
587
+ | `title` | `string(optional)` | `N/A` | Text to be displayed in the progressbar title. |
588
+ | `showPercentage` | `boolean(optional)` | `false` | Toggles the display of the completion percentage. |
589
+ | `value` | `number(optional)` | `0` | The value of the progress indicator.
590
+ | `valueMax` | `number(optional)` | `100` | The maximum value of the progress.
591
+ | `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"**
592
+ | `variant` | `'success' \| 'danger' \| 'warning'` | `'success'` | The type of progressbar to display. Defaults to success.
593
+
594
+ ##### Usage
595
+ ```javascript
596
+ const Extension = () => {
597
+ return (
598
+ <ProgressBar
599
+ variant="warning"
600
+ value={50}
601
+ valueMax={200}
602
+ showPercentage={true}
603
+ />
604
+ );
605
+ }
606
+ ```
607
+
608
+ ### Select
609
+
610
+ ##### Import
611
+ ```javascript
612
+ import { Select } from '@hubspot/ui-extensions';
613
+ ```
614
+
615
+ ##### Props
616
+ ```typescript
617
+ interface SelectProps {
618
+ label: string;
619
+ name: string;
620
+ value?: string | number | boolean;
621
+ required?: boolean;
622
+ readonly?: boolean;
623
+ description?: string;
624
+ tooltip?: string;
625
+ placeholder?: string;
626
+ error?: boolean;
627
+ errorMessage?: string;
628
+ onChange: (value: string) => void;
629
+ options: {
630
+ label: string;
631
+ value: string | number | boolean;
632
+ }[];
633
+ }
634
+
635
+ ```
636
+ | Prop | Type | Default | Description |
637
+ | - | - | - | - |
638
+ | `label` | `string` | `N/A`| The label text to display for the select element |
639
+ | `name` | `string` | `N/A`| The unique identifier for the select element. |
640
+ | `value` | `string \| number \| boolean` | `''`| The value of the select input. |
641
+ | `required` | `boolean` | `false`| Determines if the required indicator should be displayed |
642
+ | `readonly` | `boolean` | `false`| Determines if the field is editable or not. |
643
+ | `description` | `string` | `N/A`| Instructional message to display to the user to help understand the purpose of the input. |
644
+ | `tooltip` | `string` | `N/A`| Text that will appear in a tooltip next to the input label. |
645
+ | `placeholder` | `string` | `N/A`| Text that appears in the input when it has no value set. |
646
+ | `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. |
647
+ | `validationMessage` | `string(optional)` | `''`| The text to show if the input has an error. |
648
+ | `onChange` | `(value: string) => void` | `N/A`| Function that is called with the new value when it is updated. |
649
+ | `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. |
650
+
651
+ ##### Usage
652
+ ```javascript
653
+ const Extension = () => {
654
+ const [ name, setName ] = useState(null);
655
+ const [ validationMessage, setValidationMessage ] = useState('');
656
+ const [ isValid, setIsValid ] = useState(true);
657
+
658
+ const options = [
659
+ {label: 'Bill', value: 42},
660
+ {label: 'Ted', value: 43}
661
+ ];
662
+
663
+ return (
664
+ <Form>
665
+ <Select
666
+ label="Best Bill & Ted Character?"
667
+ name="best-char"
668
+ tooltip="Please choose"
669
+ description="Please choose"
670
+ placeholder="Bill or Ted?"
671
+ required={true}
672
+ error={!isValid}
673
+ validationMessage={validationMessage}
674
+ onChange={(value) => {
675
+ setName(value)
676
+ if(!value) {
677
+ setValidationMessage('This is required');
678
+ setIsValid(false);
679
+ } else {
680
+ setValidationMessage('Excellent!');
681
+ setIsValid(true);
682
+ }
683
+ }}
684
+ options={options}
685
+ />
686
+ </Form>
687
+ );
688
+ }
689
+ ```
690
+
691
+ ### Stack
692
+
693
+ ##### Import
694
+ ```javascript
695
+ import { Stack } from '@hubspot/ui-extensions';
696
+ ```
697
+
698
+ ##### Props
699
+ ```typescript
700
+ interface StackProps {
701
+ distance?: 'flush' | 'small';
702
+ children?: ReactNode;
703
+ }
704
+ ```
705
+ | Prop | Type | Default | Description |
706
+ | - | - | - | - |
707
+ | `distance` | `'flush' \| 'small'` | `'small'`| Amount of padding between each child component passed as children |
708
+ | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
709
+
710
+ ##### Usage
711
+ ```javascript
712
+ const Extension = () => {
713
+ return (
714
+ <Stack>
715
+ <Image {...} />
716
+ <Text {...} />
717
+ </Stack>
718
+ );
719
+ }
720
+ ```
721
+
722
+ ### Statistics
723
+
724
+ ##### Import
725
+ ```javascript
726
+ import { Statistics } from '@hubspot/ui-extensions';
727
+ ```
728
+
729
+ ##### Props
730
+ ```typescript
731
+ interface StatisticsProps {
732
+ children: ReactNode;
733
+ }
734
+ ```
735
+ | Prop | Type | Default | Description |
736
+ | - | - | - | - |
737
+ | `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) |
738
+
739
+ ##### Usage
740
+ ```javascript
741
+ const Extension = () => {
742
+ return (
743
+ <Statistics>
744
+ <StatisticsItem {...} />
745
+ <StatisticsTrend {...} />
746
+ </Statistics>
747
+ );
748
+ }
749
+ ```
750
+
751
+ #### StatisticsItem
752
+
753
+ ##### Import
754
+ ```javascript
755
+ import { StatisticsItem } from '@hubspot/ui-extensions';
756
+ ```
757
+
758
+ ##### Props
759
+ ```typescript
760
+ interface StatisticsItemProps {
761
+ id?: string;
762
+ label: string;
763
+ number: string;
764
+ children: ReactNode;
765
+ }
766
+ ```
767
+ | Prop | Type | Default | Description |
768
+ | - | - | - | - |
769
+ | `id` | `string(optional)` | `N/A`| The unique identifier |
770
+ | `label` | `string` | `N/A`| The text to be used as a label |
771
+ | `number` | `string` | `N/A`| Fully formatted string to be displayed as the item's primary number |
772
+ | `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) |
773
+
774
+ ##### Usage
775
+ ```javascript
776
+ const Extension = () => {
777
+ return (
778
+ <Statistics>
779
+ <StatisticsItem label="Sales" number={'30000'}>
780
+ <Text text="Big Numbers" />
781
+ </StatisticsItem>
782
+ </Statistics>
783
+ );
784
+ }
785
+ ```
786
+
787
+ #### StatisticsTrend
788
+
789
+ ##### Import
790
+ ```javascript
791
+ import { StatisticsTrend } from '@hubspot/ui-extensions';
792
+ ```
793
+
794
+ ##### Props
795
+ ```typescript
796
+ interface StatisticsTrendProps {
797
+ value: string;
798
+ direction: 'increase' | 'decrease';
799
+ }
800
+ ```
801
+ | Prop | Type | Default | Description |
802
+ | - | - | - | - |
803
+ | `value` | `string` | `N/A`| Formatted string to be displayed as trend value |
804
+ | `direction` | `'increase' \| 'decrease'` | `N/A`| Direction in which the trend arrow should be displayed |
805
+
806
+ ##### Usage
807
+ ```javascript
808
+ const Extension = () => {
809
+ return (
810
+ <Statistics>
811
+ <StatisticsItem label="Item A Sales" number="10000">
812
+ <StatisticsTrend direction="decrease" value="200%" />
813
+ </StatisticsItem>
814
+ <StatisticsItem label="Item B Sales" number="100000">
815
+ <StatisticsTrend direction="increase" value="100%" />
816
+ </StatisticsItem>
817
+ </Statistics>
818
+ );
819
+ }
820
+ ```
821
+
822
+
823
+ ### Table
824
+
825
+ ##### Import
826
+ ```javascript
827
+ import { Table } from '@hubspot/ui-extensions';
828
+ ```
829
+
830
+ ##### Props
831
+ ```typescript
832
+ interface TableProps {
833
+ children: ReactNode;
834
+ flush?: boolean;
835
+ bordered?: boolean;
836
+ }
837
+ ```
838
+ | Prop | Type | Default | Description |
839
+ | - | - | - | - |
840
+ | `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) |
841
+ | `flush` | `boolean(optional)` | `false`| If true the table will not have bottom margin. |
842
+ | `bordered` | `boolean(optional)` | `true`| If false the table will not haver borders around its content. |
843
+
844
+ ##### Usage
845
+ ```javascript
846
+ const Extension = () => {
847
+ return (
848
+ <Table bordered={true}>
849
+ <TableHead>
850
+ <TableRow>
851
+ <TableHeader>Name</TableHeader>
852
+ <TableHeader>Phone</TableHeader>
853
+ </TableRow>
854
+ </TableHead>
855
+ <TableBody>
856
+ <TableRow>
857
+ <TableCell>Roger Federer</TableCell>
858
+ <TableCell>555-555-7866</TableCell>
859
+ </TableRow>
860
+ </TableBody>
861
+ </Table>
862
+ );
863
+ }
864
+ ```
865
+ ### TableBody
866
+
867
+ ##### Import
868
+ ```javascript
869
+ import { TableBody } from '@hubspot/ui-extensions';
870
+ ```
871
+
872
+ ##### Props
873
+ ```typescript
874
+ interface TableBodyProps {
875
+ children: ReactNode;
876
+ }
877
+ ```
878
+ | Prop | Type | Default | Description |
879
+ | - | - | - | - |
880
+ | `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). |
881
+
882
+ ##### Usage
883
+ ```javascript
884
+ const Extension = () => {
885
+ return (
886
+ <Table bordered={true}>
887
+ <TableHead>
888
+ <TableRow>
889
+ <TableHeader>Name</TableHeader>
890
+ <TableHeader>Phone</TableHeader>
891
+ </TableRow>
892
+ </TableHead>
893
+ <TableBody>
894
+ <TableRow>
895
+ <TableCell>Roger Federer</TableCell>
896
+ <TableCell>555-555-7866</TableCell>
897
+ </TableRow>
898
+ </TableBody>
899
+ </Table>
900
+ );
901
+ }
902
+ ```
903
+ ### TableCell
904
+
905
+ ##### Import
906
+ ```javascript
907
+ import { TableCell } from '@hubspot/ui-extensions';
908
+ ```
909
+
910
+ ##### Props
911
+ ```typescript
912
+ interface TableCellProps {
913
+ children: ReactNode;
914
+ }
915
+ ```
916
+ | Prop | Type | Default | Description |
917
+ | - | - | - | - |
918
+ | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.|
919
+
920
+ ##### Usage
921
+ ```javascript
922
+ const Extension = () => {
923
+ return (
924
+ <Table bordered={true}>
925
+ <TableHead>
926
+ <TableRow>
927
+ <TableHeader>Name</TableHeader>
928
+ <TableHeader>Phone</TableHeader>
929
+ </TableRow>
930
+ </TableHead>
931
+ <TableBody>
932
+ <TableRow>
933
+ <TableCell>Roger Federer</TableCell>
934
+ <TableCell>555-555-7866</TableCell>
935
+ </TableRow>
936
+ </TableBody>
937
+ </Table>
938
+ );
939
+ }
940
+ ```
941
+ ### TableFooter
942
+
943
+ ##### Import
944
+ ```javascript
945
+ import { TableFooter } from '@hubspot/ui-extensions';
946
+ ```
947
+
948
+ ##### Props
949
+ ```typescript
950
+ interface TableFooterProps {
951
+ children: ReactNode;
952
+ }
953
+ ```
954
+ | Prop | Type | Default | Description |
955
+ | - | - | - | - |
956
+ | `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). |
957
+
958
+ ##### Usage
959
+ ```javascript
960
+ const Extension = () => {
961
+ return (
962
+ <Table>
963
+ <TableHead>
964
+ <TableRow>
965
+ <TableHeader>Series</TableHeader>
966
+ <TableHeader>Years on air</TableHeader>
967
+ <TableHeader>Emmys</TableHeader>
968
+ </TableRow>
969
+ </TableHead>
970
+ <TableFooter>
971
+ <TableRow>
972
+ <TableHeader>Totals</TableHeader>
973
+ <TableHeader>43</TableHeader>
974
+ <TableHeader>50</TableHeader>
975
+ </TableRow>
976
+ </TableFooter>
977
+ <TableBody>
978
+ <TableRow>
979
+ <TableCell>The Simpsons</TableCell>
980
+ <TableCell>28</TableCell>
981
+ <TableCell>31</TableCell>
982
+ </TableRow>
983
+ <TableRow>
984
+ <TableCell>M*A*S*H</TableCell>
985
+ <TableCell>11</TableCell>
986
+ <TableCell>14</TableCell>
987
+ </TableRow>
988
+ <TableRow>
989
+ <TableCell>Arrested Development</TableCell>
990
+ <TableCell>4</TableCell>
991
+ <TableCell>5</TableCell>
992
+ </TableRow>
993
+ </TableBody>
994
+ </Table>
995
+ );
996
+ }
997
+ ```
998
+
999
+ ### TableHead
1000
+
1001
+ ##### Import
1002
+ ```javascript
1003
+ import { TableHead } from '@hubspot/ui-extensions';
1004
+ ```
1005
+
1006
+ ##### Props
1007
+ ```typescript
1008
+ interface TableHeadProps {
1009
+ children: ReactNode;
1010
+ }
1011
+ ```
1012
+ | Prop | Type | Default | Description |
1013
+ | - | - | - | - |
1014
+ | `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). |
1015
+
1016
+ ##### Usage
1017
+ ```javascript
1018
+ const Extension = () => {
1019
+ return (
1020
+ <Table bordered={true}>
1021
+ <TableHead>
1022
+ <TableRow>
1023
+ <TableHeader>Name</TableHeader>
1024
+ <TableHeader>Phone</TableHeader>
1025
+ </TableRow>
1026
+ </TableHead>
1027
+ <TableBody>
1028
+ <TableRow>
1029
+ <TableCell>Roger Federer</TableCell>
1030
+ <TableCell>555-555-7866</TableCell>
1031
+ </TableRow>
1032
+ </TableBody>
1033
+ </Table>
1034
+ );
1035
+ }
1036
+ ```
1037
+ ### TableHeader
1038
+
1039
+ ##### Import
1040
+ ```javascript
1041
+ import { TableHeader } from '@hubspot/ui-extensions';
1042
+ ```
1043
+
1044
+ ##### Props
1045
+ ```typescript
1046
+ interface TableHeaderProps {
1047
+ children: ReactNode;
1048
+ }
1049
+ ```
1050
+ | Prop | Type | Default | Description |
1051
+ | - | - | - | - |
1052
+ | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.|
1053
+
1054
+ ##### Usage
1055
+ ```javascript
1056
+ const Extension = () => {
1057
+ return (
1058
+ <Table bordered={true}>
1059
+ <TableHead>
1060
+ <TableRow>
1061
+ <TableHeader>Name</TableHeader>
1062
+ <TableHeader>Phone</TableHeader>
1063
+ </TableRow>
1064
+ </TableHead>
1065
+ <TableBody>
1066
+ <TableRow>
1067
+ <TableCell>Roger Federer</TableCell>
1068
+ <TableCell>555-555-7866</TableCell>
1069
+ </TableRow>
1070
+ </TableBody>
1071
+ </Table>
1072
+ );
1073
+ }
1074
+ ```
1075
+ ### TableRow
1076
+
1077
+ ##### Import
1078
+ ```javascript
1079
+ import { TableRow } from '@hubspot/ui-extensions';
1080
+ ```
1081
+
1082
+ ##### Props
1083
+ ```typescript
1084
+ interface TableRowProps {
1085
+ children: ReactNode;
1086
+ }
1087
+ ```
1088
+ | Prop | Type | Default | Description |
1089
+ | - | - | - | - |
1090
+ | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.|
1091
+
1092
+ ##### Usage
1093
+ ```javascript
1094
+ const Extension = () => {
1095
+ return (
1096
+ <Table bordered={true}>
1097
+ <TableHead>
1098
+ <TableRow>
1099
+ <TableHeader>Name</TableHeader>
1100
+ <TableHeader>Phone</TableHeader>
1101
+ </TableRow>
1102
+ </TableHead>
1103
+ <TableBody>
1104
+ <TableRow>
1105
+ <TableCell>Roger Federer</TableCell>
1106
+ <TableCell>555-555-7866</TableCell>
1107
+ </TableRow>
1108
+ </TableBody>
1109
+ </Table>
1110
+ );
1111
+ }
1112
+ ```
1113
+
1114
+ ### Tag
1115
+
1116
+ ##### Import
1117
+ ```javascript
1118
+ import { Tag } from '@hubspot/ui-extensions';
1119
+ ```
1120
+
1121
+ ##### Props
1122
+ ```typescript
1123
+ interface TagProps {
1124
+ text: string;
1125
+ onClick?: () => void;
1126
+ variant?: 'default' | 'warning' | 'success' | 'error';
1127
+ }
1128
+ ```
1129
+ | Prop | Type | Default | Description |
1130
+ | - | - | - | - |
1131
+ | `text` | `string` | `N/A`| Text to be displayed in the tag. |
1132
+ | `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. |
1133
+ | `variant` | `'default' \| 'warning' \| 'success' \| 'error'` `(optional)` | `'default'`| The color variation of the tag to display |
1134
+
1135
+ ##### Usage
1136
+ ```javascript
1137
+ const Extension = () => {
1138
+ return (
1139
+ <Tag
1140
+ text="Success"
1141
+ variant='success'
1142
+ onClick={() => {
1143
+ console.log('Tag clicked!');
1144
+ }}
1145
+ />
1146
+ );
1147
+ }
1148
+ ```
1149
+
1150
+ ### Text
1151
+
1152
+ ##### Import
1153
+ ```javascript
1154
+ import { Text } from '@hubspot/ui-extensions';
1155
+ ```
1156
+
1157
+ ##### Props
1158
+ ```typescript
1159
+ interface TextProps {
1160
+ format?: 'plaintext' | 'markdown';
1161
+ text: string;
1162
+ variant?: 'bodytext' | 'microcopy';
1163
+ }
1164
+ ```
1165
+ | Prop | Type | Default | Description |
1166
+ | - | - | - | - |
1167
+ | `format` | `'plaintext' \| 'markdown'` `(optional)`| `'plaintext'`| Type of formatting for the display text. |
1168
+ | `text` | `string` | `N/A`| Text to be displayed as body text. If format is `"markdown"`, inline markdown elements (i.e. bold, italics, code, links) are supported |
1169
+ | `variant` | `'bodytext' \| 'microcopy'` | `'bodytext`| Type of text to display |
1170
+
1171
+ #### Markdown
1172
+ Markdown syntax supported in the component:
1173
+
1174
+ - bold text: `**like this**` or `__like this__`
1175
+ - italicized text: `*like this*` or `_like this_`
1176
+ - inline code: `` `like this` ``
1177
+ - links: `[visible anchor text](https://www.hubspot.com/)`
1178
+
1179
+ ##### Usage
1180
+ ```javascript
1181
+ const Extension = () => {
1182
+ return (
1183
+ <>
1184
+ <Text text="**Bold**" format="markdown"/>
1185
+ <Text text="*Italics*" format="markdown"/>
1186
+ <Text text="**Not Bold because format isn't markdown**"/>
1187
+ <Text text="This is going to be small" variant="microcopy"/>
1188
+ </>
1189
+ );
1190
+ }
1191
+ ```
1192
+
1193
+ ### Tile
1194
+
1195
+ ##### Import
1196
+ ```javascript
1197
+ import { Tile } from '@hubspot/ui-extensions';
1198
+ ```
1199
+
1200
+ ##### Props
1201
+ ```typescript
1202
+ interface TileProps {
1203
+ children: ReactNode;
1204
+ flush?: boolean;
1205
+ }
1206
+ ```
1207
+ | Prop | Type | Default | Description |
1208
+ | - | - | - | - |
1209
+ | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
1210
+ | `flush` | `boolean(optional)` | `false`| If true the content of the Tile will have no left or right padding. |
1211
+
1212
+ ##### Usage
1213
+ ```javascript
1214
+ const Extension = () => {
1215
+ return (
1216
+ <>
1217
+ <Tile flush={true}>
1218
+ <Text text="No left padding" />
1219
+ </Tile>
1220
+ <Tile>
1221
+ <Text text="Small amount of left padding" />
1222
+ </Tile>
1223
+ </>
1224
+ );
1225
+ }
1226
+
1227
+
1228
+ ```