@teambit/compositions 1.0.107 → 1.0.108

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/composition.ts ADDED
@@ -0,0 +1,60 @@
1
+ import { humanizeCompositionId } from '@teambit/compositions.model.composition-id';
2
+
3
+ export type CompositionProps = {
4
+ identifier: string;
5
+ filepath?: string;
6
+ displayName?: string;
7
+ };
8
+
9
+ export type CompositionBrowserMetadata = {
10
+ displayName?: string;
11
+ identifier: string;
12
+ };
13
+
14
+ export type CompositionBrowserMetadataObject = {
15
+ compositions: CompositionBrowserMetadata[];
16
+ };
17
+
18
+ export class Composition {
19
+ constructor(
20
+ /**
21
+ * identifier of the composition
22
+ */
23
+ readonly identifier: string,
24
+
25
+ /**
26
+ * file path in which the composition is contained.
27
+ */
28
+ readonly filepath?: string,
29
+
30
+ /**
31
+ * set explicit display name
32
+ */
33
+ private _displayName?: string
34
+ ) {}
35
+
36
+ get displayName() {
37
+ return this._displayName || humanizeCompositionId(this.identifier);
38
+ }
39
+
40
+ toObject() {
41
+ return {
42
+ identifier: this.identifier,
43
+ filepath: this.filepath,
44
+ displayName: this._displayName,
45
+ };
46
+ }
47
+
48
+ toBrowserMetaDataObject(): CompositionBrowserMetadata {
49
+ return {
50
+ identifier: this.identifier,
51
+ displayName: this._displayName,
52
+ };
53
+ }
54
+
55
+ static fromArray(compositions: CompositionProps[]): Composition[] {
56
+ return compositions.map((composition) => {
57
+ return new Composition(composition.identifier, composition.filepath, composition.displayName);
58
+ });
59
+ }
60
+ }
@@ -0,0 +1,9 @@
1
+ import { Aspect } from '@teambit/harmony';
2
+
3
+ export const CompositionsAspect = Aspect.create({
4
+ id: 'teambit.compositions/compositions',
5
+ dependencies: [],
6
+ defaultConfig: {},
7
+ });
8
+
9
+ export default CompositionsAspect;
@@ -0,0 +1,32 @@
1
+ import { Component } from '@teambit/component';
2
+ import { Schema } from '@teambit/graphql';
3
+ import gql from 'graphql-tag';
4
+
5
+ import { CompositionsMain } from './compositions.main.runtime';
6
+
7
+ export function compositionsSchema(compositions: CompositionsMain): Schema {
8
+ return {
9
+ typeDefs: gql`
10
+ extend type Component {
11
+ compositions: [Composition]
12
+ }
13
+
14
+ type Subscription {
15
+ compositionAdded: Composition
16
+ }
17
+
18
+ type Composition {
19
+ filepath: String
20
+ identifier: String
21
+ displayName: String
22
+ }
23
+ `,
24
+ resolvers: {
25
+ Component: {
26
+ compositions: (component: Component) => {
27
+ return compositions.getCompositions(component);
28
+ },
29
+ },
30
+ },
31
+ };
32
+ }
@@ -0,0 +1,214 @@
1
+ import { MainRuntime } from '@teambit/cli';
2
+ import { AspectData, Component, ComponentMap, IComponent } from '@teambit/component';
3
+ import ScopeAspect, { ScopeMain } from '@teambit/scope';
4
+ import { DevFilesAspect, DevFilesMain } from '@teambit/dev-files';
5
+ import EnvsAspect, { EnvsMain } from '@teambit/envs';
6
+ import { GraphqlAspect, GraphqlMain } from '@teambit/graphql';
7
+ import { ComponentLoadOptions } from '@teambit/legacy/dist/consumer/component/component-loader';
8
+ import { AbstractVinyl } from '@teambit/legacy/dist/consumer/component/sources';
9
+ import { PreviewAspect, PreviewMain } from '@teambit/preview';
10
+ import { SchemaAspect, SchemaMain } from '@teambit/schema';
11
+ import { matchPatterns, splitPatterns } from '@teambit/toolbox.path.match-patterns';
12
+ import { Workspace, WorkspaceAspect } from '@teambit/workspace';
13
+ import { join } from 'path';
14
+ import { Composition } from './composition';
15
+ import { CompositionsAspect } from './compositions.aspect';
16
+ import { compositionsSchema } from './compositions.graphql';
17
+ import { CompositionPreviewDefinition } from './compositions.preview-definition';
18
+
19
+ export type CompositionsConfig = {
20
+ /**
21
+ * glob pattern to detect composition files. This includes all related files, like styles and jsons.
22
+ * @example ['/*.composition?(s).*']
23
+ */
24
+ compositionFilePattern: string[];
25
+ /**
26
+ * glob pattern to select Preview files. this will only include files matched by compositionFilePattern.
27
+ * @example ['*.{t,j}s', '*.{t,j}sx']
28
+ */
29
+ compositionPreviewFilePattern: string[];
30
+ };
31
+
32
+ /**
33
+ * the component documentation extension.
34
+ */
35
+ export class CompositionsMain {
36
+ constructor(
37
+ /**
38
+ * Glob pattern to select all composition files
39
+ */
40
+ private compositionFilePattern: string[],
41
+
42
+ /**
43
+ * Glob pattern to select composition preview files
44
+ */
45
+ private previewFilePattern: string[],
46
+
47
+ /**
48
+ * envs extension.
49
+ */
50
+ private preview: PreviewMain,
51
+
52
+ /**
53
+ * workspace extension.
54
+ */
55
+ private workspace: Workspace,
56
+
57
+ /**
58
+ * schema extension.
59
+ */
60
+ private schema: SchemaMain,
61
+
62
+ private devFiles: DevFilesMain,
63
+
64
+ private envs: EnvsMain
65
+ ) {}
66
+
67
+ /**
68
+ * returns an array of doc file paths for a set of components.
69
+ */
70
+ getPreviewFiles(components: Component[]): ComponentMap<AbstractVinyl[]> {
71
+ return ComponentMap.as<AbstractVinyl[]>(components, (component) => {
72
+ // this includes non executables, like `button.compositions.module.scss` or `presets.compositions.json`
73
+ const compositionFiles = component.state.filesystem.byGlob(this.compositionFilePattern);
74
+
75
+ // select only relevant preview files (.tsx, etc)
76
+ const previewFiles = new Set(
77
+ component.state.filesystem.byGlob(this.previewFilePattern).map((file) => file.relative)
78
+ );
79
+ const files = compositionFiles.filter((file) => previewFiles.has(file.relative));
80
+
81
+ return files;
82
+ });
83
+ }
84
+
85
+ /**
86
+ * checks if a file matches the composition file pattern.
87
+ */
88
+ isCompositionFile(filePath: string): boolean {
89
+ const { includePatterns, excludePatterns } = splitPatterns(this.compositionFilePattern);
90
+ return matchPatterns(filePath, includePatterns, excludePatterns);
91
+ }
92
+
93
+ /**
94
+ * get component compositions.
95
+ */
96
+ getCompositions(component: IComponent): Composition[] {
97
+ const entry = component.get(CompositionsAspect.id);
98
+ if (!entry) return [];
99
+ const compositions = entry.data.compositions;
100
+ if (!compositions) return [];
101
+
102
+ return Composition.fromArray(compositions);
103
+ }
104
+
105
+ /**
106
+ * read composition from the component source code.
107
+ */
108
+ readCompositions(component: Component): Composition[] {
109
+ const maybeFiles = this.getPreviewFiles([component]).byComponent(component);
110
+
111
+ if (!maybeFiles) return [];
112
+ const [, files] = maybeFiles;
113
+ return files.map((file) => this.computeCompositions(component, file)).flat();
114
+ }
115
+
116
+ getCompositionFilePattern() {
117
+ return this.compositionFilePattern;
118
+ }
119
+
120
+ getComponentDevPatterns(component: Component) {
121
+ const env = this.envs.calculateEnv(component, { skipWarnings: !!this.workspace?.inInstallContext }).env;
122
+ const componentEnvCompositionsDevPatterns: string[] = env.getCompositionsDevPatterns
123
+ ? env.getCompositionsDevPatterns(component)
124
+ : [];
125
+ const componentPatterns = componentEnvCompositionsDevPatterns.concat(this.getCompositionFilePattern());
126
+ return { name: 'compositions', pattern: componentPatterns };
127
+ }
128
+
129
+ getDevPatternToRegister() {
130
+ return this.getComponentDevPatterns.bind(this);
131
+ }
132
+
133
+ async onComponentLoad(component: Component, loadOpts?: ComponentLoadOptions): Promise<AspectData | undefined> {
134
+ if (loadOpts?.loadCompositions === false) return undefined;
135
+ const compositions = this.readCompositions(component);
136
+ return {
137
+ compositions: compositions.map((composition) => composition.toObject()),
138
+ };
139
+ }
140
+
141
+ private computeCompositions(component: Component, file: AbstractVinyl): Composition[] {
142
+ // :TODO hacked for a specific file extension now until david will take care in the compiler.
143
+ const pathArray = file.path.split('.');
144
+ pathArray[pathArray.length - 1] = 'js';
145
+
146
+ const modulePath = this.workspace ? join(this.workspace.componentDir(component.id), file.relative) : file.relative;
147
+ const exports = this.schema.parseModule(modulePath, file.contents.toString());
148
+ return exports.map((exportModel) => {
149
+ const displayName = exportModel.staticProperties?.get('compositionName');
150
+
151
+ return new Composition(
152
+ exportModel.identifier,
153
+ file.relative,
154
+ typeof displayName === 'string' ? displayName : undefined
155
+ );
156
+ });
157
+ }
158
+
159
+ static defaultConfig: CompositionsConfig = {
160
+ compositionFilePattern: ['**/*.composition?(s).*'],
161
+ compositionPreviewFilePattern: ['**/*.{t,j}s?(x)'],
162
+ };
163
+
164
+ static runtime = MainRuntime;
165
+ static dependencies = [
166
+ PreviewAspect,
167
+ GraphqlAspect,
168
+ WorkspaceAspect,
169
+ SchemaAspect,
170
+ DevFilesAspect,
171
+ EnvsAspect,
172
+ ScopeAspect,
173
+ ];
174
+
175
+ static async provider(
176
+ [preview, graphql, workspace, schema, devFiles, envs, scope]: [
177
+ PreviewMain,
178
+ GraphqlMain,
179
+ Workspace,
180
+ SchemaMain,
181
+ DevFilesMain,
182
+ EnvsMain,
183
+ ScopeMain
184
+ ],
185
+ config: CompositionsConfig
186
+ ) {
187
+ const compositions = new CompositionsMain(
188
+ config.compositionFilePattern,
189
+ config.compositionPreviewFilePattern,
190
+ preview,
191
+ workspace,
192
+ schema,
193
+ devFiles,
194
+ envs
195
+ );
196
+
197
+ // TODO: use the docs implementation to allow component specific pattern
198
+ devFiles.registerDevPattern(compositions.getDevPatternToRegister());
199
+
200
+ graphql.register(compositionsSchema(compositions));
201
+ preview.registerDefinition(new CompositionPreviewDefinition(compositions));
202
+
203
+ if (workspace) {
204
+ workspace.registerOnComponentLoad(compositions.onComponentLoad.bind(compositions));
205
+ }
206
+ if (scope) {
207
+ scope.registerOnCompAspectReCalc(compositions.onComponentLoad.bind(compositions));
208
+ }
209
+
210
+ return compositions;
211
+ }
212
+ }
213
+
214
+ CompositionsAspect.addRuntime(CompositionsMain);
@@ -0,0 +1,40 @@
1
+ import { Component, ComponentMap } from '@teambit/component';
2
+ import type { ExecutionContext, Environment } from '@teambit/envs';
3
+ import { PreviewDefinition } from '@teambit/preview';
4
+ import { isFunction } from 'lodash';
5
+ import { AbstractVinyl } from '@teambit/legacy/dist/consumer/component/sources';
6
+
7
+ import { CompositionsMain } from './compositions.main.runtime';
8
+ import { CompositionBrowserMetadataObject } from './composition';
9
+
10
+ export class CompositionPreviewDefinition implements PreviewDefinition {
11
+ readonly prefix = 'compositions';
12
+ readonly includePeers = true;
13
+
14
+ constructor(private compositions: CompositionsMain) {}
15
+
16
+ async renderTemplatePath(context: ExecutionContext): Promise<string | undefined> {
17
+ return this.renderTemplatePathByEnv(context.env);
18
+ }
19
+
20
+ async renderTemplatePathByEnv(env: Environment): Promise<string | undefined> {
21
+ if (env.getMounter && isFunction(env.getMounter)) {
22
+ return env.getMounter();
23
+ }
24
+ return undefined;
25
+ }
26
+
27
+ async getModuleMap(components: Component[]): Promise<ComponentMap<AbstractVinyl[]>> {
28
+ const map = this.compositions.getPreviewFiles(components);
29
+ return map;
30
+ }
31
+
32
+ async getMetadata(component: Component): Promise<CompositionBrowserMetadataObject> {
33
+ const compositions = this.compositions
34
+ .getCompositions(component)
35
+ .map((composition) => ({ displayName: composition.displayName, identifier: composition.identifier }));
36
+ return {
37
+ compositions,
38
+ };
39
+ }
40
+ }
@@ -0,0 +1,93 @@
1
+ import { ComponentID } from '@teambit/component-id';
2
+ import {
3
+ PreviewAspect,
4
+ PreviewPreview,
5
+ RenderingContext,
6
+ PreviewRuntime,
7
+ PreviewModule,
8
+ ModuleFile,
9
+ } from '@teambit/preview';
10
+ import head from 'lodash.head';
11
+ import { CompositionBrowserMetadataObject } from './composition';
12
+
13
+ import { CompositionsAspect } from './compositions.aspect';
14
+
15
+ export class CompositionsPreview {
16
+ constructor(
17
+ /**
18
+ * preview extension.
19
+ */
20
+ private preview: PreviewPreview
21
+ ) {}
22
+
23
+ render(componentId: ComponentID, envId: string, modules: PreviewModule, otherPreviewDefs, context: RenderingContext) {
24
+ if (!modules.componentMap[componentId.fullName]) return;
25
+
26
+ const compositions = this.selectPreviewModel(componentId.fullName, modules);
27
+ const metadata = this.getMetadata(componentId.fullName, modules);
28
+ const active = this.getActiveComposition(compositions, metadata);
29
+
30
+ const mainModule = modules.modulesMap[envId] || modules.modulesMap.default;
31
+ const defaultExports = mainModule.default;
32
+
33
+ defaultExports(active, context);
34
+ }
35
+
36
+ /** gets relevant information for this preview to render */
37
+ selectPreviewModel(componentFullName: string, previewModule: PreviewModule) {
38
+ const files = previewModule.componentMap[componentFullName] || [];
39
+
40
+ // allow compositions to come from many files. It is assumed they will have unique named
41
+ const combined = Object.assign({}, ...files);
42
+ return combined;
43
+ }
44
+
45
+ getMetadata(componentFullName: string, previewModule: PreviewModule): CompositionBrowserMetadataObject | undefined {
46
+ const metadata = previewModule?.componentMapMetadata
47
+ ? previewModule.componentMapMetadata[componentFullName]
48
+ : undefined;
49
+ if (metadata) {
50
+ return metadata as CompositionBrowserMetadataObject;
51
+ }
52
+ return undefined;
53
+ }
54
+
55
+ private getActiveComposition(module: ModuleFile, metadata?: CompositionBrowserMetadataObject) {
56
+ const firstQueryParam = window.location.hash.split('&')[1];
57
+ const query = this.preview.getQuery();
58
+ const compositionId = this.preview.getParam(query, 'name') || firstQueryParam;
59
+
60
+ if (compositionId && module[compositionId]) {
61
+ return module[compositionId];
62
+ }
63
+
64
+ if (metadata && metadata.compositions) {
65
+ const first = head(metadata.compositions);
66
+ const firstId = first?.identifier;
67
+ if (firstId && module[firstId]) {
68
+ return module[firstId];
69
+ }
70
+ }
71
+
72
+ const first = head(Object.values(module));
73
+ return first;
74
+ }
75
+
76
+ static runtime = PreviewRuntime;
77
+
78
+ static dependencies = [PreviewAspect];
79
+
80
+ static async provider([preview]: [PreviewPreview]) {
81
+ const compPreview = new CompositionsPreview(preview);
82
+ preview.registerPreview({
83
+ name: 'compositions',
84
+ render: compPreview.render.bind(compPreview),
85
+ selectPreviewModel: compPreview.selectPreviewModel.bind(compPreview),
86
+ default: true,
87
+ });
88
+
89
+ return compPreview;
90
+ }
91
+ }
92
+
93
+ CompositionsAspect.addRuntime(CompositionsPreview);
@@ -1,13 +1,13 @@
1
- export declare type CompositionProps = {
1
+ export type CompositionProps = {
2
2
  identifier: string;
3
3
  filepath?: string;
4
4
  displayName?: string;
5
5
  };
6
- export declare type CompositionBrowserMetadata = {
6
+ export type CompositionBrowserMetadata = {
7
7
  displayName?: string;
8
8
  identifier: string;
9
9
  };
10
- export declare type CompositionBrowserMetadataObject = {
10
+ export type CompositionBrowserMetadataObject = {
11
11
  compositions: CompositionBrowserMetadata[];
12
12
  };
13
13
  export declare class Composition {
@@ -18,7 +18,7 @@ export declare class Composition {
18
18
  /**
19
19
  * file path in which the composition is contained.
20
20
  */
21
- readonly filepath?: string | undefined;
21
+ readonly filepath?: string;
22
22
  /**
23
23
  * set explicit display name
24
24
  */
@@ -31,16 +31,16 @@ export declare class Composition {
31
31
  /**
32
32
  * file path in which the composition is contained.
33
33
  */
34
- filepath?: string | undefined,
34
+ filepath?: string,
35
35
  /**
36
36
  * set explicit display name
37
37
  */
38
- _displayName?: string | undefined);
38
+ _displayName?: string);
39
39
  get displayName(): string;
40
40
  toObject(): {
41
41
  identifier: string;
42
- filepath: string | undefined;
43
- displayName: string | undefined;
42
+ filepath: string;
43
+ displayName: string;
44
44
  };
45
45
  toBrowserMetaDataObject(): CompositionBrowserMetadata;
46
46
  static fromArray(compositions: CompositionProps[]): Composition[];
@@ -1,7 +1,7 @@
1
+ /// <reference types="react" />
1
2
  import { Section } from '@teambit/component';
2
- import React from 'react';
3
3
  import type { CompositionsUI, CompositionsMenuSlot, EmptyStateSlot } from './compositions.ui.runtime';
4
- declare type Options = {
4
+ type Options = {
5
5
  menuBarWidgetSlot: CompositionsMenuSlot;
6
6
  };
7
7
  export declare class CompositionsSection implements Section {
@@ -22,7 +22,7 @@ export declare class CompositionsSection implements Section {
22
22
  };
23
23
  route: {
24
24
  path: string;
25
- element: React.JSX.Element;
25
+ element: JSX.Element;
26
26
  };
27
27
  order: number;
28
28
  }
@@ -1,2 +1,2 @@
1
- import React from 'react';
2
- export declare const Logo: () => React.JSX.Element;
1
+ /// <reference types="react" />
2
+ export declare const Logo: () => JSX.Element;
@@ -1,22 +1,22 @@
1
- import React, { ReactNode } from 'react';
1
+ import { ReactNode } from 'react';
2
2
  import { ComponentModel } from '@teambit/component';
3
3
  import { EmptyStateSlot } from './compositions.ui.runtime';
4
4
  import { Composition } from './composition';
5
5
  import type { CompositionsMenuSlot } from './compositions.ui.runtime';
6
6
  import { ComponentCompositionProps } from './ui/composition-preview';
7
- export declare type MenuBarWidget = {
7
+ export type MenuBarWidget = {
8
8
  location: 'start' | 'end';
9
9
  content: ReactNode;
10
10
  };
11
- export declare type CompositionsProp = {
11
+ export type CompositionsProp = {
12
12
  menuBarWidgets?: CompositionsMenuSlot;
13
13
  emptyState?: EmptyStateSlot;
14
14
  };
15
- export declare function Compositions({ menuBarWidgets, emptyState }: CompositionsProp): React.JSX.Element;
16
- export declare type CompositionContentProps = {
15
+ export declare function Compositions({ menuBarWidgets, emptyState }: CompositionsProp): JSX.Element;
16
+ export type CompositionContentProps = {
17
17
  component: ComponentModel;
18
18
  selected?: Composition;
19
19
  queryParams?: string | string[];
20
20
  emptyState?: EmptyStateSlot;
21
21
  } & ComponentCompositionProps;
22
- export declare function CompositionContent({ component, selected, queryParams, emptyState, ...componentCompositionProps }: CompositionContentProps): React.JSX.Element;
22
+ export declare function CompositionContent({ component, selected, queryParams, emptyState, ...componentCompositionProps }: CompositionContentProps): JSX.Element;
@@ -205,7 +205,6 @@ function Compositions({
205
205
  menuBarWidgets,
206
206
  emptyState
207
207
  }) {
208
- var _component$preview, _component$preview2, _component$preview3;
209
208
  const component = (0, _react().useContext)(_component().ComponentContext);
210
209
  // const [searchParams, setSearchParams] = useSearchParams();
211
210
  const params = (0, _reactRouterDom().useParams)();
@@ -232,9 +231,9 @@ function Compositions({
232
231
  const [isSidebarOpen, setSidebarOpenness] = (0, _react().useState)(showSidebar);
233
232
  const sidebarOpenness = isSidebarOpen ? _baseUiSurfacesSplitPane().Layout.row : _baseUiSurfacesSplitPane().Layout.left;
234
233
  const compositionUrl = (0, _previewUi().toPreviewUrl)(component, 'compositions');
235
- const isScaling = component === null || component === void 0 || (_component$preview = component.preview) === null || _component$preview === void 0 ? void 0 : _component$preview.isScaling;
236
- const includesEnvTemplates = component === null || component === void 0 || (_component$preview2 = component.preview) === null || _component$preview2 === void 0 ? void 0 : _component$preview2.includesEnvTemplate;
237
- const compositionIdentifierParam = isScaling && includesEnvTemplates === false ? `name=${currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.identifier}` : currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.identifier;
234
+ const isScaling = component?.preview?.isScaling;
235
+ const includesEnvTemplates = component?.preview?.includesEnvTemplate;
236
+ const compositionIdentifierParam = isScaling && includesEnvTemplates === false ? `name=${currentComposition?.identifier}` : currentComposition?.identifier;
238
237
  const currentCompositionFullUrl = (0, _previewUi().toPreviewUrl)(component, 'compositions', compositionIdentifierParam);
239
238
  const [compositionParams, setCompositionParams] = (0, _react().useState)({});
240
239
  const queryParams = (0, _react().useMemo)(() => _queryString().default.stringify(compositionParams), [compositionParams]);
@@ -285,7 +284,7 @@ function Compositions({
285
284
  className: _compositionsModule().default.tabContent
286
285
  }, /*#__PURE__*/_react().default.createElement(_compositionsPanel().CompositionsPanel, {
287
286
  isScaling: isScaling,
288
- includesEnvTemplate: (_component$preview3 = component.preview) === null || _component$preview3 === void 0 ? void 0 : _component$preview3.includesEnvTemplate,
287
+ includesEnvTemplate: component.preview?.includesEnvTemplate,
289
288
  onSelectComposition: composition => {
290
289
  if (!currentComposition || !location) return;
291
290
  if (location.pathname.includes(currentComposition.identifier.toLowerCase())) {
@@ -312,7 +311,6 @@ function Compositions({
312
311
  }) : /*#__PURE__*/_react().default.createElement("div", null)))))));
313
312
  }
314
313
  function CompositionContent(_ref) {
315
- var _component$environmen;
316
314
  let {
317
315
  component,
318
316
  selected,
@@ -320,8 +318,8 @@ function CompositionContent(_ref) {
320
318
  emptyState
321
319
  } = _ref,
322
320
  componentCompositionProps = _objectWithoutProperties(_ref, _excluded);
323
- const env = (_component$environmen = component.environment) === null || _component$environmen === void 0 ? void 0 : _component$environmen.id;
324
- const EmptyStateTemplate = emptyState === null || emptyState === void 0 ? void 0 : emptyState.get(env || ''); // || defaultTemplate;
321
+ const env = component.environment?.id;
322
+ const EmptyStateTemplate = emptyState?.get(env || ''); // || defaultTemplate;
325
323
 
326
324
  if (component.compositions.length === 0 && component.host === 'teambit.workspace/workspace' && EmptyStateTemplate) {
327
325
  return /*#__PURE__*/_react().default.createElement("div", {
@@ -336,12 +334,12 @@ function CompositionContent(_ref) {
336
334
  title: "There are no compositions for this Component. Learn how to add compositions:"
337
335
  }, /*#__PURE__*/_react().default.createElement(_mdxUi().MDXLayout, null, /*#__PURE__*/_react().default.createElement(EmptyStateTemplate, null)))));
338
336
  }
339
- if ((component === null || component === void 0 ? void 0 : component.buildStatus) === 'pending' && (component === null || component === void 0 ? void 0 : component.host) === 'teambit.scope/scope') return /*#__PURE__*/_react().default.createElement(_designUiSurfaces().StatusMessageCard, {
337
+ if (component?.buildStatus === 'pending' && component?.host === 'teambit.scope/scope') return /*#__PURE__*/_react().default.createElement(_designUiSurfaces().StatusMessageCard, {
340
338
  className: _compositionsModule().default.buildStatusMessage,
341
339
  status: "PROCESSING",
342
340
  title: "component preview pending"
343
341
  }, "this might take some time");
344
- if ((component === null || component === void 0 ? void 0 : component.buildStatus) === 'failed' && (component === null || component === void 0 ? void 0 : component.host) === 'teambit.scope/scope') return /*#__PURE__*/_react().default.createElement(_designUiSurfaces().StatusMessageCard, {
342
+ if (component?.buildStatus === 'failed' && component?.host === 'teambit.scope/scope') return /*#__PURE__*/_react().default.createElement(_designUiSurfaces().StatusMessageCard, {
345
343
  className: _compositionsModule().default.buildStatusMessage,
346
344
  status: "FAILURE",
347
345
  title: "failed to get component preview "