@hubspot/ui-extensions 0.0.1-prealpha.6 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # ui-extensions-components
1
+ # UI Extensions
2
+
3
+ React components and utilities for extending HubSpot's UI.
2
4
 
3
5
  ## TOC
4
6
 
@@ -7,29 +9,35 @@
7
9
  - [ButtonRow](#buttonrow)
8
10
  - [Card](#card)
9
11
  - [DescriptionList](#descriptionlist)
10
- - [DescriptionListItem](#descriptionlistitem)
12
+ - [DescriptionListItem](#descriptionlistitem)
11
13
  - [Divider](#divider)
12
14
  - [Form](#form)
15
+ - [EmptyState](#emptystate)
16
+ - [ErrorState](#errorstate)
13
17
  - [Heading](#heading)
14
18
  - [Image](#image)
15
19
  - [Input](#input)
20
+ - [Link](#link)
16
21
  - [LoadingSpinner](#loadingspinner)
22
+ - [NumberInput](#numberInput)
17
23
  - [ProgressBar](#progressbar)
18
24
  - [Select](#select)
19
25
  - [Stack](#stack)
20
26
  - [Statistics](#statistics)
21
- - [StatisticsItem](#statisticsitem)
22
- - [StatisticsTrend](#statisticstrend)
27
+ - [StatisticsItem](#statisticsitem)
28
+ - [StatisticsTrend](#statisticstrend)
23
29
  - [Table](#table)
24
- - [TableBody](#tablebody)
25
- - [TableCell](#tablecell)
26
- - [TableFooter](#tablefooter)
27
- - [TableHead](#tablehead)
28
- - [TableHeader](#tableheader)
29
- - [TableRow](#tablerow)
30
+ - [TableBody](#tablebody)
31
+ - [TableCell](#tablecell)
32
+ - [TableFooter](#tablefooter)
33
+ - [TableHead](#tablehead)
34
+ - [TableHeader](#tableheader)
35
+ - [TableRow](#tablerow)
30
36
  - [Tag](#tag)
31
37
  - [Text](#text)
38
+ - [Textarea](#textarea)
32
39
  - [Tile](#tile)
40
+ - [ToggleGroup](#togglegroup)
33
41
 
34
42
  ## Components
35
43
 
@@ -48,7 +56,6 @@ The Alert component accepts the following props:
48
56
  ```typescript
49
57
  export interface AlertProps {
50
58
  title: string;
51
- body?: string;
52
59
  children?: ReactNode;
53
60
  variant?: 'info' | 'warning' | 'success' | 'error' | 'danger';
54
61
  }
@@ -57,7 +64,6 @@ export interface AlertProps {
57
64
  | Prop | Type | Default | Description |
58
65
  | --- | --- | --- | --- |
59
66
  | `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
67
  | `children` | `ReactNode(optional)` | `N/A` | The main content of the alert message when the body prop is not provided. |
62
68
  | `variant` | `'info' \| 'warning' \| 'success' \|'error' \| 'danger'` `(optional)` | `'info'` | Sets the color variation of the alert |
63
69
 
@@ -70,22 +76,18 @@ const Extension = () => {
70
76
  <Alert title="Important Info" variant="info">
71
77
  This is an informative message.
72
78
  </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
- />
79
+ <Alert title="Success"variant="success">
80
+ Operation completed successfully.
81
+ </Alert>
82
+ <Alert title="Warning" variant="warning" >
83
+ Proceed with caution.
84
+ </Alert>
85
+ <Alert title="Error" variant="error" >
86
+ Something went wrong. Please try again.
87
+ </Alert>
88
+ <Alert title="Danger" variant="danger" >
89
+ This action cannot be undone. Be careful.
90
+ </Alert>
89
91
  </>
90
92
  );
91
93
  };
@@ -94,14 +96,16 @@ const Extension = () => {
94
96
  ### Button
95
97
 
96
98
  ##### Import
99
+
97
100
  ```javascript
98
101
  import { Button } from '@hubspot/ui-extensions';
99
102
  ```
100
103
 
101
104
  ##### Props
105
+
102
106
  ```typescript
103
107
  interface ButtonProps {
104
- text: string;
108
+ children: string;
105
109
  onClick?: () => void;
106
110
  href?: string;
107
111
  disabled?: boolean;
@@ -109,194 +113,219 @@ interface ButtonProps {
109
113
  type?: 'button' | 'reset' | 'submit';
110
114
  }
111
115
  ```
116
+
112
117
  | 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 |
118
+ | --- | --- | --- | --- |
119
+ | `children` | `string` | `N/A` | The displayable text for the Button |
120
+ | `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 |
121
+ | `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. |
122
+ | `disabled` | `boolean(optional)` | `N/A` | Determines if the button should be disabled or not. |
123
+ | `variant` | `'primary' \| 'secondary' \| 'destructive'` `(optional)` | `'secondary'` | Sets the color variation of the button |
124
+ | `type` | `'button' \| 'reset' \| 'submit'` `(optional)` | `'button'` | Sets the HTML attribute "role" of the button |
120
125
 
121
126
  ##### Usage
127
+
122
128
  ```javascript
123
129
  const Extension = () => {
124
130
  return (
125
131
  <Button
126
- text="Click me!"
127
132
  onClick={() => {
128
133
  console.log('Someone clicked on the button!');
129
134
  }}
130
135
  href="https://hubspot.com"
131
136
  variant="destructive"
132
137
  type="button"
133
- />
138
+ >
139
+ Click me!
140
+ </Button>
134
141
  );
135
- }
142
+ };
136
143
  ```
137
144
 
138
145
  ### ButtonRow
139
146
 
140
147
  ##### Import
148
+
141
149
  ```javascript
142
150
  import { ButtonRow } from '@hubspot/ui-extensions';
143
151
  ```
144
152
 
145
153
  ##### Props
154
+
146
155
  ```typescript
147
156
  interface ButtonRowProps {
148
157
  children: ReactNode;
149
158
  disableDropdown?: boolean;
150
159
  }
151
160
  ```
161
+
152
162
  | 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. |
163
+ | --- | --- | --- | --- |
164
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
155
165
  | `disableDropdown` | `boolean(optional)` | `false` | Disables the dropdown list of buttons that appears the the children expand beyond the horizontal space |
156
166
 
157
167
  ##### Usage
168
+
158
169
  ```javascript
159
170
  const Extension = () => {
160
171
  return (
161
172
  <ButtonRow disableDropdown={false}>
162
173
  <Button
163
- text="Regular Button"
164
174
  onClick={() => {
165
175
  console.log('Regular button clicked');
166
176
  }}
167
- />
177
+ >
178
+ Regular Button
179
+ </Button>
168
180
  <Button
169
- text="Reset"
170
181
  onClick={() => {
171
182
  console.log('Reset button clicked');
172
183
  }}
173
184
  variant="destructive"
174
185
  type="reset"
175
- />
186
+ >
187
+ Reset
188
+ </Button>
176
189
  <Button
177
- text="Submit"
178
190
  onClick={() => {
179
191
  console.log('Submit button clicked');
180
192
  }}
181
193
  variant="primary"
182
194
  type="submit"
183
- />
195
+ >
196
+ Submit
197
+ </Button>
184
198
  </ButtonRow>
185
199
  );
186
- }
200
+ };
187
201
  ```
188
202
 
189
203
  ### Card
190
204
 
191
205
  ##### Import
206
+
192
207
  ```javascript
193
208
  import { Card } from '@hubspot/ui-extensions';
194
209
  ```
195
210
 
196
211
  ##### Props
212
+
197
213
  ```typescript
198
214
  interface CardProps {
199
215
  children: ReactNode;
200
216
  }
201
217
  ```
218
+
202
219
  | 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. |
220
+ | --- | --- | --- | --- |
221
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
205
222
 
206
223
  ##### Usage
224
+
207
225
  ```javascript
208
226
  const Extension = () => {
209
227
  return (
210
228
  <Card>
211
229
  <Button
212
- text="Regular Button"
213
230
  onClick={() => {
214
231
  console.log('Regular button clicked');
215
232
  }}
216
- />
233
+ >
234
+ Regular Button
235
+ </Button>
217
236
  </Card>
218
237
  );
219
- }
238
+ };
220
239
  ```
221
240
 
222
241
  ### DescriptionList
223
242
 
224
243
  ##### Import
244
+
225
245
  ```javascript
226
246
  import { DescriptionList } from '@hubspot/ui-extensions';
227
247
  ```
228
248
 
229
249
  ##### Props
250
+
230
251
  ```typescript
231
252
  interface DescriptionListProps {
232
253
  children: ReactNode;
233
254
  direction?: 'row' | 'column';
234
255
  }
235
256
  ```
257
+
236
258
  | 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. |
259
+ | --- | --- | --- | --- |
260
+ | `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) |
261
+ | `direction` | `'row' \| 'column'` `(optional)` | `'column'` | The direction the label/value pairs are placed in the description list container. |
240
262
 
241
263
  ##### Usage
264
+
242
265
  ```javascript
243
266
  const Extension = () => {
244
267
  return (
245
268
  <DescriptionList direction="row">
246
- <DescriptionListItem label={"First Name"}>
247
- <Text text="Alan" />
269
+ <DescriptionListItem label={'First Name'}>
270
+ <Text>Alan</Text>
248
271
  </DescriptionListItem>
249
- <DescriptionListItem label={"Last Name"}>
250
- <Text text="Turing" />
272
+ <DescriptionListItem label={'Last Name'}>
273
+ <Text>Turing</Text>
251
274
  </DescriptionListItem>
252
275
  </DescriptionList>
253
276
  );
254
- }
277
+ };
255
278
  ```
256
279
 
257
280
  #### DescriptionListItem
258
281
 
259
282
  ##### Import
283
+
260
284
  ```javascript
261
285
  import { DescriptionListItem } from '@hubspot/ui-extensions';
262
286
  ```
263
287
 
264
288
  ##### Props
289
+
265
290
  ```typescript
266
291
  interface DescriptionListItemProps {
267
292
  children: ReactNode;
268
293
  label: string;
269
294
  }
270
295
  ```
296
+
271
297
  | 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 |
298
+ | --- | --- | --- | --- |
299
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
300
+ | `label` | `string` | `N/A` | Text to be displayed as the label |
275
301
 
276
302
  ##### Usage
303
+
277
304
  ```javascript
278
305
  const Extension = () => {
279
306
  return (
280
307
  <DescriptionList direction="row">
281
- <DescriptionListItem label={"First Name"}>
282
- <Text text="Alan" />
308
+ <DescriptionListItem label={'First Name'}>
309
+ <Text>Alan</Text>
283
310
  </DescriptionListItem>
284
- <DescriptionListItem label={"Last Name"}>
285
- <Text text="Turing" />
311
+ <DescriptionListItem label={'Last Name'}>
312
+ <Text>Turing</Text>
286
313
  </DescriptionListItem>
287
314
  </DescriptionList>
288
315
  );
289
- }
316
+ };
290
317
  ```
291
318
 
292
319
  ### Divider
293
320
 
294
321
  ##### Import
322
+
295
323
  ```javascript
296
324
  import { Divider } from '@hubspot/ui-extensions';
297
325
  ```
298
326
 
299
327
  ##### Props
328
+
300
329
  ```typescript
301
330
  interface DividerProps {
302
331
  distance?:
@@ -308,27 +337,29 @@ interface DividerProps {
308
337
  | 'extra-large';
309
338
  }
310
339
  ```
340
+
311
341
  | 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. |
342
+ | --- | --- | --- | --- |
343
+ | `distance` | `'flush'\| 'extra-small' \| 'small' \| 'medium' \| 'large'\| 'extra-large'` `(optional)` | `'small'` | The size of the padding above and below the divider. |
314
344
 
315
345
  ##### Usage
346
+
316
347
  ```javascript
317
348
  const Extension = () => {
318
- return (
319
- <Divider distance="extra-large"/>
320
- );
321
- }
349
+ return <Divider distance="extra-large" />;
350
+ };
322
351
  ```
323
352
 
324
353
  ### Form
325
354
 
326
355
  ##### Import
356
+
327
357
  ```javascript
328
358
  import { Form } from '@hubspot/ui-extensions';
329
359
  ```
330
360
 
331
361
  ##### Props
362
+
332
363
  ```typescript
333
364
  interface FormProps {
334
365
  children: ReactNode;
@@ -336,13 +367,15 @@ interface FormProps {
336
367
  preventDefault?: boolean;
337
368
  }
338
369
  ```
370
+
339
371
  | 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 a `RemoteEvent` as argument 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. |
372
+ | --- | --- | --- | --- |
373
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
374
+ | `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. |
375
+ | `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
376
 
345
377
  ##### Usage
378
+
346
379
  ```javascript
347
380
  const Extension = () => {
348
381
  return (
@@ -350,13 +383,14 @@ const Extension = () => {
350
383
  <Input {...} />
351
384
  <Select {...} />
352
385
  <Button
353
- text="Submit"
354
386
  onClick={() => {
355
387
  console.log('Submit button clicked');
356
388
  }}
357
389
  variant="primary"
358
390
  type="submit"
359
- />
391
+ >
392
+ Submit
393
+ </Button>
360
394
  </Form>
361
395
  );
362
396
  }
@@ -365,11 +399,13 @@ const Extension = () => {
365
399
  ### EmptyState
366
400
 
367
401
  ##### Import
402
+
368
403
  ```javascript
369
404
  import { EmptyState } from '@hubspot/ui-extensions';
370
405
  ```
371
406
 
372
407
  ##### Props
408
+
373
409
  ```typescript
374
410
  interface EmptyStateProps {
375
411
  children: ReactNode;
@@ -380,22 +416,24 @@ interface EmptyStateProps {
380
416
  title?: string;
381
417
  }
382
418
  ```
419
+
383
420
  | Prop | Type | Default | Description |
384
- | - | - | - | - |
385
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
421
+ | --- | --- | --- | --- |
422
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
386
423
  | `flush` | `boolean(optional)` | `false` | Removes the default vertical margins for the component. |
387
- | `imageWidth` | `number(optional)` | `250`| The max-width for the image container. |
388
- | `layout` | `'horizontal' | 'vertical'` `(optional)` | `'horizontal'` | Sets the layout direction for the content. |
424
+ | `imageWidth` | `number(optional)` | `250` | The max-width for the image container. |
425
+ | `layout` | `'horizontal' \| 'vertical'` `(optional)` | `'horizontal'` | Sets the layout direction for the content. |
389
426
  | `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. |
390
- | `title` | `string(optional)` | `Intl("All is not lost.")` | The text for the title header rendered above the `children`. |
427
+ | `title` | `string(optional)` | `Intl('All is not lost.')` | The text for the title header rendered above the `children`. |
391
428
 
392
429
  ##### Usage
430
+
393
431
  ```javascript
394
432
  const Extension = ({ data }) => {
395
433
  if (!data || !data.length) {
396
434
  return (
397
435
  <EmptyState title="Nothing here yet" layout="vertical" reverseOrder={true}>
398
- <Text text="Go out there and get some leads!" />
436
+ <Text>Go out there and get some leads!</Text>
399
437
  </EmptyState>
400
438
  )
401
439
  }
@@ -411,11 +449,13 @@ const Extension = ({ data }) => {
411
449
  ### ErrorState
412
450
 
413
451
  ##### Import
452
+
414
453
  ```javascript
415
454
  import { ErrorState } from '@hubspot/ui-extensions';
416
455
  ```
417
456
 
418
457
  ##### Props
458
+
419
459
  ```typescript
420
460
  interface ErrorStateProps {
421
461
  children: ReactNode;
@@ -423,21 +463,27 @@ interface ErrorStateProps {
423
463
  type?: 'error' | 'support' | 'lock';
424
464
  }
425
465
  ```
466
+
426
467
  | Prop | Type | Default | Description |
427
- | - | - | - | - |
428
- | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
429
- | `title` | `string(optional)` | `Intl("All is not lost.")` | The text for the title header rendered above the `children`. |
430
- | `type` | `'error' | 'support' | 'lock'` `(optional)` | `'error'` | Sets the type of error image that will be shown. |
468
+ | --- | --- | --- | --- |
469
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
470
+ | `title` | `string(optional)` | `Intl('All is not lost.')` | The text for the title header rendered above the `children`. |
471
+ | `type` | `'error' \| 'support' \| 'lock'` `(optional)` | `'error'` | Sets the type of error image that will be shown. |
431
472
 
432
473
  ##### Usage
474
+
433
475
  ```javascript
434
476
  const Extension = ({ data, error, fetchData }) => {
435
477
  if (error) {
436
478
  return (
437
479
  <ErrorState title="Trouble fetching properties." layout="vertical" reverseOrder={true}>
438
480
  <Stack>
439
- <Text text="Please try again in a few moments." />
440
- <Button text="Try again" onClick={fetchData} />
481
+ <Text>
482
+ Please try again in a few moments.
483
+ </Text>
484
+ <Button onClick={fetchData}>
485
+ Try again
486
+ </Button>
441
487
  </Stack>
442
488
  </ErrorState>
443
489
  )
@@ -454,78 +500,65 @@ const Extension = ({ data, error, fetchData }) => {
454
500
  ### Heading
455
501
 
456
502
  ##### Import
503
+
457
504
  ```javascript
458
505
  import { Heading } from '@hubspot/ui-extensions';
459
506
  ```
460
507
 
461
508
  ##### Props
509
+
462
510
  ```typescript
463
511
  interface HeadingProps {
464
- text: string;
465
- format?: 'plaintext' | 'markdown';
512
+ children: ReactNode;
513
+ inline?: boolean;
466
514
  }
467
515
  ```
468
- | Prop | Type | Default | Description |
469
- | - | - | - | - |
470
- | `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|
471
- | `format` | `'plaintext' \| 'markdown'` `(optional)` | `'plaintext'`| Type of formatting for the display text. |
472
516
 
473
- #### Markdown
474
- Markdown syntax supported in the component:
475
-
476
- - bold text: `**like this**` or `__like this__`
477
- - italicized text: `*like this*` or `_like this_`
478
- - inline code: `` `like this` ``
479
- - links: `[visible anchor text](https://www.hubspot.com/)`
517
+ | Prop | Type | Default | Description |
518
+ | --- | --- | --- | --- |
519
+ | `children` | `string` | `N/A` | Text to be displayed as heading text. |
520
+ | `inline` | `boolean(optional)` | `false` | Determines if the text will break line or share the space. |
480
521
 
481
522
  ##### Usage
523
+
482
524
  ```javascript
483
525
  const Extension = () => {
484
- return (
485
- <>
486
- <Heading text="Plain text, nothing special here"/>
487
- <Heading text="**It's a Bold Strategy Cotton, lets see if it pays off for them.**" format="markdown"/>
488
- </>
489
- );
490
- }
526
+ return <Heading>Plain text, nothing special here</Heading>;
527
+ };
491
528
  ```
492
529
 
493
530
  ### Image
494
- ##### Import
495
531
 
532
+ ##### Import
496
533
 
497
534
  ```javascript
498
535
  import { Image } from '@hubspot/ui-extensions';
499
536
  ```
500
537
 
501
538
  ##### Props
539
+
502
540
  ```typescript
503
- interface ImageProps {
541
+ interface ImageProps {
504
542
  alt?: string;
505
543
  href?: string;
506
544
  onClick?: () => void;
507
545
  src: string;
508
546
  width?: number;
547
+ height?: number;
509
548
  }
510
549
  ```
511
550
 
512
- | Prop | Type | Description |
513
- | - | - | - |
514
- | `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) |
515
- | `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 |
516
- | `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. |
517
- | `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)|
518
- | `width` | `number(optional)` | The pixel width of the image |
519
-
520
- | Prop | Type | Description |
521
- | - | - | - |
551
+ | Prop | Type | Description |
552
+ | --- | --- | --- |
522
553
  | `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) |
523
554
  | `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 |
524
555
  | `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. |
525
- | `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)|
556
+ | `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) |
526
557
  | `width` | `number(optional)` | The pixel width of the image |
558
+ | `height` | `number(optional)` | The pixel height of the image |
527
559
 
528
560
  ##### Usage
561
+
529
562
  ```javascript
530
563
  const Extension = () => {
531
564
  return (
@@ -534,29 +567,31 @@ const Extension = () => {
534
567
  src="https://picsum.photos/id/237/200/300"
535
568
  href="https://picsum.photos/id/237"
536
569
  onClick={() => {
537
- console.log('Someone clicked on the image!')
570
+ console.log('Someone clicked on the image!');
538
571
  }}
539
572
  width={200}
540
573
  />
541
574
  );
542
- }
575
+ };
543
576
  ```
544
577
 
545
578
  ### Input
546
579
 
547
580
  ##### Import
581
+
548
582
  ```javascript
549
583
  import { Input } from '@hubspot/ui-extensions';
550
584
  ```
551
585
 
552
586
  ##### Props
587
+
553
588
  ```typescript
554
589
  interface InputProps {
555
590
  label: string;
556
591
  name: string;
557
592
  value?: string;
558
593
  required?: boolean;
559
- readonly?: boolean;
594
+ readOnly?: boolean;
560
595
  description?: string;
561
596
  tooltip?: string;
562
597
  placeholder?: string;
@@ -568,31 +603,33 @@ interface InputProps {
568
603
  onFocus?: (value: string) => void;
569
604
  }
570
605
  ```
606
+
571
607
  | Prop | Type | Default | Description |
572
- | - | - | - | - |
573
- | `label` | `string` | `N/A`| The label text to display for the form input element |
574
- | `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) |
575
- | `value` | `string(optional)` | `''`| The value of the input |
576
- | `required` | `boolean(optional)` | `false`| Determines if the required indicator should be displayed |
577
- | `readonly` | `boolean(optional)` | `false`| Determines if the field is editable or not. |
578
- | `description` | `string(optional)` | `N/A`| Instructional message to display to the user to help understand the purpose of the input. |
579
- | `tooltip` | `string(optional)` | `N/A`| Text that will appear in a tooltip next to the input label. |
580
- | `placeholder` | `string(optional)` | `N/A`| Text that appears in the input when it has no value set. |
581
- | `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. |
582
- | `validationMessage` | `string(optional)` | `''`| The text to show if the input has an error. |
583
- | `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. |
584
- | `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. |
585
- | `onBlur` | `(value: string) => void(optional)` | `N/A`| A function that is called and passed the value every time the field loses focus. |
586
- | `onFocus` | `(value: string) => void(optional)` | `N/A`| A function that is called and passed the value every time the field gets focused. |
608
+ | --- | --- | --- | --- |
609
+ | `label` | `string` | `N/A` | The label text to display for the form input element |
610
+ | `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) |
611
+ | `value` | `string(optional)` | `''` | The value of the input |
612
+ | `required` | `boolean(optional)` | `false` | Determines if the required indicator should be displayed |
613
+ | `readOnly` | `boolean(optional)` | `false` | Determines if the field is editable or not. |
614
+ | `description` | `string(optional)` | `N/A` | Instructional message to display to the user to help understand the purpose of the input. |
615
+ | `tooltip` | `string(optional)` | `N/A` | Text that will appear in a tooltip next to the input label. |
616
+ | `placeholder` | `string(optional)` | `N/A` | Text that appears in the input when it has no value set. |
617
+ | `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. |
618
+ | `validationMessage` | `string(optional)` | `''` | The text to show if the input has an error. |
619
+ | `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. |
620
+ | `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. |
621
+ | `onBlur` | `(value: string) => void(optional)` | `N/A` | A function that is called and passed the value every time the field loses focus. |
622
+ | `onFocus` | `(value: string) => void(optional)` | `N/A` | A function that is called and passed the value every time the field gets focused. |
587
623
 
588
624
  ##### Usage
625
+
589
626
  ```javascript
590
627
  import { useState } from 'react';
591
628
 
592
629
  const Extension = () => {
593
- const [ name, setName ] = useState('');
594
- const [ validationMessage, setValidationMessage ] = useState('');
595
- const [ isValid, setIsValid ] = useState(true);
630
+ const [name, setName] = useState('');
631
+ const [validationMessage, setValidationMessage] = useState('');
632
+ const [isValid, setIsValid] = useState(true);
596
633
 
597
634
  return (
598
635
  <Form>
@@ -605,68 +642,180 @@ const Extension = () => {
605
642
  required={true}
606
643
  error={!isValid}
607
644
  validationMessage={validationMessage}
608
- onChange={(value) => {
609
- setName(value)
645
+ onChange={value => {
646
+ setName(value);
610
647
  }}
611
- onInput={(value) => {
612
- if(value !== 'Bill') {
648
+ onInput={value => {
649
+ if (value !== 'Bill') {
613
650
  setValidationMessage('This form only works for people named Bill');
614
651
  setIsValid(false);
615
652
  } else if (value === '') {
616
- setValidationMessage('First name is required')
653
+ setValidationMessage('First name is required');
617
654
  setIsValid(false);
618
655
  } else {
619
- setValidationMessage('Valid first name!')
656
+ setValidationMessage('Valid first name!');
620
657
  setIsValid(true);
621
658
  }
622
659
  }}
623
660
  />
624
661
  </Form>
625
662
  );
663
+ };
664
+ ```
665
+
666
+ ### Link
667
+
668
+ ##### Import
669
+
670
+ ```javascript
671
+ import { Link } from '@hubspot/ui-extensions';
672
+ ```
673
+
674
+ ##### Props
675
+
676
+ ```typescript
677
+ export interface LinkProps {
678
+ href: string;
679
+ variant?: 'primary' | 'destructive' | 'light' | 'dark';
680
+ children: ReactNode;
681
+ onClick?: () => void;
626
682
  }
627
683
  ```
628
684
 
685
+ | Prop | Type | Default | Description |
686
+ | --- | --- | --- | --- |
687
+ | `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. |
688
+ | `variant` | `'primary' \| 'light' \| 'dark' \| 'destructive'` `(optional)` | `'primary'` | Sets the color variation of the link |
689
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. |
690
+ | `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 |
691
+
692
+ ##### Usage
693
+
694
+ ```javascript
695
+ const Extension = () => {
696
+ return <Link href="https://app.hubspot.com/">HubSpot</Link>;
697
+ };
698
+ ```
699
+
629
700
  ### LoadingSpinner
630
701
 
631
702
  ##### Import
703
+
632
704
  ```javascript
633
705
  import { LoadingSpinner } from '@hubspot/ui-extensions';
634
706
  ```
635
707
 
636
708
  ##### Props
709
+
637
710
  ```typescript
638
711
  export interface LoadingSpinnerProps {
639
712
  label: string;
640
713
  showLabel?: boolean;
641
- size?: 'xs' | 'sm' | 'md';
714
+ size?: 'xs' | 'extra-small' | 'sm' | 'small' | 'md' | 'medium';
642
715
  layout?: 'inline' | 'centered';
643
- grow?: boolean;
644
716
  }
645
717
  ```
718
+
646
719
  | Prop | Type | Default | Description |
647
720
  | --- | --- | --- | --- |
648
- | `label` | `string` | `N/A`| The companion text for the loading spinner. |
721
+ | `label` | `string` | `N/A` | The companion text for the loading spinner. |
649
722
  | `showLabel` | `boolean(optional)` | `false` | if `true`, the label will be visible alongside the loading spinner. |
650
- | `size` | `'xs'\| 'sm' \| 'md'` `(optional)`| `'sm'` | The size of the loading spinner icon. |
651
- | `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. |
652
- | `grow` | `boolean(optional)` | `false` | if `true`, sets the height and width of the loading spinner to 100%.|
723
+ | `size` | `'xs' \| 'sm' \| 'md' \| 'extra-small' \| 'small' \| 'medium'` `(optional)` | `'sm'` | The size of the loading spinner icon. |
724
+ | `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. |
653
725
 
654
726
  ##### Usage
727
+
655
728
  ```javascript
656
729
  const Extension = () => {
657
730
  return <LoadingSpinner label="Loading..." />;
731
+ };
732
+ ```
733
+ ### NumberInput
734
+
735
+ ##### Import
736
+
737
+ ```javascript
738
+ import { NumberInput } from '@hubspot/ui-extensions';
739
+ ```
740
+
741
+ ##### Props
742
+
743
+ ```typescript
744
+ export interface NumberInputProps {
745
+ label: string;
746
+ name: string;
747
+ value?: number;
748
+ required?: boolean;
749
+ readOnly?: boolean;
750
+ description?: string;
751
+ tooltip?: string;
752
+ placeholder?: string;
753
+ error?: boolean;
754
+ defaultValue?: number;
755
+ validationMessage?: string;
756
+ onChange?: (value: number) => void;
757
+ onInput?: (value: number) => void;
758
+ onBlur?: (value: number) => void;
759
+ onFocus?: (value: number) => void;
760
+ min?: number;
761
+ max?: number;
762
+ precision?: number;
763
+ formatStyle?: 'decimal' | 'percentage';
658
764
  }
659
765
  ```
766
+
767
+ | Prop | Type | Default | Description |
768
+ | --- | --- | --- | --- |
769
+ | `label` | `string` | `N/A` | The label text to display for the form input element |
770
+ | `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) |
771
+ | `value` | `number(optional)` | `''` | The value of the input |
772
+ | `required` | `boolean(optional)` | `false` | Determines if the required indicator should be displayed |
773
+ | `readOnly` | `boolean(optional)` | `false` | Determines if the field is editable or not. |
774
+ | `description` | `string(optional)` | `N/A` | Instructional message to display to the user to help understand the purpose of the input. |
775
+ | `tooltip` | `string(optional)` | `N/A` | Text that will appear in a tooltip next to the input label. |
776
+ | `placeholder` | `string(optional)` | `N/A` | Text that appears in the input when it has no value set. |
777
+ | `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. |
778
+ | `validationMessage` | `string(optional)` | `''` | The text to show if the input has an error. |
779
+ | `onChange` | `(value: number) => 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. |
780
+ | `onInput` | `(value: number) => 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. |
781
+ | `onBlur` | `(value: number) => void(optional)` | `N/A` | A function that is called and passed the value every time the field loses focus. |
782
+ | `onFocus` | `(value: number) => void(optional)` | `N/A` | A function that is called and passed the value every time the field gets focused. |
783
+ | `min` | `number(optional)` | `N/A` | Sets the lower bound of your input. |
784
+ | `max` | `number(optional)` | `N/A` | Sets the upper bound of your input. |
785
+ | `precision` | `number(optional)` | `N/A` | Represents the number of digits to the right of the decimal point. |
786
+ | `precision` | `number(optional)` | `N/A` | Represents the number of digits to the right of the decimal point. |
787
+ | `formatStyle` | `'decimal' \| 'percentage'` | `'decimal'` | Formats the input as a decimal point number or a percentage. |
788
+
789
+ ##### Usage
790
+
791
+ ```javascript
792
+ const Extension = () => {
793
+ const [portalCount, setPortalCount] = useState(0);
794
+ return (
795
+ <NumberInput
796
+ label={'HubSpot Portal Count'}
797
+ name="portalsNumber"
798
+ description={'Number of active portals'}
799
+ placeholder={'number of portals'}
800
+ value={portalCount}
801
+ onChange={value => setPortalCount(value)}
802
+ />
803
+ );
804
+ };
805
+ ```
806
+
660
807
  ### ProgressBar
661
808
 
662
809
  ##### Import
810
+
663
811
  ```javascript
664
812
  import { ProgressBar } from '@hubspot/ui-extensions';
665
813
  ```
666
814
 
667
815
  ##### Props
816
+
668
817
  ```typescript
669
- export interface ProgressBarProps {
818
+ export interface ProgressBarProps {
670
819
  title?: string;
671
820
  showPercentage?: boolean;
672
821
  value?: number;
@@ -675,16 +824,18 @@ import { ProgressBar } from '@hubspot/ui-extensions';
675
824
  variant?: 'success' | 'danger' | 'warning';
676
825
  }
677
826
  ```
827
+
678
828
  | Prop | Type | Default | Description |
679
829
  | --- | --- | --- | --- |
680
830
  | `title` | `string(optional)` | `N/A` | Text to be displayed in the progressbar title. |
681
- | `showPercentage` | `boolean(optional)` | `false` | Toggles the display of the completion percentage. |
682
- | `value` | `number(optional)` | `0` | The value of the progress indicator.
683
- | `valueMax` | `number(optional)` | `100` | The maximum value of the progress.
684
- | `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"**
685
- | `variant` | `'success' \| 'danger' \| 'warning'` | `'success'` | The type of progressbar to display. Defaults to success.
831
+ | `showPercentage` | `boolean(optional)` | `false` | Toggles the display of the completion percentage. |
832
+ | `value` | `number(optional)` | `0` | The value of the progress indicator. |
833
+ | `valueMax` | `number(optional)` | `100` | The maximum value of the progress. |
834
+ | `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"** |
835
+ | `variant` | `'success' \| 'danger' \| 'warning'` | `'success'` | The type of progressbar to display. Defaults to success. |
686
836
 
687
837
  ##### Usage
838
+
688
839
  ```javascript
689
840
  const Extension = () => {
690
841
  return (
@@ -694,25 +845,27 @@ const Extension = () => {
694
845
  valueMax={200}
695
846
  showPercentage={true}
696
847
  />
697
- );
698
- }
848
+ );
849
+ };
699
850
  ```
700
851
 
701
852
  ### Select
702
853
 
703
854
  ##### Import
855
+
704
856
  ```javascript
705
857
  import { Select } from '@hubspot/ui-extensions';
706
858
  ```
707
859
 
708
860
  ##### Props
861
+
709
862
  ```typescript
710
863
  interface SelectProps {
711
864
  label: string;
712
865
  name: string;
713
866
  value?: string | number | boolean;
714
867
  required?: boolean;
715
- readonly?: boolean;
868
+ readOnly?: boolean;
716
869
  description?: string;
717
870
  tooltip?: string;
718
871
  placeholder?: string;
@@ -724,33 +877,34 @@ interface SelectProps {
724
877
  value: string | number | boolean;
725
878
  }[];
726
879
  }
727
-
728
880
  ```
881
+
729
882
  | Prop | Type | Default | Description |
730
- | - | - | - | - |
731
- | `label` | `string` | `N/A`| The label text to display for the select element |
732
- | `name` | `string` | `N/A`| The unique identifier for the select element. |
733
- | `value` | `string \| number \| boolean` | `''`| The value of the select input. |
734
- | `required` | `boolean` | `false`| Determines if the required indicator should be displayed |
735
- | `readonly` | `boolean` | `false`| Determines if the field is editable or not. |
736
- | `description` | `string` | `N/A`| Instructional message to display to the user to help understand the purpose of the input. |
737
- | `tooltip` | `string` | `N/A`| Text that will appear in a tooltip next to the input label. |
738
- | `placeholder` | `string` | `N/A`| Text that appears in the input when it has no value set. |
739
- | `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. |
740
- | `validationMessage` | `string(optional)` | `''`| The text to show if the input has an error. |
741
- | `onChange` | `(value: string) => void` | `N/A`| Function that is called with the new value when it is updated. |
742
- | `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. |
883
+ | --- | --- | --- | --- |
884
+ | `label` | `string` | `N/A` | The label text to display for the select element |
885
+ | `name` | `string` | `N/A` | The unique identifier for the select element. |
886
+ | `value` | `string \| number \| boolean` | `''` | The value of the select input. |
887
+ | `required` | `boolean` | `false` | Determines if the required indicator should be displayed |
888
+ | `readOnly` | `boolean` | `false` | Determines if the field is editable or not. |
889
+ | `description` | `string` | `N/A` | Instructional message to display to the user to help understand the purpose of the input. |
890
+ | `tooltip` | `string` | `N/A` | Text that will appear in a tooltip next to the input label. |
891
+ | `placeholder` | `string` | `N/A` | Text that appears in the input when it has no value set. |
892
+ | `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. |
893
+ | `validationMessage` | `string(optional)` | `''` | The text to show if the input has an error. |
894
+ | `onChange` | `(value: string) => void` | `N/A` | Function that is called with the new value when it is updated. |
895
+ | `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. |
743
896
 
744
897
  ##### Usage
898
+
745
899
  ```javascript
746
900
  const Extension = () => {
747
- const [ name, setName ] = useState(null);
748
- const [ validationMessage, setValidationMessage ] = useState('');
749
- const [ isValid, setIsValid ] = useState(true);
901
+ const [name, setName] = useState(null);
902
+ const [validationMessage, setValidationMessage] = useState('');
903
+ const [isValid, setIsValid] = useState(true);
750
904
 
751
905
  const options = [
752
- {label: 'Bill', value: 42},
753
- {label: 'Ted', value: 43}
906
+ { label: 'Bill', value: 42 },
907
+ { label: 'Ted', value: 43 },
754
908
  ];
755
909
 
756
910
  return (
@@ -764,9 +918,9 @@ const Extension = () => {
764
918
  required={true}
765
919
  error={!isValid}
766
920
  validationMessage={validationMessage}
767
- onChange={(value) => {
768
- setName(value)
769
- if(!value) {
921
+ onChange={value => {
922
+ setName(value);
923
+ if (!value) {
770
924
  setValidationMessage('This is required');
771
925
  setIsValid(false);
772
926
  } else {
@@ -778,31 +932,46 @@ const Extension = () => {
778
932
  />
779
933
  </Form>
780
934
  );
781
- }
935
+ };
782
936
  ```
783
937
 
784
938
  ### Stack
785
939
 
786
940
  ##### Import
941
+
787
942
  ```javascript
788
943
  import { Stack } from '@hubspot/ui-extensions';
789
944
  ```
790
945
 
791
946
  ##### Props
947
+
792
948
  ```typescript
793
949
  interface StackProps {
794
- distance?: 'flush' | 'small' | 'extra-small' | 'medium' | 'large';
950
+ distance?:
951
+ | 'flush'
952
+ | 'small'
953
+ | 'extra-small'
954
+ | 'medium'
955
+ | 'large'
956
+ | 'extra-large'
957
+ | 'xs'
958
+ | 'sm'
959
+ | 'md'
960
+ | 'lg'
961
+ | 'xl';
795
962
  direction?: 'row' | 'column';
796
963
  children?: ReactNode;
797
964
  }
798
965
  ```
966
+
799
967
  | Prop | Type | Default | Description |
800
- | - | - | - | - |
801
- | `distance` | `'flush' \| 'extra-small' \| 'small' \| 'medium' \| 'large'` | `'small'`| Amount of space between each child component passed as children |
802
- | `direction` | `'row' \| 'column'` | `'column'`| Stacks elements in the vertical or horizontal direction. |
803
- | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
968
+ | --- | --- | --- | --- |
969
+ | `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 |
970
+ | `direction` | `'row' \| 'column'` | `'column'` | Stacks elements in the vertical or horizontal direction. |
971
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
804
972
 
805
973
  ##### Usage
974
+
806
975
  ```javascript
807
976
  const Extension = () => {
808
977
  return (
@@ -817,21 +986,25 @@ const Extension = () => {
817
986
  ### Statistics
818
987
 
819
988
  ##### Import
989
+
820
990
  ```javascript
821
991
  import { Statistics } from '@hubspot/ui-extensions';
822
992
  ```
823
993
 
824
994
  ##### Props
995
+
825
996
  ```typescript
826
997
  interface StatisticsProps {
827
998
  children: ReactNode;
828
999
  }
829
1000
  ```
1001
+
830
1002
  | Prop | Type | Default | Description |
831
- | - | - | - | - |
832
- | `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) |
1003
+ | --- | --- | --- | --- |
1004
+ | `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) |
833
1005
 
834
1006
  ##### Usage
1007
+
835
1008
  ```javascript
836
1009
  const Extension = () => {
837
1010
  return (
@@ -846,11 +1019,13 @@ const Extension = () => {
846
1019
  #### StatisticsItem
847
1020
 
848
1021
  ##### Import
1022
+
849
1023
  ```javascript
850
1024
  import { StatisticsItem } from '@hubspot/ui-extensions';
851
1025
  ```
852
1026
 
853
1027
  ##### Props
1028
+
854
1029
  ```typescript
855
1030
  interface StatisticsItemProps {
856
1031
  id?: string;
@@ -859,46 +1034,52 @@ interface StatisticsItemProps {
859
1034
  children: ReactNode;
860
1035
  }
861
1036
  ```
1037
+
862
1038
  | Prop | Type | Default | Description |
863
- | - | - | - | - |
864
- | `id` | `string(optional)` | `N/A`| The unique identifier |
865
- | `label` | `string` | `N/A`| The text to be used as a label |
866
- | `number` | `string` | `N/A`| Fully formatted string to be displayed as the item's primary number |
867
- | `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) |
1039
+ | --- | --- | --- | --- |
1040
+ | `id` | `string(optional)` | `N/A` | The unique identifier |
1041
+ | `label` | `string` | `N/A` | The text to be used as a label |
1042
+ | `number` | `string` | `N/A` | Fully formatted string to be displayed as the item's primary number |
1043
+ | `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) |
868
1044
 
869
1045
  ##### Usage
1046
+
870
1047
  ```javascript
871
1048
  const Extension = () => {
872
1049
  return (
873
1050
  <Statistics>
874
1051
  <StatisticsItem label="Sales" number={'30000'}>
875
- <Text text="Big Numbers" />
1052
+ <Text>Big Numbers</Text>
876
1053
  </StatisticsItem>
877
1054
  </Statistics>
878
1055
  );
879
- }
1056
+ };
880
1057
  ```
881
1058
 
882
1059
  #### StatisticsTrend
883
1060
 
884
1061
  ##### Import
1062
+
885
1063
  ```javascript
886
1064
  import { StatisticsTrend } from '@hubspot/ui-extensions';
887
1065
  ```
888
1066
 
889
1067
  ##### Props
1068
+
890
1069
  ```typescript
891
1070
  interface StatisticsTrendProps {
892
1071
  value: string;
893
1072
  direction: 'increase' | 'decrease';
894
1073
  }
895
1074
  ```
1075
+
896
1076
  | Prop | Type | Default | Description |
897
- | - | - | - | - |
898
- | `value` | `string` | `N/A`| Formatted string to be displayed as trend value |
899
- | `direction` | `'increase' \| 'decrease'` | `N/A`| Direction in which the trend arrow should be displayed |
1077
+ | --- | --- | --- | --- |
1078
+ | `value` | `string` | `N/A` | Formatted string to be displayed as trend value |
1079
+ | `direction` | `'increase' \| 'decrease'` | `N/A` | Direction in which the trend arrow should be displayed |
900
1080
 
901
1081
  ##### Usage
1082
+
902
1083
  ```javascript
903
1084
  const Extension = () => {
904
1085
  return (
@@ -911,18 +1092,19 @@ const Extension = () => {
911
1092
  </StatisticsItem>
912
1093
  </Statistics>
913
1094
  );
914
- }
1095
+ };
915
1096
  ```
916
1097
 
917
-
918
1098
  ### Table
919
1099
 
920
1100
  ##### Import
1101
+
921
1102
  ```javascript
922
1103
  import { Table } from '@hubspot/ui-extensions';
923
1104
  ```
924
1105
 
925
1106
  ##### Props
1107
+
926
1108
  ```typescript
927
1109
  interface TableProps {
928
1110
  children: ReactNode;
@@ -938,26 +1120,27 @@ interface TableProps {
938
1120
  page?: number;
939
1121
  }
940
1122
  ```
1123
+
941
1124
  | Prop | Type | Default | Description |
942
- | - | - | - | - |
943
- | `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) |
944
- | `flush` | `boolean(optional)` | `false`| If true the table will not have bottom margin. |
945
- | `bordered` | `boolean(optional)` | `true`| If false the table will not haver borders around its content. |
946
- | `paginated` | `boolean(optional)` | `false`| If true, the table will display the paginator component and consumer will have to provide extra pagination props. |
1125
+ | --- | --- | --- | --- |
1126
+ | `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) |
1127
+ | `flush` | `boolean(optional)` | `false` | If true the table will not have bottom margin. |
1128
+ | `bordered` | `boolean(optional)` | `true` | If false the table will not haver borders around its content. |
1129
+ | `paginated` | `boolean(optional)` | `false` | If true, the table will display the paginator component and consumer will have to provide extra pagination props. |
947
1130
 
948
1131
  **Props for paginated=true**
949
1132
 
950
1133
  | Prop | Type | Default | Description |
951
- | - | - | - | - |
952
- | `pageCount` | `number` | `N/A`| The total number of pages available |
953
- | `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. |
1134
+ | --- | --- | --- | --- |
1135
+ | `pageCount` | `number` | `N/A` | The total number of pages available |
1136
+ | `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. |
954
1137
  | `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. |
955
1138
  | `showFirstLastButtons` | `boolean(optional)` | `false` | if `true`, it displays the First page and Last page buttons. |
956
1139
  | `maxVisiblePageButtons` | `number(optional)` | `5` | Changes how many page buttons are shown. |
957
1140
  | `page` | `number(optional)` | `N/A` | Denotes the current page. |
958
1141
 
959
-
960
1142
  ##### Usage
1143
+
961
1144
  ```javascript
962
1145
  const Extension = () => {
963
1146
  return (
@@ -976,8 +1159,7 @@ const Extension = () => {
976
1159
  </TableBody>
977
1160
  </Table>
978
1161
  );
979
- }
980
-
1162
+ };
981
1163
 
982
1164
  // Paginated example
983
1165
 
@@ -1036,24 +1218,29 @@ function PaginatedTable() {
1036
1218
  );
1037
1219
  }
1038
1220
  ```
1221
+
1039
1222
  ### TableBody
1040
1223
 
1041
1224
  ##### Import
1225
+
1042
1226
  ```javascript
1043
1227
  import { TableBody } from '@hubspot/ui-extensions';
1044
1228
  ```
1045
1229
 
1046
1230
  ##### Props
1231
+
1047
1232
  ```typescript
1048
1233
  interface TableBodyProps {
1049
1234
  children: ReactNode;
1050
1235
  }
1051
1236
  ```
1237
+
1052
1238
  | Prop | Type | Default | Description |
1053
- | - | - | - | - |
1054
- | `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). |
1239
+ | --- | --- | --- | --- |
1240
+ | `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). |
1055
1241
 
1056
1242
  ##### Usage
1243
+
1057
1244
  ```javascript
1058
1245
  const Extension = () => {
1059
1246
  return (
@@ -1072,26 +1259,31 @@ const Extension = () => {
1072
1259
  </TableBody>
1073
1260
  </Table>
1074
1261
  );
1075
- }
1262
+ };
1076
1263
  ```
1264
+
1077
1265
  ### TableCell
1078
1266
 
1079
1267
  ##### Import
1268
+
1080
1269
  ```javascript
1081
1270
  import { TableCell } from '@hubspot/ui-extensions';
1082
1271
  ```
1083
1272
 
1084
1273
  ##### Props
1274
+
1085
1275
  ```typescript
1086
1276
  interface TableCellProps {
1087
1277
  children: ReactNode;
1088
1278
  }
1089
1279
  ```
1280
+
1090
1281
  | Prop | Type | Default | Description |
1091
- | - | - | - | - |
1092
- | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.|
1282
+ | --- | --- | --- | --- |
1283
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
1093
1284
 
1094
1285
  ##### Usage
1286
+
1095
1287
  ```javascript
1096
1288
  const Extension = () => {
1097
1289
  return (
@@ -1110,26 +1302,31 @@ const Extension = () => {
1110
1302
  </TableBody>
1111
1303
  </Table>
1112
1304
  );
1113
- }
1305
+ };
1114
1306
  ```
1307
+
1115
1308
  ### TableFooter
1116
1309
 
1117
1310
  ##### Import
1311
+
1118
1312
  ```javascript
1119
1313
  import { TableFooter } from '@hubspot/ui-extensions';
1120
1314
  ```
1121
1315
 
1122
1316
  ##### Props
1317
+
1123
1318
  ```typescript
1124
1319
  interface TableFooterProps {
1125
1320
  children: ReactNode;
1126
1321
  }
1127
1322
  ```
1323
+
1128
1324
  | Prop | Type | Default | Description |
1129
- | - | - | - | - |
1130
- | `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). |
1325
+ | --- | --- | --- | --- |
1326
+ | `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). |
1131
1327
 
1132
1328
  ##### Usage
1329
+
1133
1330
  ```javascript
1134
1331
  const Extension = () => {
1135
1332
  return (
@@ -1167,27 +1364,31 @@ const Extension = () => {
1167
1364
  </TableBody>
1168
1365
  </Table>
1169
1366
  );
1170
- }
1367
+ };
1171
1368
  ```
1172
1369
 
1173
1370
  ### TableHead
1174
1371
 
1175
1372
  ##### Import
1373
+
1176
1374
  ```javascript
1177
1375
  import { TableHead } from '@hubspot/ui-extensions';
1178
1376
  ```
1179
1377
 
1180
1378
  ##### Props
1379
+
1181
1380
  ```typescript
1182
1381
  interface TableHeadProps {
1183
1382
  children: ReactNode;
1184
1383
  }
1185
1384
  ```
1385
+
1186
1386
  | Prop | Type | Default | Description |
1187
- | - | - | - | - |
1188
- | `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). |
1387
+ | --- | --- | --- | --- |
1388
+ | `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). |
1189
1389
 
1190
1390
  ##### Usage
1391
+
1191
1392
  ```javascript
1192
1393
  const Extension = () => {
1193
1394
  return (
@@ -1206,26 +1407,31 @@ const Extension = () => {
1206
1407
  </TableBody>
1207
1408
  </Table>
1208
1409
  );
1209
- }
1410
+ };
1210
1411
  ```
1412
+
1211
1413
  ### TableHeader
1212
1414
 
1213
1415
  ##### Import
1416
+
1214
1417
  ```javascript
1215
1418
  import { TableHeader } from '@hubspot/ui-extensions';
1216
1419
  ```
1217
1420
 
1218
1421
  ##### Props
1422
+
1219
1423
  ```typescript
1220
1424
  interface TableHeaderProps {
1221
1425
  children: ReactNode;
1222
1426
  }
1223
1427
  ```
1428
+
1224
1429
  | Prop | Type | Default | Description |
1225
- | - | - | - | - |
1226
- | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.|
1430
+ | --- | --- | --- | --- |
1431
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
1227
1432
 
1228
1433
  ##### Usage
1434
+
1229
1435
  ```javascript
1230
1436
  const Extension = () => {
1231
1437
  return (
@@ -1244,26 +1450,31 @@ const Extension = () => {
1244
1450
  </TableBody>
1245
1451
  </Table>
1246
1452
  );
1247
- }
1453
+ };
1248
1454
  ```
1455
+
1249
1456
  ### TableRow
1250
1457
 
1251
1458
  ##### Import
1459
+
1252
1460
  ```javascript
1253
1461
  import { TableRow } from '@hubspot/ui-extensions';
1254
1462
  ```
1255
1463
 
1256
1464
  ##### Props
1465
+
1257
1466
  ```typescript
1258
1467
  interface TableRowProps {
1259
1468
  children: ReactNode;
1260
1469
  }
1261
1470
  ```
1471
+
1262
1472
  | Prop | Type | Default | Description |
1263
- | - | - | - | - |
1264
- | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components.|
1473
+ | --- | --- | --- | --- |
1474
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
1265
1475
 
1266
1476
  ##### Usage
1477
+
1267
1478
  ```javascript
1268
1479
  const Extension = () => {
1269
1480
  return (
@@ -1282,125 +1493,324 @@ const Extension = () => {
1282
1493
  </TableBody>
1283
1494
  </Table>
1284
1495
  );
1285
- }
1496
+ };
1286
1497
  ```
1287
1498
 
1288
1499
  ### Tag
1289
1500
 
1290
1501
  ##### Import
1502
+
1291
1503
  ```javascript
1292
1504
  import { Tag } from '@hubspot/ui-extensions';
1293
1505
  ```
1294
1506
 
1295
1507
  ##### Props
1508
+
1296
1509
  ```typescript
1297
1510
  interface TagProps {
1298
- text: string;
1511
+ children: ReactNode;
1299
1512
  onClick?: () => void;
1300
1513
  variant?: 'default' | 'warning' | 'success' | 'error';
1301
1514
  }
1302
1515
  ```
1516
+
1303
1517
  | Prop | Type | Default | Description |
1304
- | - | - | - | - |
1305
- | `text` | `string` | `N/A`| Text to be displayed in the tag. |
1306
- | `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. |
1307
- | `variant` | `'default' \| 'warning' \| 'success' \| 'error'` `(optional)` | `'default'`| The color variation of the tag to display |
1518
+ | --- | --- | --- | --- |
1519
+ | `children` | `string` | `N/A` | Text to be displayed in the tag. |
1520
+ | `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. |
1521
+ | `variant` | `'default' \| 'warning' \| 'success' \| 'error'` `(optional)` | `'default'` | The color variation of the tag to display |
1308
1522
 
1309
1523
  ##### Usage
1524
+
1310
1525
  ```javascript
1311
1526
  const Extension = () => {
1312
1527
  return (
1313
1528
  <Tag
1314
- text="Success"
1315
- variant='success'
1529
+ variant="success"
1316
1530
  onClick={() => {
1317
1531
  console.log('Tag clicked!');
1318
1532
  }}
1319
- />
1533
+ >
1534
+ Success
1535
+ </Tag>
1320
1536
  );
1321
- }
1537
+ };
1322
1538
  ```
1323
1539
 
1324
1540
  ### Text
1325
1541
 
1326
1542
  ##### Import
1543
+
1327
1544
  ```javascript
1328
1545
  import { Text } from '@hubspot/ui-extensions';
1329
1546
  ```
1330
1547
 
1331
1548
  ##### Props
1549
+
1332
1550
  ```typescript
1333
- interface TextProps {
1334
- format?: 'plaintext' | 'markdown';
1335
- text: string;
1551
+ export interface TextFormatOptions {
1552
+ fontWeight?: 'regular' | 'bold' | 'demibold';
1553
+ italic?: boolean;
1554
+ lineDecoration?: 'none' | 'underline' | 'strikethrough';
1555
+ }
1556
+
1557
+ export type TextProps = {
1336
1558
  variant?: 'bodytext' | 'microcopy';
1559
+ inline?: boolean;
1337
1560
  children: ReactNode;
1338
- tagName?: 'p' | 'span' | 'small';
1339
- }
1561
+ format?: TextFormatOptions;
1562
+ };
1340
1563
  ```
1564
+
1341
1565
  | Prop | Type | Default | Description |
1342
- | - | - | - | - |
1343
- | `format` | `'plaintext' \| 'markdown'` `(optional)`| `'plaintext'`| Type of formatting for the display text. |
1344
- | `text` | `string` | `N/A`| Text to be displayed as body text iff format is `"markdown"`. Inline markdown elements (i.e. bold, italics, code, links) are supported |
1345
- | `children` | `string` | `N/A`| Text to be displayed as body text iff format is `"plaintext"`. |
1346
- | `variant` | `'bodytext' \| 'microcopy'` | `'bodytext`| Type of text to display |
1347
- | `tagName` | `'p' \| 'small' \| 'span'` | `'bodytext`| Type of text element(tag) to display. |
1566
+ | --- | --- | --- | --- |
1567
+ | `format` | `'TextFormatOptions'` `(optional)` | `N/A` | Type of formatting options for the text. |
1568
+ | `children` | `string` | `N/A` | Text to be displayed as body text. |
1569
+ | `variant` | `'bodytext' \| 'microcopy'` | `'bodytext'` | Type of text to display |
1570
+ | `inline` | `boolean(optional)` | `false` | If `false` the text component will not insert a line break. |
1571
+
1572
+ #### Format Options
1348
1573
 
1349
- #### Markdown
1350
- Markdown syntax supported in the component:
1574
+ - bold text: `{ fontWeight: 'bold' }`
1575
+ - semibold text: `{ fontWeight: 'demibold' }`
1576
+ - italicized text: `{ italic: true }`
1577
+ - strikethrough text: `{ lineDecoration: 'strikethrough' }`
1578
+ - underlined text: `{ lineDecoration: 'underline' }`
1579
+ - inline text: `<Text inline={true}/>`
1351
1580
 
1352
- - bold text: `**like this**` or `__like this__`
1353
- - italicized text: `*like this*` or `_like this_`
1354
- - inline code: `` `like this` ``
1355
- - links: `[visible anchor text](https://www.hubspot.com/)`
1356
1581
 
1357
1582
  ##### Usage
1583
+
1358
1584
  ```javascript
1359
1585
  const Extension = () => {
1360
1586
  return (
1361
1587
  <>
1362
- <Text text="**Bold**" format="markdown"/>
1363
- <Text text="*Italics*" format="markdown"/>
1364
- <Text text="**Not Bold because format isn't markdown**"/>
1365
- <Text text="This is going to be small" variant="microcopy"/>
1588
+ <Text>Plain text</Text>
1589
+ <Text format={{ fontWeight: 'bold' }}>Bold</Text>
1590
+ <Text format={{ italic: true }}>Italics</Text>
1591
+ <Text format={{ fontWeight: 'bold', italic: true }}>
1592
+ Bold and Italic text
1593
+ </Text>
1594
+ <Text format={{ lineDecoration: 'strikethrough' }}>
1595
+ Strikethrough Text
1596
+ </Text>
1597
+ <Text variant="microcopy">
1598
+ Microcopy text
1599
+ <Text inline={true} format={{ fontWeight: 'bold' }}>
1600
+ with inner bold
1601
+ </Text>
1602
+ </Text>
1366
1603
  </>
1367
1604
  );
1605
+ };
1606
+ ```
1607
+
1608
+ ### Textarea
1609
+
1610
+ ##### Import
1611
+
1612
+ ```javascript
1613
+ import { Textarea } from '@hubspot/ui-extensions';
1614
+ ```
1615
+
1616
+ ##### Props
1617
+
1618
+ ```typescript
1619
+ interface TextareaProps {
1620
+ label: string;
1621
+ name: string;
1622
+ value?: string;
1623
+ required?: boolean;
1624
+ readOnly?: boolean;
1625
+ description?: string;
1626
+ tooltip?: string;
1627
+ placeholder?: string;
1628
+ error?: boolean;
1629
+ validationMessage?: string;
1630
+ onChange?: (value: string) => void;
1631
+ onInput?: (value: string) => void;
1632
+ onBlur?: (value: string) => void;
1633
+ onFocus?: (value: string) => void;
1634
+ cols?: number;
1635
+ maxLength?: number;
1636
+ rows?: number;
1637
+ resize?: 'vertical' | 'horizontal' | 'both' | 'none';
1368
1638
  }
1369
1639
  ```
1370
1640
 
1641
+ | Prop | Type | Default | Description |
1642
+ | --- | --- | --- | --- |
1643
+ | `label` | `string` | `N/A` | The label text to display for the textarea element |
1644
+ | `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) |
1645
+ | `value` | `string(optional)` | `''` | The value of the textarea |
1646
+ | `required` | `boolean(optional)` | `false` | Determines if the required indicator should be displayed |
1647
+ | `readOnly` | `boolean(optional)` | `false` | Determines if the field is editable or not. |
1648
+ | `description` | `string(optional)` | `N/A` | Instructional message to display to the user to help understand the purpose of the textarea. |
1649
+ | `tooltip` | `string(optional)` | `N/A` | Text that will appear in a tooltip next to the textarea label. |
1650
+ | `placeholder` | `string(optional)` | `N/A` | Text that appears in the textarea when it has no value set. |
1651
+ | `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. |
1652
+ | `validationMessage` | `string(optional)` | `''` | The text to show if the textarea has an error. |
1653
+ | `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. |
1654
+ | `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. |
1655
+ | `onBlur` | `(value: string) => void(optional)` | `N/A` | A function that is called and passed the value every time the field loses focus. |
1656
+ | `onFocus` | `(value: string) => void(optional)` | `N/A` | A function that is called and passed the value every time the field gets focused. |
1657
+ | `cols` | `number(optional)` | `N/A` | The visible width of the text control, in average character widths. |
1658
+ | `rows` | `number(optional)` | `N/A` | The number of visible text lines for the control. |
1659
+ | `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. |
1660
+ | `resize` | `'vertical' \| 'horizontal' \| 'both' \| 'none'` `(optional)` | `'vertical'` | Sets whether an element is resizable, and if so, in which directions. |
1661
+
1662
+ ##### Usage
1663
+
1664
+ ```javascript
1665
+ import { useState } from 'react';
1666
+
1667
+ const Extension = () => {
1668
+ const [desciptiption, setDescription] = useState('');
1669
+ const [validationMessage, setValidationMessage] = useState('');
1670
+ const [isValid, setIsValid] = useState(true);
1671
+
1672
+ return (
1673
+ <Form>
1674
+ <Textarea
1675
+ label="Description"
1676
+ name="description"
1677
+ tooltip="Provide as much detail as possible"
1678
+ description="Please include a link"
1679
+ placeholder="My desription"
1680
+ required={true}
1681
+ error={!isValid}
1682
+ validationMessage={validationMessage}
1683
+ onChange={value => {
1684
+ setDescription(value);
1685
+ }}
1686
+ onInput={value => {
1687
+ if (!value.includes('http')) {
1688
+ setValidationMessage('A link must be included.');
1689
+ setIsValid(false);
1690
+ } else {
1691
+ setValidationMessage('Valid description!');
1692
+ setIsValid(true);
1693
+ }
1694
+ }}
1695
+ />
1696
+ </Form>
1697
+ );
1698
+ };
1699
+ ```
1700
+
1371
1701
  ### Tile
1372
1702
 
1373
1703
  ##### Import
1704
+
1374
1705
  ```javascript
1375
1706
  import { Tile } from '@hubspot/ui-extensions';
1376
1707
  ```
1377
1708
 
1378
1709
  ##### Props
1710
+
1379
1711
  ```typescript
1380
1712
  interface TileProps {
1381
1713
  children: ReactNode;
1382
1714
  flush?: boolean;
1383
1715
  }
1384
1716
  ```
1717
+
1385
1718
  | Prop | Type | Default | Description |
1386
- | - | - | - | - |
1387
- | `children` | `ReactNode` | `N/A`| Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
1388
- | `flush` | `boolean(optional)` | `false`| If true the content of the Tile will have no left or right padding. |
1719
+ | --- | --- | --- | --- |
1720
+ | `children` | `ReactNode` | `N/A` | Sets the content that will render inside the component. This prop is passed implicitly by providing sub-components. |
1721
+ | `flush` | `boolean(optional)` | `false` | If true the content of the Tile will have no left or right padding. |
1389
1722
 
1390
1723
  ##### Usage
1724
+
1391
1725
  ```javascript
1392
1726
  const Extension = () => {
1393
1727
  return (
1394
1728
  <>
1395
1729
  <Tile flush={true}>
1396
- <Text text="No left padding" />
1730
+ <Text>No left padding</Text>
1397
1731
  </Tile>
1398
1732
  <Tile>
1399
- <Text text="Small amount of left padding" />
1733
+ <Text>Small amount of left padding</Text>
1400
1734
  </Tile>
1401
1735
  </>
1402
1736
  );
1403
- }
1737
+ };
1738
+ ```
1739
+
1740
+ ### ToggleGroup
1741
+
1742
+ ##### Import
1404
1743
 
1744
+ ```javascript
1745
+ import { ToggleGroup } from '@hubspot/ui-extensions';
1746
+ ```
1747
+
1748
+ ##### Props
1405
1749
 
1750
+ ```typescript
1751
+ type ToggleGroupProps = {
1752
+ toggleType: 'checkboxList' | 'radioButtonList';
1753
+ name: string;
1754
+ label: string;
1755
+ value?: string | string[];
1756
+ onChange?: (value: string) => void | (value: string[]) => void;
1757
+ validationMessage?: string;
1758
+ required?: boolean;
1759
+ tooltip?: string;
1760
+ error?: boolean;
1761
+ options: {
1762
+ label: string;
1763
+ value: string;
1764
+ initialIsChecked?: boolean;
1765
+ readonly?: boolean;
1766
+ description?: string;
1767
+ }[];
1768
+ inline?: boolean;
1769
+ variant?: 'default' | 'small';
1770
+ };
1771
+
1772
+ ```
1773
+
1774
+ | Prop | Type | Default | Description |
1775
+ | --- | --- | --- | --- | --- |
1776
+ | `toggleType` | `'radioButtonList' \| 'checkboxList'` | `N/A` | The type of toggles that will be shown. `'checkboxList'` is a multi-select and `'radioButtonList'` is a single select | ; |
1777
+ | `name` | `string` | `N/A` | The unique identifier for the toggle group element. |
1778
+ | `label` | `string` | `N/A` | The label text to display for the toggle group element. |
1779
+ | `options` | `Array<{ label: string; value: string; initialIsChecked?: boolean; readonly?: boolean; description?: string }>` | `N/A` | |
1780
+ | `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. |
1781
+ | `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. |
1782
+ | `required` | `boolean(optional)` | `false` | Determines if the required indicator should be displayed |
1783
+ | `tooltip` | `string` | `N/A` | Text that will appear in a tooltip next to the toggle group label. |
1784
+ | `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. |
1785
+ | `validationMessage` | `string(optional)` | `''` | The text to show if the input has an error. |
1786
+ | `inline` | `boolean(optional)` | `false` | Determines of the options are stacked vertically or share a line horizontally. |
1787
+ | `variant` | `'default' \| 'small'` `(optional)` | `default` | The size variation of the individual options. |
1788
+
1789
+ ##### Usage
1790
+
1791
+ ```javascript
1792
+ const options = [1, 2, 3, 4].map(n => ({
1793
+ label: `Option ${n}`,
1794
+ value: `${n}`,
1795
+ initialIsChecked: n === 2,
1796
+ readonly: false,
1797
+ description: `This is option ${n}`,
1798
+ }));
1799
+
1800
+ const Extension = () => {
1801
+ return (
1802
+ <ToggleGroup
1803
+ name="toggle-checkboxes"
1804
+ label="Toggle these things"
1805
+ error={false}
1806
+ options={options}
1807
+ tooltip="Here's a secret tip."
1808
+ validationMessage="Make sure you do the thing correctly."
1809
+ required={false}
1810
+ inline={false}
1811
+ toggleType="checkboxList"
1812
+ variant="default"
1813
+ />
1814
+ );
1815
+ };
1406
1816
  ```