{"id":50372428,"url":"https://github.com/sumanthnagireddi/atlas-editor","last_synced_at":"2026-06-01T10:00:43.156Z","repository":{"id":355690087,"uuid":"1229088718","full_name":"sumanthnagireddi/atlas-editor","owner":"sumanthnagireddi","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-04T19:32:23.000Z","size":262,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-04T21:28:41.785Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sumanthnagireddi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-04T17:30:15.000Z","updated_at":"2026-05-04T19:32:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sumanthnagireddi/atlas-editor","commit_stats":null,"previous_names":["sumanthnagireddi/atlas-editor"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/sumanthnagireddi/atlas-editor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sumanthnagireddi%2Fatlas-editor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sumanthnagireddi%2Fatlas-editor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sumanthnagireddi%2Fatlas-editor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sumanthnagireddi%2Fatlas-editor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sumanthnagireddi","download_url":"https://codeload.github.com/sumanthnagireddi/atlas-editor/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sumanthnagireddi%2Fatlas-editor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33769492,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-30T08:00:26.078Z","updated_at":"2026-06-01T10:00:43.149Z","avatar_url":"https://github.com/sumanthnagireddi.png","language":"TypeScript","funding_links":[],"categories":["Framework Interoperability"],"sub_categories":["Wrappers"],"readme":"# Atlas Angular Integration Guide\n\nThis repo ships two Atlaskit-based UI runtimes:\n\n- an editor\n- a side navigation\n\nThey are implemented with React internally, but the recommended consumer API is Angular.\n\nThe Angular app should use these wrapper components:\n\n```html\n\u003capp-atlaskit-editor\u003e\u003c/app-atlaskit-editor\u003e\n\u003capp-atlaskit-side-nav\u003e\u003c/app-atlaskit-side-nav\u003e\n```\n\nThose wrappers lazy-load the generated web-component bundles for you, so the consumer app does not need to manage React directly.\n\n## Recommended distribution model\n\nThe Angular-first package in this repo is now:\n\n```text\n@sumanthnagireddi/atlas-angular\n```\n\nThat package is the recommended consumer entrypoint.\n\nIt gives Angular teams:\n\n1. Angular components as the public API\n2. React kept internal\n3. packaged runtime loading by default\n4. an `assetBaseUrl` escape hatch when you want to self-host or override the runtime assets\n\n## What gets built\n\nRunning the workspace build produces this folder:\n\n```text\ndist/web-components/\n  atlas-editor.js\n  atlas-side-nav.js\n  atlaskit-editor/\n    atlas-atlaskit-editor.js\n    atlas-atlaskit-editor.css\n    ...many chunk files...\n  atlaskit-navigation/\n    atlas-atlaskit-navigation.js\n    atlas-atlaskit-navigation.css\n    ...many chunk files...\n```\n\nImportant: keep the full folder structure intact. Do not publish only the top-level `atlas-editor.js` or `atlas-side-nav.js` files.\n\n## Build the bundle\n\nFrom this repo:\n\n```bash\nnpm ci\nnpm run build\n```\n\nIf you only need the standalone bundle output:\n\n```bash\nnpm run build:bundle\n```\n\nIf you only need the Angular wrapper package output:\n\n```bash\nnpm run build:angular-lib\n```\n\n## Recommended integration model\n\nThis is the supported Angular-first approach:\n\n1. build and publish `@sumanthnagireddi/atlas-angular`\n2. install that package in the consumer Angular app\n3. use the Angular components directly\n4. let the wrappers load the packaged runtime automatically\n\nYou do not need to:\n\n- copy wrapper files into the consumer app\n- add `\u003cscript\u003e` tags to `index.html`\n- manage React directly\n\n## Publish or consume the Angular package\n\nThe package source lives here:\n\n- [C:\\Users\\HP\\Desktop\\code\\atlas-editor\\packages\\angular](C:\\Users\\HP\\Desktop\\code\\atlas-editor\\packages\\angular)\n\nBuild it with:\n\n```bash\nnpm run build:angular-lib\n```\n\nThat produces:\n\n```text\npackages/angular/dist/\n  public-api.js\n  public-api.d.ts\n  lib/\n    atlaskit-editor.component.js\n    atlaskit-editor.component.d.ts\n    atlaskit-side-nav.component.js\n    atlaskit-side-nav.component.d.ts\n```\n\nIf you want to publish to npm, publish the `@sumanthnagireddi/atlas-angular` package from `packages/angular`.\n\nIf you want to consume it before publishing, you can install it from a packed tarball or a git dependency after building it.\n\nCI also publishes the Angular package automatically after the main workspace build passes on pushes to `master` or `main`.\n\nTo make that work in GitHub Actions, configure:\n\n- `NPM_TOKEN` as a repository secret with publish permission for npm\n\nThe publish job checks whether the current `packages/angular/package.json` version already exists on npm. If it does, the workflow skips publish cleanly, so version bumps are what trigger new package releases.\n\n## Wrapper selectors\n\nThe wrappers support both selector styles:\n\n- editor:\n  - `app-atlaskit-editor`\n  - `app-atlaskit-editor-host`\n- side nav:\n  - `app-atlaskit-side-nav`\n  - `app-atlaskit-side-nav-host`\n\nFor new consumers, prefer:\n\n- `app-atlaskit-editor`\n- `app-atlaskit-side-nav`\n\n## Angular import surface\n\nIn the consumer app, import from `@sumanthnagireddi/atlas-angular`:\n\n```ts\nimport {\n  AtlaskitEditorComponent,\n  AtlaskitSideNavComponent\n} from '@sumanthnagireddi/atlas-angular';\n```\n\nThese are exported as real standalone Angular component classes, so they can be used directly in:\n\n```ts\nimports: [CommonModule, AtlaskitEditorComponent, AtlaskitSideNavComponent]\n```\n\n## Ready-to-paste Angular consumer page\n\nThis is the recommended standalone Angular usage pattern.\n\n```ts\nimport { CommonModule } from '@angular/common';\nimport { Component, signal } from '@angular/core';\nimport {\n  AtlaskitEditorComponent,\n  AtlaskitSideNavComponent,\n  type ADFDoc,\n  type AtlasEditorPage,\n  type AtlasSideNavModel\n} from '@sumanthnagireddi/atlas-angular';\n\n@Component({\n  selector: 'app-atlas-consumer-page',\n  standalone: true,\n  imports: [CommonModule, AtlaskitEditorComponent, AtlaskitSideNavComponent],\n  template: `\n    \u003cdiv class=\"shell\"\u003e\n      \u003caside class=\"shell__nav\"\u003e\n        \u003capp-atlaskit-side-nav\n          [model]=\"model()\"\n          [darkMode]=\"darkMode()\"\n          (ready)=\"handleNavReady()\"\n          (itemInvoke)=\"handleItemInvoke($event)\"\n          (actionInvoke)=\"handleActionInvoke($event)\"\n          (expandChange)=\"handleExpandChange($event)\"\n          (flyoutOpenChange)=\"handleFlyoutOpenChange($event)\"\u003e\n        \u003c/app-atlaskit-side-nav\u003e\n      \u003c/aside\u003e\n\n      \u003cmain class=\"shell__content\"\u003e\n        \u003capp-atlaskit-editor\n          [value]=\"document()\"\n          [page]=\"page()\"\n          [readOnly]=\"readOnly()\"\n          [mode]=\"mode()\"\n          [darkMode]=\"darkMode()\"\n          [debounceMs]=\"debounceMs()\"\n          [placeholder]=\"placeholder()\"\n          (valueChange)=\"handleValueChange($event)\"\n          (change)=\"handleChange($event)\"\n          (pageChange)=\"handlePageChange($event)\"\n          (pageSubmit)=\"handlePageSubmit($event)\"\n          (pageCancel)=\"handlePageCancel($event)\"\n          (editModeChange)=\"handleEditModeChange($event)\"\n          (ready)=\"handleEditorReady()\"\n          (editorError)=\"handleEditorError($event)\"\u003e\n        \u003c/app-atlaskit-editor\u003e\n      \u003c/main\u003e\n    \u003c/div\u003e\n  `,\n  styles: [\n    `\n      :host {\n        display: block;\n        min-height: 100vh;\n        background: #101214;\n      }\n\n      .shell {\n        display: grid;\n        grid-template-columns: 320px minmax(0, 1fr);\n        min-height: 100vh;\n      }\n\n      .shell__nav {\n        min-width: 0;\n        border-right: 1px solid rgba(255, 255, 255, 0.08);\n      }\n\n      .shell__content {\n        min-width: 0;\n      }\n    `\n  ]\n})\nexport class AtlasConsumerPageComponent {\n  readonly darkMode = signal(true);\n  readonly readOnly = signal(false);\n  readonly mode = signal\u003c'editor' | 'renderer'\u003e('editor');\n  readonly debounceMs = signal(250);\n  readonly placeholder = signal('Give this page a title...');\n\n  readonly document = signal\u003cADFDoc\u003e({\n    version: 1,\n    type: 'doc',\n    content: [\n      {\n        type: 'paragraph',\n        content: [{ type: 'text', text: 'Hello from another Angular app.' }]\n      }\n    ]\n  });\n\n  readonly page = signal\u003cAtlasEditorPage\u003e({\n    title: 'OSI (Open Systems Interconnection)',\n    authorName: 'Sumanth',\n    authorInitials: 'S',\n    updatedText: 'Updated 1h ago',\n    metaItems: ['5 min', 'See views', 'Add a reaction'],\n    statusText: 'Verified',\n    statusAppearance: 'success',\n    widthMode: 'centered',\n    titleAlignment: 'left'\n  });\n\n  readonly model = signal\u003cAtlasSideNavModel\u003e({\n    label: 'Workspace navigation',\n    header: {\n      title: 'Atlas workspace',\n      description: 'Angular consumer app',\n      icon: 'apps'\n    },\n    sections: [\n      {\n        id: 'primary',\n        title: 'Main',\n        items: [\n          {\n            id: 'home',\n            kind: 'link',\n            label: 'Home',\n            href: '/home',\n            icon: 'home',\n            isSelected: true\n          },\n          {\n            id: 'create-page',\n            kind: 'button',\n            label: 'Create page',\n            icon: 'add'\n          },\n          {\n            id: 'projects',\n            kind: 'expandable',\n            variant: 'button',\n            label: 'Projects',\n            icon: 'project',\n            isOpen: true,\n            children: [\n              {\n                id: 'kanban',\n                kind: 'link',\n                label: 'My Kanban Project',\n                description: 'Board',\n                href: '/projects/kanban',\n                icon: 'board'\n              },\n              {\n                id: 'analytics',\n                kind: 'link',\n                label: 'Analytics workspace',\n                description: 'Dashboard',\n                href: '/projects/analytics',\n                icon: 'dashboard'\n              }\n            ]\n          },\n          {\n            id: 'recent',\n            kind: 'flyout',\n            label: 'Recent',\n            icon: 'recent',\n            flyout: {\n              title: 'Recent',\n              searchPlaceholder: 'Search recent items',\n              footerLabel: 'View all recent items',\n              sections: [\n                {\n                  id: 'recent-this-week',\n                  title: 'This week',\n                  items: [\n                    {\n                      id: 'kanban-recent',\n                      kind: 'link',\n                      label: 'My Kanban Project',\n                      description: '5 days ago',\n                      href: '/recent/kanban',\n                      icon: 'board'\n                    }\n                  ]\n                }\n              ]\n            }\n          }\n        ]\n      }\n    ]\n  });\n\n  handleValueChange(nextDoc: ADFDoc): void {\n    this.document.set(nextDoc);\n  }\n\n  handleChange(nextDoc: ADFDoc): void {\n    console.log('Editor change', nextDoc);\n  }\n\n  handlePageChange(nextPage: AtlasEditorPage): void {\n    this.page.set(nextPage);\n  }\n\n  handlePageSubmit(payload: unknown): void {\n    console.log('Page submit', payload);\n  }\n\n  handlePageCancel(payload: unknown): void {\n    console.log('Page cancel', payload);\n  }\n\n  handleEditModeChange(isEditing: boolean): void {\n    console.log('Edit mode', isEditing);\n  }\n\n  handleEditorReady(): void {\n    console.log('Editor ready');\n  }\n\n  handleEditorError(error: unknown): void {\n    console.error('Editor error', error);\n  }\n\n  handleNavReady(): void {\n    console.log('Side nav ready');\n  }\n\n  handleItemInvoke(detail: unknown): void {\n    console.log('Item invoke', detail);\n  }\n\n  handleActionInvoke(detail: unknown): void {\n    console.log('Action invoke', detail);\n  }\n\n  handleExpandChange(detail: unknown): void {\n    console.log('Expand change', detail);\n  }\n\n  handleFlyoutOpenChange(detail: unknown): void {\n    console.log('Flyout open change', detail);\n  }\n}\n```\n\n## Inputs and outputs\n\n### `app-atlaskit-editor` inputs\n\n- `assetBaseUrl`\n- `value`\n- `page`\n- `readOnly`\n- `mode`\n- `darkMode`\n- `debounceMs`\n- `placeholder`\n\n### `app-atlaskit-editor` outputs\n\n- `valueChange`\n- `change`\n- `pageChange`\n- `pageSubmit`\n- `pageCancel`\n- `editModeChange`\n- `ready`\n- `editorError`\n\n### `app-atlaskit-side-nav` inputs\n\n- `assetBaseUrl`\n- `model`\n- `darkMode`\n\n### `app-atlaskit-side-nav` outputs\n\n- `itemInvoke`\n- `actionInvoke`\n- `expandChange`\n- `flyoutOpenChange`\n- `ready`\n- `sideNavError`\n\n## Default runtime location\n\n`@sumanthnagireddi/atlas-angular` defaults to the packaged runtime bundle that ships inside the npm library itself.\n\nThat means the simplest Angular consumer often does not need to pass `assetBaseUrl` at all.\n\nIf you want to override the runtime location, pass the folder URL, not an individual loader file. Internally:\n\n- editor wrapper loads `atlas-editor.js`\n- side-nav wrapper loads `atlas-side-nav.js`\n- `atlas-editor.js` loads `./atlaskit-editor/atlas-atlaskit-editor.js`\n- `atlas-side-nav.js` loads `./atlaskit-navigation/atlas-atlaskit-navigation.js`\n\nIf you want to be explicit, or you want to swap environments, pass your base URL to:\n\n- `[assetBaseUrl]` on `app-atlaskit-editor`\n- `[assetBaseUrl]` on `app-atlaskit-side-nav`\n\nNo `index.html` script tags are required in either mode.\n\n## Self-hosting the runtime bundle\n\nIf you prefer to host the runtime assets yourself, copy:\n\n- [C:\\Users\\HP\\Desktop\\code\\atlas-editor\\dist\\web-components](C:\\Users\\HP\\Desktop\\code\\atlas-editor\\dist\\web-components)\n\ninto your own static hosting path and point `assetBaseUrl` there, for example:\n\n```ts\nbundleBaseUrl = '/assets/atlas';\n```\n\n## Dynamic data compatibility\n\nThe wrappers are built to support both:\n\n- initial object input\n- later updates from Angular state\n\nFor the side nav specifically, the wrapper also handles in-place JSON mutations by fingerprinting the model during Angular change detection. That means both of these patterns are supported:\n\n```ts\nthis.model.set(nextModel);\n```\n\nand:\n\n```ts\nconst current = this.model();\ncurrent.sections[0].items.push({\n  id: 'new-item',\n  kind: 'link',\n  label: 'New item',\n  href: '/new-item',\n  icon: 'page'\n});\n```\n\nAs long as Angular change detection runs, the wrapper will push the updated model into the runtime.\n\n## Editor page-shell behavior\n\nWhen a `page` object is provided, the editor renders in the Confluence-style page shell:\n\n- top metadata row\n- title area\n- view mode with `Edit`\n- edit mode with page controls\n- emitted page updates back to the consumer\n\nThe consumer remains responsible for:\n\n- providing the initial page metadata\n- storing updated ADF\n- storing submitted page metadata\n- deciding what to do with `pageSubmit`\n\n## Raw web-component fallback\n\nOnly use this section if you do not want the Angular wrappers.\n\nYou can still load the generated custom elements directly:\n\n```html\n\u003cscript type=\"module\" src=\"https://sumanthnagireddi.github.io/atlas-editor/web-components/atlas-editor.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"module\" src=\"https://sumanthnagireddi.github.io/atlas-editor/web-components/atlas-side-nav.js\"\u003e\u003c/script\u003e\n\n\u003catlas-editor\u003e\u003c/atlas-editor\u003e\n\u003catlas-side-nav\u003e\u003c/atlas-side-nav\u003e\n```\n\nThen assign object data as element properties:\n\n```ts\nconst editor = document.querySelector('atlas-editor');\nconst sideNav = document.querySelector('atlas-side-nav');\n\neditor.value = doc;\neditor.page = page;\neditor.darkMode = true;\n\nsideNav.model = sideNavModel;\nsideNav.darkMode = true;\n```\n\nFor Angular consumers, this is a fallback only. The wrapper path above is the preferred integration model.\n\n## Local testing\n\nIn this repo:\n\n```bash\nnpm ci\nnpm run build\nnpm run start\n```\n\nIf the consumer app still shows stale behavior after a bundle update:\n\n1. rebuild the bundle\n2. restart `ng serve`\n3. hard refresh the browser\n\nThis matters because the Angular wrappers load generated runtime assets from `assetBaseUrl`.\n\n## Troubleshooting\n\n### The editor never leaves the loading state\n\nCheck that the full runtime folder exists under the same base URL:\n\n```text\n\u003cassetBaseUrl\u003e/atlas-editor.js\n\u003cassetBaseUrl\u003e/atlaskit-editor/...\n```\n\nIf you are using the side nav too:\n\n```text\n\u003cassetBaseUrl\u003e/atlas-side-nav.js\n\u003cassetBaseUrl\u003e/atlaskit-navigation/...\n```\n\n### My ADF does not render\n\nPass a valid ADF `doc` object into `[value]`, for example:\n\n```json\n{\n  \"version\": 1,\n  \"type\": \"doc\",\n  \"content\": []\n}\n```\n\nDo not pass HTML and expect automatic conversion.\n\n### Dark mode looks wrong\n\nSet:\n\n```ts\ndarkMode = true;\n```\n\nand avoid global CSS overrides that restyle Atlaskit internals.\n\n### Local `npm ci` fails on Windows with `EPERM` around `esbuild.exe`\n\nThat usually means a local process is still holding `node_modules/@esbuild/win32-x64/esbuild.exe` open. This does not indicate a broken CI dependency graph by itself. Close running dev processes and retry locally.\n\n## Files in this repo that matter\n\n- Angular package entrypoint: [C:\\Users\\HP\\Desktop\\code\\atlas-editor\\packages\\angular\\src\\public-api.ts](C:\\Users\\HP\\Desktop\\code\\atlas-editor\\packages\\angular\\src\\public-api.ts)\n- editor wrapper source: [C:\\Users\\HP\\Desktop\\code\\atlas-editor\\packages\\angular\\src\\lib\\atlaskit-editor.component.ts](C:\\Users\\HP\\Desktop\\code\\atlas-editor\\packages\\angular\\src\\lib\\atlaskit-editor.component.ts)\n- side-nav wrapper source: [C:\\Users\\HP\\Desktop\\code\\atlas-editor\\packages\\angular\\src\\lib\\atlaskit-side-nav.component.ts](C:\\Users\\HP\\Desktop\\code\\atlas-editor\\packages\\angular\\src\\lib\\atlaskit-side-nav.component.ts)\n- generated assets: [C:\\Users\\HP\\Desktop\\code\\atlas-editor\\dist\\web-components](C:\\Users\\HP\\Desktop\\code\\atlas-editor\\dist\\web-components)\n- bundle builder: [C:\\Users\\HP\\Desktop\\code\\atlas-editor\\scripts\\build-web-components.mjs](C:\\Users\\HP\\Desktop\\code\\atlas-editor\\scripts\\build-web-components.mjs)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsumanthnagireddi%2Fatlas-editor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsumanthnagireddi%2Fatlas-editor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsumanthnagireddi%2Fatlas-editor/lists"}