BodyEditor.svelte 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. <script lang="ts">
  2. import { state as _state } from "$lib/state.svelte";
  3. import { Button } from "$lib/components/ui/button";
  4. import { EditorView } from "codemirror";
  5. import { onMount } from "svelte";
  6. import { BrushCleaning, Clipboard, FastForward } from "@lucide/svelte";
  7. import {
  8. copyContent,
  9. formatJson,
  10. setContent,
  11. setUpdateHandler,
  12. toggleVim,
  13. isVimEnabled,
  14. } from "$lib/codemirror.svelte";
  15. import { init } from "$lib/codemirror.svelte";
  16. let { input = null, onStateChange } = $props();
  17. let view: EditorView;
  18. onMount(async () => {
  19. view = init("editor", false, true);
  20. setUpdateHandler(view, onStateChange);
  21. });
  22. $effect(() => {
  23. if (input != null && input !== view.state.doc.toString()) {
  24. setContent(view, input);
  25. }
  26. });
  27. </script>
  28. <div class="w-full flex rounded-md border max-h-60">
  29. <!-- EDITOR SIDEBAR -->
  30. <div class="sticky flex flex-col gap-2 p-2 border-r">
  31. <Button
  32. onclick={() => toggleVim(view)}
  33. variant={isVimEnabled() ? "default" : "outline"}
  34. size="icon-sm"
  35. >
  36. <FastForward />
  37. </Button>
  38. <Button onclick={() => copyContent(view)} variant="outline" size="icon-sm"
  39. ><Clipboard /></Button
  40. >
  41. <Button onclick={() => formatJson(view)} variant="outline" size="icon-sm"
  42. ><BrushCleaning /></Button
  43. >
  44. </div>
  45. <!-- EDITOR -->
  46. <div
  47. id="editor"
  48. class="mx-auto w-full rounded-md overflow-scroll max-h-fit"
  49. ></div>
  50. </div>