@herdingbits/trailhead-cloudscape 0.0.13 → 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
  }
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,10 +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.basePath + appPath;
84
+ const appBasePath = shell.appBasePath + appPath;
85
85
  try {
86
- const pluginUrl = `${shell.basePath}${appPath}/app.js`;
87
- const pluginCss = `${shell.basePath}${appPath}/${appName}.css`;
86
+ const pluginUrl = `${shell.appBasePath}${appPath}/app.js`;
87
+ const pluginCss = `${shell.appBasePath}${appPath}/${appName}.css`;
88
88
  // Load CSS
89
89
  const link = document.createElement("link");
90
90
  link.rel = "stylesheet";
@@ -148,5 +148,5 @@ export function ShellApp({ shell }) {
148
148
  padding: '24px',
149
149
  borderRadius: '8px',
150
150
  textAlign: 'center',
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.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 }) })] }));
152
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.13",
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,16 +21,16 @@
21
21
  "build": "npm run clean && tsc && cp src/shell.css dist/"
22
22
  },
23
23
  "peerDependencies": {
24
- "@herdingbits/trailhead-core": "^0.0.15",
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.12",
32
31
  "@cloudscape-design/components": "^3.0.1297",
33
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
36
  "react": "^19.2.6",