{"id":35725609,"url":"https://github.com/willwade/aac-board-viewer","last_synced_at":"2026-01-19T14:00:45.374Z","repository":{"id":332037325,"uuid":"1128330262","full_name":"willwade/aac-board-viewer","owner":"willwade","description":"A component to preview any AAC system","archived":false,"fork":false,"pushed_at":"2026-01-09T00:02:43.000Z","size":989,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T21:19:58.401Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willwade.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":"This open-source project develops tools for the AAC (Augmentative and Alternative Communication) community."},"created_at":"2026-01-05T13:31:19.000Z","updated_at":"2026-01-09T00:02:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/willwade/aac-board-viewer","commit_stats":null,"previous_names":["willwade/aac-board-viewer"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/willwade/aac-board-viewer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willwade%2Faac-board-viewer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willwade%2Faac-board-viewer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willwade%2Faac-board-viewer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willwade%2Faac-board-viewer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willwade","download_url":"https://codeload.github.com/willwade/aac-board-viewer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willwade%2Faac-board-viewer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28571556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T12:50:50.164Z","status":"ssl_error","status_checked_at":"2026-01-19T12:50:42.704Z","response_time":67,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-01-06T08:14:15.836Z","updated_at":"2026-01-19T14:00:45.351Z","avatar_url":"https://github.com/willwade.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AAC Board Viewer\n\nUniversal AAC (Augmentative and Alternative Communication) board viewer component for React. Display and interact with communication boards from multiple AAC systems.\n\n## Supported Formats\n\n- **Grid 3** (`.gridset` files)\n- **TouchChat** (`.ce` files)\n- **TD Snap** (`.sps`, `.spb` files)\n- **OpenBoard** (`.obf`, `.obz` files)\n- **Asterics Grid** (`.grd` files)\n- **Apple Panels** (`.plist` files)\n- **OPML** (`.opml` files)\n- **Excel** (`.xlsx` boards)\n- **DOT files** (`.dot` visualizations)\n\nNote: In-browser loading of SQLite-backed formats (`.sps`, `.spb`, `.ce`) requires SQL.js configuration.\n\n## Features\n\n- 🎯 **Universal Support** - Works with all major AAC file formats\n- 📱 **Responsive Design** - Mobile-friendly with touch support\n- 🎨 **Preserves Styling** - Maintains original colors, fonts, and layouts\n- 🔗 **Interactive Navigation** - Click buttons to navigate between pages\n- 🗣️ **Sentence Building** - Tap buttons to build sentences\n- 🔧 **Customizable** - Flexible styling and behavior options (toggle message bar, link indicators, effort badges)\n- 🌙 **Dark-mode Friendly** - Inherits host app theme when a parent adds the `dark` class\n\n## Installation\n\nRequires Node 20+.\n\n```bash\nnpm install aac-board-viewer\n```\n\nOr with yarn:\n\n```bash\nyarn add aac-board-viewer\n```\n\n## Quick Start\n\n### Browser Usage\n\nSQLite-backed formats (Snap `.sps`/`.spb` and TouchChat `.ce`) require SQL.js to be configured in your bundler before loading files:\n\n```tsx\nimport { configureBrowserSqlJs, loadAACFile, BoardViewer } from 'aac-board-viewer';\nimport sqlWasmUrl from 'sql.js/dist/sql-wasm.wasm?url';\nimport 'aac-board-viewer/styles';\n\nconfigureBrowserSqlJs({\n  locateFile: () =\u003e sqlWasmUrl,\n});\n\nfunction MyViewer({ file }: { file: File }) {\n  const [tree, setTree] = useState(null);\n\n  useEffect(() =\u003e {\n    async function load() {\n      const loadedTree = await loadAACFile(file);\n      setTree(loadedTree);\n    }\n    load();\n  }, [file]);\n\n  if (!tree) return \u003cdiv\u003eLoading...\u003c/div\u003e;\n  return \u003cBoardViewer tree={tree} /\u003e;\n}\n```\n\n### Server-Side / API Usage\n\n```tsx\nimport { BoardViewer } from 'aac-board-viewer';\nimport 'aac-board-viewer/styles';\n\nfunction MyViewer({ treeData }) {\n  return (\n    \u003cBoardViewer\n      tree={treeData}\n      buttonMetrics={metricsData}\n      showMessageBar={true}\n      showEffortBadges={true}\n    /\u003e\n  );\n}\n```\n\n### Client/Server Split (Lightweight Frontend)\n\nParse boards on the server and send the `AACTree` JSON to the browser for rendering. This keeps the frontend lightweight while the backend handles heavy formats.\n\nServer (Node/Express):\n\n```ts\nimport express from 'express';\nimport { loadAACFile } from 'aac-board-viewer';\n\nconst app = express();\n\napp.get('/api/boards/:id', async (req, res) =\u003e {\n  const tree = await loadAACFile(`/data/boards/${req.params.id}.sps`);\n  res.json(tree);\n});\n```\n\nClient (React):\n\n```tsx\nimport { BoardViewer } from 'aac-board-viewer';\nimport 'aac-board-viewer/styles';\n\nfunction RemoteBoard({ id }: { id: string }) {\n  const [tree, setTree] = useState(null);\n\n  useEffect(() =\u003e {\n    fetch(`/api/boards/${id}`)\n      .then((res) =\u003e res.json())\n      .then(setTree);\n  }, [id]);\n\n  if (!tree) return \u003cdiv\u003eLoading...\u003c/div\u003e;\n  return \u003cBoardViewer tree={tree} /\u003e;\n}\n```\n\n### With Metrics\n\n```tsx\nimport { BoardViewer, loadAACFile, calculateMetrics } from 'aac-board-viewer';\n\nfunction MetricsViewer({ filePath }) {\n  const [tree, setTree] = useState(null);\n  const [metrics, setMetrics] = useState(null);\n\n  useEffect(() =\u003e {\n    async function load() {\n      const loadedTree = await loadAACFile(filePath);\n      const calculatedMetrics = await calculateMetrics(loadedTree);\n\n      setTree(loadedTree);\n      setMetrics(calculatedMetrics);\n    }\n    load();\n  }, [filePath]);\n\n  if (!tree) return \u003cdiv\u003eLoading...\u003c/div\u003e;\n\n  return (\n    \u003cBoardViewer\n      tree={tree}\n      buttonMetrics={metrics}\n      showEffortBadges={true}\n    /\u003e\n  );\n}\n```\n\n## Props\n\n### BoardViewer\n\n```typescript\ninterface BoardViewerProps {\n  tree: AACTree;\n  buttonMetrics?: ButtonMetric[] | null;\n  showMessageBar?: boolean;\n  showEffortBadges?: boolean;\n  showLinkIndicators?: boolean;\n  onButtonClick?: (button: AACButton) =\u003e void;\n  onPageChange?: (pageId: string) =\u003e void;\n  className?: string;\n}\n```\n\n### AACTree\n\n```typescript\ninterface AACTree {\n  pages: { [key: string]: AACPage };\n  rootId?: string;\n  toolbarId?: string;\n  metadata?: {\n    format?: string;\n    name?: string;\n    description?: string;\n    [key: string]: any;\n  };\n}\n```\n\n## Advanced Usage\n\n### Custom Styling\n\n```tsx\n\u003cBoardViewer\n  tree={tree}\n  className=\"my-custom-board\"\n/\u003e\n```\n\n### Event Handling\n\n```tsx\n\u003cBoardViewer\n  tree={tree}\n  onButtonClick={(button) =\u003e {\n    console.log('Button clicked:', button.label);\n    // Track analytics, play sound, etc.\n  }}\n  onPageChange={(pageId) =\u003e {\n    console.log('Page changed to:', pageId);\n    // Track navigation\n  }}\n/\u003e\n```\n\n### Hide Message Bar\n\n```tsx\n\u003cBoardViewer\n  tree={tree}\n  showMessageBar={false}\n/\u003e\n```\n\n## File Loading\n\nThe library provides utilities for loading AAC files:\n\n### Programmatic Loading\n\n```tsx\nimport { loadAACFile } from 'aac-board-viewer';\n\nconst tree = await loadAACFile('/path/to/file.gridset');\n```\n\n### From File Input\n\n```tsx\nimport { loadAACFileFromFile } from 'aac-board-viewer';\n\nfunction FileInput() {\n  const handleChange = async (e) =\u003e {\n    const file = e.target.files[0];\n    const tree = await loadAACFileFromFile(file);\n    // Use tree...\n  };\n\n  return \u003cinput type=\"file\" onChange={handleChange} /\u003e;\n}\n```\n\n## Metrics Calculation\n\nCalculate cognitive effort metrics for buttons:\n\n```tsx\nimport { calculateMetrics } from 'aac-board-viewer';\n\nconst metrics = await calculateMetrics(tree, {\n  accessMethod: 'direct', // or 'scanning'\n  scanningConfig: {\n    pattern: 'row-column', // 'linear', 'row-column', 'block'\n    selectionMethod: 'auto-1-switch',\n    errorCorrection: false,\n  },\n});\n\n// metrics is an array of ButtonMetric objects:\n// [{ id, label, effort, count, is_word, level }, ...]\n```\n\n## Format-Specific Notes\n\n### Apple Panels\n\nApple Panels use free-form positioning. The viewer automatically:\n- Converts absolute positioning to grid layout\n- Calculates appropriate grid dimensions\n- Preserves original button placement\n\n### Asterics Grid\n\nAsterics files (`.grd`) are automatically detected and processed using the Asterics Grid processor.\n\n### GridSet / SNAP / TouchChat\n\nThese formats use native grid layouts and are displayed as-is, preserving:\n- Grid dimensions (rows × columns)\n- Button colors and borders\n- Font sizes and styles\n- Navigation links between pages\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run demo app\nnpm run dev\n\n# Build library\nnpm run build\n\n# Type check\nnpm run type-check\n\n# Lint\nnpm run lint\n```\n\n## Examples\n\nSee the `/demo` directory for complete examples:\n- Basic viewer\n- With metrics\n- Multiple formats\n- Server-side rendering\n\n## Contributing\n\nContributions are welcome! Please read our contributing guidelines before submitting PRs.\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Related Packages\n\n- [@willwade/aac-processors](https://github.com/willwade/AACProcessors-nodejs) - Core AAC file processing library\n\n## Support\n\n- Issues: [GitHub Issues](https://github.com/willwade/aac-board-viewer/issues)\n- Documentation: [Full Docs](https://github.com/willwade/aac-board-viewer/wiki)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillwade%2Faac-board-viewer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillwade%2Faac-board-viewer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillwade%2Faac-board-viewer/lists"}