@hubspot/ui-extensions 0.0.1-prealpha.3 → 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 CHANGED
@@ -1,6 +1,35 @@
1
1
  # ui-extensions-components
2
2
 
3
- ## Overview
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)
4
33
 
5
34
  ## Components
6
35
 
@@ -458,8 +487,8 @@ interface InputProps {
458
487
  | `description` | `string(optional)` | `N/A`| Instructional message to display to the user to help understand the purpose of the input. |
459
488
  | `tooltip` | `string(optional)` | `N/A`| Text that will appear in a tooltip next to the input label. |
460
489
  | `placeholder` | `string(optional)` | `N/A`| Text that appears in the input when it has no value set. |
461
- | `error` | `boolean(optional)` | `false`| If set to true, displays an `errorMessage` if provided and renders the error state for the input. |
462
- | `errorMessage` | `string(optional)` | `''`| The text to show if the input has an error. |
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. |
463
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. |
464
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. |
465
494
 
@@ -469,7 +498,8 @@ import { useState } from 'react';
469
498
 
470
499
  const Extension = () => {
471
500
  const [ name, setName ] = useState('');
472
- const [ errorMessage, setErrorMessage ] = useState('');
501
+ const [ validationMessage, setValidationMessage ] = useState('');
502
+ const [ isValid, setIsValid ] = useState(true);
473
503
 
474
504
  return (
475
505
  <Form>
@@ -480,18 +510,21 @@ const Extension = () => {
480
510
  description="Please enter your first name"
481
511
  placeholder="First name"
482
512
  required={true}
483
- error={errorMessage !== ''}
484
- errorMessage={errorMessage}
513
+ error={!isValid}
514
+ validationMessage={validationMessage}
485
515
  onChange={(value) => {
486
516
  setName(value)
487
517
  }}
488
518
  onInput={(value) => {
489
519
  if(value !== 'Bill') {
490
- setErrorMessage('This form only works for people named Bill');
520
+ setValidationMessage('This form only works for people named Bill');
521
+ setIsValid(false);
491
522
  } else if (value === '') {
492
- setErrorMessage('First name is required')
523
+ setValidationMessage('First name is required')
524
+ setIsValid(false);
493
525
  } else {
494
- setErrorMessage('')
526
+ setValidationMessage('Valid first name!')
527
+ setIsValid(true);
495
528
  }
496
529
  }}
497
530
  />
@@ -500,6 +533,37 @@ const Extension = () => {
500
533
  }
501
534
  ```
502
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
+ ```
503
567
  ### ProgressBar
504
568
 
505
569
  ##### Import
@@ -579,8 +643,8 @@ interface SelectProps {
579
643
  | `description` | `string` | `N/A`| Instructional message to display to the user to help understand the purpose of the input. |
580
644
  | `tooltip` | `string` | `N/A`| Text that will appear in a tooltip next to the input label. |
581
645
  | `placeholder` | `string` | `N/A`| Text that appears in the input when it has no value set. |
582
- | `error` | `boolean` | `false`| If set to true, displays an `errorMessage` if provided and renders the error state for the input. |
583
- | `errorMessage` | `string` | `''`| The text to show if the input has an error. |
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. |
584
648
  | `onChange` | `(value: string) => void` | `N/A`| Function that is called with the new value when it is updated. |
585
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. |
586
650
 
@@ -588,7 +652,8 @@ interface SelectProps {
588
652
  ```javascript
589
653
  const Extension = () => {
590
654
  const [ name, setName ] = useState(null);
591
- const [ errorMessage, setErrorMessage ] = useState('');
655
+ const [ validationMessage, setValidationMessage ] = useState('');
656
+ const [ isValid, setIsValid ] = useState(true);
592
657
 
593
658
  const options = [
594
659
  {label: 'Bill', value: 42},
@@ -597,21 +662,23 @@ const Extension = () => {
597
662
 
598
663
  return (
599
664
  <Form>
600
- <Input
665
+ <Select
601
666
  label="Best Bill & Ted Character?"
602
667
  name="best-char"
603
668
  tooltip="Please choose"
604
669
  description="Please choose"
605
670
  placeholder="Bill or Ted?"
606
671
  required={true}
607
- error={errorMessage !== ''}
608
- errorMessage={errorMessage}
672
+ error={!isValid}
673
+ validationMessage={validationMessage}
609
674
  onChange={(value) => {
610
675
  setName(value)
611
676
  if(!value) {
612
- setErrorMessage('This is required');
677
+ setValidationMessage('This is required');
678
+ setIsValid(false);
613
679
  } else {
614
- setErrorMessage('');
680
+ setValidationMessage('Excellent!');
681
+ setIsValid(true);
615
682
  }
616
683
  }}
617
684
  options={options}
@@ -753,6 +820,297 @@ const Extension = () => {
753
820
  ```
754
821
 
755
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
+
756
1114
  ### Tag
757
1115
 
758
1116
  ##### Import
package/package.json CHANGED
@@ -1,17 +1,51 @@
1
1
  {
2
2
  "name": "@hubspot/ui-extensions",
3
- "version": "0.0.1-prealpha.3",
3
+ "version": "0.0.1-prealpha.4",
4
4
  "description": "",
5
5
  "type": "module",
6
- "main": "index.ts",
7
- "scripts": {},
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "rm -rf dist/ && tsc",
10
+ "watch": "rm -rf dist/ && tsc --watch"
11
+ },
12
+ "files": [
13
+ "dist/**/*"
14
+ ],
15
+ "prepare": "npm run build",
8
16
  "publishConfig": {
9
17
  "access": "public"
10
18
  },
19
+ "exports": {
20
+ ".": "./dist/index.js",
21
+ "./crm": "./dist/crm/index.js"
22
+ },
11
23
  "license": "MIT",
12
24
  "dependencies": {
13
25
  "@remote-ui/react": "^5.0.0",
14
26
  "react": "^18.2.0"
15
27
  },
16
- "gitHead": "74dbffa7fe6e4ad7d5029897801c11dc5d5edae1"
28
+ "engines": {
29
+ "node": ">=16"
30
+ },
31
+ "peerDependencies": {
32
+ "@remote-ui/react": "^5.0.0",
33
+ "react": "^18.2.0",
34
+ "typescript": "^5.0.4"
35
+ },
36
+ "peerDependenciesMeta": {
37
+ "react": {
38
+ "optional": false
39
+ },
40
+ "@remote-ui/react": {
41
+ "optional": false
42
+ },
43
+ "typescript": {
44
+ "optional": true
45
+ }
46
+ },
47
+ "devDependencies": {
48
+ "typescript": "5.0.4"
49
+ },
50
+ "gitHead": "d3ed42de0f9675a2f599416ba1886ba379ecfcd0"
17
51
  }
@@ -1,11 +0,0 @@
1
- /* Hello! To create your first component, uncomment the code below and replace
2
- * the entry with your props and component name
3
- * import { createExtensionComponent } from '../utils/createExtensionComponent';
4
- * import type { ExampleCrmComponentProps } from '../types';
5
-
6
- * const ExampleCrmComponent = createExtensionComponent<
7
- * 'ExampleCrmComponent',
8
- * ExampleCrmComponentProps
9
- * >('ExampleCrmComponent');
10
- */
11
- export {};
@@ -1 +0,0 @@
1
- export {};
package/coreComponents.ts DELETED
@@ -1,94 +0,0 @@
1
- import { createRemoteReactComponent } from '@remote-ui/react';
2
-
3
- import type {
4
- AlertProps,
5
- ButtonProps,
6
- ButtonRowProps,
7
- CardProps,
8
- DescriptionListProps,
9
- DescriptionListItemProps,
10
- FormProps,
11
- HeadingProps,
12
- ImageProps,
13
- InputProps,
14
- LoadingSpinnerProps,
15
- ProgressBarProps,
16
- SelectProps,
17
- TagProps,
18
- TextProps,
19
- TileProps,
20
- StackProps,
21
- StatisticsProps,
22
- StatisticsItemProps,
23
- StatisticsTrendProps,
24
- } from './types';
25
-
26
- const Alert = createRemoteReactComponent<'Alert', AlertProps>('Alert');
27
- const Button = createRemoteReactComponent<'Button', ButtonProps>('Button');
28
- const ButtonRow = createRemoteReactComponent<'ButtonRow', ButtonRowProps>(
29
- 'ButtonRow'
30
- );
31
- const Card = createRemoteReactComponent<'Card', CardProps>('Card');
32
- const DescriptionList = createRemoteReactComponent<
33
- 'DescriptionList',
34
- DescriptionListProps
35
- >('DescriptionList');
36
- const DescriptionListItem = createRemoteReactComponent<
37
- 'DescriptionListItem',
38
- DescriptionListItemProps
39
- >('DescriptionListItem');
40
- const Divider = createRemoteReactComponent<'Divider', {}>('Divider');
41
- const Form = createRemoteReactComponent<'Form', FormProps>('Form');
42
- const Heading = createRemoteReactComponent<'Heading', HeadingProps>('Heading');
43
- const Image = createRemoteReactComponent<'Image', ImageProps>('Image');
44
- const Input = createRemoteReactComponent<'Input', InputProps>('Input');
45
- const LoadingSpinner = createRemoteReactComponent<
46
- 'LoadingSpinner',
47
- LoadingSpinnerProps
48
- >('LoadingSpinner');
49
- const ProgressBar = createRemoteReactComponent<'ProgressBar', ProgressBarProps>(
50
- 'ProgressBar'
51
- );
52
- const Select = createRemoteReactComponent<'Select', SelectProps>('Select');
53
- const Tag = createRemoteReactComponent<'Tag', TagProps>('Tag');
54
- const Text = createRemoteReactComponent<'Text', TextProps>('Text');
55
- const Tile = createRemoteReactComponent<'Tile', TileProps>('Tile');
56
- const Stack = createRemoteReactComponent<'Stack', StackProps>('Stack');
57
-
58
- const StatisticsItem = createRemoteReactComponent<
59
- 'StatisticsItem',
60
- StatisticsItemProps
61
- >('StatisticsItem');
62
-
63
- const Statistics = createRemoteReactComponent<'Statistics', StatisticsProps>(
64
- 'Statistics'
65
- );
66
-
67
- const StatisticsTrend = createRemoteReactComponent<
68
- 'StatisticsTrend',
69
- StatisticsTrendProps
70
- >('StatisticsTrend');
71
-
72
- export {
73
- Alert,
74
- Button,
75
- ButtonRow,
76
- Card,
77
- DescriptionList,
78
- DescriptionListItem,
79
- Divider,
80
- Form,
81
- Heading,
82
- Image,
83
- Input,
84
- LoadingSpinner,
85
- ProgressBar,
86
- Select,
87
- Stack,
88
- Statistics,
89
- StatisticsItem,
90
- StatisticsTrend,
91
- Tag,
92
- Text,
93
- Tile,
94
- };
package/hubspot.ts DELETED
@@ -1,32 +0,0 @@
1
- /* eslint-disable hubspot-dev/no-confusing-browser-globals */
2
-
3
- import { createRoot, RemoteRoot } from '@remote-ui/react';
4
- import { ReactElement, isValidElement } from 'react';
5
- import { ExtensionPoints, ExtensionPointApi } from './types';
6
-
7
- export const hubspot = {
8
- extend: render,
9
- };
10
-
11
- const extend = (...args) => (self as any).extend(...args);
12
-
13
- function render<ExtensionPointName extends keyof ExtensionPoints>(
14
- renderCallback: (
15
- api: ExtensionPointApi<ExtensionPointName>
16
- ) => ReactElement<any>
17
- ) {
18
- return extend(
19
- (root: RemoteRoot, api: ExtensionPointApi<ExtensionPointName>) => {
20
- const renderCallbackResult = renderCallback(api);
21
-
22
- if (!isValidElement(renderCallbackResult)) {
23
- throw new Error(
24
- `[hubspot.extend]: Expected callback function to return a valid element, got: ${renderCallbackResult}`
25
- );
26
- }
27
-
28
- createRoot(root).render(renderCallbackResult);
29
- root.mount();
30
- }
31
- );
32
- }
package/index.ts DELETED
@@ -1,25 +0,0 @@
1
- export {
2
- Alert,
3
- Button,
4
- ButtonRow,
5
- Card,
6
- DescriptionList,
7
- DescriptionListItem,
8
- Divider,
9
- Form,
10
- Heading,
11
- Image,
12
- Input,
13
- LoadingSpinner,
14
- ProgressBar,
15
- Select,
16
- Stack,
17
- Statistics,
18
- StatisticsItem,
19
- StatisticsTrend,
20
- Tag,
21
- Text,
22
- Tile,
23
- } from './coreComponents';
24
-
25
- export { hubspot } from './hubspot';
package/types.ts DELETED
@@ -1,297 +0,0 @@
1
- // Do not manually update this file, changes will be overridden from ui-extensions-remote-renderer/static/js/types.ts
2
- import { ReactNode, ComponentType } from 'react';
3
-
4
- export interface AlertProps {
5
- title: string;
6
- body?: string;
7
- children?: ReactNode;
8
- variant?: 'info' | 'warning' | 'success' | 'error' | 'danger';
9
- }
10
-
11
- export interface ButtonProps {
12
- text: string;
13
- onClick?: () => void;
14
- href?: string;
15
- disabled?: boolean;
16
- variant?: 'primary' | 'secondary' | 'destructive';
17
- type?: 'button' | 'reset' | 'submit';
18
- }
19
-
20
- export interface ButtonRowProps {
21
- children: ReactNode;
22
- disableDropdown?: boolean;
23
- }
24
-
25
- export interface CardProps {
26
- children: ReactNode;
27
- }
28
-
29
- export interface DescriptionListItemProps {
30
- children: ReactNode;
31
- label: string;
32
- }
33
-
34
- export interface DescriptionListProps {
35
- children: ReactNode;
36
- direction?: 'row' | 'column';
37
- }
38
-
39
- export interface DividerProps {
40
- distance?:
41
- | 'flush'
42
- | 'extra-small'
43
- | 'small'
44
- | 'medium'
45
- | 'large'
46
- | 'extra-large';
47
- }
48
-
49
- export interface FormProps {
50
- children: ReactNode;
51
- onSubmit?: () => void;
52
- preventDefault?: boolean;
53
- }
54
-
55
- export interface HeadingProps {
56
- text: string;
57
- format?: 'plaintext' | 'markdown';
58
- }
59
-
60
- export interface ImageProps {
61
- alt?: string;
62
- href?: string;
63
- onClick?: () => void;
64
- src: string;
65
- width?: number;
66
- }
67
-
68
- export interface InputProps {
69
- label: string;
70
- name: string;
71
- value?: string;
72
- required?: boolean;
73
- readonly?: boolean;
74
- description?: string;
75
- tooltip?: string;
76
- placeholder?: string;
77
- error?: boolean;
78
- errorMessage?: string;
79
- onChange: (value: string) => void;
80
- onInput: (value: string) => void;
81
- }
82
-
83
- export interface ProgressBarProps {
84
- title?: string;
85
- showPercentage?: boolean;
86
- value?: number;
87
- valueMax?: number;
88
- valueDescription?: string;
89
- variant?: 'success' | 'danger' | 'warning';
90
- }
91
-
92
- export interface SelectProps {
93
- label: string;
94
- name: string;
95
- value?: string | number | boolean;
96
- required?: boolean;
97
- readonly?: boolean;
98
- description?: string;
99
- tooltip?: string;
100
- placeholder?: string;
101
- error?: boolean;
102
- errorMessage?: string;
103
- onChange: (value: string) => void;
104
- options: {
105
- label: string;
106
- value: string | number | boolean;
107
- }[];
108
- }
109
-
110
- export interface TagProps {
111
- text: string;
112
- onClick?: () => void;
113
- variant?: 'default' | 'warning' | 'success' | 'error';
114
- }
115
-
116
- export interface TextProps {
117
- format?: 'plaintext' | 'markdown';
118
- text: string;
119
- variant?: 'bodytext' | 'microcopy';
120
- }
121
-
122
- export interface TileProps {
123
- children: ReactNode;
124
- flush?: boolean;
125
- }
126
-
127
- interface Team {
128
- id: number;
129
- name: string;
130
- teammates: number[];
131
- }
132
-
133
- export interface UserContext {
134
- id: number;
135
- emails: string[];
136
- email: string;
137
- firstName: string;
138
- lastName: string;
139
- roles: string[];
140
- teams: Team[];
141
- locale?: string;
142
- }
143
-
144
- export interface PortalContext {
145
- id: number;
146
- timezone: string;
147
- }
148
-
149
- export interface Context {
150
- user: UserContext;
151
- portal: PortalContext;
152
- }
153
-
154
- type distanceOptions = 'flush' | 'small';
155
-
156
- export interface StackProps {
157
- distance?: distanceOptions;
158
- children?: React.ReactNode;
159
- }
160
- export interface StatisticsTrendProps {
161
- value: string;
162
- direction: 'increase' | 'decrease';
163
- }
164
-
165
- export interface StatisticsItemProps {
166
- id?: string;
167
- label: string;
168
- number: string;
169
- children: ReactNode;
170
- }
171
-
172
- export interface StatisticsProps {
173
- children: ReactNode;
174
- }
175
-
176
- export interface ServerlessRunnerParams {
177
- name: string;
178
- payload: Record<string, unknown>;
179
- onError?: () => void;
180
- }
181
-
182
- export type ServerlessFuncRunner = (
183
- params: ServerlessRunnerParams
184
- ) => Promise<any>;
185
-
186
- export interface ServerlessSuccessResponse {
187
- logId: string;
188
- response: {
189
- message?:
190
- | {
191
- type: 'SUCCESS' | 'ERROR';
192
- body: string;
193
- }
194
- | string;
195
- context?: Record<string, unknown>;
196
- section?: Record<string, unknown>;
197
- };
198
- }
199
-
200
- export interface ServerlessErrorResponse {
201
- responseJSON?: {
202
- message: string;
203
- correlationId: string;
204
- category: string;
205
- subCategory?: string;
206
- errors?: { message: string; subCategory: string }[];
207
- };
208
- status: number;
209
- }
210
-
211
- export interface ExtensionCardContextData {
212
- cardId: string;
213
- appId: number | string;
214
- objectId: number | string;
215
- objectTypeId: string;
216
- location: keyof ExtensionPoints;
217
- }
218
-
219
- export type ExtensionPointAction = (...args: any[]) => Promise<any> | void;
220
-
221
- export interface ExtensionPointContract {
222
- actions?: { [k: string]: ExtensionPointAction } | {};
223
- customComponents: Record<string, ComponentType<any>>;
224
- }
225
- type AlertType = 'info' | 'warning' | 'success' | 'danger' | 'tip' | undefined;
226
-
227
- export type AddAlertAction = (args: {
228
- type?: AlertType;
229
- message: string;
230
- }) => void;
231
-
232
- export type ReloadPageAction = () => void;
233
-
234
- export type FetchCrmObjectPropertiesAction = (
235
- properties: string[]
236
- ) => Promise<{ name: string; value: string }[]>;
237
-
238
- interface CrmMiddleExtensionPoint extends ExtensionPointContract {
239
- actions: {
240
- addAlert: AddAlertAction;
241
- reloadPage: ReloadPageAction;
242
- fetchCrmObjectProperties: FetchCrmObjectPropertiesAction;
243
- openIframeModal: (action: OpenIframeActionPayload) => void;
244
- };
245
- }
246
-
247
- interface CrmSidebarExtensionPoint extends ExtensionPointContract {
248
- actions: {
249
- reloadPage: ReloadPageAction;
250
- };
251
- }
252
-
253
- interface RemotePlaygroundExtensionPoint extends ExtensionPointContract {
254
- actions: {
255
- warn: () => void;
256
- };
257
- customComponents: {
258
- ExampleCrmComponent: ComponentType<ExampleCrmComponentProps>;
259
- };
260
- }
261
-
262
- export interface ExtensionPoints {
263
- 'uie.playground.middle': RemotePlaygroundExtensionPoint;
264
- 'crm.record.tab': CrmMiddleExtensionPoint;
265
- 'crm.record.sidebar': CrmSidebarExtensionPoint;
266
- }
267
-
268
- //TODO(Randy): Delete once we have real custom components
269
- export interface ExampleCrmComponentProps {
270
- name: string;
271
- size: 'sm' | 'md' | 'lg';
272
- count: number;
273
- }
274
-
275
- export interface ExtensionPointApi<
276
- ExtensionPointName extends keyof ExtensionPoints
277
- > {
278
- context: Context;
279
- runServerlessFunction: ServerlessFuncRunner;
280
- actions: ExtensionPoints[ExtensionPointName]['actions'];
281
- customComponents: string[];
282
- }
283
-
284
- interface OpenIframeActionPayload {
285
- uri: string;
286
- height: number;
287
- width: number;
288
- associatedObjectProperties?: string[];
289
- }
290
-
291
- export interface LoadingSpinnerProps {
292
- label: string;
293
- showLabel?: boolean;
294
- size?: 'xs' | 'sm' | 'md';
295
- layout?: 'inline' | 'centered';
296
- grow?: boolean;
297
- }
@@ -1,20 +0,0 @@
1
- import type { RemoteComponentType } from '@remote-ui/core';
2
- import type { ReactComponentTypeFromRemoteComponentType } from '@remote-ui/react';
3
- import { createRemoteReactComponent } from '@remote-ui/react';
4
-
5
- export function createExtensionComponent<
6
- ComponentType extends string,
7
- Props = Record<string, never>,
8
- AllowedChildren extends RemoteComponentType<string, any> | boolean = true
9
- >(
10
- componentType:
11
- | ComponentType
12
- | RemoteComponentType<ComponentType, Props, AllowedChildren>
13
- ): RemoteComponentType<ComponentType, Props, AllowedChildren> &
14
- ReactComponentTypeFromRemoteComponentType<
15
- RemoteComponentType<ComponentType, Props, AllowedChildren>
16
- > {
17
- return createRemoteReactComponent<ComponentType, Props, AllowedChildren>(
18
- componentType
19
- );
20
- }