{"id":22371305,"url":"https://github.com/fartinmartin/extendscript-ui","last_synced_at":"2025-04-12T22:44:15.529Z","repository":{"id":266386978,"uuid":"896242379","full_name":"fartinmartin/extendscript-ui","owner":"fartinmartin","description":"JSX templating for Adobe ScriptUI/ExtendScript","archived":false,"fork":false,"pushed_at":"2025-01-07T03:15:53.000Z","size":356,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-26T16:53:01.710Z","etag":null,"topics":["extendscript","jsx"],"latest_commit_sha":null,"homepage":"","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/fartinmartin.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}},"created_at":"2024-11-29T21:25:08.000Z","updated_at":"2025-01-07T10:44:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"b28904da-756e-4c1f-88a9-227161b33bf3","html_url":"https://github.com/fartinmartin/extendscript-ui","commit_stats":null,"previous_names":["fartinmartin/extendscript-ui"],"tags_count":0,"template":false,"template_full_name":"fartinmartin/adobe-lib-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fartinmartin%2Fextendscript-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fartinmartin%2Fextendscript-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fartinmartin%2Fextendscript-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fartinmartin%2Fextendscript-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fartinmartin","download_url":"https://codeload.github.com/fartinmartin/extendscript-ui/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248643048,"owners_count":21138353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["extendscript","jsx"],"created_at":"2024-12-04T20:18:47.878Z","updated_at":"2025-04-12T22:44:15.510Z","avatar_url":"https://github.com/fartinmartin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `extendscript-ui`\n\n## JSX templating for ScriptUI/ExtendScript\n\nHave you ever wanted to compose [ScriptUI](https://extendscript.docsforadobe.dev/user-interface-tools/scriptui-programming-model.html) with JSX-like syntax, like so:\n\n\u003c!-- prettier-ignore --\u003e\n```jsx\n\u003cdialog text=\"Neat!\" properties={{ closeButton: true }}\u003e\n  \u003cbutton text=\"Click me!\" size={[100, 200]} onClick={() =\u003e alert(\"Doink!\")} /\u003e\n\u003c/dialog\u003e\n```\n\nWell, now you can! Plus, TypeScript will guide you through each prop with auto completions!\n\nYou can even create functional components:\n\n\u003c!-- prettier-ignore --\u003e\n```jsx\nconst Header = ({ text }: { text: string }) =\u003e (\n  \u003cgroup orientation={\"row\"} alignChildren={\"fill\"}\u003e\n    \u003cstatic-text text={text}\u003e\u003c/static-text\u003e\n  \u003c/group\u003e\n);\n\nconst ui = (\n  \u003cdialog text=\"Could it be?!\" properties={{ resizeable: true }}\u003e\n    \u003cHeader text=\"Neat!\" /\u003e\n  \u003c/dialog\u003e\n);\n```\n\n## Try it\n\n\u003e [!TIP]\n\u003e For a super basic example, check out [`/examples/basic`](/examples/basic)!\n\n### Prerequisites\n\nYou'll need TypeScript and a bundler for your code. Here are some ExtendScript starters with TypeScript support to check out:\n\n- [`@motiondeveloper/adobe-script-starter`](https://github.com/motiondeveloper/adobe-script-starter)\n- [`@fartinmartin/adobe-lib-starter`](https://github.com/fartinmartin/adobe-lib-starter)\n- [`@Klustre/extender`](https://github.com/Klustre/extender) (see [note on TypeScript](https://github.com/Klustre/extender?tab=readme-ov-file#typescript))\n\n### Installation\n\n```bash\nnpm i extendscript-ui\n```\n\n### Configuration\n\nUpdate your `tsconfig.json`:\n\n\u003c!-- prettier-ignore --\u003e\n```jsonc\n{\n  \"compilerOptions\": {\n    // ...your other config options, then:\n    // tell TypeScript how to find extendscript-ui's jsx.d.ts declarations:\n    \"typeRoots\": [\"./node_modules/extendscript-ui/dist\"],\n    \"types\": [\"types/jsx.d.ts\"],\n    // tell TypeScript how to transform your JSX code and the name of the jsxFactory fn to use when doing so:\n    \"jsx\": \"react\",\n    \"jsxFactory\": \"jsx\" // this is the fn that extendscript-ui exports!\n  }\n  // ...any other options\n}\n```\n\n### Usage\n\nBe sure to use `.tsx` files for JSX syntax highlighting. Import `jsx` to satisfy TypeScript and for code completion:\n\n\u003c!-- prettier-ignore --\u003e\n```jsx\n// index.tsx\nimport { jsx } from \"extendscript-ui\";\n\nexport const ui = (\n  \u003cdialog text=\"Neat!\" properties={{ closeButton: true }}\u003e\n    \u003cbutton text=\"Click me!\" onClick={() =\u003e alert(\"Doink!\")} /\u003e\n  \u003c/dialog\u003e\n);\n```\n\nYou can create custom components too:\n\n```jsx\nconst Header = ({ text }: { text: string }) =\u003e (\n  \u003cgroup orientation={\"row\"} alignChildren={\"fill\"}\u003e\n    \u003cstatic-text text={text}\u003e\u003c/static-text\u003e\n  \u003c/group\u003e\n);\n\n// later\n\nconst ui = (\n  \u003cdialog text=\"Neat!\" properties={{ resizeable: true }}\u003e\n    \u003cHeader text=\"Could it be?!\" /\u003e\n    // other stuff...\n  \u003c/dialog\u003e\n);\n```\n\nUse `renderSpec` to render your template. This will create a `Window` and wire up your `onClick` events. It will then return an object with your `Window` as well as a cleanup fn:\n\n\u003c!-- prettier-ignore --\u003e\n```jsx\nimport { renderSpec } from \"extendscript-ui\";\n\nconst { window, destroy } = renderSpec(ui);\nwindow.show();\n```\n\n\u003e [!WARNING]\n\u003e The `renderSpec` API might evolve, but it's functional for now...\n\n## How?\n\n`extendscript-ui` uses a [custom `jsxFactory`](https://www.typescriptlang.org/tsconfig/#jsxFactory) to transform JSX into a [ScriptUI Resource Specifications](https://extendscript.docsforadobe.dev/user-interface-tools/resource-specifications.html)-compliant string. This string is passed to `new Window(specString)` to build the UI. Once the UI is built, `renderSpec` adds any event handlers to the created UI elements.\n\n## TODO\n\n- [ ] Test/add more ScriptUI functionality beyond `onClick`...\n- [ ] More type safety:\n    - [ ] `renderSpec` should only accept specString with a root of type `Window`\n    - [ ] remove `type` attribute since it's defined by tag (generally, make sure all attrs are cleaned up)\n- [ ] Figure out `TreeView | ListBox | DropDownList` rendering\n- [ ] Default text nodes to `text` attr and/or `\u003cstatic-text/\u003e`? e.g `\u003cbutton\u003ehello!\u003c/button\u003e === \u003cbutton text=\"hello!\"/\u003e`\n- [ ] ProgressBar helpers, etc?\n- [ ] Look up how to auto import `jsx`, though this may just be documentation/guidance rather than a feature as it will probably depend on user's build setup?\n- [ ] Likely other things I've not thought of...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffartinmartin%2Fextendscript-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffartinmartin%2Fextendscript-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffartinmartin%2Fextendscript-ui/lists"}