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

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.1",
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": "d9459af4e3027da7ae3fa9a9d91c48c1f612677b"
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;
@@ -21,6 +21,10 @@ export interface ButtonRowProps {
21
21
  disableDropdown?: boolean;
22
22
  }
23
23
 
24
+ export interface CardProps {
25
+ children: ReactNode;
26
+ }
27
+
24
28
  export interface DescriptionListItemProps {
25
29
  children: ReactNode;
26
30
  label: string;
@@ -70,7 +74,6 @@ export interface InputProps {
70
74
  placeholder?: string;
71
75
  error?: boolean;
72
76
  errorMessage?: string;
73
- visible?: boolean;
74
77
  onChange: (value: string) => void;
75
78
  onInput: (value: string) => void;
76
79
  }
@@ -78,7 +81,6 @@ export interface InputProps {
78
81
  export interface ProgressBarProps {
79
82
  title?: string;
80
83
  showPercentage?: boolean;
81
- type: 'progressBar';
82
84
  value?: number;
83
85
  valueMax?: number;
84
86
  valueDescription?: string;
@@ -169,7 +171,7 @@ export interface StatisticsProps {
169
171
  children: ReactNode;
170
172
  }
171
173
 
172
- interface ServerlessRunnerParams {
174
+ export interface ServerlessRunnerParams {
173
175
  name: string;
174
176
  payload: Record<string, unknown>;
175
177
  onError?: () => void;
@@ -209,5 +211,77 @@ export interface ExtensionCardContextData {
209
211
  appId: number | string;
210
212
  objectId: number | string;
211
213
  objectTypeId: string;
212
- location: string;
214
+ location: keyof ExtensionPoints;
215
+ }
216
+
217
+ export type ExtensionPointAction = (...args: any[]) => Promise<any> | void;
218
+
219
+ export interface ExtensionPointContract {
220
+ actions?: { [k: string]: ExtensionPointAction } | {};
221
+ customComponents: Record<string, ComponentType<any>>;
222
+ }
223
+ type AlertType = 'info' | 'warning' | 'success' | 'danger' | 'tip' | undefined;
224
+
225
+ export type AddAlertAction = (args: {
226
+ type?: AlertType;
227
+ message: string;
228
+ }) => void;
229
+
230
+ export type ReloadPageAction = () => void;
231
+
232
+ export type FetchCrmObjectPropertiesAction = (
233
+ properties: string[]
234
+ ) => Promise<{ name: string; value: string }[]>;
235
+
236
+ interface CrmMiddleExtensionPoint extends ExtensionPointContract {
237
+ actions: {
238
+ addAlert: AddAlertAction;
239
+ reloadPage: ReloadPageAction;
240
+ fetchCrmObjectProperties: FetchCrmObjectPropertiesAction;
241
+ openIframeModal?: (action: OpenIframeActionPayload) => void;
242
+ };
243
+ }
244
+
245
+ interface CrmSidebarExtensionPoint extends ExtensionPointContract {
246
+ actions: {
247
+ reloadPage: ReloadPageAction;
248
+ };
249
+ }
250
+
251
+ interface RemotePlaygroundExtensionPoint extends ExtensionPointContract {
252
+ actions: {
253
+ warn: () => void;
254
+ };
255
+ customComponents: {
256
+ ExampleCrmComponent: ComponentType<ExampleCrmComponentProps>;
257
+ };
258
+ }
259
+
260
+ export interface ExtensionPoints {
261
+ 'uie.playground.middle': RemotePlaygroundExtensionPoint;
262
+ 'crm.record.tab': CrmMiddleExtensionPoint;
263
+ 'crm.record.sidebar': CrmSidebarExtensionPoint;
264
+ }
265
+
266
+ //TODO(Randy): Delete once we have real custom components
267
+ export interface ExampleCrmComponentProps {
268
+ name: string;
269
+ size: 'sm' | 'md' | 'lg';
270
+ count: number;
271
+ }
272
+
273
+ export interface ExtensionPointApi<
274
+ ExtensionPointName extends keyof ExtensionPoints
275
+ > {
276
+ context: Context;
277
+ runServerlessFunction: ServerlessFuncRunner;
278
+ actions: ExtensionPoints[ExtensionPointName]['actions'];
279
+ customComponents: string[];
280
+ }
281
+
282
+ interface OpenIframeActionPayload {
283
+ uri: string;
284
+ height: number;
285
+ width: number;
286
+ associatedObjectProperties?: string[];
213
287
  }
@@ -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
+ }