@tulipfarm/sprout 0.1.0 → 0.3.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.
Files changed (98) hide show
  1. package/README.md +111 -0
  2. package/dist/components/agent-fanout.d.ts +46 -0
  3. package/dist/components/agent-fanout.js +228 -0
  4. package/dist/components/attachment.js +2 -2
  5. package/dist/components/brand-icon.js +4 -0
  6. package/dist/components/canvas.js +2 -2
  7. package/dist/components/chat-input.d.ts +94 -0
  8. package/dist/components/chat-input.js +279 -0
  9. package/dist/components/chat-sources.js +11 -2
  10. package/dist/components/code-block.js +2 -33
  11. package/dist/components/file-explorer.d.ts +27 -0
  12. package/dist/components/file-explorer.js +300 -0
  13. package/dist/components/file-viewer.d.ts +18 -1
  14. package/dist/components/file-viewer.js +35 -8
  15. package/dist/components/presence-cursor.d.ts +19 -0
  16. package/dist/components/presence-cursor.js +14 -0
  17. package/dist/components/questionnaire.js +2 -1
  18. package/dist/components/schema-diagram.js +5 -78
  19. package/dist/components/search-dialog.js +5 -4
  20. package/dist/components/sql-viewer.d.ts +76 -0
  21. package/dist/components/sql-viewer.js +409 -0
  22. package/dist/components/state-panel.js +2 -2
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.js +5 -0
  25. package/dist/internal/brand-glyphs.d.ts +28 -0
  26. package/dist/internal/brand-glyphs.js +24 -0
  27. package/dist/internal/code-tokens.d.ts +4 -0
  28. package/dist/internal/code-tokens.js +34 -0
  29. package/dist/internal/flow.d.ts +22 -0
  30. package/dist/internal/flow.js +82 -0
  31. package/dist/styles/accordion.css +2 -2
  32. package/dist/styles/agent-fanout.css +529 -0
  33. package/dist/styles/alert-dialog.css +2 -2
  34. package/dist/styles/alert.css +2 -2
  35. package/dist/styles/attachment.css +4 -24
  36. package/dist/styles/badge.css +2 -2
  37. package/dist/styles/brand-icon.css +2 -2
  38. package/dist/styles/breadcrumb.css +2 -2
  39. package/dist/styles/button.css +2 -2
  40. package/dist/styles/calendar.css +3 -3
  41. package/dist/styles/canvas.css +4 -18
  42. package/dist/styles/carousel.css +2 -2
  43. package/dist/styles/chart.css +2 -2
  44. package/dist/styles/chat-confirmation.css +2 -2
  45. package/dist/styles/chat-input.css +240 -0
  46. package/dist/styles/chat-sources.css +2 -2
  47. package/dist/styles/checkbox.css +2 -3
  48. package/dist/styles/choice-list.css +2 -2
  49. package/dist/styles/code-block.css +2 -2
  50. package/dist/styles/collapsible.css +2 -2
  51. package/dist/styles/combobox.css +6 -6
  52. package/dist/styles/command.css +2 -2
  53. package/dist/styles/context-menu.css +3 -3
  54. package/dist/styles/dialog.css +2 -2
  55. package/dist/styles/dropdown-menu.css +1 -1
  56. package/dist/styles/field.css +2 -3
  57. package/dist/styles/file-explorer.css +517 -0
  58. package/dist/styles/file-viewer.css +113 -16
  59. package/dist/styles/hover-card.css +2 -2
  60. package/dist/styles/index.css +9 -0
  61. package/dist/styles/input-group.css +6 -11
  62. package/dist/styles/input-otp.css +2 -2
  63. package/dist/styles/input.css +3 -4
  64. package/dist/styles/mention-list.css +1 -1
  65. package/dist/styles/menubar.css +3 -3
  66. package/dist/styles/message-response.css +4 -4
  67. package/dist/styles/message-scroller.css +2 -2
  68. package/dist/styles/message.css +5 -5
  69. package/dist/styles/navigation-menu.css +2 -2
  70. package/dist/styles/page-header.css +4 -4
  71. package/dist/styles/plan-outline.css +6 -6
  72. package/dist/styles/presence-cursor.css +68 -0
  73. package/dist/styles/prompt-list.css +2 -2
  74. package/dist/styles/questionnaire.css +2 -17
  75. package/dist/styles/radio-group.css +2 -3
  76. package/dist/styles/reasoning-effort.css +2 -2
  77. package/dist/styles/review-card.css +2 -2
  78. package/dist/styles/rich-text-editor.css +2 -2
  79. package/dist/styles/schema-diagram.css +4 -4
  80. package/dist/styles/scroll-area.css +2 -2
  81. package/dist/styles/search-dialog.css +0 -83
  82. package/dist/styles/select.css +3 -3
  83. package/dist/styles/separator.css +2 -2
  84. package/dist/styles/sheet.css +2 -2
  85. package/dist/styles/sidebar.css +2 -2
  86. package/dist/styles/slider.css +1 -1
  87. package/dist/styles/sql-viewer.css +406 -0
  88. package/dist/styles/state-panel.css +1 -10
  89. package/dist/styles/switch.css +2 -2
  90. package/dist/styles/table.css +10 -10
  91. package/dist/styles/tabs.css +4 -4
  92. package/dist/styles/textarea.css +3 -4
  93. package/dist/styles/themes/tulipfarm.css +89 -99
  94. package/dist/styles/toast.css +2 -2
  95. package/dist/styles/toggle-group.css +2 -2
  96. package/dist/styles/toggle.css +2 -2
  97. package/dist/styles/tool-activity.css +5 -5
  98. package/package.json +27 -6
@@ -37,6 +37,34 @@ export declare const brandGlyphs: {
37
37
  readonly evenOdd: true;
38
38
  }];
39
39
  };
40
+ readonly gemini: {
41
+ readonly viewBox: "0 0 24 24";
42
+ readonly paths: readonly [{
43
+ readonly d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z";
44
+ readonly evenOdd: true;
45
+ }];
46
+ };
47
+ readonly mistral: {
48
+ readonly viewBox: "0 0 24 24";
49
+ readonly paths: readonly [{
50
+ readonly d: "M3.428 3.4h3.429v3.428h3.429v3.429h-.002 3.431V6.828h3.427V3.4h3.43v13.714H24v3.429H13.714v-3.428h-3.428v-3.429h-3.43v3.428h3.43v3.429H0v-3.429h3.428V3.4zm10.286 13.715h3.428v-3.429h-3.427v3.429z";
51
+ readonly evenOdd: true;
52
+ }];
53
+ };
54
+ readonly meta: {
55
+ readonly viewBox: "0 0 24 24";
56
+ readonly paths: readonly [{
57
+ readonly d: "M6.897 4c1.915 0 3.516.932 5.43 3.376l.282-.373c.19-.246.383-.484.58-.71l.313-.35C14.588 4.788 15.792 4 17.225 4c1.273 0 2.469.557 3.491 1.516l.218.213c1.73 1.765 2.917 4.71 3.053 8.026l.011.392.002.25c0 1.501-.28 2.759-.818 3.7l-.14.23-.108.153c-.301.42-.664.758-1.086 1.009l-.265.142-.087.04a3.493 3.493 0 01-.302.118 4.117 4.117 0 01-1.33.208c-.524 0-.996-.067-1.438-.215-.614-.204-1.163-.56-1.726-1.116l-.227-.235c-.753-.812-1.534-1.976-2.493-3.586l-1.43-2.41-.544-.895-1.766 3.13-.343.592C7.597 19.156 6.227 20 4.356 20c-1.21 0-2.205-.42-2.936-1.182l-.168-.184c-.484-.573-.837-1.311-1.043-2.189l-.067-.32a8.69 8.69 0 01-.136-1.288L0 14.468c.002-.745.06-1.49.174-2.23l.1-.573c.298-1.53.828-2.958 1.536-4.157l.209-.34c1.177-1.83 2.789-3.053 4.615-3.16L6.897 4zm-.033 2.615l-.201.01c-.83.083-1.606.673-2.252 1.577l-.138.199-.01.018c-.67 1.017-1.185 2.378-1.456 3.845l-.004.022a12.591 12.591 0 00-.207 2.254l.002.188c.004.18.017.36.04.54l.043.291c.092.503.257.908.486 1.208l.117.137c.303.323.698.492 1.17.492 1.1 0 1.796-.676 3.696-3.641l2.175-3.4.454-.701-.139-.198C9.11 7.3 8.084 6.616 6.864 6.616zm10.196-.552l-.176.007c-.635.048-1.223.359-1.82.933l-.196.198c-.439.462-.887 1.064-1.367 1.807l.266.398c.18.274.362.56.55.858l.293.475 1.396 2.335.695 1.114c.583.926 1.03 1.6 1.408 2.082l.213.262c.282.326.529.54.777.673l.102.05c.227.1.457.138.718.138.176.002.35-.023.518-.073.338-.104.61-.32.813-.637l.095-.163.077-.162c.194-.459.29-1.06.29-1.785l-.006-.449c-.08-2.871-.938-5.372-2.2-6.798l-.176-.189c-.67-.683-1.444-1.074-2.27-1.074z";
58
+ readonly evenOdd: true;
59
+ }];
60
+ };
61
+ readonly qwen: {
62
+ readonly viewBox: "0 0 24 24";
63
+ readonly paths: readonly [{
64
+ readonly d: "M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z";
65
+ readonly evenOdd: true;
66
+ }];
67
+ };
40
68
  readonly google: {
41
69
  readonly viewBox: "0 0 24 24";
42
70
  readonly paths: readonly [{
@@ -34,6 +34,30 @@ export const brandGlyphs = {
34
34
  { "d": "M11.065 11.199l7.257-7.2c.137-.136.06-.41-.116-.41H14.3a.164.164 0 00-.117.051l-7.82 7.756c-.122.12-.302.013-.302-.179V3.82c0-.127-.083-.23-.185-.23H3.186c-.103 0-.186.103-.186.23V19.77c0 .128.083.23.186.23h2.69c.103 0 .186-.102.186-.23v-3.25c0-.069.025-.135.069-.178l2.424-2.406a.158.158 0 01.205-.023l6.484 4.772a7.677 7.677 0 003.453 1.283c.108.012.2-.095.2-.23v-3.06c0-.117-.07-.212-.164-.227a5.028 5.028 0 01-2.027-.807l-5.613-4.064c-.117-.078-.132-.279-.028-.381z", "evenOdd": true },
35
35
  ],
36
36
  },
37
+ "gemini": {
38
+ viewBox: "0 0 24 24",
39
+ paths: [
40
+ { "d": "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z", "evenOdd": true },
41
+ ],
42
+ },
43
+ "mistral": {
44
+ viewBox: "0 0 24 24",
45
+ paths: [
46
+ { "d": "M3.428 3.4h3.429v3.428h3.429v3.429h-.002 3.431V6.828h3.427V3.4h3.43v13.714H24v3.429H13.714v-3.428h-3.428v-3.429h-3.43v3.428h3.43v3.429H0v-3.429h3.428V3.4zm10.286 13.715h3.428v-3.429h-3.427v3.429z", "evenOdd": true },
47
+ ],
48
+ },
49
+ "meta": {
50
+ viewBox: "0 0 24 24",
51
+ paths: [
52
+ { "d": "M6.897 4c1.915 0 3.516.932 5.43 3.376l.282-.373c.19-.246.383-.484.58-.71l.313-.35C14.588 4.788 15.792 4 17.225 4c1.273 0 2.469.557 3.491 1.516l.218.213c1.73 1.765 2.917 4.71 3.053 8.026l.011.392.002.25c0 1.501-.28 2.759-.818 3.7l-.14.23-.108.153c-.301.42-.664.758-1.086 1.009l-.265.142-.087.04a3.493 3.493 0 01-.302.118 4.117 4.117 0 01-1.33.208c-.524 0-.996-.067-1.438-.215-.614-.204-1.163-.56-1.726-1.116l-.227-.235c-.753-.812-1.534-1.976-2.493-3.586l-1.43-2.41-.544-.895-1.766 3.13-.343.592C7.597 19.156 6.227 20 4.356 20c-1.21 0-2.205-.42-2.936-1.182l-.168-.184c-.484-.573-.837-1.311-1.043-2.189l-.067-.32a8.69 8.69 0 01-.136-1.288L0 14.468c.002-.745.06-1.49.174-2.23l.1-.573c.298-1.53.828-2.958 1.536-4.157l.209-.34c1.177-1.83 2.789-3.053 4.615-3.16L6.897 4zm-.033 2.615l-.201.01c-.83.083-1.606.673-2.252 1.577l-.138.199-.01.018c-.67 1.017-1.185 2.378-1.456 3.845l-.004.022a12.591 12.591 0 00-.207 2.254l.002.188c.004.18.017.36.04.54l.043.291c.092.503.257.908.486 1.208l.117.137c.303.323.698.492 1.17.492 1.1 0 1.796-.676 3.696-3.641l2.175-3.4.454-.701-.139-.198C9.11 7.3 8.084 6.616 6.864 6.616zm10.196-.552l-.176.007c-.635.048-1.223.359-1.82.933l-.196.198c-.439.462-.887 1.064-1.367 1.807l.266.398c.18.274.362.56.55.858l.293.475 1.396 2.335.695 1.114c.583.926 1.03 1.6 1.408 2.082l.213.262c.282.326.529.54.777.673l.102.05c.227.1.457.138.718.138.176.002.35-.023.518-.073.338-.104.61-.32.813-.637l.095-.163.077-.162c.194-.459.29-1.06.29-1.785l-.006-.449c-.08-2.871-.938-5.372-2.2-6.798l-.176-.189c-.67-.683-1.444-1.074-2.27-1.074z", "evenOdd": true },
53
+ ],
54
+ },
55
+ "qwen": {
56
+ viewBox: "0 0 24 24",
57
+ paths: [
58
+ { "d": "M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z", "evenOdd": true },
59
+ ],
60
+ },
37
61
  "google": {
38
62
  viewBox: "0 0 24 24",
39
63
  paths: [
@@ -0,0 +1,4 @@
1
+ import type { ThemedToken } from "shiki/core";
2
+ import type { CodeLanguage } from "./languages.js";
3
+ export declare function useCodeTokens(code: string, language: CodeLanguage | null): ThemedToken[][] | null;
4
+ export declare function tokenClass(token: ThemedToken): string | undefined;
@@ -0,0 +1,34 @@
1
+ import { useEffect, useMemo, useState } from "react";
2
+ import { codeTokens, embeddedLanguages, isLanguageReady, loadCodeLanguage, maxHighlightedLength, } from "./syntax.js";
3
+ export function useCodeTokens(code, language) {
4
+ const [loaded, setLoaded] = useState(0);
5
+ const highlightable = language !== null && code.length <= maxHighlightedLength;
6
+ const needed = useMemo(() => highlightable ? [language, ...embeddedLanguages(code, language)] : [], [code, language, highlightable]);
7
+ const missing = needed.filter((name) => !isLanguageReady(name));
8
+ const key = missing.join(" ");
9
+ useEffect(() => {
10
+ if (!key)
11
+ return;
12
+ let live = true;
13
+ void Promise.all(key.split(" ").map((name) => loadCodeLanguage(name))).then(() => live && setLoaded((value) => value + 1), () => undefined);
14
+ return () => {
15
+ live = false;
16
+ };
17
+ }, [key]);
18
+ return useMemo(() => (highlightable ? codeTokens(code, language) : null),
19
+ // `loaded` and `key` re-run this once the grammars arrive.
20
+ [code, language, highlightable, loaded, key]);
21
+ }
22
+ const fontStyleClasses = [
23
+ [1, "sprout-syntax-italic"],
24
+ [2, "sprout-syntax-bold"],
25
+ [4, "sprout-syntax-underline"],
26
+ ];
27
+ export function tokenClass(token) {
28
+ const role = /--sprout-syntax-(?:token-)?([a-z-]+)/.exec(token.color ?? "")?.[1];
29
+ const classes = role && role !== "foreground" ? [`sprout-syntax-${role}`] : [];
30
+ for (const [flag, name] of fontStyleClasses)
31
+ if ((token.fontStyle ?? 0) & flag)
32
+ classes.push(name);
33
+ return classes.length ? classes.join(" ") : undefined;
34
+ }
@@ -0,0 +1,22 @@
1
+ import { type FitViewOptions, type Node } from "@xyflow/react";
2
+ import { type KeyboardEvent } from "react";
3
+ export declare const flowMinZoom = 0.2;
4
+ export declare const flowMaxZoom = 1.5;
5
+ export declare function useViewportMobile(): boolean;
6
+ export declare const motion: (ms: number) => number;
7
+ /**
8
+ * Refits whenever the pane resizes or the nodes change. The canvas panel
9
+ * animates open, so the first fit sees a narrower pane than the final one.
10
+ */
11
+ export declare function FitOnResize({ nodes, fit, }: {
12
+ nodes: readonly Node[];
13
+ fit: FitViewOptions;
14
+ }): null;
15
+ export declare function ZoomControls({ position, fit, className, slot, }: {
16
+ position: "top-right" | "bottom-right";
17
+ fit: FitViewOptions;
18
+ className: string;
19
+ slot: string;
20
+ }): import("react").JSX.Element;
21
+ /** Arrow keys pan, plus and minus zoom, and 0 fits, from the pane or a node. */
22
+ export declare function useKeyboardView(fit: FitViewOptions): (event: KeyboardEvent<HTMLDivElement>) => void;
@@ -0,0 +1,82 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Panel, useNodesInitialized, useReactFlow, useStore, } from "@xyflow/react";
4
+ import { useEffect, useSyncExternalStore } from "react";
5
+ import { Add } from "reicon-react/icons/Add";
6
+ import { Minus } from "reicon-react/icons/Minus";
7
+ import { Scan } from "reicon-react/icons/Scan";
8
+ import { Button } from "../components/button.js";
9
+ export const flowMinZoom = 0.2;
10
+ export const flowMaxZoom = 1.5;
11
+ const panStep = 48;
12
+ const mobileQuery = "(max-width: 767px)";
13
+ const motionQuery = "(prefers-reduced-motion: reduce)";
14
+ function subscribeMobile(callback) {
15
+ const media = window.matchMedia(mobileQuery);
16
+ media.addEventListener("change", callback);
17
+ return () => media.removeEventListener("change", callback);
18
+ }
19
+ export function useViewportMobile() {
20
+ return useSyncExternalStore(subscribeMobile, () => window.matchMedia(mobileQuery).matches, () => false);
21
+ }
22
+ export const motion = (ms) => typeof window !== "undefined" && window.matchMedia(motionQuery).matches
23
+ ? 0
24
+ : ms;
25
+ /**
26
+ * Refits whenever the pane resizes or the nodes change. The canvas panel
27
+ * animates open, so the first fit sees a narrower pane than the final one.
28
+ */
29
+ export function FitOnResize({ nodes, fit, }) {
30
+ const { fitView } = useReactFlow();
31
+ const width = useStore((state) => state.width);
32
+ const height = useStore((state) => state.height);
33
+ const measured = useNodesInitialized();
34
+ useEffect(() => {
35
+ if (!measured)
36
+ return;
37
+ const frame = requestAnimationFrame(() => void fitView(fit));
38
+ return () => cancelAnimationFrame(frame);
39
+ }, [fitView, fit, width, height, measured, nodes]);
40
+ return null;
41
+ }
42
+ export function ZoomControls({ position, fit, className, slot, }) {
43
+ const { zoomIn, zoomOut, fitView } = useReactFlow();
44
+ const zoom = useStore((state) => state.transform[2]);
45
+ return (_jsxs(Panel, { position: position, className: className, "data-slot": slot, role: "toolbar", "aria-label": "Diagram view", "aria-orientation": "vertical", children: [_jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Zoom in", title: "Zoom in", disabled: zoom >= flowMaxZoom, onClick: () => void zoomIn({ duration: motion(160) }), children: _jsx(Add, { size: 16, "aria-hidden": "true" }) }), _jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Zoom out", title: "Zoom out", disabled: zoom <= flowMinZoom, onClick: () => void zoomOut({ duration: motion(160) }), children: _jsx(Minus, { size: 16, "aria-hidden": "true" }) }), _jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Fit to view", title: "Fit to view", onClick: () => void fitView({ ...fit, duration: motion(180) }), children: _jsx(Scan, { size: 16, "aria-hidden": "true" }) })] }));
46
+ }
47
+ /** Arrow keys pan, plus and minus zoom, and 0 fits, from the pane or a node. */
48
+ export function useKeyboardView(fit) {
49
+ const { getViewport, setViewport, zoomIn, zoomOut, fitView } = useReactFlow();
50
+ return (event) => {
51
+ const target = event.target;
52
+ if (event.altKey || event.ctrlKey || event.metaKey)
53
+ return;
54
+ if (target !== event.currentTarget &&
55
+ !target.classList.contains("react-flow__node"))
56
+ return;
57
+ const step = panStep * (event.shiftKey ? 4 : 1);
58
+ const pan = {
59
+ ArrowLeft: [step, 0],
60
+ ArrowRight: [-step, 0],
61
+ ArrowUp: [0, step],
62
+ ArrowDown: [0, -step],
63
+ };
64
+ const move = pan[event.key];
65
+ if (move) {
66
+ const { x, y, zoom } = getViewport();
67
+ void setViewport({ x: x + move[0], y: y + move[1], zoom }, { duration: motion(120) });
68
+ }
69
+ else if (event.key === "+" || event.key === "=") {
70
+ void zoomIn({ duration: motion(160) });
71
+ }
72
+ else if (event.key === "-" || event.key === "_") {
73
+ void zoomOut({ duration: motion(160) });
74
+ }
75
+ else if (event.key === "0") {
76
+ void fitView({ ...fit, duration: motion(180) });
77
+ }
78
+ else
79
+ return;
80
+ event.preventDefault();
81
+ };
82
+ }
@@ -40,8 +40,8 @@
40
40
  text-decoration-line: underline;
41
41
  }
42
42
  .sprout-accordion-trigger:focus-visible {
43
- outline: 2px solid var(--sprout-focus);
44
- outline-offset: 2px;
43
+ outline: var(--sprout-focus-width) solid var(--sprout-focus-ring);
44
+ outline-offset: 0;
45
45
  }
46
46
  .sprout-accordion-trigger[data-disabled] {
47
47
  cursor: not-allowed;