@jxsuite/studio 0.23.2 → 0.25.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 (106) hide show
  1. package/dist/studio.js +2311 -718
  2. package/dist/studio.js.map +121 -104
  3. package/package.json +8 -7
  4. package/src/browse/{browse-modal.js → browse-modal.ts} +9 -10
  5. package/src/browse/{browse.js → browse.ts} +109 -84
  6. package/src/canvas/{canvas-diff.js → canvas-diff.ts} +42 -35
  7. package/src/canvas/{canvas-helpers.js → canvas-helpers.ts} +25 -19
  8. package/src/canvas/{canvas-live-render.js → canvas-live-render.ts} +53 -63
  9. package/src/canvas/{canvas-render.js → canvas-render.ts} +110 -121
  10. package/src/canvas/{canvas-utils.js → canvas-utils.ts} +48 -44
  11. package/src/canvas/{nested-site-style.js → nested-site-style.ts} +3 -3
  12. package/src/editor/{component-inline-edit.js → component-inline-edit.ts} +45 -33
  13. package/src/editor/{content-inline-edit.js → content-inline-edit.ts} +27 -45
  14. package/src/editor/{context-menu.js → context-menu.ts} +38 -36
  15. package/src/editor/{convert-targets.js → convert-targets.ts} +15 -12
  16. package/src/editor/{convert-to-component.js → convert-to-component.ts} +25 -26
  17. package/src/editor/{convert-to-repeater.js → convert-to-repeater.ts} +60 -40
  18. package/src/editor/{inline-edit.js → inline-edit.ts} +91 -55
  19. package/src/editor/{inline-format.js → inline-format.ts} +46 -51
  20. package/src/editor/{insertion-helper.js → insertion-helper.ts} +47 -63
  21. package/src/editor/{shortcuts.js → shortcuts.ts} +45 -31
  22. package/src/editor/{slash-menu.js → slash-menu.ts} +34 -35
  23. package/src/files/{components.js → components.ts} +12 -15
  24. package/src/files/{file-ops.js → file-ops.ts} +36 -29
  25. package/src/files/{files.js → files.ts} +102 -84
  26. package/src/github/{github-auth.js → github-auth.ts} +3 -3
  27. package/src/github/{github-publish.js → github-publish.ts} +20 -18
  28. package/src/markdown/{md-allowlist.js → md-allowlist.ts} +5 -2
  29. package/src/markdown/{md-convert.js → md-convert.ts} +146 -169
  30. package/src/new-project/{new-project-modal.js → new-project-modal.ts} +16 -18
  31. package/src/panels/{activity-bar.js → activity-bar.ts} +26 -34
  32. package/src/panels/{ai-panel.js → ai-panel.ts} +30 -30
  33. package/src/panels/{block-action-bar.js → block-action-bar.ts} +64 -73
  34. package/src/panels/{canvas-dnd.js → canvas-dnd.ts} +44 -49
  35. package/src/panels/{data-explorer.js → data-explorer.ts} +21 -15
  36. package/src/panels/dnd.ts +417 -0
  37. package/src/panels/{editors.js → editors.ts} +43 -50
  38. package/src/panels/{elements-panel.js → elements-panel.ts} +30 -27
  39. package/src/panels/{events-panel.js → events-panel.ts} +33 -25
  40. package/src/panels/{git-panel.js → git-panel.ts} +97 -83
  41. package/src/panels/{head-panel.js → head-panel.ts} +117 -139
  42. package/src/panels/{imports-panel.js → imports-panel.ts} +69 -89
  43. package/src/panels/{layers-panel.js → layers-panel.ts} +61 -57
  44. package/src/panels/{left-panel.js → left-panel.ts} +56 -63
  45. package/src/panels/{overlays.js → overlays.ts} +28 -36
  46. package/src/panels/{panel-events.js → panel-events.ts} +53 -51
  47. package/src/panels/{preview-render.js → preview-render.ts} +20 -15
  48. package/src/panels/{properties-panel.js → properties-panel.ts} +212 -246
  49. package/src/panels/{pseudo-preview.js → pseudo-preview.ts} +9 -8
  50. package/src/panels/{quick-search.js → quick-search.ts} +16 -17
  51. package/src/panels/{right-panel.js → right-panel.ts} +41 -59
  52. package/src/panels/{shared.js → shared.ts} +8 -6
  53. package/src/panels/{signals-panel.js → signals-panel.ts} +322 -362
  54. package/src/panels/{statusbar.js → statusbar.ts} +14 -14
  55. package/src/panels/{style-inputs.js → style-inputs.ts} +66 -48
  56. package/src/panels/{style-panel.js → style-panel.ts} +235 -290
  57. package/src/panels/{style-utils.js → style-utils.ts} +32 -31
  58. package/src/panels/{stylebook-layers-panel.js → stylebook-layers-panel.ts} +22 -14
  59. package/src/panels/{stylebook-panel.js → stylebook-panel.ts} +127 -140
  60. package/src/panels/{tab-strip.js → tab-strip.ts} +12 -14
  61. package/src/panels/{toolbar.js → toolbar.ts} +68 -70
  62. package/src/panels/{welcome-screen.js → welcome-screen.ts} +14 -16
  63. package/src/{platform.js → platform.ts} +5 -3
  64. package/src/platforms/{devserver.js → devserver.ts} +53 -44
  65. package/src/{recent-projects.js → recent-projects.ts} +17 -12
  66. package/src/{resize-edges.js → resize-edges.ts} +18 -13
  67. package/src/services/{cem-export.js → cem-export.ts} +14 -7
  68. package/src/services/{code-services.js → code-services.ts} +29 -20
  69. package/src/services/{monaco-setup.js → monaco-setup.ts} +2 -3
  70. package/src/settings/{content-types-editor.js → content-types-editor.ts} +88 -67
  71. package/src/settings/{css-vars-editor.js → css-vars-editor.ts} +78 -51
  72. package/src/settings/{defs-editor.js → defs-editor.ts} +70 -56
  73. package/src/settings/{general-settings.js → general-settings.ts} +29 -28
  74. package/src/settings/{head-editor.js → head-editor.ts} +37 -35
  75. package/src/settings/{schema-field-ui.js → schema-field-ui.ts} +86 -76
  76. package/src/settings/{settings-modal.js → settings-modal.ts} +14 -16
  77. package/src/{site-context.js → site-context.ts} +35 -32
  78. package/src/{state.js → state.ts} +95 -78
  79. package/src/{store.js → store.ts} +60 -63
  80. package/src/{studio.js → studio.ts} +117 -119
  81. package/src/tabs/tab.ts +196 -0
  82. package/src/tabs/{transact.js → transact.ts} +107 -60
  83. package/src/types.ts +185 -0
  84. package/src/ui/{button-group.js → button-group.ts} +21 -21
  85. package/src/ui/{color-selector.js → color-selector.ts} +44 -37
  86. package/src/ui/{expression-editor.js → expression-editor.ts} +65 -40
  87. package/src/ui/{field-row.js → field-row.ts} +19 -2
  88. package/src/ui/{icons.js → icons.ts} +2 -2
  89. package/src/ui/{layers.js → layers.ts} +33 -24
  90. package/src/ui/{media-picker.js → media-picker.ts} +13 -9
  91. package/src/ui/{panel-resize.js → panel-resize.ts} +9 -4
  92. package/src/ui/{spectrum.js → spectrum.ts} +4 -4
  93. package/src/ui/{unit-selector.js → unit-selector.ts} +16 -19
  94. package/src/ui/{value-selector.js → value-selector.ts} +28 -28
  95. package/src/ui/{widgets.js → widgets.ts} +62 -15
  96. package/src/utils/{canvas-media.js → canvas-media.ts} +29 -14
  97. package/src/utils/edit-display.ts +298 -0
  98. package/src/utils/{google-fonts.js → google-fonts.ts} +14 -13
  99. package/src/utils/{inherited-style.js → inherited-style.ts} +15 -10
  100. package/src/utils/{studio-utils.js → studio-utils.ts} +35 -23
  101. package/src/{view.js → view.ts} +53 -55
  102. package/src/workspace/{workspace.js → workspace.ts} +44 -33
  103. package/src/panels/dnd.js +0 -426
  104. package/src/tabs/tab.js +0 -192
  105. package/src/utils/edit-display.js +0 -203
  106. /package/src/{reactivity.js → reactivity.ts} +0 -0
@@ -1,3 +1,4 @@
1
+ /// <reference lib="dom" />
1
2
  /**
2
3
  * Git panel — Source control sidebar with sync status, branch selector, Local Changes / History
3
4
  * tabs, commit form, and changed-components view.
@@ -6,13 +7,44 @@
6
7
  import { html, nothing } from "lit-html";
7
8
  import { live } from "lit-html/directives/live.js";
8
9
  import { repeat } from "lit-html/directives/repeat.js";
9
- import { getPlatform } from "../platform.js";
10
- import { updateUi, renderOnly, projectState } from "../store.js";
11
- import { activeTab } from "../workspace/workspace.js";
12
- import { view } from "../view.js";
13
- import { showDialog, showConfirmDialog } from "../ui/layers.js";
14
- import { statusMessage } from "./statusbar.js";
15
- import { publishToGithub } from "../github/github-publish.js";
10
+ import { getPlatform } from "../platform";
11
+ import { updateUi, renderOnly, projectState } from "../store";
12
+ import { activeTab } from "../workspace/workspace";
13
+ import { view } from "../view";
14
+ import { showDialog, showConfirmDialog } from "../ui/layers";
15
+ import { statusMessage } from "./statusbar";
16
+ import { publishToGithub } from "../github/github-publish";
17
+ import type { StudioPlatform } from "../types";
18
+
19
+ interface GitFileEntry {
20
+ path: string;
21
+ status: string;
22
+ staged: boolean;
23
+ }
24
+
25
+ interface GitLogEntry {
26
+ hash: string;
27
+ message: string;
28
+ author: string;
29
+ date: string;
30
+ }
31
+
32
+ interface GitUiState {
33
+ gitStatus?: {
34
+ files?: GitFileEntry[];
35
+ branch?: string;
36
+ ahead?: number;
37
+ behind?: number;
38
+ isRepo?: boolean;
39
+ remotes?: string[];
40
+ } | null;
41
+ gitBranches?: { current?: string; branches?: string[] } | null;
42
+ gitLoading?: boolean;
43
+ gitError?: string | null;
44
+ gitCommitMessage?: string;
45
+ gitLogEntries?: GitLogEntry[] | null;
46
+ [key: string]: unknown;
47
+ }
16
48
 
17
49
  export async function refreshGitStatus() {
18
50
  if (!projectState) return;
@@ -24,8 +56,8 @@ export async function refreshGitStatus() {
24
56
  updateUi("gitStatus", status);
25
57
  updateUi("gitBranches", branches);
26
58
  _lastUpdated = new Date();
27
- } catch (/** @type {unknown} */ e) {
28
- updateUi("gitError", /** @type {Error} */ (e).message);
59
+ } catch (e) {
60
+ updateUi("gitError", (e as Error).message);
29
61
  } finally {
30
62
  updateUi("gitLoading", false);
31
63
  renderOnly("leftPanel");
@@ -37,14 +69,14 @@ export async function refreshGitStatus() {
37
69
  *
38
70
  * @param {{ openRecentProject: (root: string) => Promise<void> }} ctx
39
71
  */
40
- export async function cloneRepository(ctx) {
72
+ export async function cloneRepository(ctx: { openRecentProject: (root: string) => Promise<void> }) {
41
73
  const platform = getPlatform();
42
74
  if (!platform.gitClone) {
43
75
  statusMessage("Clone not supported on this platform");
44
76
  return;
45
77
  }
46
78
 
47
- const url = await showDialog(
79
+ const url = await showDialog<string | null>(
48
80
  (done) => html`
49
81
  <sp-underlay open @close=${() => done(null)}></sp-underlay>
50
82
  <sp-dialog-wrapper
@@ -52,12 +84,10 @@ export async function cloneRepository(ctx) {
52
84
  confirmLabel="Clone"
53
85
  cancelLabel="Cancel"
54
86
  open
55
- @confirm=${(/** @type {Event} */ e) => {
56
- const input = /** @type {HTMLInputElement | null} */ (
57
- /** @type {HTMLElement} */ (
58
- /** @type {HTMLElement} */ (e.target).parentElement
59
- ).querySelector("sp-textfield")
60
- );
87
+ @confirm=${(e: Event) => {
88
+ const input = ((e.target as HTMLElement).parentElement as HTMLElement).querySelector(
89
+ "sp-textfield",
90
+ ) as HTMLInputElement | null;
61
91
  done(input?.value?.trim() || null);
62
92
  }}
63
93
  @cancel=${() => done(null)}
@@ -82,8 +112,8 @@ export async function cloneRepository(ctx) {
82
112
  statusMessage("Clone complete");
83
113
  await ctx.openRecentProject(result.root);
84
114
  }
85
- } catch (/** @type {unknown} */ e) {
86
- statusMessage(`Clone failed: ${/** @type {Error} */ (e).message}`);
115
+ } catch (e) {
116
+ statusMessage(`Clone failed: ${(e as Error).message}`);
87
117
  }
88
118
  }
89
119
 
@@ -96,54 +126,32 @@ export function platformSupportsClone() {
96
126
  * @param {string} action
97
127
  * @param {unknown} [body]
98
128
  */
99
- async function gitAction(action, body) {
100
- const plat = /** @type {Record<string, Function> & StudioPlatform} */ (getPlatform());
129
+ async function gitAction(action: string, body?: unknown) {
130
+ const plat = getPlatform() as Record<string, Function> & StudioPlatform;
101
131
  updateUi("gitLoading", true);
102
132
  updateUi("gitError", null);
103
133
  try {
104
134
  await plat[action](body);
105
135
  await refreshGitStatus();
106
- } catch (/** @type {unknown} */ e) {
107
- updateUi("gitError", /** @type {Error} */ (e).message);
136
+ } catch (e) {
137
+ updateUi("gitError", (e as Error).message);
108
138
  updateUi("gitLoading", false);
109
139
  renderOnly("leftPanel");
110
140
  }
111
141
  }
112
142
 
113
- let _pollTimer = /** @type {ReturnType<typeof setInterval> | null} */ (null);
114
- let _lastUpdated = /** @type {Date | null} */ (null);
143
+ let _pollTimer = null as ReturnType<typeof setInterval> | null;
144
+ let _lastUpdated = null as Date | null;
115
145
  let _gitSubTab = "changes";
116
146
 
117
- /** @typedef {{ path: string; status: string; staged: boolean }} GitFileEntry */
118
- /** @typedef {{ hash: string; message: string; author: string; date: string }} GitLogEntry */
119
-
120
- /**
121
- * @typedef {{
122
- * gitStatus?: {
123
- * files?: GitFileEntry[];
124
- * branch?: string;
125
- * ahead?: number;
126
- * behind?: number;
127
- * isRepo?: boolean;
128
- * remotes?: string[];
129
- * } | null;
130
- * gitBranches?: { current?: string; branches?: string[] } | null;
131
- * gitLoading?: boolean;
132
- * gitError?: string | null;
133
- * gitCommitMessage?: string;
134
- * gitLogEntries?: GitLogEntry[] | null;
135
- * [key: string]: unknown;
136
- * }} GitUiState
137
- */
138
-
139
147
  async function fetchGitLog() {
140
148
  const plat = getPlatform();
141
149
  try {
142
150
  const entries = await plat.gitLog(30);
143
151
  updateUi("gitLogEntries", entries);
144
152
  renderOnly("leftPanel");
145
- } catch (/** @type {unknown} */ e) {
146
- updateUi("gitError", /** @type {Error} */ (e).message);
153
+ } catch (e) {
154
+ updateUi("gitError", (e as Error).message);
147
155
  renderOnly("leftPanel");
148
156
  }
149
157
  }
@@ -156,7 +164,14 @@ async function fetchGitLog() {
156
164
  * cloneRepository?: () => void;
157
165
  * }} ctx
158
166
  */
159
- export function renderGitPanel(S, ctx) {
167
+ export function renderGitPanel(
168
+ S: { ui: GitUiState },
169
+ ctx: {
170
+ setCanvasMode?: (mode: string) => void;
171
+ setGitDiffState?: (state: unknown) => void;
172
+ cloneRepository?: () => void;
173
+ },
174
+ ) {
160
175
  if (!projectState) {
161
176
  return html`<div class="git-panel git-panel-empty">
162
177
  <div class="git-empty-state">
@@ -214,8 +229,8 @@ export function renderGitPanel(S, ctx) {
214
229
  }, 30000);
215
230
  }
216
231
 
217
- const stagedFiles = status?.files?.filter((/** @type {GitFileEntry} */ f) => f.staged) || [];
218
- const unstagedFiles = status?.files?.filter((/** @type {GitFileEntry} */ f) => !f.staged) || [];
232
+ const stagedFiles = status?.files?.filter((f: GitFileEntry) => f.staged) || [];
233
+ const unstagedFiles = status?.files?.filter((f: GitFileEntry) => !f.staged) || [];
219
234
  const totalChanges = status?.files?.length || 0;
220
235
 
221
236
  const doCommit = async () => {
@@ -238,8 +253,8 @@ export function renderGitPanel(S, ctx) {
238
253
  await plat.gitCommit(msg);
239
254
  await plat.gitPush();
240
255
  await refreshGitStatus();
241
- } catch (/** @type {unknown} */ e) {
242
- updateUi("gitError", /** @type {Error} */ (e).message);
256
+ } catch (e) {
257
+ updateUi("gitError", (e as Error).message);
243
258
  updateUi("gitLoading", false);
244
259
  renderOnly("leftPanel");
245
260
  }
@@ -355,10 +370,10 @@ export function renderGitPanel(S, ctx) {
355
370
  quiet
356
371
  class="git-branch-picker"
357
372
  .value=${live(branches?.current || "")}
358
- @change=${async (/** @type {Event} */ e) => {
359
- const val = /** @type {HTMLInputElement} */ (e.target).value;
373
+ @change=${async (e: Event) => {
374
+ const val = (e.target as HTMLInputElement).value;
360
375
  if (val === "__new__") {
361
- /** @type {HTMLInputElement} */ (e.target).value = branches?.current || "";
376
+ (e.target as HTMLInputElement).value = branches?.current || "";
362
377
  const name = prompt("New branch name:");
363
378
  if (name?.trim()) await gitAction("gitCreateBranch", name.trim());
364
379
  return;
@@ -367,7 +382,7 @@ export function renderGitPanel(S, ctx) {
367
382
  }}
368
383
  >
369
384
  ${(branches?.branches || []).map(
370
- (/** @type {string} */ b) => html`<sp-menu-item value=${b}>${b}</sp-menu-item>`,
385
+ (b: string) => html`<sp-menu-item value=${b}>${b}</sp-menu-item>`,
371
386
  )}
372
387
  <sp-menu-divider></sp-menu-divider>
373
388
  <sp-menu-item value="__new__">+ New branch...</sp-menu-item>
@@ -376,7 +391,7 @@ export function renderGitPanel(S, ctx) {
376
391
  `;
377
392
 
378
393
  // ─── 3. Tabs: Local Changes / History ────────────────────────────────────
379
- const switchTab = (/** @type {string} */ tab) => {
394
+ const switchTab = (tab: string) => {
380
395
  _gitSubTab = tab;
381
396
  if (tab === "history" && !S.ui.gitLogEntries) fetchGitLog();
382
397
  renderOnly("leftPanel");
@@ -409,9 +424,8 @@ export function renderGitPanel(S, ctx) {
409
424
  class="git-commit-input"
410
425
  placeholder="Describe your changes"
411
426
  .value=${live(S.ui.gitCommitMessage || "")}
412
- @input=${(/** @type {Event} */ e) =>
413
- updateUi("gitCommitMessage", /** @type {HTMLInputElement} */ (e.target).value)}
414
- @keydown=${(/** @type {KeyboardEvent} */ e) => {
427
+ @input=${(e: Event) => updateUi("gitCommitMessage", (e.target as HTMLInputElement).value)}
428
+ @keydown=${(e: KeyboardEvent) => {
415
429
  if (e.ctrlKey && e.key === "Enter") {
416
430
  e.preventDefault();
417
431
  doCommit();
@@ -431,9 +445,9 @@ export function renderGitPanel(S, ctx) {
431
445
  <sp-action-button
432
446
  class="git-split-trigger"
433
447
  size="s"
434
- @click=${(/** @type {Event} */ e) => {
435
- const menu = /** @type {HTMLElement} */ (
436
- /** @type {HTMLElement} */ (e.currentTarget).parentElement
448
+ @click=${(e: Event) => {
449
+ const menu = (
450
+ (e.currentTarget as HTMLElement).parentElement as HTMLElement
437
451
  ).querySelector(".git-split-menu");
438
452
  if (menu) menu.toggleAttribute("hidden");
439
453
  }}
@@ -443,10 +457,11 @@ export function renderGitPanel(S, ctx) {
443
457
  <div class="git-split-menu" hidden>
444
458
  <button
445
459
  class="git-split-menu-item"
446
- @click=${(/** @type {Event} */ e) => {
447
- /** @type {HTMLElement} */ (
448
- /** @type {HTMLElement} */ (e.currentTarget).parentElement
449
- ).setAttribute("hidden", "");
460
+ @click=${(e: Event) => {
461
+ ((e.currentTarget as HTMLElement).parentElement as HTMLElement).setAttribute(
462
+ "hidden",
463
+ "",
464
+ );
450
465
  doCommit();
451
466
  }}
452
467
  >
@@ -459,7 +474,7 @@ export function renderGitPanel(S, ctx) {
459
474
  `;
460
475
 
461
476
  // ─── 5. Changed Components ───────────────────────────────────────────────
462
- const fileRowT = (/** @type {GitFileEntry} */ file) => {
477
+ const fileRowT = (file: GitFileEntry) => {
463
478
  const parts = file.path.split("/");
464
479
  const name = parts.pop();
465
480
  const dir = parts.join("/");
@@ -494,8 +509,8 @@ export function renderGitPanel(S, ctx) {
494
509
  if (ctx.setGitDiffState) ctx.setGitDiffState(diffState);
495
510
  ctx.setCanvasMode("git-diff");
496
511
  }
497
- } catch (/** @type {unknown} */ e) {
498
- updateUi("gitError", `Failed to load diff: ${/** @type {Error} */ (e).message}`);
512
+ } catch (e) {
513
+ updateUi("gitError", `Failed to load diff: ${(e as Error).message}`);
499
514
  } finally {
500
515
  updateUi("gitLoading", false);
501
516
  }
@@ -559,9 +574,8 @@ export function renderGitPanel(S, ctx) {
559
574
  };
560
575
 
561
576
  /** Group files by component (parent directory for .json/.class.json, or "Other") */
562
- const groupFilesByComponent = (/** @type {GitFileEntry[]} */ files) => {
563
- /** @type {Map<string, GitFileEntry[]>} */
564
- const groups = new Map();
577
+ const groupFilesByComponent = (files: GitFileEntry[]) => {
578
+ const groups: Map<string, GitFileEntry[]> = new Map();
565
579
  for (const f of files) {
566
580
  const parts = f.path.split("/");
567
581
  let component;
@@ -571,7 +585,7 @@ export function renderGitPanel(S, ctx) {
571
585
  component = "Other";
572
586
  }
573
587
  if (!groups.has(component)) groups.set(component, []);
574
- /** @type {GitFileEntry[]} */ (groups.get(component)).push(f);
588
+ (groups.get(component) as GitFileEntry[]).push(f);
575
589
  }
576
590
  return groups;
577
591
  };
@@ -593,13 +607,13 @@ export function renderGitPanel(S, ctx) {
593
607
  @click=${() =>
594
608
  gitAction(
595
609
  "gitUnstage",
596
- stagedFiles.map((/** @type {GitFileEntry} */ f) => f.path),
610
+ stagedFiles.map((f: GitFileEntry) => f.path),
597
611
  )}
598
612
  >
599
613
  <sp-icon-remove slot="icon" size="xs"></sp-icon-remove>
600
614
  </sp-action-button>
601
615
  </div>
602
- ${repeat(stagedFiles, (/** @type {GitFileEntry} */ f) => f.path, fileRowT)}
616
+ ${repeat(stagedFiles, (f: GitFileEntry) => f.path, fileRowT)}
603
617
  </div>
604
618
  `
605
619
  : nothing}
@@ -616,7 +630,7 @@ export function renderGitPanel(S, ctx) {
616
630
  @click=${() =>
617
631
  gitAction(
618
632
  "gitStage",
619
- unstagedFiles.map((/** @type {GitFileEntry} */ f) => f.path),
633
+ unstagedFiles.map((f: GitFileEntry) => f.path),
620
634
  )}
621
635
  >
622
636
  <sp-icon-add slot="icon" size="xs"></sp-icon-add>
@@ -640,7 +654,7 @@ export function renderGitPanel(S, ctx) {
640
654
  </sp-action-button>
641
655
  <span class="git-component-name">${comp}</span>
642
656
  </div>
643
- ${repeat(files, (/** @type {GitFileEntry} */ f) => f.path, fileRowT)}
657
+ ${repeat(files, (f: GitFileEntry) => f.path, fileRowT)}
644
658
  </div>
645
659
  `,
646
660
  )}
@@ -657,8 +671,8 @@ export function renderGitPanel(S, ctx) {
657
671
  ? html`<div class="git-empty">No history</div>`
658
672
  : repeat(
659
673
  logEntries,
660
- (/** @type {GitLogEntry} */ e) => e.hash,
661
- (/** @type {GitLogEntry} */ entry) => html`
674
+ (e: GitLogEntry) => e.hash,
675
+ (entry: GitLogEntry) => html`
662
676
  <div class="git-history-entry">
663
677
  <span class="git-history-hash">${entry.hash.slice(0, 7)}</span>
664
678
  <span class="git-history-message">${entry.message}</span>
@@ -680,7 +694,7 @@ export function renderGitPanel(S, ctx) {
680
694
  }
681
695
 
682
696
  /** @param {string} iso */
683
- function _relativeDate(iso) {
697
+ function _relativeDate(iso: string) {
684
698
  const d = new Date(iso);
685
699
  const now = Date.now();
686
700
  const diff = now - d.getTime();