@elastic/isomer-studio 0.0.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +93 -0
- package/NOTICE.txt +17329 -0
- package/README.md +64 -0
- package/THIRD_PARTY_LICENSES.md +404 -0
- package/bin/isomer-studio.js +10 -0
- package/dist/app/assets/codicon-5T574S7B.ttf +0 -0
- package/dist/app/assets/editor.worker.js +11 -0
- package/dist/app/assets/esbuild.wasm +0 -0
- package/dist/app/assets/json.worker.js +47 -0
- package/dist/app/assets/slack.css +1 -0
- package/dist/app/assets/studio.css +11 -0
- package/dist/app/assets/ts.worker.js +37029 -0
- package/dist/app/index.html +16 -0
- package/dist/apps/app_host.d.ts +8 -0
- package/dist/apps/app_host.d.ts.map +1 -0
- package/dist/apps/app_host.js +73 -0
- package/dist/apps/app_host.js.map +1 -0
- package/dist/browser/dev_host.d.ts +5 -0
- package/dist/browser/dev_host.d.ts.map +1 -0
- package/dist/browser/dev_host.js +46 -0
- package/dist/browser/dev_host.js.map +1 -0
- package/dist/browser/mount.d.ts +16 -0
- package/dist/browser/mount.d.ts.map +1 -0
- package/dist/browser/mount.js +37 -0
- package/dist/browser/mount.js.map +1 -0
- package/dist/browser/static_host.d.ts +5 -0
- package/dist/browser/static_host.d.ts.map +1 -0
- package/dist/browser/static_host.js +55 -0
- package/dist/browser/static_host.js.map +1 -0
- package/dist/chrome/accent.d.ts +14 -0
- package/dist/chrome/accent.d.ts.map +1 -0
- package/dist/chrome/accent.js +31 -0
- package/dist/chrome/accent.js.map +1 -0
- package/dist/chrome/app_pages.d.ts +13 -0
- package/dist/chrome/app_pages.d.ts.map +1 -0
- package/dist/chrome/app_pages.js +33 -0
- package/dist/chrome/app_pages.js.map +1 -0
- package/dist/chrome/color_mode.d.ts +10 -0
- package/dist/chrome/color_mode.d.ts.map +1 -0
- package/dist/chrome/color_mode.js +45 -0
- package/dist/chrome/color_mode.js.map +1 -0
- package/dist/chrome/dev_tint.d.ts +7 -0
- package/dist/chrome/dev_tint.d.ts.map +1 -0
- package/dist/chrome/dev_tint.js +31 -0
- package/dist/chrome/dev_tint.js.map +1 -0
- package/dist/chrome/header.d.ts +20 -0
- package/dist/chrome/header.d.ts.map +1 -0
- package/dist/chrome/header.js +124 -0
- package/dist/chrome/header.js.map +1 -0
- package/dist/chrome/icon_data_uri.d.ts +12 -0
- package/dist/chrome/icon_data_uri.d.ts.map +1 -0
- package/dist/chrome/icon_data_uri.js +21 -0
- package/dist/chrome/icon_data_uri.js.map +1 -0
- package/dist/chrome/isomer_mark.d.ts +17 -0
- package/dist/chrome/isomer_mark.d.ts.map +1 -0
- package/dist/chrome/isomer_mark.js +46 -0
- package/dist/chrome/isomer_mark.js.map +1 -0
- package/dist/chrome/nav.d.ts +22 -0
- package/dist/chrome/nav.d.ts.map +1 -0
- package/dist/chrome/nav.js +306 -0
- package/dist/chrome/nav.js.map +1 -0
- package/dist/chrome/nav_groups.d.ts +6 -0
- package/dist/chrome/nav_groups.d.ts.map +1 -0
- package/dist/chrome/nav_groups.js +48 -0
- package/dist/chrome/nav_groups.js.map +1 -0
- package/dist/chrome/nav_sections.d.ts +29 -0
- package/dist/chrome/nav_sections.d.ts.map +1 -0
- package/dist/chrome/nav_sections.js +55 -0
- package/dist/chrome/nav_sections.js.map +1 -0
- package/dist/chrome/oklch.d.ts +10 -0
- package/dist/chrome/oklch.d.ts.map +1 -0
- package/dist/chrome/oklch.js +61 -0
- package/dist/chrome/oklch.js.map +1 -0
- package/dist/chrome/primitive_glyph.d.ts +14 -0
- package/dist/chrome/primitive_glyph.d.ts.map +1 -0
- package/dist/chrome/primitive_glyph.js +48 -0
- package/dist/chrome/primitive_glyph.js.map +1 -0
- package/dist/chrome/primitive_heading.d.ts +14 -0
- package/dist/chrome/primitive_heading.d.ts.map +1 -0
- package/dist/chrome/primitive_heading.js +32 -0
- package/dist/chrome/primitive_heading.js.map +1 -0
- package/dist/chrome/primitive_peek.d.ts +8 -0
- package/dist/chrome/primitive_peek.d.ts.map +1 -0
- package/dist/chrome/primitive_peek.js +51 -0
- package/dist/chrome/primitive_peek.js.map +1 -0
- package/dist/chrome/primitive_search.d.ts +9 -0
- package/dist/chrome/primitive_search.d.ts.map +1 -0
- package/dist/chrome/primitive_search.js +93 -0
- package/dist/chrome/primitive_search.js.map +1 -0
- package/dist/chrome/route.d.ts +48 -0
- package/dist/chrome/route.d.ts.map +1 -0
- package/dist/chrome/route.js +136 -0
- package/dist/chrome/route.js.map +1 -0
- package/dist/cli/args.d.ts +39 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +171 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/run.d.ts +15 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +113 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +22 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +118 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -0
- package/dist/dev/code_editor.d.ts +10 -0
- package/dist/dev/code_editor.d.ts.map +1 -0
- package/dist/dev/code_editor.js +22 -0
- package/dist/dev/code_editor.js.map +1 -0
- package/dist/dev/dev_view.d.ts +9 -0
- package/dist/dev/dev_view.d.ts.map +1 -0
- package/dist/dev/dev_view.js +65 -0
- package/dist/dev/dev_view.js.map +1 -0
- package/dist/dev/editor_panel.d.ts +17 -0
- package/dist/dev/editor_panel.d.ts.map +1 -0
- package/dist/dev/editor_panel.js +51 -0
- package/dist/dev/editor_panel.js.map +1 -0
- package/dist/dev/monaco_editor.d.ts +15 -0
- package/dist/dev/monaco_editor.d.ts.map +1 -0
- package/dist/dev/monaco_editor.js +159 -0
- package/dist/dev/monaco_editor.js.map +1 -0
- package/dist/dev/preview_panel.d.ts +10 -0
- package/dist/dev/preview_panel.d.ts.map +1 -0
- package/dist/dev/preview_panel.js +45 -0
- package/dist/dev/preview_panel.js.map +1 -0
- package/dist/dev/prop_reference.d.ts +9 -0
- package/dist/dev/prop_reference.d.ts.map +1 -0
- package/dist/dev/prop_reference.js +134 -0
- package/dist/dev/prop_reference.js.map +1 -0
- package/dist/dev/tsx_language.d.ts +10 -0
- package/dist/dev/tsx_language.d.ts.map +1 -0
- package/dist/dev/tsx_language.js +283 -0
- package/dist/dev/tsx_language.js.map +1 -0
- package/dist/dev/use_editor.d.ts +23 -0
- package/dist/dev/use_editor.d.ts.map +1 -0
- package/dist/dev/use_editor.js +124 -0
- package/dist/dev/use_editor.js.map +1 -0
- package/dist/docs/docs_view.d.ts +10 -0
- package/dist/docs/docs_view.d.ts.map +1 -0
- package/dist/docs/docs_view.js +80 -0
- package/dist/docs/docs_view.js.map +1 -0
- package/dist/docs/example_source.d.ts +7 -0
- package/dist/docs/example_source.d.ts.map +1 -0
- package/dist/docs/example_source.js +56 -0
- package/dist/docs/example_source.js.map +1 -0
- package/dist/docs/examples_panel.d.ts +10 -0
- package/dist/docs/examples_panel.d.ts.map +1 -0
- package/dist/docs/examples_panel.js +51 -0
- package/dist/docs/examples_panel.js.map +1 -0
- package/dist/docs/gallery_view.d.ts +9 -0
- package/dist/docs/gallery_view.d.ts.map +1 -0
- package/dist/docs/gallery_view.js +98 -0
- package/dist/docs/gallery_view.js.map +1 -0
- package/dist/docs/inline_code.d.ts +11 -0
- package/dist/docs/inline_code.d.ts.map +1 -0
- package/dist/docs/inline_code.js +24 -0
- package/dist/docs/inline_code.js.map +1 -0
- package/dist/docs/on_this_page.d.ts +17 -0
- package/dist/docs/on_this_page.d.ts.map +1 -0
- package/dist/docs/on_this_page.js +77 -0
- package/dist/docs/on_this_page.js.map +1 -0
- package/dist/docs/props_table.d.ts +14 -0
- package/dist/docs/props_table.d.ts.map +1 -0
- package/dist/docs/props_table.js +34 -0
- package/dist/docs/props_table.js.map +1 -0
- package/dist/home/apps_section.d.ts +6 -0
- package/dist/home/apps_section.d.ts.map +1 -0
- package/dist/home/apps_section.js +44 -0
- package/dist/home/apps_section.js.map +1 -0
- package/dist/home/featured_strip.d.ts +12 -0
- package/dist/home/featured_strip.d.ts.map +1 -0
- package/dist/home/featured_strip.js +176 -0
- package/dist/home/featured_strip.js.map +1 -0
- package/dist/home/home_view.d.ts +11 -0
- package/dist/home/home_view.d.ts.map +1 -0
- package/dist/home/home_view.js +261 -0
- package/dist/home/home_view.js.map +1 -0
- package/dist/home/links.d.ts +8 -0
- package/dist/home/links.d.ts.map +1 -0
- package/dist/home/links.js +14 -0
- package/dist/home/links.js.map +1 -0
- package/dist/home/loaded_panel.d.ts +6 -0
- package/dist/home/loaded_panel.d.ts.map +1 -0
- package/dist/home/loaded_panel.js +116 -0
- package/dist/home/loaded_panel.js.map +1 -0
- package/dist/home/surface_chart.d.ts +6 -0
- package/dist/home/surface_chart.d.ts.map +1 -0
- package/dist/home/surface_chart.js +263 -0
- package/dist/home/surface_chart.js.map +1 -0
- package/dist/home/tokens.d.ts +49 -0
- package/dist/home/tokens.d.ts.map +1 -0
- package/dist/home/tokens.js +171 -0
- package/dist/home/tokens.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/model/app_problems.d.ts +4 -0
- package/dist/model/app_problems.d.ts.map +1 -0
- package/dist/model/app_problems.js +90 -0
- package/dist/model/app_problems.js.map +1 -0
- package/dist/model/authoring_types.d.ts +23 -0
- package/dist/model/authoring_types.d.ts.map +1 -0
- package/dist/model/authoring_types.js +35 -0
- package/dist/model/authoring_types.js.map +1 -0
- package/dist/model/compile_jsx.d.ts +19 -0
- package/dist/model/compile_jsx.d.ts.map +1 -0
- package/dist/model/compile_jsx.js +55 -0
- package/dist/model/compile_jsx.js.map +1 -0
- package/dist/model/compose_example.d.ts +9 -0
- package/dist/model/compose_example.d.ts.map +1 -0
- package/dist/model/compose_example.js +24 -0
- package/dist/model/compose_example.js.map +1 -0
- package/dist/model/composition_key.d.ts +6 -0
- package/dist/model/composition_key.d.ts.map +1 -0
- package/dist/model/composition_key.js +26 -0
- package/dist/model/composition_key.js.map +1 -0
- package/dist/model/describe_runtime.d.ts +33 -0
- package/dist/model/describe_runtime.d.ts.map +1 -0
- package/dist/model/describe_runtime.js +77 -0
- package/dist/model/describe_runtime.js.map +1 -0
- package/dist/model/featured.d.ts +11 -0
- package/dist/model/featured.d.ts.map +1 -0
- package/dist/model/featured.js +70 -0
- package/dist/model/featured.js.map +1 -0
- package/dist/model/jsx_transform.d.ts +10 -0
- package/dist/model/jsx_transform.d.ts.map +1 -0
- package/dist/model/jsx_transform.js +31 -0
- package/dist/model/jsx_transform.js.map +1 -0
- package/dist/model/png_manifest.d.ts +23 -0
- package/dist/model/png_manifest.d.ts.map +1 -0
- package/dist/model/png_manifest.js +26 -0
- package/dist/model/png_manifest.js.map +1 -0
- package/dist/model/read_examples.d.ts +12 -0
- package/dist/model/read_examples.d.ts.map +1 -0
- package/dist/model/read_examples.js +43 -0
- package/dist/model/read_examples.js.map +1 -0
- package/dist/model/search.d.ts +4 -0
- package/dist/model/search.d.ts.map +1 -0
- package/dist/model/search.js +29 -0
- package/dist/model/search.js.map +1 -0
- package/dist/model/sha256.d.ts +3 -0
- package/dist/model/sha256.d.ts.map +1 -0
- package/dist/model/sha256.js +72 -0
- package/dist/model/sha256.js.map +1 -0
- package/dist/model/slack_limits.d.ts +9 -0
- package/dist/model/slack_limits.d.ts.map +1 -0
- package/dist/model/slack_limits.js +213 -0
- package/dist/model/slack_limits.js.map +1 -0
- package/dist/node/app_bundle.d.ts +45 -0
- package/dist/node/app_bundle.d.ts.map +1 -0
- package/dist/node/app_bundle.js +212 -0
- package/dist/node/app_bundle.js.map +1 -0
- package/dist/node/build_site.d.ts +28 -0
- package/dist/node/build_site.d.ts.map +1 -0
- package/dist/node/build_site.js +90 -0
- package/dist/node/build_site.js.map +1 -0
- package/dist/node/check.d.ts +40 -0
- package/dist/node/check.d.ts.map +1 -0
- package/dist/node/check.js +162 -0
- package/dist/node/check.js.map +1 -0
- package/dist/node/dev_bundle.d.ts +21 -0
- package/dist/node/dev_bundle.d.ts.map +1 -0
- package/dist/node/dev_bundle.js +121 -0
- package/dist/node/dev_bundle.js.map +1 -0
- package/dist/node/dev_server.d.ts +16 -0
- package/dist/node/dev_server.d.ts.map +1 -0
- package/dist/node/dev_server.js +291 -0
- package/dist/node/dev_server.js.map +1 -0
- package/dist/node/init_config.d.ts +30 -0
- package/dist/node/init_config.d.ts.map +1 -0
- package/dist/node/init_config.js +158 -0
- package/dist/node/init_config.js.map +1 -0
- package/dist/node/load_config.d.ts +34 -0
- package/dist/node/load_config.d.ts.map +1 -0
- package/dist/node/load_config.js +246 -0
- package/dist/node/load_config.js.map +1 -0
- package/dist/node/project_resolution.d.ts +17 -0
- package/dist/node/project_resolution.d.ts.map +1 -0
- package/dist/node/project_resolution.js +66 -0
- package/dist/node/project_resolution.js.map +1 -0
- package/dist/node/rasterize.d.ts +23 -0
- package/dist/node/rasterize.d.ts.map +1 -0
- package/dist/node/rasterize.js +79 -0
- package/dist/node/rasterize.js.map +1 -0
- package/dist/node/report.d.ts +8 -0
- package/dist/node/report.d.ts.map +1 -0
- package/dist/node/report.js +57 -0
- package/dist/node/report.js.map +1 -0
- package/dist/node/resolve_hooks.d.ts +16 -0
- package/dist/node/resolve_hooks.d.ts.map +1 -0
- package/dist/node/resolve_hooks.js +104 -0
- package/dist/node/resolve_hooks.js.map +1 -0
- package/dist/studio.d.ts +4 -0
- package/dist/studio.d.ts.map +1 -0
- package/dist/studio.js +188 -0
- package/dist/studio.js.map +1 -0
- package/dist/studio_context.d.ts +27 -0
- package/dist/studio_context.d.ts.map +1 -0
- package/dist/studio_context.js +17 -0
- package/dist/studio_context.js.map +1 -0
- package/dist/surfaces/adopt_stylesheet.d.ts +7 -0
- package/dist/surfaces/adopt_stylesheet.d.ts.map +1 -0
- package/dist/surfaces/adopt_stylesheet.js +64 -0
- package/dist/surfaces/adopt_stylesheet.js.map +1 -0
- package/dist/surfaces/app_preview.d.ts +4 -0
- package/dist/surfaces/app_preview.d.ts.map +1 -0
- package/dist/surfaces/app_preview.js +28 -0
- package/dist/surfaces/app_preview.js.map +1 -0
- package/dist/surfaces/app_surface.d.ts +9 -0
- package/dist/surfaces/app_surface.d.ts.map +1 -0
- package/dist/surfaces/app_surface.js +27 -0
- package/dist/surfaces/app_surface.js.map +1 -0
- package/dist/surfaces/applicable_enhancements.d.ts +4 -0
- package/dist/surfaces/applicable_enhancements.d.ts.map +1 -0
- package/dist/surfaces/applicable_enhancements.js +16 -0
- package/dist/surfaces/applicable_enhancements.js.map +1 -0
- package/dist/surfaces/enhancement_select.d.ts +10 -0
- package/dist/surfaces/enhancement_select.d.ts.map +1 -0
- package/dist/surfaces/enhancement_select.js +28 -0
- package/dist/surfaces/enhancement_select.js.map +1 -0
- package/dist/surfaces/example_picker.d.ts +11 -0
- package/dist/surfaces/example_picker.d.ts.map +1 -0
- package/dist/surfaces/example_picker.js +44 -0
- package/dist/surfaces/example_picker.js.map +1 -0
- package/dist/surfaces/format_source.d.ts +4 -0
- package/dist/surfaces/format_source.d.ts.map +1 -0
- package/dist/surfaces/format_source.js +30 -0
- package/dist/surfaces/format_source.js.map +1 -0
- package/dist/surfaces/html_surface.d.ts +14 -0
- package/dist/surfaces/html_surface.d.ts.map +1 -0
- package/dist/surfaces/html_surface.js +122 -0
- package/dist/surfaces/html_surface.js.map +1 -0
- package/dist/surfaces/png_surface.d.ts +13 -0
- package/dist/surfaces/png_surface.d.ts.map +1 -0
- package/dist/surfaces/png_surface.js +68 -0
- package/dist/surfaces/png_surface.js.map +1 -0
- package/dist/surfaces/react_surface.d.ts +11 -0
- package/dist/surfaces/react_surface.d.ts.map +1 -0
- package/dist/surfaces/react_surface.js +55 -0
- package/dist/surfaces/react_surface.js.map +1 -0
- package/dist/surfaces/render_output.d.ts +31 -0
- package/dist/surfaces/render_output.d.ts.map +1 -0
- package/dist/surfaces/render_output.js +119 -0
- package/dist/surfaces/render_output.js.map +1 -0
- package/dist/surfaces/scaled_preview.d.ts +17 -0
- package/dist/surfaces/scaled_preview.d.ts.map +1 -0
- package/dist/surfaces/scaled_preview.js +74 -0
- package/dist/surfaces/scaled_preview.js.map +1 -0
- package/dist/surfaces/shadow_root.d.ts +8 -0
- package/dist/surfaces/shadow_root.d.ts.map +1 -0
- package/dist/surfaces/shadow_root.js +41 -0
- package/dist/surfaces/shadow_root.js.map +1 -0
- package/dist/surfaces/slack_surface.d.ts +12 -0
- package/dist/surfaces/slack_surface.d.ts.map +1 -0
- package/dist/surfaces/slack_surface.js +27 -0
- package/dist/surfaces/slack_surface.js.map +1 -0
- package/dist/surfaces/snapshot_surface.d.ts +6 -0
- package/dist/surfaces/snapshot_surface.d.ts.map +1 -0
- package/dist/surfaces/snapshot_surface.js +5 -0
- package/dist/surfaces/snapshot_surface.js.map +1 -0
- package/dist/surfaces/surface_board.d.ts +19 -0
- package/dist/surfaces/surface_board.d.ts.map +1 -0
- package/dist/surfaces/surface_board.js +128 -0
- package/dist/surfaces/surface_board.js.map +1 -0
- package/dist/surfaces/surface_frame.d.ts +8 -0
- package/dist/surfaces/surface_frame.d.ts.map +1 -0
- package/dist/surfaces/surface_frame.js +4 -0
- package/dist/surfaces/surface_frame.js.map +1 -0
- package/dist/surfaces/surface_logos.d.ts +9 -0
- package/dist/surfaces/surface_logos.d.ts.map +1 -0
- package/dist/surfaces/surface_logos.js +21 -0
- package/dist/surfaces/surface_logos.js.map +1 -0
- package/dist/surfaces/surface_preview.d.ts +32 -0
- package/dist/surfaces/surface_preview.d.ts.map +1 -0
- package/dist/surfaces/surface_preview.js +66 -0
- package/dist/surfaces/surface_preview.js.map +1 -0
- package/dist/surfaces/surface_select.d.ts +34 -0
- package/dist/surfaces/surface_select.d.ts.map +1 -0
- package/dist/surfaces/surface_select.js +119 -0
- package/dist/surfaces/surface_select.js.map +1 -0
- package/dist/surfaces/text_surfaces.d.ts +14 -0
- package/dist/surfaces/text_surfaces.d.ts.map +1 -0
- package/dist/surfaces/text_surfaces.js +31 -0
- package/dist/surfaces/text_surfaces.js.map +1 -0
- package/dist/surfaces/zoom_select.d.ts +9 -0
- package/dist/surfaces/zoom_select.d.ts.map +1 -0
- package/dist/surfaces/zoom_select.js +32 -0
- package/dist/surfaces/zoom_select.js.map +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/docs/ci.md +55 -0
- package/docs/commands.md +167 -0
- package/docs/config.md +192 -0
- package/docs/images/home.png +0 -0
- package/docs/images/reference.png +0 -0
- package/docs/images/workbench.png +0 -0
- package/docs/index.md +96 -0
- package/docs/toc.yml +10 -0
- package/package.json +89 -5
package/docs/ci.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
navigation_title: In CI
|
|
3
|
+
description: Run isomer-studio check and build in GitHub Actions with the composite action, and upload the report and the site.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# In CI
|
|
7
|
+
|
|
8
|
+
`check` is the gate: it exits 1 when any example fails to validate or render. `build` is the preview: upload the site and every PR gets a Studio a reviewer can download.
|
|
9
|
+
|
|
10
|
+
## The GitHub Action
|
|
11
|
+
|
|
12
|
+
The Isomer repository has a composite action that runs both and uploads what they write. It runs the `isomer-studio` binary installed in `working-directory`, so install the pack's dependencies, `@elastic/isomer-studio` among them, first. Then:
|
|
13
|
+
|
|
14
|
+
```yaml
|
|
15
|
+
- uses: elastic/isomer/.github/actions/isomer-studio@main
|
|
16
|
+
with:
|
|
17
|
+
config: isomer-studio.config.ts
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
| Input | Default | What it does |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| `config` | Required | The config, relative to `working-directory`. |
|
|
23
|
+
| `working-directory` | `.` | Where the `isomer-studio` command resolves. `config`, `out` and `report` resolve against it. |
|
|
24
|
+
| `check` | `true` | Runs `check`, writing a JUnit report. A failure fails the step. |
|
|
25
|
+
| `png` | `false` | Adds `--png` to the check. |
|
|
26
|
+
| `report` | `isomer-studio-report.xml` | Where the report goes. It uploads as `<artifact-name>-report`, even when the check fails. |
|
|
27
|
+
| `build` | `true` | Runs `build`, even when the check failed. |
|
|
28
|
+
| `out` | `dist/studio` | Where the site goes. |
|
|
29
|
+
| `base` | `./` | The URL path the site is served from. |
|
|
30
|
+
| `artifact-name` | `isomer-studio` | The name of the uploaded site. |
|
|
31
|
+
|
|
32
|
+
The Isomer repository runs it on the slides pack in its own CI, after `pnpm verify`.
|
|
33
|
+
|
|
34
|
+
## Without the action
|
|
35
|
+
|
|
36
|
+
The action is two commands. On another CI system, run them yourself:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
npx isomer-studio check --config isomer-studio.config.ts --format junit --report isomer-studio-report.xml
|
|
40
|
+
npx isomer-studio build --config isomer-studio.config.ts --out dist/studio
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`npx @elastic/isomer-studio check` also works without installing the Studio, but an installed one keeps CI on the version the lockfile pins.
|
|
44
|
+
|
|
45
|
+
`build` and `check --png` rasterize with `@elastic/isomer-image-takumi`, a native dependency the Studio installs for the platform it runs on.
|
|
46
|
+
|
|
47
|
+
## Deploying with docs
|
|
48
|
+
|
|
49
|
+
To serve the Studio from a docs site, build it into the site's output with the path it will be served from:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
npx isomer-studio build --config isomer-studio.config.ts --out site/studio-app --base /my-docs/studio-app/
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Give the app its own directory, not the one the Studio's or the pack's docs build into, so neither overwrites the other.
|
package/docs/commands.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
navigation_title: Commands
|
|
3
|
+
description: The flags of isomer-studio init, dev, build and check, the config init writes, the files a build writes, and what a static site can and cannot do.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Commands
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
isomer-studio [command] [options]
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
With no command, `isomer-studio` runs `dev`. Every command takes these options:
|
|
13
|
+
|
|
14
|
+
| Option | Default | What it does |
|
|
15
|
+
| -------------------- | --------------------- | ----------------------------------------------------------------------------------------------- |
|
|
16
|
+
| `--cwd <dir>` | The current directory | The project. Resolves `--config`, `--out` and `--report`. |
|
|
17
|
+
| `--loader tsx\|none` | `tsx` | How the config is imported in Node. See [How the config loads](config.md#how-the-config-loads). |
|
|
18
|
+
|
|
19
|
+
`dev`, `build` and `check` also take `--config <file>`, which defaults to `isomer-studio.config.ts`, `.tsx` or `.js` in `--cwd`. Without a config they stop and say to run `init`.
|
|
20
|
+
|
|
21
|
+
The exit code is 0 on success, 1 when a command fails or `check` finds a failure, and 2 on bad usage, which also prints the usage text. `isomer-studio help` and `-h` print it too.
|
|
22
|
+
|
|
23
|
+
## `init`
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npx @elastic/isomer-studio init
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Writes a config that default-exports `defineStudioConfig({ title, runtime })`, registering by name each pack the package's entry exports: `isomer-studio.config.ts` beside a `tsconfig.json`, `isomer-studio.config.js` otherwise. Add `previewExample`, `stylesheet` or apps to it as the pack needs; see [The config](config.md). It stops when a config already exists or the entry exports no pack.
|
|
30
|
+
|
|
31
|
+
The entry is the first of `src/index` and `index`, as `.tsx`, `.ts`, `.jsx` or `.js`, that exists, then the `package.json` root export (following its `import`, `module`, `require`, `node` and `default` conditions, nested ones included), `module` or `main`. Every export shaped like `definePrimitivePack`'s result is a pack: named exports, the default export, and the properties of a default-exported object. A pack exported under more than one name is registered once, and a pack whose name the config's own imports take is imported under another. The title is the `package.json` `name`.
|
|
32
|
+
|
|
33
|
+
The project needs React 18, `@elastic/isomer-sdk` and `zod`, which a pack has already. `@elastic/isomer-runtime` and `@elastic/isomer-studio` come from the Studio's own install when the project lacks them; see [How the config loads](config.md#how-the-config-loads).
|
|
34
|
+
|
|
35
|
+
## `dev`
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
npx @elastic/isomer-studio dev --port 5179 --open
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Serves the Studio on `127.0.0.1` and prints its URL.
|
|
42
|
+
|
|
43
|
+
| Option | Default | What it does |
|
|
44
|
+
| ----------------- | ------- | ---------------------------------------- |
|
|
45
|
+
| `--port <number>` | `5179` | `0` picks a free port. |
|
|
46
|
+
| `--open` | Off | Opens the Studio in the default browser. |
|
|
47
|
+
|
|
48
|
+
The server runs on Vite. When the config or anything it imports changes, the Studio re-renders in place with the new config: the page does not reload, so the route, the editor's text and every panel's state survive. The server re-runs the same modules in Node before the page updates, so PNGs never show a stale pack. A syntax error shows Vite's error overlay, and the Studio picks up again once the file is fixed. The editor compiles JSX on the server, and the PNG preview rasterizes the composition being edited.
|
|
49
|
+
|
|
50
|
+
### Comparing outputs
|
|
51
|
+
|
|
52
|
+
Workbench combines browser renders in one **Web** panel, labeled **HTML / React /
|
|
53
|
+
Snapshot** beneath its title, without a per-panel dropdown. HTML and its stylesheet
|
|
54
|
+
render in a shadow root, not an iframe; its links open in a new tab so following one
|
|
55
|
+
never unloads the draft. PNG stays separate; Slack, Markdown and
|
|
56
|
+
Text appear below. The **Outputs** menu lists these displayed outputs rather than
|
|
57
|
+
separate React and Snapshot entries when HTML is available. Workbench starts with every
|
|
58
|
+
output selected; pick one to inspect it at full size, or add others to compare.
|
|
59
|
+
Runtimes without HTML retain their React or Snapshot output.
|
|
60
|
+
|
|
61
|
+
**Enhancements**, aligned at the right of the Web header, is off by default.
|
|
62
|
+
The menu tests each registered enhancement's `appliesTo` predicate against the
|
|
63
|
+
current composition, including nested primitives through the runtime's child
|
|
64
|
+
walker. Only applicable enhancements appear. A dropdown showing the selected and
|
|
65
|
+
applicable counts (such as **Enhancements (0/1)**) lets you enable each
|
|
66
|
+
independently. Each is listed by its `name` and `description`, falling back to its
|
|
67
|
+
id (such as `slideCopy` or `slideBuilds`) when it has no `name`.
|
|
68
|
+
Enhancements without a script are host-driven;
|
|
69
|
+
selecting one enables its render-time behavior but does not supply host controls
|
|
70
|
+
such as advancing a slide build. Scripted enhancements run on the HTML preview through the SDK's
|
|
71
|
+
host-run enhancement helper. Turning them off
|
|
72
|
+
remounts the unenhanced preview so script-created elements and listeners do not
|
|
73
|
+
linger. Only explicitly requested pack scripts run; embedded script elements are
|
|
74
|
+
not executed. The controls are disabled for Snapshot, in Source view, when no
|
|
75
|
+
enhancements are registered, or for a React-only preview without
|
|
76
|
+
`createReactContext` or `stylesheet`. Snapshot retains its fixed frame, theme resolution and
|
|
77
|
+
visibility rules. Sharing a panel is not a claim of pixel equality.
|
|
78
|
+
|
|
79
|
+
Studio does not install or launch a headless browser to capture previews.
|
|
80
|
+
It does not report pixel-difference percentages or infer matching outputs.
|
|
81
|
+
DOM or markup similarity is not proof of identical rendered
|
|
82
|
+
pixels. PNG previews still use Takumi, not a browser screenshot.
|
|
83
|
+
|
|
84
|
+
The editor, outputs, and prop drawer share one panel, with a resizer between
|
|
85
|
+
the borderless columns and independent scrolling in each. Its bottom strip has **Props** at the
|
|
86
|
+
left and validity at the right. Copy sits beside the source-format controls in
|
|
87
|
+
the editor as a compact icon with a tooltip. Output previews always form a
|
|
88
|
+
single vertical list, even in wide columns. Each output has a solid header against
|
|
89
|
+
the recessed output canvas in both color modes. The shared footer owns its top
|
|
90
|
+
divider; the editor has no additional bottom border.
|
|
91
|
+
**Props** toggles a full-width drawer, collapsed by default. Component
|
|
92
|
+
tabs select one schema-derived table for the selected primitive or its branded
|
|
93
|
+
JSX child components (including nested members).
|
|
94
|
+
It also includes other primitives in the draft and their children, rather than
|
|
95
|
+
offering a `+ Prop` action that edits only the first node. Tables are read-only;
|
|
96
|
+
edit props in JSX or JSON. Name, type and description columns use proportional
|
|
97
|
+
widths and top-aligned cells. The drawer sits outside the editor/output resizer,
|
|
98
|
+
so adjusting the split does not narrow the reference.
|
|
99
|
+
The 72-pixel collapsed navigation rail uses full-opacity white icons in centered,
|
|
100
|
+
32-pixel buttons. Its toggle stays fixed while the grouped entries scroll
|
|
101
|
+
vertically when they exceed the available height.
|
|
102
|
+
The white sidebar toggle sits beside the filter, using `transitionRightIn` to
|
|
103
|
+
collapse and `transitionLeftIn` to expand. At 1120 pixels or narrower, navigation
|
|
104
|
+
starts collapsed, expands over the content when toggled, and does not expand on
|
|
105
|
+
hover. Component tabs replace prop section
|
|
106
|
+
headings and label the active table for assistive technology.
|
|
107
|
+
Slack's preview padding uses the message canvas
|
|
108
|
+
background in both color modes.
|
|
109
|
+
|
|
110
|
+
## `build`
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
npx @elastic/isomer-studio build --out dist/studio --base /studio/
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Writes the Studio as a static site.
|
|
117
|
+
|
|
118
|
+
| Option | Default | What it does |
|
|
119
|
+
| --------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
120
|
+
| `--out <dir>` | `dist/studio` | Where the site goes. A previous build there, marked by its `.isomer-studio-build` file, is replaced; any other non-empty directory is refused. |
|
|
121
|
+
| `--base <path>` | `./` | The URL path the site is served from. A trailing slash is added. |
|
|
122
|
+
|
|
123
|
+
Every URL in the site resolves against `--base`, so the same build works at a domain's root or under a sub-path. Routes live in the URL's hash, so the host needs no rewrites. A `./` base works when the site is opened from any single directory, such as an unzipped CI artifact behind a static server.
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
<out>/index.html
|
|
127
|
+
<out>/assets/app.js, assets/chunks/* # the Studio and the config
|
|
128
|
+
<out>/assets/app.css # every stylesheet the config imports, apps included
|
|
129
|
+
<out>/assets/media/* # fonts and images those stylesheets reference
|
|
130
|
+
<out>/assets/studio.css # the Studio's chrome and Monaco's stylesheet
|
|
131
|
+
<out>/assets/codicon-<hash>.ttf # Monaco's icon font
|
|
132
|
+
<out>/assets/editor.worker.js, ts.worker.js, json.worker.js
|
|
133
|
+
<out>/assets/slack.css # the Slack preview's stylesheet
|
|
134
|
+
<out>/assets/esbuild.wasm # compiles JSX in the browser
|
|
135
|
+
<out>/png/manifest.json, png/<key>.png # when the runtime has a snapshot surface
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Static sites
|
|
139
|
+
|
|
140
|
+
A static site has no server, so two things work differently from `dev`:
|
|
141
|
+
|
|
142
|
+
- **JSX** compiles in the browser with `esbuild-wasm`, fetched the first time the editor needs it.
|
|
143
|
+
- **PNGs** are prerendered. `build` composes every example in both themes through the config's `compose` or `previewExample`, rasterizes each one, and names the file by the SHA-256 of the composition's canonical JSON. The page computes the same key and fetches the file. An edited composition has no file, so the PNG preview says "PNG previews of edited compositions need `isomer-studio dev`." An example that fails to compose or rasterize is reported and left out; the build still succeeds.
|
|
144
|
+
|
|
145
|
+
## `check`
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
npx @elastic/isomer-studio check --format junit --report studio-report.xml --png
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Validates and renders every example of every primitive, composed through the config's `compose` or `previewExample`, without a browser. It prints each failure and the totals, and exits 1 on any failure.
|
|
152
|
+
|
|
153
|
+
| Option | Default | What it does |
|
|
154
|
+
| ---------------------- | ----------------------------- | ---------------------------------------------------------------------------------------- |
|
|
155
|
+
| `--report <file>` | None | Also writes the report to a file. |
|
|
156
|
+
| `--format json\|junit` | `json` | The report's format. JUnit has a test suite per primitive and a test case per check. |
|
|
157
|
+
| `--png` | Off | Also rasterizes every example. Needs a snapshot surface. |
|
|
158
|
+
| `--surfaces <list>` | Every surface the runtime has | A comma-separated subset of `react`, `html`, `snapshot`, `slack`, `markdown` and `text`. |
|
|
159
|
+
|
|
160
|
+
For each primitive and example, `check` runs:
|
|
161
|
+
|
|
162
|
+
- **`icon`:** the primitive has an icon, from the pack's `icons` or its definition, and it passes `assertPackIconsValid`.
|
|
163
|
+
- **`props`:** the composed example validates against the runtime. When it throws or the composition is invalid, every surface for that example is skipped.
|
|
164
|
+
- **One check per surface:** the surface renders without throwing. React renders through `react-dom/server` from the config's React. Slack output is also held to `SLACK_LIMITS` from `@elastic/isomer-sdk/slack`, and fails on a block wrapped in `unmodeledSlackBlock` whose type Isomer now models. A surface the primitive has no native renderer for is skipped, not failed.
|
|
165
|
+
- **`png`,** with `--png`: the composition rasterizes.
|
|
166
|
+
|
|
167
|
+
`check` renders the light theme.
|
package/docs/config.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
---
|
|
2
|
+
navigation_title: The config
|
|
3
|
+
description: What an isomer-studio.config.ts exports, how previewExample and compose wrap examples, how apps add pages, and how the Studio loads the config in Node and the browser.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# The config
|
|
7
|
+
|
|
8
|
+
A config file default-exports `defineStudioConfig({ ... })`. `defineStudioConfig` returns its argument; it exists so the object is typed. The runtime exports are `defineStudioConfig` and `adoptStylesheet`. The types are `StudioConfig`, `StudioCompose`, `StudioRuntime`, `StudioTheme`, and, for [apps](#apps), `StudioApp`, `StudioAppPage`, `StudioAppProps`, `StudioAppSurface`, `StudioPreviewProps`, `StudioSurfaceProps`, `PreviewZoom` and `RenderPdf`.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { createIsomerRuntime } from '@elastic/isomer-runtime';
|
|
12
|
+
import { defineStudioConfig } from '@elastic/isomer-studio';
|
|
13
|
+
|
|
14
|
+
import { previewSlide } from './src/examples/preview_slide';
|
|
15
|
+
import { slideDeckFrame, slidesPack, slideStylesheet } from './src/index';
|
|
16
|
+
|
|
17
|
+
export default defineStudioConfig({
|
|
18
|
+
runtime: createIsomerRuntime({
|
|
19
|
+
packs: [slidesPack],
|
|
20
|
+
frames: { slide: slideDeckFrame },
|
|
21
|
+
}),
|
|
22
|
+
stylesheet: slideStylesheet,
|
|
23
|
+
previewExample: previewSlide,
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| Field | Required | What it does |
|
|
28
|
+
| --------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
29
|
+
| `runtime` | Yes | The runtime from `createIsomerRuntime`. Its packs are what the Studio lists, and its surfaces are the previews it offers. |
|
|
30
|
+
| `title` | No | Replaces the header, the page title, and the `check` report name. Defaults to `Isomer Studio`. Leave it unset to keep the product name; a runtime with more than one pack shows each pack in the nav. |
|
|
31
|
+
| `stylesheet()` | No | The CSS the React preview needs. The Studio calls it once and adopts the result into each preview's shadow root. |
|
|
32
|
+
| `createReactContext(root)` | No | Returns the render context the pack's renderers expect, inside the React preview's shadow root, after `stylesheet` is adopted there. Call `adoptStylesheet(root, css)` for any other CSS. Without it the context is empty, and without it or `stylesheet` the React preview shows the `html` surface instead. |
|
|
33
|
+
| `previewExample(node)` | No | The composition one node is shown in on its own, such as a slide around it. The Studio adds the theme and puts several nodes in a `view`. See [`previewExample` and `compose`](#previewexample-and-compose). |
|
|
34
|
+
| `compose(nodes, { theme })` | No | Wraps example nodes in a composition, for full control. Wins over `previewExample`. Defaults to `{ type: 'view', body: nodes, theme }`. |
|
|
35
|
+
| `apps` | No | Pages that demonstrate the pack, listed in the nav and on Home. See [Apps](#apps). |
|
|
36
|
+
| `imageFonts` | No | A module path, relative to the config, whose default export lists the takumi `FontLoader`s PNGs and PDFs draw text with. See [Image fonts](#image-fonts). |
|
|
37
|
+
| `featured` | No | Primitive types Home features, in order. Without it Home draws six at random on each load. See [Featured primitives](#featured-primitives). |
|
|
38
|
+
|
|
39
|
+
## `previewExample` and `compose`
|
|
40
|
+
|
|
41
|
+
Examples are nodes, not compositions. Every place the Studio needs a composition, the config's `compose`, or its `previewExample`, builds it: the gallery, the docs pages, the editor's preview, the PNGs a static build prerenders and every example `check` renders. A pack writes the envelope once and every mode agrees on it.
|
|
42
|
+
|
|
43
|
+
The default fits a pack whose primitives render inside a plain `view`. A pack whose frame requires a particular root says how one node is shown with `previewExample`. The slides frame draws exactly one `slideFrame`, so the slides `previewExample` wraps a lone node in a preview slide, and passes a node that is already a `slideFrame` through unwrapped. `compose` replaces both when a pack needs to shape several nodes too.
|
|
44
|
+
|
|
45
|
+
`compose` receives the theme the Studio is showing, `light` or `dark`, and puts it on the composition; with `previewExample`, the Studio does. That theme is the app's color mode, so previews always match the chrome around them. Light and dark are then different compositions, which is how a static build tells their PNGs apart.
|
|
46
|
+
|
|
47
|
+
## Featured primitives
|
|
48
|
+
|
|
49
|
+
Home opens with a strip of featured primitives, each with a link to its Reference page and to the Workbench. `featured` names them by type, in the order they appear:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
export default defineStudioConfig({
|
|
53
|
+
runtime,
|
|
54
|
+
featured: ['titleSlide', 'slideBulletList', 'slideSplitLayout'],
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Without `featured`, Home draws six primitives at random each time it loads, so a pack with no opinion still shows its range. `dev`, `build` and `check` reject a `featured` entry the runtime has no primitive for, or one listed twice, and name it. A browser hot update with an invalid entry reports it and skips it.
|
|
59
|
+
|
|
60
|
+
## Apps
|
|
61
|
+
|
|
62
|
+
An app is a whole page of the Studio, such as a deck viewer. Each one gets a top-level nav entry beside Gallery, a tile on Home, and a route at `#/app/<id>/`.
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
export default defineStudioConfig({
|
|
66
|
+
runtime,
|
|
67
|
+
apps: [
|
|
68
|
+
{
|
|
69
|
+
id: 'decks',
|
|
70
|
+
title: 'Decks',
|
|
71
|
+
description: 'Whole presentations, played one slide at a time.',
|
|
72
|
+
load: () => import('./studio/decks_app'),
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
| Field | Required | What it does |
|
|
79
|
+
| ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
80
|
+
| `id` | Yes | The route segment, matching `/^[a-z][a-z0-9-]*$/` and unique within the config. |
|
|
81
|
+
| `title` | Yes | The nav entry, the header's label while the app is open, and the Home tile's title. |
|
|
82
|
+
| `description` | No | One line under the title on the Home tile and in Home's Loaded panel. |
|
|
83
|
+
| `icon` | No | A `PrimitiveIcon`, held to the same rules as a primitive's icon by `check`. Without one, the nav and Home show the title's initial. |
|
|
84
|
+
| `load` | Yes | Imports a module whose default export is the app's page. |
|
|
85
|
+
| `pages` | No | Nav rows under the app's own row. See [Pages](#pages). |
|
|
86
|
+
|
|
87
|
+
`dev`, `build` and `check` reject invalid apps and name each one. A hot update with invalid apps keeps the last valid ones and shows why. `check` counts the apps but never calls `load`.
|
|
88
|
+
|
|
89
|
+
### Pages
|
|
90
|
+
|
|
91
|
+
An app can list its own pages in the nav, such as one per deck. The nav shows them without loading the app, so a config builds them from data it already imports.
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
pages: [
|
|
95
|
+
{ path: 'isomer', title: 'Isomer', section: 'Decks' },
|
|
96
|
+
{ path: 'distillate', title: 'Distillate', section: 'Decks' },
|
|
97
|
+
],
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
| Field | Required | What it does |
|
|
101
|
+
| --------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
102
|
+
| `path` | Yes | Opens `#/app/<id>/<path>`. One or more non-empty segments, with no leading or trailing `/`, unique within the app. |
|
|
103
|
+
| `title` | Yes | The row's label. The nav filter matches it. |
|
|
104
|
+
| `section` | No | Pages with the same `section` are listed under it, in order of first appearance. Pages without one come first. |
|
|
105
|
+
|
|
106
|
+
A page is current when the app's `path` equals the page's `path` or starts with it plus `/`. The longest match wins, so `isomer/3` keeps a page at `isomer/3` current over one at `isomer`. While a page is current, the app's own row is not. The collapsed rail shows only the app's row.
|
|
107
|
+
|
|
108
|
+
`dev`, `build` and `check` reject invalid pages as they do invalid apps, naming the app and the page's index.
|
|
109
|
+
|
|
110
|
+
### The page
|
|
111
|
+
|
|
112
|
+
The page is a React component, and the Studio hands it `StudioAppProps`:
|
|
113
|
+
|
|
114
|
+
| Prop | What it is |
|
|
115
|
+
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
116
|
+
| `Preview` | Renders pack output inside a shadow root, isolated from the app's styles and the Studio's. Pass `nodes`, which go through the config's `compose` or `previewExample` at the current theme, or a finished `composition`. `zoom` defaults to `fit`, and `maxHeight` caps a fitted preview's height. `heading={false}` leaves out the composition's leading title, as a slide shown on its own wants. `enhancements` are enhancement ids the surface renders with, such as the slides pack's `SLIDE_BUILDS`. `onCommit(root)` runs with the shadow root after each render commits, for a host step such as `showSlideBuild`. Without `createReactContext` or `stylesheet`, it shows the `html` surface, which gets `enhancements` but has no shadow root, so `onCommit` is never called. |
|
|
117
|
+
| `Surface` | Shows a `composition` on one of `surfaces`, as the Studio's own previews do: `surface` picks it, `view` is `render` or `source`, and `zoom` and `heading` work as on `Preview`. `png` is drawn by the host. |
|
|
118
|
+
| `surfaces` | The `{ id, label }` surfaces `Surface` can show, in the Studio's order: the runtime's, then `png` when the host rasterizes. |
|
|
119
|
+
| `renderPdf` | `renderPdf(compositions, { title })` resolves to a PDF `Blob`, a page per composition, drawn as PNGs are. Only `dev` has one; it is `undefined` in a static build. |
|
|
120
|
+
| `runtime` | The config's runtime. |
|
|
121
|
+
| `theme` | `light` or `dark`, following the Studio's color mode. |
|
|
122
|
+
| `path` | Everything after `#/app/<id>/`, slashes included, with each segment percent-decoded. |
|
|
123
|
+
| `navigate(path)` | Moves to another `path` within the app, adding a history entry. Each segment is percent-encoded in the hash, so `path` reads back the same after a reload. |
|
|
124
|
+
|
|
125
|
+
Import only types from `@elastic/isomer-studio` in an app module. The Studio hands the page everything it needs as props.
|
|
126
|
+
|
|
127
|
+
The page stays mounted when `path`, the theme or the config changes. When the config changes, the Studio calls the new `load` and remounts the page only if the module's default export is a different component. Edits to the app module update it in place through React Fast Refresh, as long as the module exports only components. A module that exports anything else re-runs the config instead.
|
|
128
|
+
|
|
129
|
+
`load` runs only in the browser. Node imports the config for `check` and `build`, but never calls `load`, so code that must stay off the server belongs behind it.
|
|
130
|
+
|
|
131
|
+
### EUI
|
|
132
|
+
|
|
133
|
+
Apps render under the Studio's own `EuiProvider`. Use EUI components directly, and nest `EuiThemeProvider` to change the theme for part of the page. Never mount a second `EuiProvider`.
|
|
134
|
+
|
|
135
|
+
EUI's theme and Emotion's cache reach the app only when it imports the same copies the Studio does. When a config with apps resolves `@elastic/eui` or `@emotion/react`, it must resolve the Studio's copy, and `dev`, `build` and `check` stop when it does not. A config without apps is not checked. Install the Studio's versions of EUI and its peers beside the config: `@elastic/eui`, `@elastic/eui-theme-borealis`, `@elastic/datemath`, `@emotion/react`, `@emotion/css` and `moment`.
|
|
136
|
+
|
|
137
|
+
Apps are not inside a shadow root, because EUI's popovers, flyouts, modals and toasts portal to `document.body`.
|
|
138
|
+
|
|
139
|
+
### CSS
|
|
140
|
+
|
|
141
|
+
| Form | Scope | Notes |
|
|
142
|
+
| --------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
143
|
+
| Emotion's `css` | Scoped | Needs `@emotion/react` as the JSX import source: add `/** @jsxImportSource @emotion/react */` to the file, or set `jsxImportSource` in a `tsconfig.json` for the app's folder. |
|
|
144
|
+
| CSS Modules, `*.module.css` | Scoped | TypeScript needs a declaration such as `declare module '*.module.css' { const classes: Readonly<Record<string, string>>; export default classes; }`. |
|
|
145
|
+
| Plain `.css` | Global | Scope its selectors under the app's root element. `url()`s to fonts (`woff2`, `woff`, `ttf`, `otf`, `eot`) and images (`png`, `jpg`, `jpeg`, `gif`, `webp`, `avif`, `svg`, `ico`) resolve under any `--base`. |
|
|
146
|
+
|
|
147
|
+
In `dev`, a stylesheet loads when the app first opens. A static build bundles every stylesheet the config imports into `assets/app.css`, which loads with the page.
|
|
148
|
+
|
|
149
|
+
## Surfaces a runtime may lack
|
|
150
|
+
|
|
151
|
+
The Studio offers the surfaces `runtime.surfaces` has. A runtime without a frame has no `snapshot` surface, so it gets no Snapshot or PNG previews, a static build prerenders no PNGs, and `check` reports those checks as skipped.
|
|
152
|
+
|
|
153
|
+
## Image fonts
|
|
154
|
+
|
|
155
|
+
PNGs and PDFs are drawn by takumi in Node, which knows no fonts but its own. `imageFonts` names a module that default-exports the faces to draw with, as `FontLoader[]` from `@elastic/isomer-image-takumi`:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
// studio/image_fonts.ts
|
|
159
|
+
export { slideFonts as default } from '../src/examples/fonts';
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Node imports it the way it imports the config, the first time it draws, and the browser never does, so it may read font files from disk. `dev`, `build` and `check --png` all draw with it. Without it, PNGs fall back to takumi's built-in face and a PDF cannot draw text.
|
|
163
|
+
|
|
164
|
+
## How the config loads
|
|
165
|
+
|
|
166
|
+
The config runs in two places: in Node, for `check` and for the dev server's PNGs, and in the browser, bundled into the app.
|
|
167
|
+
|
|
168
|
+
**In Node**, `check` and `build` import the config with `tsx`, which compiles TypeScript and JSX as it loads and leaves resolution to Node. The config, its pack, React and the runtime all resolve from the config's own directory, so they come from the pack's `node_modules`. `tsx` applies the `tsconfig.json` nearest the config, so the pack's `jsx` setting holds in both ES module and CommonJS projects.
|
|
169
|
+
|
|
170
|
+
`dev` loads the config through Vite's server-side module graph instead, with the same nearest-`tsconfig.json` JSX settings. Packages in `node_modules` load once through Node, and an edit re-runs only the files that changed and the modules that import them.
|
|
171
|
+
|
|
172
|
+
`--loader none` skips both and imports the config with a plain `import()`. Use it for a JavaScript config, or to bring another loader through `NODE_OPTIONS=--import ...`. Node caches that import, so under `dev` the browser picks up edits but PNGs keep the config and pack as they were at startup; restart `dev` to refresh them.
|
|
173
|
+
|
|
174
|
+
**In the browser**, `build` bundles the config with esbuild and `dev` serves it through Vite. `react`, `react-dom` and their subpaths resolve as if imported from the config, so the Studio's own components, Emotion and the pack share one React, and each package's browser build is the one loaded.
|
|
175
|
+
|
|
176
|
+
**Run with `npx`**, the Studio sits in npm's cache rather than the pack's `node_modules`. Two rules make that work in Node, Vite and esbuild alike:
|
|
177
|
+
|
|
178
|
+
- `react`, `react-dom`, `@elastic/isomer-sdk` and `zod`, imported from outside the project, resolve from the project, so the runtime and the pack share them.
|
|
179
|
+
- `@elastic/isomer-runtime` and `@elastic/isomer-studio`, when the project does not have them, resolve from the Studio's install. A config can import both without installing either.
|
|
180
|
+
|
|
181
|
+
The project is the directory of the `package.json` nearest the config. In Node the rules cover `import` and `require`, which a `.ts` config in a project that is not `"type": "module"` loads through.
|
|
182
|
+
|
|
183
|
+
## One React
|
|
184
|
+
|
|
185
|
+
The Studio, the pack and the runtime must use one copy of React, and it must be React 18, which EUI requires. Before loading the config, the Studio resolves `react` from the config, stops when it is not 18, then resolves `react` from the `@elastic/isomer-runtime` the config sees, and stops when they differ:
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
The Studio config and @elastic/isomer-runtime resolve different copies of React:
|
|
189
|
+
config: /work/pack/node_modules/react
|
|
190
|
+
runtime: /work/pack/node_modules/@elastic/isomer-runtime/node_modules/react
|
|
191
|
+
Install one React for both, for example by deduplicating your lockfile.
|
|
192
|
+
```
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
navigation_title: Isomer Studio
|
|
3
|
+
description: A gallery, per-primitive Reference, a composition Workbench and a preview of every surface for any Isomer pack, run as a dev server, a static site or a CI check.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Isomer Studio
|
|
7
|
+
|
|
8
|
+
`@elastic/isomer-studio` is a learning and testing shell for any Isomer pack. Run it in a pack's package directory, and it shows:
|
|
9
|
+
|
|
10
|
+
- a Home page with search, featured primitives, the pack's apps, and what the runtime loaded;
|
|
11
|
+
- a gallery of every primitive, grouped as the pack's authoring groups are, whose React previews mount as they near the viewport;
|
|
12
|
+
- a Reference page per primitive, with its purpose, guidance, props and live examples to teach its use;
|
|
13
|
+
- a Workbench for editing a composition and seeing its live preview;
|
|
14
|
+
- the same composition on every surface the runtime has: React, HTML, Snapshot, PNG, Slack, Markdown and text.
|
|
15
|
+
|
|
16
|
+
It ships as a command-line tool, not a React library. EUI, Emotion and Monaco are bundled into it, so a pack never takes them as dependencies.
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npx @elastic/isomer-studio init # a config for the packs the package exports
|
|
20
|
+
npx @elastic/isomer-studio # a local server with hot updates
|
|
21
|
+
npx @elastic/isomer-studio build --out dist/studio --base /studio/ # a static site
|
|
22
|
+
npx @elastic/isomer-studio check --report studio-report.json # a headless CI gate
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Each command reads `isomer-studio.config.ts` (or `.tsx` or `.js`) from the current directory unless `--config` names another file, and without one says to run `init`; see [`init`](commands.md#init). Nothing needs installing first: the Studio uses the pack's React, SDK and zod, and brings the runtime. To pin the version and type-check a config, install `@elastic/isomer-studio` and `@elastic/isomer-runtime` as dev dependencies and run `npx isomer-studio`. In this repository, `pnpm studio:dev` runs the Studio from source against the slides pack.
|
|
26
|
+
|
|
27
|
+
In the interface, **Reference** teaches how and when to use each primitive, while **Workbench** is where you edit compositions.
|
|
28
|
+
|
|
29
|
+

|
|
30
|
+
|
|
31
|
+
## A first config
|
|
32
|
+
|
|
33
|
+
`init` writes one like this, registering each pack the package's entry exports:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
// isomer-studio.config.ts
|
|
37
|
+
import { createIsomerRuntime } from '@elastic/isomer-runtime';
|
|
38
|
+
import { defineStudioConfig } from '@elastic/isomer-studio';
|
|
39
|
+
|
|
40
|
+
import { myPack } from './src/index';
|
|
41
|
+
|
|
42
|
+
export default defineStudioConfig({
|
|
43
|
+
title: 'my-pack',
|
|
44
|
+
runtime: createIsomerRuntime({ packs: [myPack] }),
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
That is enough for a pack whose primitives render inside a plain `view`. A pack with a frame that needs a particular root, or with styling the React surface must load, adds `previewExample` and `stylesheet`; see [The config](config.md).
|
|
49
|
+
|
|
50
|
+
## The app
|
|
51
|
+
|
|
52
|
+

|
|
53
|
+
|
|
54
|
+

|
|
55
|
+
|
|
56
|
+
Home is a landing page for the configured developer workbench, not the introductory Isomer site. Its entry points and loaded-runtime panel reflect the packs and applications supplied by the host. The surface chart keeps its explanatory copy separate at every width, and reflows into a composition row above the surface cards when its column is narrow. Connecting lines follow the cards across wrapped rows.
|
|
57
|
+
|
|
58
|
+
Studio is primarily a desktop learning and demo tool. When Home's main column is narrower than 620px, its application, learning, and featured tiles stack vertically. Featured primitives show three tiles per page, with Previous and Next buttons; the final gallery tile occupies a paging slot. Wider columns retain the horizontal strip. This is a readable narrow-window fallback, not a mobile Workbench.
|
|
59
|
+
|
|
60
|
+
Home's Reference and Workbench actions keep the exact blue and teal from the Isomer logo. Featured and learning cards use deeper, opaque plum surfaces so their small action text stays readable without washing out the brand colors.
|
|
61
|
+
|
|
62
|
+
Home exposes its primary column as the main landmark, with level-two headings for Featured primitives, Applications, and Learn more about Isomer. The loaded-runtime panel remains a separate complementary landmark.
|
|
63
|
+
|
|
64
|
+
Links and buttons within Home use a white keyboard-focus outline that stays visible on the fixed dark palette, independently of the Workbench and Reference color mode.
|
|
65
|
+
|
|
66
|
+
Home respects reduced-motion preferences: the surface chart keeps its focus and color feedback without scaling or lifting cards, and horizontal featured paging moves immediately instead of scrolling smoothly.
|
|
67
|
+
|
|
68
|
+
- **Home.** An empty or unknown hash, `#/home`, and the mark in the header open Home. It has the primitive search, one chip per authoring group that opens the gallery at that group, the featured primitives (the config's `featured`, or six drawn at random) with Reference and Workbench links, a tile per app, three doors into the gallery, the Workbench and the Isomer documentation site, a chart of the surfaces the runtime has, and a panel of the packs, views, apps and surfaces loaded. With no apps or no views, the panel and the Applications row say how to add them and link to the Isomer documentation. Home keeps its own dark look; the color mode applies from Reference and Workbench on.
|
|
69
|
+
- **Navigation.** With one pack, the sidebar lists primitives under that pack's authoring groups, in the pack's group order and alphabetically within each group. With more than one pack, each pack is a heading and its groups follow. Primitives no group claims are listed last, under Uncategorized. Each group collapses, the browser remembers which are closed, and a filter opens every group it matches. Resting the pointer on a name shows its first example and purpose.
|
|
70
|
+
- **Surfaces.** The Workbench preview starts with every output selected, in one column at every width. The Outputs menu checks the outputs to compare: with every output selected, choosing one shows it at full size, and choosing another adds it. Rendered or Output source applies to every card at once. The Reference example card starts on the first surface, with the example picker on the left and the same menu on the right. Its view selector switches among Rendered, Output source, and Example source; the latter shows the example as JSX or JSON.
|
|
71
|
+
- **Zoom.** With one surface picked, the preview's zoom menu scales the React, HTML, Snapshot and PNG previews: Fit width shrinks a preview to the panel's width and never enlarges it, and fixed levels run from 50% to 200%.
|
|
72
|
+
- **Color mode.** The header offers Light, Dark, and System. System follows the operating system, including when it changes. The choice is remembered per browser, and previews render in the resolved mode. In dark mode the Workbench preview pane takes the theme's recessed background.
|
|
73
|
+
|
|
74
|
+
## Requirements
|
|
75
|
+
|
|
76
|
+
- Node 22.13 or later.
|
|
77
|
+
- `react` and `react-dom` 18.2 or later, below 19, in the pack, because EUI's peer range stops there.
|
|
78
|
+
- `@elastic/isomer-sdk` and `zod`, which the pack already has. `@elastic/isomer-runtime` comes with the Studio when the pack does not have it.
|
|
79
|
+
|
|
80
|
+
The config, the pack and React load from the pack's own `node_modules`. The Studio stops when the pack's React is not 18, or when the config and `@elastic/isomer-runtime` see different copies of it.
|
|
81
|
+
|
|
82
|
+
## The slides Studio
|
|
83
|
+
|
|
84
|
+
This repository's reference pack has a config at `packages/isomer-primitives-slides/isomer-studio.config.ts`. Its Studio is deployed with these docs at [elastic.github.io/isomer/studio-app/](https://elastic.github.io/isomer/studio-app/), and every CI run uploads a build of it as the `slides-studio` artifact.
|
|
85
|
+
|
|
86
|
+
These docs build in two places, and the app only in one:
|
|
87
|
+
|
|
88
|
+
- GitHub Pages hosts the docs at `/isomer/studio/` and the app beside them at `/isomer/studio-app/`, so neither overwrites the other.
|
|
89
|
+
- Codex previews of a docs change carry the docs only. Links to the app point at its Pages URL, and a PR's app preview is the CI artifact.
|
|
90
|
+
|
|
91
|
+
## Known gaps
|
|
92
|
+
|
|
93
|
+
- **PNGs of edited compositions.** A static site has PNGs for the examples it prerendered and nothing else; an edited composition shows "PNG previews of edited compositions need `isomer-studio dev`". See [Static sites](commands.md#static-sites).
|
|
94
|
+
- **PDFs on a static site.** Only `dev` writes PDFs, so an app's `renderPdf` is `undefined` in a static build.
|
|
95
|
+
- **Slack `tag` elements.** `slack-blocks-to-jsx` cannot draw rich-text `tag` elements, so toned values render blank in the Slack preview. The Block Kit is valid, so `check` passes it.
|
|
96
|
+
- **Web fonts in the app.** The app loads no web fonts, so EUI's Inter falls back to the system font.
|
package/docs/toc.yml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
2
|
+
# or more contributor license agreements. Licensed under the Elastic License
|
|
3
|
+
# 2.0; you may not use this file except in compliance with the Elastic License
|
|
4
|
+
# 2.0.
|
|
5
|
+
|
|
6
|
+
toc:
|
|
7
|
+
- file: index.md
|
|
8
|
+
- file: config.md
|
|
9
|
+
- file: commands.md
|
|
10
|
+
- file: ci.md
|