{"id":21691361,"url":"https://github.com/just214/typescript-playground-plugin-react","last_synced_at":"2025-04-12T09:44:16.994Z","repository":{"id":47429113,"uuid":"242062766","full_name":"just214/typescript-playground-plugin-react","owner":"just214","description":"Easily create TypeScript Playground Plugins with React.","archived":false,"fork":false,"pushed_at":"2023-01-06T02:34:05.000Z","size":1347,"stargazers_count":23,"open_issues_count":12,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-26T04:41:33.170Z","etag":null,"topics":["monaco-editor","playground","plugin","react","typescript","typescript-playground-plugin"],"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/just214.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-21T05:35:44.000Z","updated_at":"2024-10-24T07:32:28.000Z","dependencies_parsed_at":"2023-02-05T03:16:29.371Z","dependency_job_id":null,"html_url":"https://github.com/just214/typescript-playground-plugin-react","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/just214%2Ftypescript-playground-plugin-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/just214%2Ftypescript-playground-plugin-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/just214%2Ftypescript-playground-plugin-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/just214%2Ftypescript-playground-plugin-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/just214","download_url":"https://codeload.github.com/just214/typescript-playground-plugin-react/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248550363,"owners_count":21122929,"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":["monaco-editor","playground","plugin","react","typescript","typescript-playground-plugin"],"created_at":"2024-11-25T17:37:35.904Z","updated_at":"2025-04-12T09:44:16.971Z","avatar_url":"https://github.com/just214.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# typescript-playground-plugin-react\n\nEasily create TypeScript [Playground Plugins](https://www.typescriptlang.org/v2/dev/playground-plugins/) with [React](https://reactjs.org/).\n\n\u003e 🚧 This project is experimental. If you have any ideas on how to improve this library, any contributions are welcomed. Also, working on TypeScript Playground plugins currently only can work in Chromium based browsers.\n\nPrefer Svelte? Check out [https://github.com/gojutin/typescript-playground-plugin-svelte](https://github.com/gojutin/typescript-playground-plugin-svelte).\n\n## Table Of Contents\n\n1. [Features](#features)\n2. [About](#about)\n3. [Getting Started](#getting-started)\n4. [usePlugin Hook](#usePlugin-hook)\n5. [Styling Your Plugin](#styling-your-plugin)\n6. [More about TypeScript Playground Plugins](#more-about-typescript-playground-plugins)\n7. [Todos](#todos)\n\n## Features\n\n✅ Write your TypeScript Playground plugin in React and TypeScript.\n\n✅ Interact with the Playground using a strongly-typed React hook.\n\n✅ Create styles with stylesheets or CSS-in-JS with Goober.\n\n✅ Linting with ESLint\n\n## About\n\nThe TypeScript Playground V3 beta comes packed with lots of new features, including the ability to create plugins. Per the TypeScript docs:\n\n\u003e The new TypeScript Playground allows people to hook into the Playground and extend it in ways in which the TypeScript team don't expect.\n\u003e\n\u003e The sidebar of the Playground uses the same plugin infrastructure as external plugins, so you have the same level of access as the playground to build interesting projects.\n\u003e\n\u003e Playground plugins have no fancy frameworks, you're free to inject them at runtime and use them if you need to - but the current plugins are built with the DOM APIs and TypeScript.\n\nThis package allows you to use React as a replacement (or addition to) the DOM APIs to create a rich, interactive UI for your plugin.\n\n#### How does it work?\n\nThe TypeScript Playground Plugin API provides a factory function with lifecycle methods that are used to interact with the playground. This library works by mounting a React app inside of the `didMount` method that the API exposes. The `modelChanged` and `modelChangedDebounce` API methods are called any time the code in the editor changes. Custom events are used to broadcast the changes to a context that wraps the app component.\n\n## Getting Started\n\n#### Step 1. Get the Code\n\n\u003e Option 1: Clone the repo\n\n```sh\ngit clone git@github.com:gojutin/typescript-playground-plugin-react.git\n```\n\n\u003e Option 2: Click the \"Use this template\" button in GitHub [(Link)](https://github.com/gojutin/typescript-playground-plugin-react)\n\n#### Step 2. Install dependencies\n\n```sh\ncd typescript-playground-plugin-react \u0026\u0026 yarn\n```\n\n#### Step 3. Start the development server\n\n```sh\nyarn start\n```\n\nThis will start a development server in watch mode, serve the `dist` directory at `localhost:5000`, and automatically open the TypeScript Playground in Chrome. As you edit any files in the `src` directory, the app will recompile and update `dist/index.js`, which is the file that is served to the TypeScript Playground.\n\n\u003e _Note: This does not reload the browser when your files change. In order to see your changes, the browser will need to be manually reloaded each time you make changes to the plugin._\n\n#### Step 4. Configure and use your plugin\n\nVisit [https://www.typescriptlang.org/play](https://www.typescriptlang.org/play).\n\nSelect the **Options** tab and tick the box for **Connect to localhost:5000/index.js**.\n\n\u003cimg src=\"./screenshots/screenshot1.png\" style=\"max-width: 80%;\"/\u003e\n\nNow, **refresh the browser**. When the playground reloads, a new tab with your plugin should appear! 🎉\n\n\u003cimg src=\"./screenshots/screenshot2.png\" style=\"max-width: 80%;\"/\u003e\n\nYou can make customizations to your plugin by modifying the `customPlugin` object in `src/index.tsx`. For instance, you can change the `displayName` property to change the tab label text for your plugin. See the `PlaygroundPlugin` interface in `src/plugin/vendor/playground.d.ts` for all of the available options.\n\n## `usePlugin` Hook\n\nThis hooks provides all of the method and properties provided by the Plugin API. It accepts a optional config object and returns an object with these properties:\n\n### **code**\n\n```typescript\nstring\n```\n\nThe current code in the Monaco editor saved as React state. This value updates on change to the Monaco editor with optional debouncing. Uses `sandbox.getText()`\n\n### **setCode**\n\n```typescript\n(code: string, options: {format: boolean}) =\u003e void\n```\n\nSet the code in the Monaco editor with optional formatting. Uses `sandbox.setText()`.\n\n### **formatCode**\n\n```typescript\n() =\u003e void\n```\n\nFormat the code in the Monaco editor. Alias for `sandbox.editor.getAction(\"editor.action.formatDocument\").run()`.\n\n\n### **markers**\n\n```typescript\n(IMarker \u0026 {key: string})[]\n```\n\nAlias for `sandbox.monaco.editor.getModelMarkers({})` with added unique `key` property. Kept in sync via `sandbox.editor.onDidChangeModelDecorations`.\n\nHere is the [type definition](https://github.com/Microsoft/monaco-editor/blob/master/monaco.d.ts#L875) for `IMarker`:\n\n```typescript\ninterface IMarker {\n  owner: string;\n  resource: Uri;\n  severity: MarkerSeverity;\n  code?:\n    | string\n    | {\n        value: string;\n        link: Uri;\n      };\n  message: string;\n  source?: string;\n  startLineNumber: number;\n  startColumn: number;\n  endLineNumber: number;\n  endColumn: number;\n  relatedInformation?: IRelatedInformation[];\n  tags?: MarkerTag[];\n}\n```\n\n### **setDebounce**\n\n```typescript\n(debounce: boolean) =\u003e void\n```\nOptionally debounce the `modelChange` event from the Plugin API. Per the Plugin docs, this is run on a delay and may not fire on every keystroke. The `code` property will be updated accordingly. \n\n### **sandbox**\n\n```typescript\nobject\n```\n\nA DOM library for interacting with TypeScript and JavaScript code, which powers the heart of the TypeScript playground. This object provides several properties and methods to interact with the playground. See all of the available types in `src/plugin/vendor/sandbox.d.ts` and read more about the sandbox at [http://www.typescriptlang.org/v2/dev/sandbox/](http://www.typescriptlang.org/v2/dev/sandbox/).\n\n### **model**\n\n```typescript\nobject\n```\n\nThe model is an object which Monaco uses to keep track of text in the editor. You can find the full type definition at `node_modules/monaco-editor/esm/vs/editor/editor.api.d.ts`.  \n\n### **container**\n\n```typescript\n{ref: HTMLDivElement, width: number, height: number}\n```\n\nThis is an object that contains the container `div` element that wraps the entire sidebar as well as it's dimensions in reactive React state. You can wrap the dimension values in a `useEffect` to be notified of any changes to the size of the container. The React app is mounted to this element. Any style changes to this element will affect the entire sidebar.\n\n### **showModal**\n\n```typescript\n(code: string, subtitle?: string, links?: string[]) =\u003e void\n```\nFrom `window.playground.ui` - This function accepts three arguments (code, subtitle, and links) and opens a model with the values you provide.\n\n### **flashInfo**\n\n```typescript\n(message: string) =\u003e void\n```\nFrom `window.playground.ui` - This function accepts one argument (message) and and flashes a quick message in the center of the screen. \n\n### **utils**\n\n```typescript\n{\n  el: (str: string, el: string, container: Element) =\u003e void;, \n  requireURL: (path: string) =\u003e string;, \n  createASTTree: (node: Node) =\u003e HTMLDivElement;\n}\n```\nAn object that contains three additional config options and functionality. `el`, `requireURL`, and `createASTTree`. See `src/plugin/vendor/pluginUtils.d.ts` for more information. \n                                                                                                                           \n\u003chr /\u003e\n\n### Example `usePlugin` Usage\n\n```tsx\nconst {\n  code,\n  setCode,\n  formatCode,\n  markers,\n  setDebounce,\n  sandbox,\n  model,\n  container,\n  flashInfo,\n  showModal,\n  utils\n} = usePlugin();\n\n// Here are some examples of things you can do:\n\nsetDebounce(true);\n\n// Set the code in the Monaco editor\nuseEffect(() =\u003e {\n  const defaultCode = `const greet = (): string =\u003e \"Hi👋\";`;\n  setCode(defaultCode, { format: true });\n}, []);\n\n// Listen for changes to the code in the Monaco editor\nuseEffect(() =\u003e {\n  flashInfo(\"The code was updated.\");\n  showModal(code, \"Here is your code\");\n}, [code]);\n\nconst renderMarkers = markers.map(marker =\u003e {\n  return \u003cdiv key={marker.key}\u003e{marker.message}\u003c/div\u003e;\n});\n\n// See App.tsx for additional usage examples\n```\n\n## Styling your plugin\n\nThis library works with normal CSS stylesheets out of the box by inlining them using PostCSS. It also includes [Goober](https://github.com/cristianbote/goober), a super light-weight (\u003c1KB) CSS-in-JS library. There are examples of both styling approaches in `src/App.tsx`. Any other styling solutions may require additional rollup configuration.\n\nThe `container` provided by the `usePlayground` hook can also be styled. Be careful as this will affect all tabs in the sidebar.\n\n## More about TypeScript Playground Plugins\n\n[Official Playground Plugin Documentation](https://www.typescriptlang.org/v2/dev/playground-plugins/)\n\nYou can create a plugin (without React) from the official plugin template:\n\n```sh\nnpm init typescript-playground-plugin playground-my-plugin\n```\n\nFor convenience, this repo contains the `CONTRIBUTING.md` file included in the official plugin template. This document contains useful information about how to work with the plugins.\n\nThe `src/plugin/vendor` directory contains all of the TypeScript type definitions for the TypeScript Playground Plugin API. This is the best place to find the various config options, properties, and methods that are available.\n\n### Need inspiration?\n\n[Orta](https://github.com/orta) created a really cool plugin that lets you create presentations in the TypeScript playground using Reveal.js. You can check it out here:\n\n[https://github.com/orta/playground-slides](https://github.com/orta/playground-slides)\n\nHe also offered these plugin ideas in [this](https://github.com/microsoft/TypeScript-Website/issues/221) issue.\n\n- An LSP-ish Playground where you can make see the response to specific calls\n- An English explainer which explains a complex TS type\n- Convert TS dts -\u003e Flow interfaces(flowgen)\n- Run tutorials in the playground against live code as a learning tool\n- AST Viewer\n- ts-query runner\n- codemod runner\n- Highlight TS vs JS (or type vs value) parts of some code code\n- Show all used types in a file\n- Show dts files in the current workspace\n- Edit an ambient dts file\n\n## TODOS\n\nIn no particular order.\n\n- [ ] Add ability to import SVGs with `import` syntax without TypeScript errors.\n- [ ] Reload the TypeScript Playground browser tab on plugin changes if possible.\n- [ ] Add configuration for other styling solutions (Styled Component, Emotion, Styled JSX)\n- [ ] Add additional examples, including AST Tree.\n- [ ] Add ability to destructure named imports `import React, { useEffect } from \"react\";` if possible.\n- [ ] Incorporate Jest and React Testing Library.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjust214%2Ftypescript-playground-plugin-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjust214%2Ftypescript-playground-plugin-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjust214%2Ftypescript-playground-plugin-react/lists"}