dart-lang / dart-pad

An online Dart editor with support for console, web, and Flutter apps
https://dartpad.dev
BSD 3-Clause "New" or "Revised" License
1.7k stars 551 forks source link

lightweight dartpad embedding #2702

Open devoncarew opened 10 months ago

devoncarew commented 10 months ago

Opening this issue after a discussion with @parlough. He noted that DartPad embeddings (an embedded version of DartPad running in an iframe in another web page) is effective but heavy weight; many such embedding can slow a page down.

@parlough - can you sketch out what you were thinking wrt but a lighter-weight embedding might look like? Just a div, styled dart text, and a 'run' button that called the dartpad backend to compile?

devoncarew commented 10 months ago

(cc @johnpryan)

parlough commented 10 months ago

Yeah sorry I hadn't gotten around to this yet. I'll add some more details and background here tomorrow.

parlough commented 10 months ago

Background

Embedded DartPads were avoided or just not explored in many of the cases they would be beneficial because of a few reasons:

However being able to run snippets helps users visualize the flow of a program and can be an important pedagogical tool, or just useful to visualize the output of a collection of Flutter code. I think it would however be most helpful when learning Dart code, such as in the language documentation/tour.

My discussion is focused on the dart.dev and docs.flutter.dev use cases, but I am assuming much of this applies to api.flutter.dev as well. api.dart.dev does not yet have runnable snippets but it definitely could benefit from them.

One exception to this discussion are codelabs (https://dart.dev/codelabs), which are meant to be edited in most situations and use additional features such as tests, solutions, etc. This issue does not cover those use cases, as I still think they are important but best served in an integrated feature more similar to DartPad workshops. I will open a separate issue discussing this and update this with the link once that is ready.

Suggestion

I propose we implement lighter weight tooling that does not use the DartPad/SketchPad user interface and a library that any website can integrate with its code snippets.

Functionality

I'm not exactly sure where the cut-off should be yet, but I believe this functionality is best split into two separate pieces, with the core being a library. It would however be nice to implement further UI functionality so that each website doesn't have to hook up the library themselves.

Library

I would hope the core library has the following functionality:

User interface

I'm not sure how much of the UI and hook-up functionality can be shared, or if any should, but I imagine a UI for this would benefit from the following functionality:

Extra: Editable snippets
While not necessary for this project, when learning coding it is important to be able to experiment and make changes, and understand how that affects app behavior. It would be nice to optionally enable a simple editing functionality (just syntax highlighting). If we can open a snippet in a full DartPad this wouldn't be necessary though. While I don't think this is necessary for this project if we can open the code in a full DartPad - Editable code block - With at least basic syntax highlighting - Can run modified snippet - Can reset to original snippet

Implementation notes

The UI portions could be implemented by each website using the built library. That may make sense as a good first step, but I worry it be a lot of repetitive work when we could share. So we could maybe introduce a customizable standard HTML web component that could be used by dart.dev, docs.flutter.dev, api.flutter.dev, and anyone in the community that wants to easily embed runnable Dart code :D

There are other options to share some of the functionality as well.

Expand for an example of how this might be written. ````markdown ```dart runnable run-on-load lazy service="beta.api.dartpad.dev" void main() { print('Hello, I'm Dash!'); } ``` ```` Might be converted to something like the following when generating the site. ```html

void main() {
  print('Hello, I'm Dash!');
}
```

Preview

A rough example of what this could look if integrated into dart.dev:

https://github.com/dart-lang/dart-pad/assets/18372958/a15b3bad-bc72-4e3f-ba6f-f4c3fcb46bb3

Related works

The following are links to an example of similar functionality in other language documentation.

rekire commented 7 months ago

I'm a bit late at the party but I think my issue goes in the same direction isn't it? https://github.com/dart-lang/dart-pad/issues/2697 I see there some similarities to #1769

johnpryan commented 7 months ago

@rekire this feature is only a change to how the UI works, supporting arbitrary packages isn't something on our roadmap.

xdega commented 1 month ago

Background

Embedded DartPads were avoided or just not explored in many of the cases they would be beneficial because of a few reasons:

* They don't fit naturally into the websites from a style point of view

* They are heavy to load and run, with each one being an isolated embedded iframe.

* Most samples don't need to be edited by users, so it was often overkill

* Embedded DartPads are generally not super accessible

However being able to run snippets helps users visualize the flow of a program and can be an important pedagogical tool, or just useful to visualize the output of a collection of Flutter code. I think it would however be most helpful when learning Dart code, such as in the language documentation/tour.

My discussion is focused on the dart.dev and docs.flutter.dev use cases, but I am assuming much of this applies to api.flutter.dev as well. api.dart.dev does not yet have runnable snippets but it definitely could benefit from them.

One exception to this discussion are codelabs (https://dart.dev/codelabs), which are meant to be edited in most situations and use additional features such as tests, solutions, etc. This issue does not cover those use cases, as I still think they are important but best served in an integrated feature more similar to DartPad workshops. I will open a separate issue discussing this and update this with the link once that is ready.

Suggestion

I propose we implement lighter weight tooling that does not use the DartPad/SketchPad user interface and a library that any website can integrate with its code snippets.

Functionality

I'm not exactly sure where the cut-off should be yet, but I believe this functionality is best split into two separate pieces, with the core being a library. It would however be nice to implement further UI functionality so that each website doesn't have to hook up the library themselves.

Library

I would hope the core library has the following functionality:

* Accepts Dart code formatted as a string and compiles it with dart-services.

* When dart-services returns the compiled code, run it.

  * Return any compilation errors back to the caller.
  * Stream the console output back to the caller.
  * If Flutter, create an iframe element with the app that the caller can place as desired.

* Some way to stop the app from running.

* Some way to open the requested code in a full DartPad.

  * Either in a new tab or a large popup/dialog. Or both.

User interface

I'm not sure how much of the UI and hook-up functionality can be shared, or if any should, but I imagine a UI for this would benefit from the following functionality:

* A potentially statically syntax highlighted `<pre><code>` element with the code to run.

  * Will remove/ignore inline spans before compiling.

* A run button to run the code.

  * Can optionally automatically run the code on load based off parameter/data of some type.

* A stop button to stop the app.

* A console/terminal that appears once running a Dart app or there is a compilation error.

* An iframe view for Flutter apps that appears (below?) the code block once ran.

  * Some Flutter use cases might want a way to hide the code, not sure.

* Some way to close the console/app view.

* A button to open the code in a full DartPad.

* **Desired but not required:** A way to hide some code from the view. Comments, line numbers, something.

  * This could be a `main` block, imports, etc. Being able to hide some of it allows the snippet to focus on what it's teaching but still be runnable.

Extra: Editable snippets While not necessary for this project, when learning coding it is important to be able to experiment and make changes, and understand how that affects app behavior. It would be nice to optionally enable a simple editing functionality (just syntax highlighting). If we can open a snippet in a full DartPad this wouldn't be necessary though. While I don't think this is necessary for this project if we can open the code in a full DartPad

Implementation notes

The UI portions could be implemented by each website using the built library. That may make sense as a good first step, but I worry it be a lot of repetitive work when we could share. So we could maybe introduce a customizable standard HTML web component that could be used by dart.dev, docs.flutter.dev, api.flutter.dev, and anyone in the community that wants to easily embed runnable Dart code :D

* A web component.

  * Perhaps implemented with [Lit 3](https://lit.dev/)
  * Could be bundled and hosted on a CDN

* [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) to style the component

* Should allow some configurable attributes. Some I can think of:

  * Run on load
  * Syntax highlight
  * Dart services endpoint (Different channel, different mirror (CN))
  * Maybe other configuration (copy button, open in DartPad, etc)

There are other options to share some of the functionality as well. Expand for an example of how this might be written.

Preview

A rough example of what this could look if integrated into dart.dev: lightweight-dartpad.mov

Related works

The following are links to an example of similar functionality in other language documentation.

* [Kotlin language docs](https://kotlinlang.org/docs/control-flow.html#if-expression)

* [Rust book](https://kotlinlang.org/docs/control-flow.html#if-expression)

I know I am waaay late to the party here, but is this initiative still ongoing? I am in the process of rebuilding my personal website, and would love a more "minimal" UI, for embedding/sharing my Dartpad projects. What is shown in the .mov here looks great.

Levi-Lesches commented 1 month ago

@devoncarew I'm taking an interest in spending more time on DartPad work. I'm not too familiar with the internals yet but if you have any concrete pointers I can take a look

devoncarew commented 1 month ago

I know I am waaay late to the party here, but is this initiative still ongoing?

@xdega, this is not actively being working on. It is something we would generally like but I'm uncertain how it fits into our general priorities (something we'd do ourselves, something we could take the bandwidth to review, whether we could take on any maintenance costs associated with a solution here, ...).

I'm taking an interest in spending more time on DartPad work.

@Levi-Lesches - great! Looking at our issues here, it doesn't look like we're tagging anything with 'good first issue' or similar. I am aware of some work we do need - we had to remove the UI we had to show dartdoc help (https://github.com/dart-lang/dart-pad/pull/3034); we would like to restore that, likely as more of a tooltips style help (tracked in https://github.com/dart-lang/dart-pad/issues/3032).

I'd suggest that if you are interested in picking up anything from the issue tracker - or todos from the code? - that you start w/ a conversation in an issue. cc'ing @johnpryan and @parlough as well