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

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.
@@ -0,0 +1,11 @@
1
+ /* Hello! To create your first component, uncomment the code below and replace
2
+ * the entrie 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 {};
@@ -0,0 +1 @@
1
+ export {};
@@ -4,6 +4,7 @@ import type {
4
4
  AlertProps,
5
5
  ButtonProps,
6
6
  ButtonRowProps,
7
+ CardProps,
7
8
  DescriptionListProps,
8
9
  DescriptionListItemProps,
9
10
  FormProps,
@@ -21,11 +22,6 @@ import type {
21
22
  StatisticsTrendProps,
22
23
  } from './types';
23
24
 
24
- interface CardProps {
25
- style: React.CSSProperties;
26
- title: string;
27
- }
28
-
29
25
  const Alert = createRemoteReactComponent<'Alert', AlertProps>('Alert');
30
26
  const Button = createRemoteReactComponent<'Button', ButtonProps>('Button');
31
27
  const ButtonRow = createRemoteReactComponent<'ButtonRow', ButtonRowProps>(
package/hubspot.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /* eslint-disable hubspot-dev/no-confusing-browser-globals */
2
2
 
3
3
  import { createRoot, RemoteRoot } from '@remote-ui/react';
4
- import { ReactElement } from 'react';
5
- import { Context } from './types';
4
+ import { ReactElement, isValidElement } from 'react';
5
+ import { ExtensionPoints, ExtensionPointApi } from './types';
6
6
 
7
7
  export const hubspot = {
8
8
  extend: render,
@@ -10,11 +10,23 @@ export const hubspot = {
10
10
 
11
11
  const extend = (...args) => (self as any).extend(...args);
12
12
 
13
- function render(
14
- renderCallback: (api: { context: Context }) => ReactElement<any>
13
+ function render<ExtensionPointName extends keyof ExtensionPoints>(
14
+ renderCallback: (
15
+ api: ExtensionPointApi<ExtensionPointName>
16
+ ) => ReactElement<any>
15
17
  ) {
16
- return extend((root: RemoteRoot, api: { context: Context }) => {
17
- createRoot(root).render(renderCallback(api));
18
- root.mount();
19
- });
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
+ );
20
32
  }
package/index.ts CHANGED
@@ -19,6 +19,6 @@ export {
19
19
  Tag,
20
20
  Text,
21
21
  Tile,
22
- } from './components';
22
+ } from './coreComponents';
23
23
 
24
24
  export { hubspot } from './hubspot';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/ui-extensions",
3
- "version": "0.0.1-prealpha.0",
3
+ "version": "0.0.1-prealpha.2",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -13,5 +13,5 @@
13
13
  "@remote-ui/react": "^5.0.0",
14
14
  "react": "^18.2.0"
15
15
  },
16
- "gitHead": "961d6ecb59b6cadfd4c19dea2d935df1a53c4fd8"
16
+ "gitHead": "236831146a8ce8906c080b3f555a8ff50d6f12da"
17
17
  }
package/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // Do not manually update this file, changes will be overridden from ui-extensions-remote-renderer/static/js/types.ts
2
- import { ReactNode } from 'react';
2
+ import { ReactNode, ComponentType } from 'react';
3
3
 
4
4
  export interface AlertProps {
5
5
  title: string;
@@ -14,6 +14,7 @@ export interface ButtonProps {
14
14
  href?: string;
15
15
  disabled?: boolean;
16
16
  variant?: 'primary' | 'secondary' | 'destructive';
17
+ type?: 'button' | 'reset' | 'submit';
17
18
  }
18
19
 
19
20
  export interface ButtonRowProps {
@@ -21,6 +22,10 @@ export interface ButtonRowProps {
21
22
  disableDropdown?: boolean;
22
23
  }
23
24
 
25
+ export interface CardProps {
26
+ children: ReactNode;
27
+ }
28
+
24
29
  export interface DescriptionListItemProps {
25
30
  children: ReactNode;
26
31
  label: string;
@@ -43,7 +48,8 @@ export interface DividerProps {
43
48
 
44
49
  export interface FormProps {
45
50
  children: ReactNode;
46
- onSubmit: () => void;
51
+ onSubmit?: () => void;
52
+ preventDefault?: boolean;
47
53
  }
48
54
 
49
55
  export interface HeadingProps {
@@ -70,7 +76,6 @@ export interface InputProps {
70
76
  placeholder?: string;
71
77
  error?: boolean;
72
78
  errorMessage?: string;
73
- visible?: boolean;
74
79
  onChange: (value: string) => void;
75
80
  onInput: (value: string) => void;
76
81
  }
@@ -78,7 +83,6 @@ export interface InputProps {
78
83
  export interface ProgressBarProps {
79
84
  title?: string;
80
85
  showPercentage?: boolean;
81
- type: 'progressBar';
82
86
  value?: number;
83
87
  valueMax?: number;
84
88
  valueDescription?: string;
@@ -169,7 +173,7 @@ export interface StatisticsProps {
169
173
  children: ReactNode;
170
174
  }
171
175
 
172
- interface ServerlessRunnerParams {
176
+ export interface ServerlessRunnerParams {
173
177
  name: string;
174
178
  payload: Record<string, unknown>;
175
179
  onError?: () => void;
@@ -209,5 +213,77 @@ export interface ExtensionCardContextData {
209
213
  appId: number | string;
210
214
  objectId: number | string;
211
215
  objectTypeId: string;
212
- location: 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[];
213
289
  }
@@ -0,0 +1,20 @@
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
+ }