@herdingbits/trailhead-cloudscape 0.0.12 → 0.0.15

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
@@ -37,7 +37,7 @@ import '@herdingbits/trailhead-cloudscape/shell.css';
37
37
 
38
38
  const shell = new Trailhead({
39
39
  adapter: new CloudScapeAdapter(),
40
- basePath: '/app',
40
+ appBasePath: '/app',
41
41
  apiUrl: 'https://api.example.com'
42
42
  });
43
43
 
@@ -45,6 +45,15 @@ const root = createRoot(document.getElementById('app')!);
45
45
  root.render(<ShellApp shell={shell} />);
46
46
  ```
47
47
 
48
+ To load the CloudScape global styles from a CDN instead of bundling via npm import, pass `cloudscapeUrl` to the adapter (and remove the `@cloudscape-design/global-styles/index.css` import from your entry point):
49
+
50
+ ```typescript
51
+ const shell = new Trailhead({
52
+ adapter: new CloudScapeAdapter({ cloudscapeUrl: 'https://unpkg.com/@cloudscape-design/global-styles@1.0.0/index.css' }),
53
+ appBasePath: '/app',
54
+ });
55
+ ```
56
+
48
57
  ## What's Included
49
58
 
50
59
  - **CloudScapeAdapter** - Implements the Trailhead adapter interface
package/dist/adapter.d.ts CHANGED
@@ -3,11 +3,16 @@
3
3
  * Uses CloudScape Flashbar, Modal, and Spinner components
4
4
  */
5
5
  import type { DesignSystemAdapter, FeedbackAdapter } from '@herdingbits/trailhead-types/adapters';
6
+ export interface CloudScapeAdapterConfig {
7
+ /** URL for the CloudScape global-styles CSS. If provided, injected dynamically instead of requiring a hardcoded HTML link tag. */
8
+ cloudscapeUrl?: string;
9
+ }
6
10
  export declare class CloudScapeAdapter implements DesignSystemAdapter {
7
11
  name: string;
8
12
  version: string;
9
13
  feedback: FeedbackAdapter;
10
- constructor();
11
- init(basePath: string): Promise<void>;
14
+ private readonly config?;
15
+ constructor(config?: CloudScapeAdapterConfig);
16
+ init(shellUrl: string): Promise<void>;
12
17
  }
13
18
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAA4C,MAAM,uCAAuC,CAAC;AAyE5I,qBAAa,iBAAkB,YAAW,mBAAmB;IAC3D,IAAI,SAAgB;IACpB,OAAO,SAAW;IAClB,QAAQ,EAAE,eAAe,CAAC;;IAMpB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG5C"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAA4C,MAAM,uCAAuC,CAAC;AAyE5I,MAAM,WAAW,uBAAuB;IACtC,kIAAkI;IAClI,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,iBAAkB,YAAW,mBAAmB;IAC3D,IAAI,SAAgB;IACpB,OAAO,SAAW;IAClB,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAA0B;gBAEtC,MAAM,CAAC,EAAE,uBAAuB;IAKtC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ5C"}
package/dist/adapter.js CHANGED
@@ -52,12 +52,18 @@ class CloudScapeFeedbackAdapter {
52
52
  }
53
53
  }
54
54
  export class CloudScapeAdapter {
55
- constructor() {
55
+ constructor(config) {
56
56
  this.name = 'cloudscape';
57
57
  this.version = '3.0.0';
58
+ this.config = config;
58
59
  this.feedback = new CloudScapeFeedbackAdapter();
59
60
  }
60
- async init(basePath) {
61
- // CloudScape styles loaded via global-styles package
61
+ async init(shellUrl) {
62
+ if (this.config?.cloudscapeUrl) {
63
+ const link = document.createElement('link');
64
+ link.rel = 'stylesheet';
65
+ link.href = this.config.cloudscapeUrl;
66
+ document.head.appendChild(link);
67
+ }
62
68
  }
63
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shell-app.d.ts","sourceRoot":"","sources":["../src/shell-app.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,UAAU,aAAa;IACrB,KAAK,EAAE,SAAS,CAAC;CAClB;AAiBD,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,aAAa,2CAiNhD"}
1
+ {"version":3,"file":"shell-app.d.ts","sourceRoot":"","sources":["../src/shell-app.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,UAAU,aAAa;IACrB,KAAK,EAAE,SAAS,CAAC;CAClB;AAiBD,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,aAAa,2CAmNhD"}
package/dist/shell-app.js CHANGED
@@ -21,8 +21,8 @@ export function ShellApp({ shell }) {
21
21
  // Get current path without basePath
22
22
  const getCurrentPath = () => {
23
23
  let path = window.location.pathname;
24
- if (shell.basePath && path.startsWith(shell.basePath)) {
25
- path = path.substring(shell.basePath.length) || '/';
24
+ if (shell.appBasePath && path.startsWith(shell.appBasePath)) {
25
+ path = path.substring(shell.appBasePath.length) || '/';
26
26
  }
27
27
  return path;
28
28
  };
@@ -72,7 +72,7 @@ export function ShellApp({ shell }) {
72
72
  const handleRoute = (path) => {
73
73
  // Normalize path by removing trailing slash for matching
74
74
  const normalizedPath = path.endsWith('/') && path !== '/' ? path.slice(0, -1) : path;
75
- const route = navigation.find(item => item.path === normalizedPath);
75
+ const route = navigation.find(item => normalizedPath.startsWith(item.path));
76
76
  if (route && contentRef.current) {
77
77
  loadApp(route.app, route.path);
78
78
  }
@@ -81,9 +81,10 @@ export function ShellApp({ shell }) {
81
81
  if (!contentRef.current)
82
82
  return;
83
83
  contentRef.current.innerHTML = '<div>Loading...</div>';
84
+ const appBasePath = shell.appBasePath + appPath;
84
85
  try {
85
- const pluginUrl = `${shell.basePath}${appPath}/app.js`;
86
- const pluginCss = `${shell.basePath}${appPath}/${appName}.css`;
86
+ const pluginUrl = `${shell.appBasePath}${appPath}/app.js`;
87
+ const pluginCss = `${shell.appBasePath}${appPath}/${appName}.css`;
87
88
  // Load CSS
88
89
  const link = document.createElement("link");
89
90
  link.rel = "stylesheet";
@@ -96,7 +97,7 @@ export function ShellApp({ shell }) {
96
97
  script.onload = () => {
97
98
  contentRef.current.innerHTML = "";
98
99
  if (window.AppMount) {
99
- window.AppMount(contentRef.current);
100
+ window.AppMount(contentRef.current, appBasePath);
100
101
  }
101
102
  };
102
103
  script.onerror = () => {
@@ -147,5 +148,5 @@ export function ShellApp({ shell }) {
147
148
  padding: '24px',
148
149
  borderRadius: '8px',
149
150
  textAlign: 'center',
150
- }, children: [_jsx(Spinner, { size: "large" }), _jsx("div", { style: { marginTop: '16px' }, children: busyMessage })] }) })), _jsx(Modal, { visible: dialogState.visible, onDismiss: handleDialogDismiss, header: dialogState.title, footer: _jsx(Box, { float: "right", children: _jsx(SpaceBetween, { direction: "horizontal", size: "xs", children: dialogState.buttons.map((btn, idx) => (_jsx(Button, { variant: btn.variant === 'primary' ? 'primary' : 'normal', onClick: () => handleDialogButton(btn.value), children: btn.label }, idx))) }) }), children: dialogState.message }), _jsx(ShellLayout, { navigation: navigation, currentPath: currentPath, basePath: shell.basePath, onNavigate: handleNavigate, children: _jsx("div", { id: "shell-content", ref: contentRef }) })] }));
151
+ }, children: [_jsx(Spinner, { size: "large" }), _jsx("div", { style: { marginTop: '16px' }, children: busyMessage })] }) })), _jsx(Modal, { visible: dialogState.visible, onDismiss: handleDialogDismiss, header: dialogState.title, footer: _jsx(Box, { float: "right", children: _jsx(SpaceBetween, { direction: "horizontal", size: "xs", children: dialogState.buttons.map((btn, idx) => (_jsx(Button, { variant: btn.variant === 'primary' ? 'primary' : 'normal', onClick: () => handleDialogButton(btn.value), children: btn.label }, idx))) }) }), children: dialogState.message }), _jsx(ShellLayout, { navigation: navigation, currentPath: currentPath, basePath: shell.appBasePath, onNavigate: handleNavigate, children: _jsx("div", { id: "shell-content", ref: contentRef }) })] }));
151
152
  }
@@ -9,7 +9,7 @@ export function ShellLayout({ navigation, currentPath, basePath, onNavigate, chi
9
9
  text: item.label,
10
10
  href: basePath + item.path + '/', // Add trailing slash for directory routing
11
11
  }));
12
- return (_jsx(AppLayout, { navigationOpen: navigationOpen, onNavigationChange: ({ detail }) => setNavigationOpen(detail.open), navigation: _jsx(SideNavigation, { activeHref: currentPath, items: navItems, onFollow: (event) => {
12
+ return (_jsx(AppLayout, { navigationOpen: navigationOpen, onNavigationChange: ({ detail }) => setNavigationOpen(detail.open), navigation: _jsx(SideNavigation, { activeHref: basePath + currentPath + (currentPath.endsWith('/') ? '' : '/'), items: navItems, onFollow: (event) => {
13
13
  event.preventDefault();
14
14
  onNavigate(event.detail.href);
15
15
  } }), content: children, toolsHide: true }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@herdingbits/trailhead-cloudscape",
3
- "version": "0.0.12",
3
+ "version": "0.0.15",
4
4
  "description": "AWS CloudScape adapter for Trailhead. React-based shell with CloudScape components. Supports React 19.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,21 +21,21 @@
21
21
  "build": "npm run clean && tsc && cp src/shell.css dist/"
22
22
  },
23
23
  "peerDependencies": {
24
- "@herdingbits/trailhead-core": "^0.0.13",
25
24
  "@cloudscape-design/components": "^3.0.0",
26
25
  "@cloudscape-design/global-styles": "^1.0.0",
26
+ "@herdingbits/trailhead-core": "^0.0.16",
27
27
  "react": "^19.0.0",
28
28
  "react-dom": "^19.0.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@herdingbits/trailhead-types": "^0.0.11",
32
- "@cloudscape-design/components": "^3.0.1284",
33
- "@cloudscape-design/global-styles": "^1.0.57",
31
+ "@cloudscape-design/components": "^3.0.1297",
32
+ "@cloudscape-design/global-styles": "^1.0.59",
33
+ "@herdingbits/trailhead-types": "^0.0.13",
34
34
  "@types/react": "^19.2.14",
35
35
  "@types/react-dom": "^19.2.3",
36
- "react": "^19.2.5",
37
- "react-dom": "^19.2.5",
38
- "typescript": "^5.9.3"
36
+ "react": "^19.2.6",
37
+ "react-dom": "^19.2.6",
38
+ "typescript": "^6.0.3"
39
39
  },
40
40
  "keywords": [
41
41
  "micro-frontend",