@shipbench/board 0.1.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 +21 -0
- package/README.md +45 -0
- package/dist/assets/ibm-plex-sans-cyrillic-400-normal-BTotfTJu.woff +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-400-normal-DZqxrq2p.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-500-normal-ByOcLdNv.woff +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-500-normal-CocWQlwt.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-600-normal-71GNu3SW.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-600-normal-BGq0mW3O.woff +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-700-normal-D_uavGvn.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-700-normal-RFb1v-CK.woff +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-ext-400-normal-Dsrv2Tcn.woff +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-ext-400-normal-g30qAdWV.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-ext-500-normal-Cs5J6C77.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-ext-500-normal-DB5PtV2g.woff +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-ext-600-normal-Bz0x94Yp.woff +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-ext-600-normal-DUMzJB7m.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-ext-700-normal-BmRLXWpJ.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-ext-700-normal-DCQwxkRk.woff +0 -0
- package/dist/assets/ibm-plex-sans-greek-400-normal-D9ESIMu3.woff +0 -0
- package/dist/assets/ibm-plex-sans-greek-400-normal-_efipK4i.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-greek-500-normal-CuWXN6rf.woff +0 -0
- package/dist/assets/ibm-plex-sans-greek-500-normal-JMMifIXV.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-greek-600-normal-D-CqTdkO.woff +0 -0
- package/dist/assets/ibm-plex-sans-greek-600-normal-DzTrcv_p.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-greek-700-normal-CkZN0sRy.woff +0 -0
- package/dist/assets/ibm-plex-sans-greek-700-normal-wyJ6jzdA.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-700-normal-Bth3BMcD.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-700-normal-Bxkt5Cjx.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-ext-400-normal-C5H60-Va.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-ext-400-normal-RBey6euL.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-ext-500-normal-D0aIdm-b.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-ext-500-normal-DakdToA3.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-ext-600-normal-DIrixKbi.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-ext-600-normal-DOrvGEcy.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-ext-700-normal-DZH6Xh-4.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-ext-700-normal-aMgXseD4.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-vietnamese-400-normal-DG4YqDda.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-vietnamese-400-normal-fK1oJ5dG.woff +0 -0
- package/dist/assets/ibm-plex-sans-vietnamese-500-normal-BEb3_waV.woff +0 -0
- package/dist/assets/ibm-plex-sans-vietnamese-500-normal-e4dixQRQ.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-vietnamese-600-normal-DgdngZtN.woff +0 -0
- package/dist/assets/ibm-plex-sans-vietnamese-600-normal-DpPYBSTl.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-vietnamese-700-normal-BV5B8Are.woff +0 -0
- package/dist/assets/ibm-plex-sans-vietnamese-700-normal-CkEo6LDy.woff2 +0 -0
- package/dist/assets/intel-one-mono-latin-400-normal-CqVdU6iH.woff2 +0 -0
- package/dist/assets/intel-one-mono-latin-400-normal-Dz-D6UFM.woff +0 -0
- package/dist/assets/intel-one-mono-latin-500-normal-CDhGZfRp.woff +0 -0
- package/dist/assets/intel-one-mono-latin-500-normal-Iu7MK5Mj.woff2 +0 -0
- package/dist/assets/intel-one-mono-latin-600-normal-DJb_B24X.woff2 +0 -0
- package/dist/assets/intel-one-mono-latin-600-normal-UTD3q2hA.woff +0 -0
- package/dist/assets/intel-one-mono-latin-700-normal-BFFlk8Op.woff2 +0 -0
- package/dist/assets/intel-one-mono-latin-700-normal-BzzNQkyM.woff +0 -0
- package/dist/assets/intel-one-mono-latin-ext-400-normal-BW7QmGmG.woff +0 -0
- package/dist/assets/intel-one-mono-latin-ext-400-normal-DpSum8DV.woff2 +0 -0
- package/dist/assets/intel-one-mono-latin-ext-500-normal-Cr2TADCY.woff +0 -0
- package/dist/assets/intel-one-mono-latin-ext-500-normal-i6u6XqNL.woff2 +0 -0
- package/dist/assets/intel-one-mono-latin-ext-600-normal-VDQcLlxR.woff +0 -0
- package/dist/assets/intel-one-mono-latin-ext-600-normal-wurdkzs-.woff2 +0 -0
- package/dist/assets/intel-one-mono-latin-ext-700-normal-Cszyb8TI.woff +0 -0
- package/dist/assets/intel-one-mono-latin-ext-700-normal-DHqel5Cm.woff2 +0 -0
- package/dist/assets/intel-one-mono-symbols2-400-normal-CD7uMPNv.woff2 +0 -0
- package/dist/assets/intel-one-mono-symbols2-400-normal-DrJQZ3Wk.woff +0 -0
- package/dist/assets/intel-one-mono-symbols2-500-normal-CFnvmC0p.woff +0 -0
- package/dist/assets/intel-one-mono-symbols2-500-normal-CW_cPKTh.woff2 +0 -0
- package/dist/assets/intel-one-mono-symbols2-600-normal-DhzUCacJ.woff2 +0 -0
- package/dist/assets/intel-one-mono-symbols2-600-normal-DoqMVv6l.woff +0 -0
- package/dist/assets/intel-one-mono-symbols2-700-normal-CYi7u3jm.woff +0 -0
- package/dist/assets/intel-one-mono-symbols2-700-normal-CkmMEo1z.woff2 +0 -0
- package/dist/assets/intel-one-mono-vietnamese-400-normal-Bn-nXHDK.woff2 +0 -0
- package/dist/assets/intel-one-mono-vietnamese-400-normal-nd8xkrKu.woff +0 -0
- package/dist/assets/intel-one-mono-vietnamese-500-normal-5IwQQhVi.woff2 +0 -0
- package/dist/assets/intel-one-mono-vietnamese-500-normal-Cm4Q0YKh.woff +0 -0
- package/dist/assets/intel-one-mono-vietnamese-600-normal-B9HWtSu2.woff2 +0 -0
- package/dist/assets/intel-one-mono-vietnamese-600-normal-Dm9ZhbyQ.woff +0 -0
- package/dist/assets/intel-one-mono-vietnamese-700-normal-Da_Xc8bO.woff +0 -0
- package/dist/assets/intel-one-mono-vietnamese-700-normal-xgkGRJps.woff2 +0 -0
- package/dist/assets/standalone-BPsBcSWX.css +1 -0
- package/dist/assets/standalone-BWUDRXLh.js +106 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +18137 -0
- package/dist/standalone.d.ts +8 -0
- package/dist/standalone.html +13 -0
- package/dist/store/BoardStoreProvider.d.ts +8 -0
- package/dist/store/boardStore.d.ts +51 -0
- package/dist/styles.css +1 -0
- package/dist/ui/ArchiveTaskDialog.d.ts +8 -0
- package/dist/ui/ArchiveView.d.ts +1 -0
- package/dist/ui/Board.d.ts +8 -0
- package/dist/ui/BoardCanvas.d.ts +1 -0
- package/dist/ui/BoardHeader.d.ts +3 -0
- package/dist/ui/BoardThemeToggle.d.ts +4 -0
- package/dist/ui/BoardToaster.d.ts +1 -0
- package/dist/ui/Chevron.d.ts +7 -0
- package/dist/ui/DetailView.d.ts +3 -0
- package/dist/ui/KanbanBoard.d.ts +116 -0
- package/dist/ui/Markdown.d.ts +15 -0
- package/dist/ui/MetadataInputs.d.ts +16 -0
- package/dist/ui/NewTaskDialog.d.ts +5 -0
- package/dist/ui/PriorityMeter.d.ts +9 -0
- package/dist/ui/Select.d.ts +19 -0
- package/dist/ui/SyncEffects.d.ts +4 -0
- package/dist/ui/TaskCard.d.ts +11 -0
- package/dist/ui/useAutosizeTextarea.d.ts +2 -0
- package/dist/utils/links.d.ts +31 -0
- package/dist/utils/time.d.ts +2 -0
- package/package.json +81 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import '@fontsource/ibm-plex-sans/400.css';
|
|
2
|
+
import '@fontsource/ibm-plex-sans/500.css';
|
|
3
|
+
import '@fontsource/ibm-plex-sans/600.css';
|
|
4
|
+
import '@fontsource/ibm-plex-sans/700.css';
|
|
5
|
+
import '@fontsource/intel-one-mono/400.css';
|
|
6
|
+
import '@fontsource/intel-one-mono/500.css';
|
|
7
|
+
import '@fontsource/intel-one-mono/600.css';
|
|
8
|
+
import '@fontsource/intel-one-mono/700.css';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>ShipBench Board</title>
|
|
7
|
+
<script type="module" crossorigin src="/assets/standalone-BWUDRXLh.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/standalone-BPsBcSWX.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body class="sb-standalone">
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BoardAPI } from '@shipbench/core';
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import { type BoardState } from './boardStore.js';
|
|
4
|
+
export declare function BoardStoreProvider({ api, children, }: {
|
|
5
|
+
api: BoardAPI;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
export declare function useBoardStore<T>(selector: (state: BoardState) => T): T;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { BoardAPI, ShipbenchConfig, Task, TaskFrontmatter, TaskValidationWarning } from '@shipbench/core';
|
|
2
|
+
import { type StoreApi } from 'zustand/vanilla';
|
|
3
|
+
export declare const UNCATEGORIZED_STATUS = "__uncategorized__";
|
|
4
|
+
export interface BoardState {
|
|
5
|
+
/**
|
|
6
|
+
* Snapshotted from `api.readOnly` at store creation. Swapping modes means
|
|
7
|
+
* providing a new `BoardAPI` — `BoardStoreProvider` recreates the store
|
|
8
|
+
* whenever the api reference changes.
|
|
9
|
+
*/
|
|
10
|
+
readOnly: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Snapshotted from `api.resolveRepoLink` on the same terms as `readOnly`.
|
|
13
|
+
* `null` when the host cannot point at repo files — the Markdown renderer
|
|
14
|
+
* then shows those links as plain paths instead of anchors that 404.
|
|
15
|
+
*/
|
|
16
|
+
resolveRepoLink: ((repoRelativePath: string) => string | null) | null;
|
|
17
|
+
config: ShipbenchConfig | null;
|
|
18
|
+
tasks: Task[];
|
|
19
|
+
warnings: TaskValidationWarning[];
|
|
20
|
+
archiveViewOpen: boolean;
|
|
21
|
+
archivedTasks: Task[] | null;
|
|
22
|
+
archiveWarnings: TaskValidationWarning[];
|
|
23
|
+
isArchiveLoading: boolean;
|
|
24
|
+
archiveLoadError: string | null;
|
|
25
|
+
selectedTaskSlug: string | null;
|
|
26
|
+
searchQuery: string;
|
|
27
|
+
lastSyncedAt: number | null;
|
|
28
|
+
isSyncing: boolean;
|
|
29
|
+
hasLoaded: boolean;
|
|
30
|
+
initialLoadError: string | null;
|
|
31
|
+
errorAtBySlug: Record<string, number>;
|
|
32
|
+
refresh: () => Promise<void>;
|
|
33
|
+
moveTask: (slug: string, toStatus: string) => Promise<void>;
|
|
34
|
+
reorderTask: (slug: string, toStatus: string, position: number) => Promise<void>;
|
|
35
|
+
updateTask: (slug: string, fields: Partial<TaskFrontmatter>, body?: string) => Promise<void>;
|
|
36
|
+
addComment: (slug: string, text: string) => Promise<boolean>;
|
|
37
|
+
editComment: (slug: string, index: number, text: string) => Promise<boolean>;
|
|
38
|
+
deleteComment: (slug: string, index: number) => Promise<boolean>;
|
|
39
|
+
createTask: (title: string, fields?: Partial<TaskFrontmatter>) => Promise<void>;
|
|
40
|
+
archiveTask: (slug: string, force?: boolean) => Promise<void>;
|
|
41
|
+
unarchiveTask: (slug: string) => Promise<void>;
|
|
42
|
+
openArchive: () => void;
|
|
43
|
+
closeArchive: () => void;
|
|
44
|
+
loadArchivedTasks: () => Promise<void>;
|
|
45
|
+
deleteTask: (slug: string) => Promise<void>;
|
|
46
|
+
selectTask: (slug: string | null) => void;
|
|
47
|
+
setSearchQuery: (query: string) => void;
|
|
48
|
+
}
|
|
49
|
+
export type BoardStore = StoreApi<BoardState>;
|
|
50
|
+
export declare function createBoardStore(api: BoardAPI): BoardStore;
|
|
51
|
+
export declare function getVisibleTasks(tasks: Task[], searchQuery: string): Task[];
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:"IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;--font-mono:"Intel One Mono", "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;--color-black:#000;--spacing:.25rem;--container-md:28rem;--container-xl:36rem;--container-5xl:64rem;--container-7xl:80rem;--text-base:1rem;--text-base--line-height: 1.5 ;--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--leading-relaxed:1.625;--radius-md:3px;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--radius:2px;--color-sb-canvas:var(--sb-canvas);--color-sb-surface:var(--sb-surface);--color-sb-surface2:var(--sb-surface2);--color-sb-divider:var(--sb-divider);--color-sb-iron:var(--sb-iron);--color-sb-ironlit:var(--sb-ironlit);--color-sb-silver:var(--sb-silver);--color-sb-frosted:var(--sb-frosted);--color-sb-accent:var(--sb-accent);--color-sb-accent-hover:var(--sb-accent-hover);--color-sb-accent-pressed:var(--sb-accent-pressed);--color-sb-danger:var(--sb-danger);--color-sb-success:var(--sb-success);--color-sb-warning:var(--sb-warning)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}@media(hover:hover){button:hover{cursor:pointer}}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-x-0{inset-inline:0}.-top-1\.5{top:calc(var(--spacing) * -1.5)}.top-0{top:0}.top-1\/2{top:50%}.right-2{right:calc(var(--spacing) * 2)}.right-4{right:calc(var(--spacing) * 4)}.-bottom-1\.5{bottom:calc(var(--spacing) * -1.5)}.bottom-4{bottom:calc(var(--spacing) * 4)}.left-1\/2{left:50%}.left-3{left:calc(var(--spacing) * 3)}.z-10{z-index:10}.z-50{z-index:50}.row-span-2{grid-row:span 2/span 2}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mr-auto{margin-right:auto}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.field-sizing-content{field-sizing:content}.h-0\.5{height:calc(var(--spacing) * .5)}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-11{height:calc(var(--spacing) * 11)}.h-fit{height:fit-content}.h-px{height:1px}.max-h-48{max-height:calc(var(--spacing) * 48)}.min-h-9{min-height:calc(var(--spacing) * 9)}.min-h-20{min-height:calc(var(--spacing) * 20)}.min-h-24{min-height:calc(var(--spacing) * 24)}.min-h-28{min-height:calc(var(--spacing) * 28)}.min-h-80{min-height:calc(var(--spacing) * 80)}.min-h-\[70vh\]{min-height:70vh}.min-h-\[calc\(100vh-var\(--sb-header-h\)\)\]{min-height:calc(100vh - var(--sb-header-h))}.min-h-\[calc\(100vh-var\(--sb-header-h\)-2\.5rem\)\]{min-height:calc(100vh - var(--sb-header-h) - 2.5rem)}.min-h-screen{min-height:100vh}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-\[20rem\]{width:20rem}.w-\[356px\]{width:356px}.w-fit{width:fit-content}.w-full{width:100%}.max-w-5xl{max-width:var(--container-5xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:0}.min-w-10{min-width:calc(var(--spacing) * 10)}.min-w-20{min-width:calc(var(--spacing) * 20)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.-rotate-90{rotate:-90deg}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-copy{cursor:copy}.cursor-default{cursor:default}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-\[1px\]{gap:1px}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-y-0\.5{row-gap:calc(var(--spacing) * .5)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:var(--radius)}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-sb-danger{border-color:var(--color-sb-danger)}.border-sb-divider{border-color:var(--color-sb-divider)}.border-sb-iron{border-color:var(--color-sb-iron)}.border-sb-ironlit{border-color:var(--color-sb-ironlit)}.border-sb-silver{border-color:var(--color-sb-silver)}.border-transparent{border-color:#0000}.border-l-sb-danger{border-left-color:var(--color-sb-danger)}.border-l-sb-success{border-left-color:var(--color-sb-success)}.border-l-sb-warning{border-left-color:var(--color-sb-warning)}.bg-black\/70{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.bg-black\/70{background-color:color-mix(in oklab,var(--color-black) 70%,transparent)}}.bg-sb-accent,.bg-sb-accent\/15{background-color:var(--color-sb-accent)}@supports (color:color-mix(in lab,red,red)){.bg-sb-accent\/15{background-color:color-mix(in oklab,var(--color-sb-accent) 15%,transparent)}}.bg-sb-canvas,.bg-sb-canvas\/95{background-color:var(--color-sb-canvas)}@supports (color:color-mix(in lab,red,red)){.bg-sb-canvas\/95{background-color:color-mix(in oklab,var(--color-sb-canvas) 95%,transparent)}}.bg-sb-divider{background-color:var(--color-sb-divider)}.bg-sb-frosted{background-color:var(--color-sb-frosted)}.bg-sb-surface{background-color:var(--color-sb-surface)}.bg-sb-surface2{background-color:var(--color-sb-surface2)}.bg-transparent{background-color:#0000}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-9{padding-left:calc(var(--spacing) * 9)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.2em\]{--tw-tracking:.2em;letter-spacing:.2em}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[0\.14em\]{--tw-tracking:.14em;letter-spacing:.14em}.tracking-\[0\.18em\]{--tw-tracking:.18em;letter-spacing:.18em}.text-sb-accent{color:var(--color-sb-accent)}.text-sb-canvas{color:var(--color-sb-canvas)}.text-sb-danger{color:var(--color-sb-danger)}.text-sb-frosted{color:var(--color-sb-frosted)}.text-sb-iron{color:var(--color-sb-iron)}.text-sb-silver{color:var(--color-sb-silver)}.text-sb-success{color:var(--color-sb-success)}.text-sb-warning{color:var(--color-sb-warning)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.accent-sb-silver{accent-color:var(--color-sb-silver)}.opacity-40{opacity:.4}.opacity-60{opacity:.6}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:text-sb-frosted:is(:where(.group):hover *){color:var(--color-sb-frosted)}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.placeholder\:text-sb-silver::placeholder,.placeholder\:text-sb-silver\/60::placeholder{color:var(--color-sb-silver)}@supports (color:color-mix(in lab,red,red)){.placeholder\:text-sb-silver\/60::placeholder{color:color-mix(in oklab,var(--color-sb-silver) 60%,transparent)}}@media(hover:hover){.hover\:border-sb-iron:hover{border-color:var(--color-sb-iron)}.hover\:border-sb-ironlit:hover{border-color:var(--color-sb-ironlit)}.hover\:border-sb-silver:hover{border-color:var(--color-sb-silver)}.hover\:bg-sb-accent-hover:hover{background-color:var(--color-sb-accent-hover)}.hover\:bg-sb-danger\/10:hover{background-color:var(--color-sb-danger)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sb-danger\/10:hover{background-color:color-mix(in oklab,var(--color-sb-danger) 10%,transparent)}}.hover\:bg-sb-surface:hover{background-color:var(--color-sb-surface)}.hover\:bg-sb-surface2:hover{background-color:var(--color-sb-surface2)}.hover\:text-sb-danger:hover{color:var(--color-sb-danger)}.hover\:text-sb-frosted:hover{color:var(--color-sb-frosted)}}.focus\:border-sb-silver:focus{border-color:var(--color-sb-silver)}.focus-visible\:border-sb-accent:focus-visible{border-color:var(--color-sb-accent)}.focus-visible\:border-sb-silver:focus-visible{border-color:var(--color-sb-silver)}.focus-visible\:bg-sb-surface:focus-visible{background-color:var(--color-sb-surface)}.focus-visible\:bg-sb-surface2:focus-visible{background-color:var(--color-sb-surface2)}.focus-visible\:text-sb-frosted:focus-visible{color:var(--color-sb-frosted)}.active\:bg-sb-accent-pressed:active{background-color:var(--color-sb-accent-pressed)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}@media(hover:hover){.disabled\:hover\:bg-transparent:disabled:hover{background-color:#0000}}.data-highlighted\:bg-sb-surface2[data-highlighted]{background-color:var(--color-sb-surface2)}.data-highlighted\:text-sb-frosted[data-highlighted]{color:var(--color-sb-frosted)}.data-placeholder\:text-sb-silver[data-placeholder]{color:var(--color-sb-silver)}.data-\[state\=checked\]\:text-sb-frosted[data-state=checked]{color:var(--color-sb-frosted)}@media(min-width:40rem){.sm\:w-80{width:calc(var(--spacing) * 80)}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}}@media(min-width:64rem){.lg\:sticky{position:sticky}.lg\:top-\[calc\(var\(--sb-header-h\)\+1\.25rem\)\]{top:calc(var(--sb-header-h) + 1.25rem)}.lg\:max-h-\[calc\(100vh-var\(--sb-header-h\)-2\.5rem\)\]{max-height:calc(100vh - var(--sb-header-h) - 2.5rem)}.lg\:grid-cols-\[minmax\(0\,7fr\)_minmax\(18rem\,3fr\)\]{grid-template-columns:minmax(0,7fr) minmax(18rem,3fr)}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:justify-between{justify-content:space-between}.lg\:self-start{align-self:flex-start}.lg\:overflow-y-auto{overflow-y:auto}}}:root{color-scheme:dark;--sb-canvas:#18171c;--sb-surface:#1e1d24;--sb-surface2:#232229;--sb-divider:#2a2f44;--sb-iron:#626b91;--sb-ironlit:#747d9e;--sb-silver:#aaa7ba;--sb-frosted:#f7f5f7;--sb-accent:#6e79f2;--sb-accent-hover:#8a93f5;--sb-accent-pressed:#5a63d6;--sb-danger:#e5605f;--sb-success:#57b37e;--sb-warning:#e3a34a}@media(prefers-color-scheme:light){:root:not([data-theme]){color-scheme:light;--sb-canvas:#ecedf2;--sb-surface:#fff;--sb-surface2:#f3f3f8;--sb-divider:#dcdce4;--sb-iron:#84838f;--sb-ironlit:#6c6b7a;--sb-silver:#56545f;--sb-frosted:#1b1a21;--sb-accent:#4b52c7;--sb-accent-hover:#3e45b5;--sb-accent-pressed:#343b9e;--sb-danger:#c4322f;--sb-success:#2a7449;--sb-warning:#8a5a00}}:root[data-theme=light]{color-scheme:light;--sb-canvas:#ecedf2;--sb-surface:#fff;--sb-surface2:#f3f3f8;--sb-divider:#dcdce4;--sb-iron:#84838f;--sb-ironlit:#6c6b7a;--sb-silver:#56545f;--sb-frosted:#1b1a21;--sb-accent:#4b52c7;--sb-accent-hover:#3e45b5;--sb-accent-pressed:#343b9e;--sb-danger:#c4322f;--sb-success:#2a7449;--sb-warning:#8a5a00}:root[data-theme=dark]{color-scheme:dark;--sb-canvas:#18171c;--sb-surface:#1e1d24;--sb-surface2:#232229;--sb-divider:#2a2f44;--sb-iron:#626b91;--sb-ironlit:#747d9e;--sb-silver:#aaa7ba;--sb-frosted:#f7f5f7;--sb-accent:#6e79f2;--sb-accent-hover:#8a93f5;--sb-accent-pressed:#5a63d6;--sb-danger:#e5605f;--sb-success:#57b37e;--sb-warning:#e3a34a}*{box-sizing:border-box}::selection{background:var(--sb-iron);color:var(--sb-frosted)}:focus-visible{outline:2px solid var(--sb-accent);outline-offset:2px;border-radius:2px}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--sb-canvas)}::-webkit-scrollbar-thumb{background:var(--sb-iron);border-radius:0}::-webkit-scrollbar-thumb:hover{background:var(--sb-ironlit)}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,:before,:after{transition:none!important;animation:none!important}}.sb-standalone{background:var(--sb-canvas);color:var(--sb-frosted);margin:0}.sb-board-root{--sb-header-h:65px}.sb-canvas-grid{background-color:var(--sb-canvas);background-image:linear-gradient(90deg,#2a2f4417 1px,#0000 1px),linear-gradient(#2a2f4417 1px,#0000 1px);background-size:40px 40px}.sb-editor{caret-color:var(--sb-accent)}.sb-editor:focus{outline:none}.sb-form-control{min-height:calc(var(--spacing) * 9);border-radius:var(--radius);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-sb-iron);background-color:var(--color-sb-surface2);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.sb-form-control:focus-within{border-color:var(--color-sb-silver)}@media(hover:hover){.sb-form-control:hover{border-color:var(--color-sb-silver)}}.sb-metadata-label{font-family:var(--font-mono);--tw-tracking:.14em;letter-spacing:.14em;color:var(--color-sb-silver);text-transform:uppercase;font-size:11px}.sb-metadata-token{border-radius:var(--radius);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-sb-iron);background-color:var(--color-sb-surface2);padding-inline:calc(var(--spacing) * 2);padding-block:var(--spacing);font-family:var(--font-mono);color:var(--color-sb-silver);font-size:11px}.sb-token-action{border-radius:var(--radius);--tw-leading:1;color:var(--color-sb-silver);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));justify-content:center;align-items:center;padding:0;line-height:1;display:inline-flex}@media(hover:hover){.sb-token-action:hover{color:var(--color-sb-frosted)}}.sb-token-action:focus-visible{color:var(--color-sb-frosted)}.sb-combobox-list{z-index:30;margin-top:var(--spacing);max-height:calc(var(--spacing) * 64);border-radius:var(--radius);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-sb-iron);background-color:var(--color-sb-surface);width:100%;padding:var(--spacing);position:absolute;top:100%;overflow-y:auto}.sb-combobox-option{cursor:default;border-radius:var(--radius);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1.5);font-family:var(--font-mono);color:var(--color-sb-silver);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-outline-style:none;outline-style:none;font-size:11px}@media(hover:hover){.sb-combobox-option:hover{background-color:var(--color-sb-surface2);color:var(--color-sb-frosted)}}.sb-combobox-option[aria-selected=true]{background-color:var(--color-sb-surface2);color:var(--color-sb-frosted)}.sb-error-shake{animation:.22s ease-in-out sb-shake}.sb-markdown{color:var(--sb-silver);font-size:14px;line-height:1.7}.sb-markdown>:first-child{margin-top:0}.sb-markdown>:last-child{margin-bottom:0}.sb-markdown :where(h1,h2,h3,h4){margin-top:calc(var(--spacing) * 7);margin-bottom:calc(var(--spacing) * 3);font-family:var(--font-sans);--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--color-sb-frosted)}.sb-markdown h1{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.sb-markdown h2{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.sb-markdown :where(h3,h4){font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.sb-markdown :where(p,ul,ol,pre,blockquote,table){margin-block:calc(var(--spacing) * 4)}.sb-markdown ul{padding-left:calc(var(--spacing) * 6);list-style-type:disc}.sb-markdown ol{padding-left:calc(var(--spacing) * 6);list-style-type:decimal}.sb-markdown li{margin-block:var(--spacing);padding-left:var(--spacing)}.sb-markdown a{color:var(--color-sb-silver);text-decoration-line:underline;-webkit-text-decoration-color:var(--color-sb-ironlit);text-decoration-color:var(--color-sb-ironlit);text-underline-offset:4px;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.sb-markdown a:hover{color:var(--color-sb-frosted)}}.sb-markdown .sb-md-path{border-radius:var(--radius);background-color:var(--color-sb-surface2);padding-inline:calc(var(--spacing) * 1.5);padding-block:calc(var(--spacing) * .5);font-family:var(--font-mono);color:var(--color-sb-silver);font-size:.9em}.sb-markdown blockquote{border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--color-sb-divider);padding-left:calc(var(--spacing) * 4);font-style:italic}.sb-markdown code{border-radius:var(--radius);background-color:var(--color-sb-surface2);padding-inline:calc(var(--spacing) * 1.5);padding-block:calc(var(--spacing) * .5);font-family:var(--font-mono);color:var(--color-sb-frosted);font-size:.9em}.sb-markdown pre{border-radius:var(--radius);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-sb-iron);background-color:var(--color-sb-surface2);padding:calc(var(--spacing) * 4);overflow-x:auto}.sb-markdown pre code{--tw-leading:calc(var(--spacing) * 6);font-size:12px;line-height:calc(var(--spacing) * 6);background-color:#0000;padding:0}.sb-markdown table{border-collapse:collapse;width:100%;font-family:var(--font-mono);font-size:12px}.sb-markdown :where(th,td){border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-sb-iron);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);text-align:left}.sb-markdown th{background-color:var(--color-sb-surface2);--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--color-sb-frosted)}.sb-markdown hr{margin-block:calc(var(--spacing) * 7);border-color:var(--color-sb-divider)}@keyframes sb-shake{0%,to{transform:translate(0)}25%{transform:translate(-4px)}75%{transform:translate(4px)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Task } from '@shipbench/core';
|
|
2
|
+
export declare function ArchiveTaskDialog({ open, taskTitle, dependents, onOpenChange, onConfirm, }: {
|
|
3
|
+
open: boolean;
|
|
4
|
+
taskTitle: string;
|
|
5
|
+
dependents: Task[];
|
|
6
|
+
onOpenChange: (open: boolean) => void;
|
|
7
|
+
onConfirm: () => void;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function ArchiveView(): import("react").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BoardAPI } from '@shipbench/core';
|
|
2
|
+
export interface BoardProps {
|
|
3
|
+
api: BoardAPI;
|
|
4
|
+
/** Standalone hosts pass true to show the theme toggle; the embed omits it
|
|
5
|
+
* and inherits the host's theme. */
|
|
6
|
+
themeControl?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function Board({ api, themeControl }: BoardProps): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function BoardCanvas(): import("react").JSX.Element;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Apply the persisted choice to <html> before first render. Called by the
|
|
2
|
+
* standalone entry so the override is honored as early as possible. */
|
|
3
|
+
export declare function applyStoredBoardTheme(): void;
|
|
4
|
+
export declare function BoardThemeToggle(): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function BoardToaster(): import("react").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Inline SVG <symbol> for the chevron primitive. Mounted once in the Board
|
|
2
|
+
* root; every `<Chevron />` references it via `<use>`. Color propagates
|
|
3
|
+
* through `currentColor` — set with any text utility. */
|
|
4
|
+
export declare function ChevronDefs(): import("react").JSX.Element;
|
|
5
|
+
export declare function Chevron({ className }: {
|
|
6
|
+
className?: string;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { type CollisionDetection } from '@dnd-kit/core';
|
|
2
|
+
import type { ShipbenchConfig, Task } from '@shipbench/core';
|
|
3
|
+
interface Column {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
tasks: Task[];
|
|
7
|
+
/** True if this column should time-sort and disable manual reorder. */
|
|
8
|
+
isDone: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Build the rendered columns from board data alone.
|
|
12
|
+
*
|
|
13
|
+
* The absent parameter is the point: **nothing about the in-progress drag may
|
|
14
|
+
* influence what is rendered.** dnd-kit derives `over` during render from the
|
|
15
|
+
* measured droppable rects and dispatches `onDragOver` from an effect keyed on
|
|
16
|
+
* it, so a preview that reorders or re-parents cards changes those rects, flips
|
|
17
|
+
* `over`, and re-enters the handler with the pointer stationary — an undamped
|
|
18
|
+
* loop that ends in React's "Maximum update depth exceeded" (#185).
|
|
19
|
+
*
|
|
20
|
+
* Keeping preview state out of this signature makes that class of bug a type
|
|
21
|
+
* error rather than something a test has to catch. The drop target is shown
|
|
22
|
+
* instead by an absolutely-positioned indicator, which occupies no space and so
|
|
23
|
+
* cannot move anything. See docs/audits/board-move-algorithm-audit.md.
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildColumns(config: ShipbenchConfig, visibleTasks: Task[], validStatuses: Set<string>): Column[];
|
|
26
|
+
/**
|
|
27
|
+
* Where to draw the insertion line, as an index into the column's *rendered*
|
|
28
|
+
* task list (`tasks.length` meaning "after the last card").
|
|
29
|
+
*
|
|
30
|
+
* `previewPosition` counts positions among the drop candidates, which exclude
|
|
31
|
+
* the dragged card. The dragged card is still rendered in place (dimmed), so a
|
|
32
|
+
* same-column drag has to step over it to land on the right gap.
|
|
33
|
+
*/
|
|
34
|
+
export declare function indicatorIndexForColumn(tasks: Task[], activeSlug: string, previewPosition: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Collision detection that keeps the gaps between cards attached to a card.
|
|
37
|
+
*
|
|
38
|
+
* `pointerWithin` already ranks a card above the column behind it — a card's
|
|
39
|
+
* rect corners are much nearer the pointer than a tall column's. But the column
|
|
40
|
+
* body uses `gap-3`, so there is a 12px band between every pair of cards where
|
|
41
|
+
* no card contains the pointer and the column wins outright. `resolveDragOver`
|
|
42
|
+
* reads a column hit as "empty space, send to the tail", so dragging up a column
|
|
43
|
+
* made the indicator flick to the bottom each time the pointer crossed a gap —
|
|
44
|
+
* and releasing in one sent the task to the bottom.
|
|
45
|
+
*
|
|
46
|
+
* Gaps belong to the card below them. Only space past the last card is genuinely
|
|
47
|
+
* empty and means "tail".
|
|
48
|
+
*/
|
|
49
|
+
export declare const cardsOverColumns: CollisionDetection;
|
|
50
|
+
export declare function KanbanBoard(): import("react").JSX.Element;
|
|
51
|
+
export interface TaskDropColumn {
|
|
52
|
+
id: string;
|
|
53
|
+
tasks: Task[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Decide what the drag preview should become for one hover, or `null` to show
|
|
57
|
+
* no preview at all.
|
|
58
|
+
*
|
|
59
|
+
* Extracted from `onDragOver` because this decision table has now been the
|
|
60
|
+
* source of two separate bugs and had no test around it.
|
|
61
|
+
*/
|
|
62
|
+
export declare function resolveDragOver({ overId, overStatus, overIsColumn, activeSlug, activeStatus, originIndex, columns, }: {
|
|
63
|
+
overId: string | null;
|
|
64
|
+
overStatus: string | undefined;
|
|
65
|
+
/** True when `over` is a column's own droppable rather than a card. */
|
|
66
|
+
overIsColumn: boolean;
|
|
67
|
+
activeSlug: string | null;
|
|
68
|
+
activeStatus: string | undefined;
|
|
69
|
+
originIndex: number;
|
|
70
|
+
columns: TaskDropColumn[];
|
|
71
|
+
}): {
|
|
72
|
+
status: string;
|
|
73
|
+
position: number;
|
|
74
|
+
} | null;
|
|
75
|
+
/**
|
|
76
|
+
* Resolve where a drag should land, or `null` for a no-op drop.
|
|
77
|
+
*
|
|
78
|
+
* Extracted from `onDragEnd` so the branchy drop logic is unit-testable. The
|
|
79
|
+
* load-bearing rule: a drop whose `over` is the dragged card itself (or its
|
|
80
|
+
* projected placeholder) — or that has no `over` at all — carries no explicit
|
|
81
|
+
* target, so we honor the standing preview position rather than recomputing it
|
|
82
|
+
* (which would collapse to -1 via `getDragPreviewPosition` and append to the
|
|
83
|
+
* bottom). When the result is the task's existing column + index, return `null`
|
|
84
|
+
* so the caller skips the write entirely — an accidental pick-up-and-drop must
|
|
85
|
+
* not reorder or bump `updated`.
|
|
86
|
+
*
|
|
87
|
+
* Note: -1 remains the "append to tail" sentinel, produced only by an explicit
|
|
88
|
+
* empty-column-space drop here — never by a self/no-target drop.
|
|
89
|
+
*/
|
|
90
|
+
export declare function resolveTaskDrop({ activeSlug, activeStatus, overId, overStatus, overIsColumn, previewStatus, previewPosition, columns, }: {
|
|
91
|
+
activeSlug: string;
|
|
92
|
+
activeStatus: string | undefined;
|
|
93
|
+
overId: string | null;
|
|
94
|
+
overStatus: string | undefined;
|
|
95
|
+
/** True when `over` is a column's own droppable rather than a card. */
|
|
96
|
+
overIsColumn: boolean;
|
|
97
|
+
previewStatus: string | null;
|
|
98
|
+
previewPosition: number;
|
|
99
|
+
columns: TaskDropColumn[];
|
|
100
|
+
}): {
|
|
101
|
+
status: string;
|
|
102
|
+
position: number;
|
|
103
|
+
} | null;
|
|
104
|
+
export declare function getDragPreviewPosition({ tasks, overSlug, activeSlug, sameColumn, }: {
|
|
105
|
+
tasks: Task[];
|
|
106
|
+
overSlug: string;
|
|
107
|
+
activeSlug: string | null;
|
|
108
|
+
/**
|
|
109
|
+
* True when the drag started in the same column being previewed. Enables
|
|
110
|
+
* direction detection from index comparison — necessary because `DragOverlay`
|
|
111
|
+
* suppresses the drag transform on the underlying active element, so we
|
|
112
|
+
* cannot infer direction from rects at runtime.
|
|
113
|
+
*/
|
|
114
|
+
sameColumn: boolean;
|
|
115
|
+
}): number;
|
|
116
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown rendering for task bodies and updates. Both surfaces get the same
|
|
3
|
+
* link behaviour — configuring one and leaving the other bare is the easiest
|
|
4
|
+
* way to ship this half-broken.
|
|
5
|
+
*
|
|
6
|
+
* `urlTransform` is deliberately not overridden. `defaultUrlTransform`
|
|
7
|
+
* sanitizes hrefs against react-markdown's safe-protocol allowlist, and in
|
|
8
|
+
* Harbor's remote mode this content arrives from a GitHub repo, so that
|
|
9
|
+
* filtering matters. Relative paths pass through it untouched, which leaves
|
|
10
|
+
* every link decision to `components.a` below — after sanitization, not
|
|
11
|
+
* instead of it.
|
|
12
|
+
*/
|
|
13
|
+
export declare function Markdown({ children }: {
|
|
14
|
+
children: string;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Task } from '@shipbench/core';
|
|
2
|
+
export declare function TagInput({ readOnly, tags, suggestions, onChange, }: {
|
|
3
|
+
readOnly: boolean;
|
|
4
|
+
tags: string[];
|
|
5
|
+
suggestions: string[];
|
|
6
|
+
onChange: (tags: string[]) => void;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
export declare function DependencyMultiSelect({ readOnly, currentTaskSlug, dependencies, tasks, doneColumn, warnings, onChange, }: {
|
|
9
|
+
readOnly: boolean;
|
|
10
|
+
currentTaskSlug: string;
|
|
11
|
+
dependencies: string[];
|
|
12
|
+
tasks: Task[];
|
|
13
|
+
doneColumn: string;
|
|
14
|
+
warnings: string[];
|
|
15
|
+
onChange: (dependencies: string[]) => void;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Doctrine: Component primitives › Priority meter. One chevron per configured
|
|
2
|
+
* priority tier — filled at or below the current value, dim above. Priorities
|
|
3
|
+
* come from `config.priority.values`, never a hardcoded low/medium/high, so the
|
|
4
|
+
* meter renders only when the value maps to a sane configured scale and falls
|
|
5
|
+
* back to a plain mono chip otherwise. */
|
|
6
|
+
export declare function PriorityMeter({ value, values, }: {
|
|
7
|
+
value: string;
|
|
8
|
+
values: string[];
|
|
9
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface SelectOption {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
}
|
|
5
|
+
export interface SelectProps {
|
|
6
|
+
value: string;
|
|
7
|
+
onValueChange: (value: string) => void;
|
|
8
|
+
options: SelectOption[];
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
ariaLabel?: string;
|
|
11
|
+
/** Optional first entry that maps to `""` (e.g. "None"). */
|
|
12
|
+
emptyOption?: {
|
|
13
|
+
label: string;
|
|
14
|
+
};
|
|
15
|
+
/** Render the column-marker square before the value — the shared "status"
|
|
16
|
+
* visual language across board columns, select triggers, and card headers. */
|
|
17
|
+
statusMarker?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function Select({ value, onValueChange, options, placeholder, ariaLabel, emptyOption, statusMarker, }: SelectProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Task } from '@shipbench/core';
|
|
2
|
+
interface TaskCardProps {
|
|
3
|
+
task: Task;
|
|
4
|
+
status: string;
|
|
5
|
+
/** When true, the card is wired up to dnd-kit as a sortable source. */
|
|
6
|
+
draggable?: boolean;
|
|
7
|
+
/** When true, render the card as a placeholder shadow (overlay handles the real one). */
|
|
8
|
+
isPlaceholder?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function TaskCard({ task, status, draggable, isPlaceholder, }: TaskCardProps): import("react").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classification of a Markdown link found in a task body or update.
|
|
3
|
+
*
|
|
4
|
+
* Task bodies overwhelmingly link to files in the same repo — relative paths
|
|
5
|
+
* written for someone reading the raw Markdown next to a checkout. Rendered in
|
|
6
|
+
* the Board, those hrefs resolve against the board's own origin and 404. This
|
|
7
|
+
* module turns an href into what it actually means, so the renderer can send it
|
|
8
|
+
* somewhere real.
|
|
9
|
+
*/
|
|
10
|
+
export type BoardLink =
|
|
11
|
+
/** In-page anchors, `mailto:`, and anything else the default renderer already handles correctly. */
|
|
12
|
+
{
|
|
13
|
+
kind: 'default';
|
|
14
|
+
}
|
|
15
|
+
/** Absolute `http(s)` — leaves the board, so it wants a new tab. */
|
|
16
|
+
| {
|
|
17
|
+
kind: 'external';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A path inside the repo, resolved to repo-root-relative form. `suffix` holds
|
|
21
|
+
* any query/hash to re-append after the host names a destination. `taskSlug`
|
|
22
|
+
* is set when the path names a live task file, which the Board can open
|
|
23
|
+
* in-place instead of navigating away.
|
|
24
|
+
*/
|
|
25
|
+
| {
|
|
26
|
+
kind: 'repo';
|
|
27
|
+
path: string;
|
|
28
|
+
suffix: string;
|
|
29
|
+
taskSlug: string | null;
|
|
30
|
+
};
|
|
31
|
+
export declare function classifyLink(href: string): BoardLink;
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shipbench/board",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React kanban board for ShipBench. Published so the CLI and out-of-repo hosts can consume it; not a supported standalone library.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/gmmurray/shipbench.git",
|
|
9
|
+
"directory": "packages/board"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://shipbench.dev",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/gmmurray/shipbench/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"shipbench",
|
|
17
|
+
"kanban",
|
|
18
|
+
"board",
|
|
19
|
+
"react",
|
|
20
|
+
"project-management"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./styles.css": "./dist/styles.css",
|
|
34
|
+
"./package.json": "./package.json",
|
|
35
|
+
"./dist/*": "./dist/*"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@dnd-kit/core": "^6.3.1",
|
|
42
|
+
"@dnd-kit/sortable": "^8.0.0",
|
|
43
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
44
|
+
"@fontsource/ibm-plex-sans": "^5.2.5",
|
|
45
|
+
"@fontsource/intel-one-mono": "^5.2.2",
|
|
46
|
+
"@radix-ui/react-dialog": "^1.1.17",
|
|
47
|
+
"@radix-ui/react-select": "^2.3.1",
|
|
48
|
+
"react-icons": "^5.7.0",
|
|
49
|
+
"react-markdown": "^10.1.0",
|
|
50
|
+
"sonner": "^2.0.7",
|
|
51
|
+
"zustand": "^5.0.14",
|
|
52
|
+
"@shipbench/core": "0.1.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"react": "^19.0.0",
|
|
56
|
+
"react-dom": "^19.0.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@tailwindcss/vite": "4.3.2",
|
|
60
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
61
|
+
"@testing-library/react": "^16.3.2",
|
|
62
|
+
"@testing-library/user-event": "^14.6.1",
|
|
63
|
+
"@types/react": "^19.0.0",
|
|
64
|
+
"@types/react-dom": "^19.0.0",
|
|
65
|
+
"@vitejs/plugin-react": "^4.0.0",
|
|
66
|
+
"jsdom": "^29.1.1",
|
|
67
|
+
"react": "^19.0.0",
|
|
68
|
+
"react-dom": "^19.0.0",
|
|
69
|
+
"tailwindcss": "4.3.2",
|
|
70
|
+
"typescript": "^5.5.0",
|
|
71
|
+
"vite": "^6.0.0",
|
|
72
|
+
"vitest": "^4.1.9"
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"dev": "vite",
|
|
76
|
+
"build": "node scripts/build.mjs && tsc -p tsconfig.lib.json",
|
|
77
|
+
"test": "vitest run",
|
|
78
|
+
"test:watch": "vitest",
|
|
79
|
+
"typecheck": "tsc -p tsconfig.app.json --noEmit && tsc -p tsconfig.demo.json --noEmit"
|
|
80
|
+
}
|
|
81
|
+
}
|