@frehilm/ordna-cli 0.1.2 → 0.1.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../src/tui/Sidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,KAAkB,MAAM,OAAO,CAAC;AAGvC,MAAM,MAAM,WAAW,GACpB;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhC,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,iBAAS,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAazC;AAED,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,IAAI,EAAE,EACb,QAAQ,EAAE,MAAM,EAAE,GAChB;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,UAAU,EAAE,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,UAAU,EAAE,CAAA;CAAE,CAyCvE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAOtE;AAED,UAAU,KAAK;IACd,IAAI,EAAE;QAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAAC,UAAU,EAAE,UAAU,EAAE,CAAC;QAAC,IAAI,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;IAC5E,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,OAAO,CAAC,EACvB,IAAI,EACJ,MAAM,EACN,UAAU,EACV,OAAO,EACP,KAAK,EACL,MAAM,GACN,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA+C3B;AAmDD,OAAO,EAAE,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../src/tui/Sidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,KAAkB,MAAM,OAAO,CAAC;AAGvC,MAAM,MAAM,WAAW,GACpB;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhC,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,iBAAS,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAazC;AAED,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,IAAI,EAAE,EACb,QAAQ,EAAE,MAAM,EAAE,GAChB;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,UAAU,EAAE,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,UAAU,EAAE,CAAA;CAAE,CAyCvE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAOtE;AAED,UAAU,KAAK;IACd,IAAI,EAAE;QAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAAC,UAAU,EAAE,UAAU,EAAE,CAAC;QAAC,IAAI,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;IAC5E,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,iBAAS,WAAW,CAAC,EACpB,IAAI,EACJ,MAAM,EACN,UAAU,EACV,OAAO,EACP,KAAK,EACL,MAAM,GACN,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA+C3B;AAKD,eAAO,MAAM,OAAO,+CAA0B,CAAC;AAmD/C,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -69,9 +69,13 @@ export function matchesFilter(task, filter) {
69
69
  return task.tags.includes(filter.tag);
70
70
  return true;
71
71
  }
72
- export function Sidebar({ rows, active, focusedKey, focused, width, height, }) {
72
+ function SidebarImpl({ rows, active, focusedKey, focused, width, height, }) {
73
73
  return (_jsxs(Box, { flexDirection: "column", width: width, height: height, paddingX: 1, paddingY: 1, children: [_jsx(Section, { title: "Views", focused: focused, children: rows.views.map((r) => (_jsx(Row, { row: r, isActive: rowKey(r.item) === rowKey(active), isFocused: focused && focusedKey === rowKey(r.item) }, rowKey(r.item)))) }), _jsx(Box, { marginTop: 1, children: _jsx(Section, { title: "Priority", focused: focused, children: rows.priorities.map((r) => (_jsx(Row, { row: r, isActive: rowKey(r.item) === rowKey(active), isFocused: focused && focusedKey === rowKey(r.item) }, rowKey(r.item)))) }) }), rows.tags.length > 0 ? (_jsx(Box, { marginTop: 1, children: _jsx(Section, { title: "Tags", focused: focused, children: rows.tags.map((r) => (_jsx(Row, { row: r, isActive: rowKey(r.item) === rowKey(active), isFocused: focused && focusedKey === rowKey(r.item) }, rowKey(r.item)))) }) })) : null] }));
74
74
  }
75
+ // Sidebar's props are all primitives or memoized refs from App, so default
76
+ // shallow equality bails on every navigation keypress (cursor moves don't
77
+ // touch filter / sidebarFocusedKey / focus / rows).
78
+ export const Sidebar = React.memo(SidebarImpl);
75
79
  function Section({ title, focused, children, }) {
76
80
  return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: focused ? theme.accent : theme.textMuted, bold: true, children: title.toUpperCase() }), _jsx(Box, { flexDirection: "column", marginTop: 0, children: children })] }));
77
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Sidebar.js","sourceRoot":"","sources":["../../src/tui/Sidebar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Sidebar.js","sourceRoot":"","sources":["../../src/tui/Sidebar.tsx"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ interface Props {
6
6
  total: number;
7
7
  searchQuery: string;
8
8
  }
9
- export declare function Subbar({ filter, visible, total, searchQuery }: Props): React.JSX.Element;
9
+ declare function SubbarImpl({ filter, visible, total, searchQuery }: Props): React.JSX.Element;
10
+ export declare const Subbar: React.MemoExoticComponent<typeof SubbarImpl>;
10
11
  export {};
11
12
  //# sourceMappingURL=Subbar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Subbar.d.ts","sourceRoot":"","sources":["../../src/tui/Subbar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAkBhD,UAAU,KAAK;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAYxF"}
1
+ {"version":3,"file":"Subbar.d.ts","sourceRoot":"","sources":["../../src/tui/Subbar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAkBhD,UAAU,KAAK;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,iBAAS,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAYrF;AAED,eAAO,MAAM,MAAM,8CAAyB,CAAC"}
@@ -16,7 +16,8 @@ function filterLabel(filter) {
16
16
  return `#${filter.tag}`;
17
17
  }
18
18
  }
19
- export function Subbar({ filter, visible, total, searchQuery }) {
19
+ function SubbarImpl({ filter, visible, total, searchQuery }) {
20
20
  return (_jsxs(Box, { paddingX: 1, paddingY: 0, children: [_jsx(Text, { color: theme.text, bold: true, children: filterLabel(filter) }), _jsx(Text, { color: theme.textMuted, children: ` · ${visible} visible · ${total} total` }), searchQuery ? (_jsx(Text, { color: theme.accent, children: ` · /${searchQuery}` })) : null] }));
21
21
  }
22
+ export const Subbar = React.memo(SubbarImpl);
22
23
  //# sourceMappingURL=Subbar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Subbar.js","sourceRoot":"","sources":["../../src/tui/Subbar.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,SAAS,WAAW,CAAC,MAAmB;IACvC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,KAAK;YACT,OAAO,WAAW,CAAC;QACpB,KAAK,UAAU;YACd,OAAO,UAAU,CAAC;QACnB,KAAK,QAAQ;YACZ,OAAO,MAAM,CAAC,MAAM,CAAC;QACtB,KAAK,UAAU;YACd,OAAO,aAAa,MAAM,CAAC,KAAK,EAAE,CAAC;QACpC,KAAK,KAAK;YACT,OAAO,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;IAC1B,CAAC;AACF,CAAC;AASD,MAAM,UAAU,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAS;IACpE,OAAO,CACN,MAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,aAC5B,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,kBAC3B,WAAW,CAAC,MAAM,CAAC,GACd,EACP,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,SAAS,YAAG,OAAO,OAAO,cAAc,KAAK,QAAQ,GAAQ,EAC/E,WAAW,CAAC,CAAC,CAAC,CACd,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,MAAM,YAAG,QAAQ,WAAW,EAAE,GAAQ,CACzD,CAAC,CAAC,CAAC,IAAI,IACH,CACN,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"Subbar.js","sourceRoot":"","sources":["../../src/tui/Subbar.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,SAAS,WAAW,CAAC,MAAmB;IACvC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,KAAK;YACT,OAAO,WAAW,CAAC;QACpB,KAAK,UAAU;YACd,OAAO,UAAU,CAAC;QACnB,KAAK,QAAQ;YACZ,OAAO,MAAM,CAAC,MAAM,CAAC;QACtB,KAAK,UAAU;YACd,OAAO,aAAa,MAAM,CAAC,KAAK,EAAE,CAAC;QACpC,KAAK,KAAK;YACT,OAAO,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;IAC1B,CAAC;AACF,CAAC;AASD,SAAS,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAS;IACjE,OAAO,CACN,MAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,aAC5B,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,kBAC3B,WAAW,CAAC,MAAM,CAAC,GACd,EACP,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,SAAS,YAAG,OAAO,OAAO,cAAc,KAAK,QAAQ,GAAQ,EAC/E,WAAW,CAAC,CAAC,CAAC,CACd,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,MAAM,YAAG,QAAQ,WAAW,EAAE,GAAQ,CACzD,CAAC,CAAC,CAAC,IAAI,IACH,CACN,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"TaskDetail.d.ts","sourceRoot":"","sources":["../../src/tui/TaskDetail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,KAAK;IACd,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,UAAU,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,MAAM,EACN,cAAc,EACd,KAAK,EACL,MAAM,GACN,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAqF3B"}
1
+ {"version":3,"file":"TaskDetail.d.ts","sourceRoot":"","sources":["../../src/tui/TaskDetail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,KAAuC,MAAM,OAAO,CAAC;AAG5D,UAAU,KAAK;IACd,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AA4BD,wBAAgB,UAAU,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,MAAM,EACN,cAAc,EACd,KAAK,EACL,MAAM,GACN,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAiL3B"}
@@ -1,19 +1,116 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Box, Text, useInput } from "ink";
3
- import React from "react";
3
+ import React, { useEffect, useMemo, useState } from "react";
4
4
  import { colorForStatus, theme } from "./theme.js";
5
+ function wrapText(text, width) {
6
+ if (width <= 0)
7
+ return [text];
8
+ const out = [];
9
+ for (const para of text.split("\n")) {
10
+ if (para.length === 0) {
11
+ out.push("");
12
+ continue;
13
+ }
14
+ let remaining = para;
15
+ while (remaining.length > width) {
16
+ let breakAt = width;
17
+ const lastSpace = remaining.lastIndexOf(" ", width);
18
+ if (lastSpace > Math.floor(width / 2))
19
+ breakAt = lastSpace;
20
+ out.push(remaining.slice(0, breakAt).trimEnd());
21
+ remaining = remaining.slice(breakAt).replace(/^ +/, "");
22
+ }
23
+ out.push(remaining);
24
+ }
25
+ return out;
26
+ }
5
27
  export function TaskDetail({ task, onClose, onEdit, onEditExternal, width, height, }) {
28
+ const innerWidth = Math.max(10, width - 4);
29
+ const hasTags = task.tags.length > 0;
30
+ const hasDeps = task.depends_on.length > 0;
31
+ const allLines = useMemo(() => {
32
+ const out = [];
33
+ for (let i = 0; i < task.sections.length; i++) {
34
+ const section = task.sections[i];
35
+ if (!section)
36
+ continue;
37
+ if (section.heading !== "") {
38
+ out.push({ kind: "heading", text: section.heading });
39
+ }
40
+ if (section.content.length > 0) {
41
+ for (const w of wrapText(section.content, innerWidth)) {
42
+ out.push({ kind: "content", text: w });
43
+ }
44
+ }
45
+ if (i < task.sections.length - 1) {
46
+ out.push({ kind: "spacer" });
47
+ }
48
+ }
49
+ return out;
50
+ }, [task.sections, innerWidth]);
51
+ // Reserved layout rows inside the popup:
52
+ // 2 border + 2 paddingY
53
+ // 1 title row + 1 marginTop above status + 1 status row
54
+ // tags? + deps?
55
+ // 1 marginTop above sections + 1 marginTop above footer + 1 footer
56
+ const reservedRows = 2 + 2 + 1 + 1 + 1 + (hasTags ? 1 : 0) + (hasDeps ? 1 : 0) + 1 + 1 + 1;
57
+ const sectionsHeight = Math.max(1, height - reservedRows);
58
+ const total = allLines.length;
59
+ const needsScroll = total > sectionsHeight;
60
+ const visibleCount = needsScroll
61
+ ? Math.max(1, sectionsHeight - 2)
62
+ : sectionsHeight;
63
+ const maxOffset = Math.max(0, total - visibleCount);
64
+ const [scrollOffset, setScrollOffset] = useState(0);
65
+ useEffect(() => {
66
+ setScrollOffset(0);
67
+ }, [task.id]);
68
+ const offset = Math.max(0, Math.min(maxOffset, scrollOffset));
69
+ const visibleLines = allLines.slice(offset, offset + visibleCount);
70
+ const aboveCount = offset;
71
+ const belowCount = Math.max(0, total - offset - visibleCount);
6
72
  useInput((input, key) => {
7
- if (key.escape || input === "q")
73
+ if (key.escape || input === "q") {
8
74
  onClose();
9
- else if (input === "e")
75
+ return;
76
+ }
77
+ if (input === "e") {
10
78
  onEdit();
11
- else if (input === "E" && onEditExternal)
79
+ return;
80
+ }
81
+ if (input === "E" && onEditExternal) {
12
82
  onEditExternal();
83
+ return;
84
+ }
85
+ if (key.upArrow || input === "k") {
86
+ setScrollOffset((o) => Math.max(0, o - 1));
87
+ return;
88
+ }
89
+ if (key.downArrow || input === "j") {
90
+ setScrollOffset((o) => Math.min(maxOffset, o + 1));
91
+ return;
92
+ }
93
+ if (key.pageUp) {
94
+ setScrollOffset((o) => Math.max(0, o - visibleCount));
95
+ return;
96
+ }
97
+ if (key.pageDown) {
98
+ setScrollOffset((o) => Math.min(maxOffset, o + visibleCount));
99
+ return;
100
+ }
13
101
  });
14
- const innerWidth = Math.max(10, width - 4);
15
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "double", borderColor: theme.borderFocused, width: width, height: height, paddingX: 2, paddingY: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.accent, bold: true, children: task.id }), _jsx(Text, { color: theme.textMuted, children: " " }), _jsx(Text, { color: theme.text, bold: true, wrap: "truncate-end", children: task.title })] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: colorForStatus(task.status), children: task.status }), _jsx(Text, { color: theme.textMuted, children: " · " }), _jsx(Text, { color: theme.textDim, children: task.assignee ? `@${task.assignee}` : "unassigned" }), task.priority ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.textMuted, children: " · " }), _jsx(Text, { color: theme.priority[task.priority], children: `!${task.priority}` })] })) : null] }), task.tags.length > 0 ? (_jsx(Text, { color: theme.textDim, children: task.tags.map((t) => `#${t}`).join(" ") })) : null, task.depends_on.length > 0 ? (_jsxs(Text, { color: theme.textDim, children: ["depends on: ", task.depends_on.join(", ")] })) : null, _jsx(Box, { marginTop: 1, flexDirection: "column", flexGrow: 1, children: task.sections.map((section, idx) => (_jsxs(Box, { flexDirection: "column", marginBottom: 1, width: innerWidth, children: [section.heading !== "" ? (_jsx(Text, { color: theme.textDim, bold: true, children: section.heading })) : null, section.content.length > 0 ? (_jsx(Text, { color: theme.text, wrap: "wrap", children: section.content })) : null] }, `${section.heading}-${idx}`))) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.textMuted, italic: true, children: onEditExternal
16
- ? "e edit · E $EDITOR · Esc / q close"
17
- : "e edit · Esc / q close" }) })] }));
102
+ const footerHint = onEditExternal
103
+ ? "↑/↓ scroll · e edit · E $EDITOR · Esc / q close"
104
+ : "↑/↓ scroll · e edit · Esc / q close";
105
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "double", borderColor: theme.borderFocused, width: width, height: height, paddingX: 2, paddingY: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.accent, bold: true, children: task.id }), _jsx(Text, { color: theme.textMuted, children: " " }), _jsx(Text, { color: theme.text, bold: true, wrap: "truncate-end", children: task.title })] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: colorForStatus(task.status), children: task.status }), _jsx(Text, { color: theme.textMuted, children: " · " }), _jsx(Text, { color: theme.textDim, children: task.assignee ? `@${task.assignee}` : "unassigned" }), task.priority ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.textMuted, children: " · " }), _jsx(Text, { color: theme.priority[task.priority], children: `!${task.priority}` })] })) : null] }), hasTags ? (_jsx(Text, { color: theme.textDim, children: task.tags.map((t) => `#${t}`).join(" ") })) : null, hasDeps ? (_jsxs(Text, { color: theme.textDim, children: ["depends on: ", task.depends_on.join(", ")] })) : null, _jsxs(Box, { marginTop: 1, flexDirection: "column", width: innerWidth, height: sectionsHeight, children: [needsScroll ? (_jsx(Text, { color: theme.textMuted, italic: true, wrap: "truncate-end", children: aboveCount > 0 ? `↑ ${aboveCount} more` : " " })) : null, visibleLines.map((line, idx) => {
106
+ const key = `${offset + idx}-${line.kind}`;
107
+ if (line.kind === "heading") {
108
+ return (_jsx(Text, { color: theme.textDim, bold: true, wrap: "truncate-end", children: line.text }, key));
109
+ }
110
+ if (line.kind === "spacer") {
111
+ return _jsx(Text, { children: " " }, key);
112
+ }
113
+ return (_jsx(Text, { color: theme.text, wrap: "truncate-end", children: line.text }, key));
114
+ }), needsScroll ? (_jsx(Text, { color: theme.textMuted, italic: true, wrap: "truncate-end", children: belowCount > 0 ? `↓ ${belowCount} more` : " " })) : null] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.textMuted, italic: true, children: footerHint }) })] }));
18
115
  }
19
116
  //# sourceMappingURL=TaskDetail.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TaskDetail.js","sourceRoot":"","sources":["../../src/tui/TaskDetail.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TaskDetail.js","sourceRoot":"","sources":["../../src/tui/TaskDetail.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TaskEditor.d.ts","sourceRoot":"","sources":["../../src/tui/TaskEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKN,KAAK,IAAI,EAET,KAAK,YAAY,EACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAA4B,MAAM,OAAO,CAAC;AAGjD,UAAU,KAAK;IACd,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,YAAY,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AA8FD,wBAAgB,UAAU,CAAC,EAC1B,IAAI,EACJ,GAAG,EACH,OAAO,EACP,OAAO,EACP,KAAK,EACL,MAAM,GACN,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAma3B"}
1
+ {"version":3,"file":"TaskEditor.d.ts","sourceRoot":"","sources":["../../src/tui/TaskEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKN,KAAK,IAAI,EAET,KAAK,YAAY,EACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAuC,MAAM,OAAO,CAAC;AAG5D,UAAU,KAAK;IACd,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,YAAY,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAiLD,wBAAgB,UAAU,CAAC,EAC1B,IAAI,EACJ,GAAG,EACH,OAAO,EACP,OAAO,EACP,KAAK,EACL,MAAM,GACN,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAkkB3B"}
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { ARCHIVED_STATUS, updateTask as updateTaskCore, } from "@frehilm/ordna-core";
3
3
  import { Box, Text, useInput } from "ink";
4
4
  import TextInput from "ink-text-input";
5
- import React, { useMemo, useState } from "react";
5
+ import React, { useEffect, useMemo, useState } from "react";
6
6
  import { colorForStatus, tagColor, theme } from "./theme.js";
7
7
  const PRIORITIES = [null, "low", "medium", "high"];
8
8
  function toDraft(task) {
@@ -46,11 +46,87 @@ function statusOptions(config) {
46
46
  function priorityLabel(p) {
47
47
  return p === null ? "—" : p;
48
48
  }
49
- function MultilineEditor({ value, onChange, width, }) {
49
+ function offsetToRowCol(value, offset) {
50
+ const lines = value.split("\n");
51
+ let acc = 0;
52
+ for (let i = 0; i < lines.length; i += 1) {
53
+ const len = (lines[i] ?? "").length;
54
+ if (offset <= acc + len)
55
+ return [i, offset - acc];
56
+ acc += len + 1;
57
+ }
58
+ const last = Math.max(0, lines.length - 1);
59
+ return [last, (lines[last] ?? "").length];
60
+ }
61
+ function rowColToOffset(value, row, col) {
62
+ const lines = value.split("\n");
63
+ const r = Math.max(0, Math.min(row, lines.length - 1));
64
+ const lineLen = (lines[r] ?? "").length;
65
+ const c = Math.max(0, Math.min(col, lineLen));
66
+ let acc = 0;
67
+ for (let i = 0; i < r; i += 1)
68
+ acc += (lines[i] ?? "").length + 1;
69
+ return acc + c;
70
+ }
71
+ function isWordChar(ch) {
72
+ return /[A-Za-z0-9_]/.test(ch);
73
+ }
74
+ function wordLeft(value, cursor) {
75
+ let i = cursor;
76
+ while (i > 0 && !isWordChar(value[i - 1] ?? ""))
77
+ i -= 1;
78
+ while (i > 0 && isWordChar(value[i - 1] ?? ""))
79
+ i -= 1;
80
+ return i;
81
+ }
82
+ function wordRight(value, cursor) {
83
+ let i = cursor;
84
+ const n = value.length;
85
+ while (i < n && !isWordChar(value[i] ?? ""))
86
+ i += 1;
87
+ while (i < n && isWordChar(value[i] ?? ""))
88
+ i += 1;
89
+ return i;
90
+ }
91
+ function wrapText(text, width) {
92
+ if (width <= 0)
93
+ return [text];
94
+ const out = [];
95
+ for (const para of text.split("\n")) {
96
+ if (para.length === 0) {
97
+ out.push("");
98
+ continue;
99
+ }
100
+ let remaining = para;
101
+ while (remaining.length > width) {
102
+ let breakAt = width;
103
+ const lastSpace = remaining.lastIndexOf(" ", width);
104
+ if (lastSpace > Math.floor(width / 2))
105
+ breakAt = lastSpace;
106
+ out.push(remaining.slice(0, breakAt).trimEnd());
107
+ remaining = remaining.slice(breakAt).replace(/^ +/, "");
108
+ }
109
+ out.push(remaining);
110
+ }
111
+ return out;
112
+ }
113
+ function sectionHeight(content, innerWidth) {
114
+ // 1 marginTop + 1 heading + content lines (paddingLeft=2)
115
+ const contentWidth = Math.max(1, innerWidth - 2);
116
+ const contentLines = content.length === 0 ? 1 : wrapText(content, contentWidth).length;
117
+ return 1 + 1 + contentLines;
118
+ }
119
+ function MultilineEditor({ value, cursor, width, }) {
50
120
  const lines = value.length === 0 ? [""] : value.split("\n");
121
+ const [cursorRow, cursorCol] = offsetToRowCol(value, cursor);
51
122
  return (_jsx(Box, { flexDirection: "column", width: width, children: lines.map((line, i) => {
52
- const isLast = i === lines.length - 1;
53
- return (_jsxs(Text, { color: theme.text, wrap: "wrap", children: [line, isLast ? _jsx(Text, { color: theme.accent, inverse: true, children: " " }) : null] }, `${i}-${line.length}`));
123
+ if (i !== cursorRow) {
124
+ return (_jsx(Text, { color: theme.text, wrap: "wrap", children: line }, `${i}-${line.length}`));
125
+ }
126
+ const before = line.slice(0, cursorCol);
127
+ const at = line[cursorCol];
128
+ const after = line.slice(cursorCol + 1);
129
+ return (_jsxs(Text, { color: theme.text, wrap: "wrap", children: [before, _jsx(Text, { color: theme.accent, inverse: true, children: at ?? " " }), after] }, `${i}-${line.length}-c`));
54
130
  }) }));
55
131
  }
56
132
  export function TaskEditor({ task, ctx, onClose, onSaved, width, height, }) {
@@ -59,10 +135,101 @@ export function TaskEditor({ task, ctx, onClose, onSaved, width, height, }) {
59
135
  const [editing, setEditing] = useState(false);
60
136
  const [saving, setSaving] = useState(false);
61
137
  const [error, setError] = useState(null);
138
+ const [cursor, setCursor] = useState(0);
139
+ const [sectionScrollIdx, setSectionScrollIdx] = useState(0);
62
140
  const fields = useMemo(() => buildFields(draft), [draft]);
63
141
  const focused = fields[focusIdx] ?? fields[0];
64
142
  const innerWidth = Math.max(10, width - 4);
65
143
  const valueWidth = Math.max(10, innerWidth - 12);
144
+ // Sections area height: total popup height minus borders/padding (4),
145
+ // id row (1), error row (0/1), 1 marginTop above metadata, 6 metadata rows,
146
+ // 1 marginTop above footer, 1 footer row.
147
+ const reservedRows = 4 + 1 + (error ? 1 : 0) + 1 + 6 + 1 + 1;
148
+ const sectionsAreaHeight = Math.max(1, height - reservedRows);
149
+ const renderableSections = useMemo(() => {
150
+ return draft.sections
151
+ .map((s, i) => ({ section: s, index: i }))
152
+ .filter((entry) => entry.section.heading !== "");
153
+ }, [draft.sections]);
154
+ const sectionLayout = useMemo(() => {
155
+ // Walk renderable sections starting at sectionScrollIdx, accumulating
156
+ // heights until we exceed the available area. Reserve indicator rows
157
+ // (1 each) only when scrolling is needed in that direction.
158
+ const total = renderableSections.length;
159
+ const start = Math.max(0, Math.min(total, sectionScrollIdx));
160
+ const hasAbove = start > 0;
161
+ let used = hasAbove ? 1 : 0;
162
+ let end = start;
163
+ while (end < total) {
164
+ const entry = renderableSections[end];
165
+ if (!entry)
166
+ break;
167
+ const h = sectionHeight(entry.section.content, innerWidth);
168
+ // Reserve a row for the bottom indicator if this isn't the last section
169
+ const bottomReserve = end < total - 1 ? 1 : 0;
170
+ if (used + h + bottomReserve > sectionsAreaHeight && end > start)
171
+ break;
172
+ used += h;
173
+ end += 1;
174
+ }
175
+ return {
176
+ start,
177
+ end,
178
+ aboveCount: start,
179
+ belowCount: Math.max(0, total - end),
180
+ total,
181
+ };
182
+ }, [renderableSections, sectionScrollIdx, sectionsAreaHeight, innerWidth]);
183
+ // When the focused field is a section that's outside the current window,
184
+ // adjust the scroll so it becomes visible. Run after render so we use the
185
+ // just-computed layout.
186
+ useEffect(() => {
187
+ if (focused?.kind !== "section")
188
+ return;
189
+ const sectionIdx = renderableSections.findIndex((e) => e.index === focused.index);
190
+ if (sectionIdx === -1)
191
+ return;
192
+ if (sectionIdx < sectionLayout.start) {
193
+ setSectionScrollIdx(sectionIdx);
194
+ return;
195
+ }
196
+ if (sectionIdx >= sectionLayout.end) {
197
+ // Scroll forward by enough sections to bring this one into view.
198
+ // Walk backward from the focused section, accumulating heights
199
+ // until the budget is filled.
200
+ let used = 1; // top indicator
201
+ let newStart = sectionIdx;
202
+ while (newStart > 0) {
203
+ const prev = renderableSections[newStart - 1];
204
+ if (!prev)
205
+ break;
206
+ const h = sectionHeight(prev.section.content, innerWidth);
207
+ const bottomReserve = sectionIdx < renderableSections.length - 1 ? 1 : 0;
208
+ const focusedH = sectionHeight(renderableSections[sectionIdx]?.section.content ?? "", innerWidth);
209
+ if (used + focusedH + h + bottomReserve > sectionsAreaHeight)
210
+ break;
211
+ newStart -= 1;
212
+ used += h;
213
+ }
214
+ setSectionScrollIdx(newStart);
215
+ }
216
+ }, [
217
+ focused,
218
+ renderableSections,
219
+ sectionLayout,
220
+ sectionsAreaHeight,
221
+ innerWidth,
222
+ ]);
223
+ useEffect(() => {
224
+ if (!editing)
225
+ return;
226
+ if (focused?.kind !== "section")
227
+ return;
228
+ const sec = draft.sections[focused.index];
229
+ if (!sec)
230
+ return;
231
+ setCursor((c) => Math.max(0, Math.min(c, sec.content.length)));
232
+ }, [editing, focused, draft.sections]);
66
233
  const save = async () => {
67
234
  setSaving(true);
68
235
  setError(null);
@@ -143,28 +310,87 @@ export function TaskEditor({ task, ctx, onClose, onSaved, width, height, }) {
143
310
  const section = draft.sections[idx];
144
311
  if (!section)
145
312
  return;
146
- if (key.return) {
147
- const next = `${section.content}\n`;
313
+ const content = section.content;
314
+ const writeContent = (next, nextCursor) => {
315
+ const clamped = Math.max(0, Math.min(next.length, nextCursor));
148
316
  setDraft((d) => ({
149
317
  ...d,
150
- sections: d.sections.map((s, i) => (i === idx ? { ...s, content: next } : s)),
318
+ sections: d.sections.map((s, i) => i === idx ? { ...s, content: next } : s),
151
319
  }));
320
+ setCursor(clamped);
321
+ };
322
+ const moveCursor = (next) => {
323
+ setCursor(Math.max(0, Math.min(content.length, next)));
324
+ };
325
+ // Word jumps (Ctrl+Left/Right)
326
+ if (key.ctrl && key.leftArrow) {
327
+ moveCursor(wordLeft(content, cursor));
152
328
  return;
153
329
  }
154
- if (key.backspace || key.delete) {
155
- const next = section.content.slice(0, -1);
156
- setDraft((d) => ({
157
- ...d,
158
- sections: d.sections.map((s, i) => (i === idx ? { ...s, content: next } : s)),
159
- }));
330
+ if (key.ctrl && key.rightArrow) {
331
+ moveCursor(wordRight(content, cursor));
332
+ return;
333
+ }
334
+ // Home / End via Ctrl+A / Ctrl+E
335
+ if (key.ctrl && (input === "a" || input === "A")) {
336
+ const [row] = offsetToRowCol(content, cursor);
337
+ moveCursor(rowColToOffset(content, row, 0));
338
+ return;
339
+ }
340
+ if (key.ctrl && (input === "e" || input === "E")) {
341
+ const [row] = offsetToRowCol(content, cursor);
342
+ moveCursor(rowColToOffset(content, row, Number.MAX_SAFE_INTEGER));
343
+ return;
344
+ }
345
+ // Arrow keys
346
+ if (key.leftArrow) {
347
+ moveCursor(cursor - 1);
348
+ return;
349
+ }
350
+ if (key.rightArrow) {
351
+ moveCursor(cursor + 1);
352
+ return;
353
+ }
354
+ if (key.upArrow) {
355
+ const [row, col] = offsetToRowCol(content, cursor);
356
+ if (row === 0)
357
+ moveCursor(0);
358
+ else
359
+ moveCursor(rowColToOffset(content, row - 1, col));
360
+ return;
361
+ }
362
+ if (key.downArrow) {
363
+ const [row, col] = offsetToRowCol(content, cursor);
364
+ const lines = content.split("\n");
365
+ if (row >= lines.length - 1)
366
+ moveCursor(content.length);
367
+ else
368
+ moveCursor(rowColToOffset(content, row + 1, col));
369
+ return;
370
+ }
371
+ // Editing operations
372
+ if (key.return) {
373
+ const next = `${content.slice(0, cursor)}\n${content.slice(cursor)}`;
374
+ writeContent(next, cursor + 1);
375
+ return;
376
+ }
377
+ if (key.backspace) {
378
+ if (cursor === 0)
379
+ return;
380
+ const next = content.slice(0, cursor - 1) + content.slice(cursor);
381
+ writeContent(next, cursor - 1);
382
+ return;
383
+ }
384
+ if (key.delete) {
385
+ if (cursor >= content.length)
386
+ return;
387
+ const next = content.slice(0, cursor) + content.slice(cursor + 1);
388
+ writeContent(next, cursor);
160
389
  return;
161
390
  }
162
391
  if (input && !key.ctrl && !key.meta) {
163
- const next = section.content + input;
164
- setDraft((d) => ({
165
- ...d,
166
- sections: d.sections.map((s, i) => (i === idx ? { ...s, content: next } : s)),
167
- }));
392
+ const next = content.slice(0, cursor) + input + content.slice(cursor);
393
+ writeContent(next, cursor + input.length);
168
394
  }
169
395
  return;
170
396
  }
@@ -193,6 +419,10 @@ export function TaskEditor({ task, ctx, onClose, onSaved, width, height, }) {
193
419
  return;
194
420
  }
195
421
  if (key.return) {
422
+ if (focused?.kind === "section") {
423
+ const sec = draft.sections[focused.index];
424
+ setCursor(sec ? sec.content.length : 0);
425
+ }
196
426
  setEditing(true);
197
427
  return;
198
428
  }
@@ -254,18 +484,17 @@ export function TaskEditor({ task, ctx, onClose, onSaved, width, height, }) {
254
484
  const isFocused = focused?.kind === "section" && focused.index === idx;
255
485
  const isEditing = isFocused && editing;
256
486
  const marker = isEditing ? "▷" : isFocused ? "▶" : " ";
257
- return (_jsxs(Box, { flexDirection: "column", width: innerWidth, marginTop: 1, children: [_jsxs(Box, { children: [_jsx(Box, { width: 2, children: _jsx(Text, { color: isFocused ? theme.accent : theme.textFaint, children: marker }) }), _jsx(Text, { color: isFocused ? theme.accent : theme.textDim, bold: true, children: section.heading })] }), _jsx(Box, { paddingLeft: 2, width: innerWidth, children: isEditing ? (_jsx(MultilineEditor, { value: section.content, onChange: (next) => setDraft((d) => ({
258
- ...d,
259
- sections: d.sections.map((s, i) => i === idx ? { ...s, content: next } : s),
260
- })), width: innerWidth - 2 })) : section.content.length === 0 ? (_jsx(Text, { color: theme.textFaint, children: "\u2014" })) : (_jsx(Text, { color: isFocused ? theme.text : theme.textDim, wrap: "wrap", children: section.content })) })] }, `${section.heading}-${idx}`));
487
+ return (_jsxs(Box, { flexDirection: "column", width: innerWidth, marginTop: 1, children: [_jsxs(Box, { children: [_jsx(Box, { width: 2, children: _jsx(Text, { color: isFocused ? theme.accent : theme.textFaint, children: marker }) }), _jsx(Text, { color: isFocused ? theme.accent : theme.textDim, bold: true, children: section.heading })] }), _jsx(Box, { paddingLeft: 2, width: innerWidth, children: isEditing ? (_jsx(MultilineEditor, { value: section.content, cursor: cursor, width: innerWidth - 2 })) : section.content.length === 0 ? (_jsx(Text, { color: theme.textFaint, children: "\u2014" })) : (_jsx(Text, { color: isFocused ? theme.text : theme.textDim, wrap: "wrap", children: section.content })) })] }, `${section.heading}-${idx}`));
261
488
  };
262
489
  const statusColor = colorForStatus(draft.status);
263
490
  const priorityColor = draft.priority
264
491
  ? theme.priority[draft.priority]
265
492
  : theme.textFaint;
266
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "double", borderColor: theme.borderFocused, width: width, height: height, paddingX: 2, paddingY: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.accent, bold: true, children: task.id }), _jsx(Text, { color: theme.textMuted, children: " edit" }), saving ? (_jsx(Text, { color: theme.textMuted, children: " · saving…" })) : null] }), error ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "#ef4444", children: error }) })) : null, _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [renderRow("Title", { kind: "title" }, renderTextValue({ kind: "title" }, draft.title, (v) => setDraft((d) => ({ ...d, title: v })))), renderRow("Status", { kind: "status" }, renderSelectValue({ kind: "status" }, draft.status, statusColor)), renderRow("Priority", { kind: "priority" }, renderSelectValue({ kind: "priority" }, priorityLabel(draft.priority), priorityColor)), renderRow("Assignee", { kind: "assignee" }, renderTextValue({ kind: "assignee" }, draft.assignee, (v) => setDraft((d) => ({ ...d, assignee: v })), "unassigned")), renderRow("Tags", { kind: "tags" }, renderTags()), renderRow("Depends", { kind: "depends_on" }, renderDependsOn())] }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: draft.sections.map((s, i) => s.heading === "" ? null : renderSection(i, s)) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.textMuted, italic: true, children: editing
493
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "double", borderColor: theme.borderFocused, width: width, height: height, paddingX: 2, paddingY: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.accent, bold: true, children: task.id }), _jsx(Text, { color: theme.textMuted, children: " edit" }), saving ? (_jsx(Text, { color: theme.textMuted, children: " · saving…" })) : null] }), error ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "#ef4444", children: error }) })) : null, _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [renderRow("Title", { kind: "title" }, renderTextValue({ kind: "title" }, draft.title, (v) => setDraft((d) => ({ ...d, title: v })))), renderRow("Status", { kind: "status" }, renderSelectValue({ kind: "status" }, draft.status, statusColor)), renderRow("Priority", { kind: "priority" }, renderSelectValue({ kind: "priority" }, priorityLabel(draft.priority), priorityColor)), renderRow("Assignee", { kind: "assignee" }, renderTextValue({ kind: "assignee" }, draft.assignee, (v) => setDraft((d) => ({ ...d, assignee: v })), "unassigned")), renderRow("Tags", { kind: "tags" }, renderTags()), renderRow("Depends", { kind: "depends_on" }, renderDependsOn())] }), _jsxs(Box, { flexDirection: "column", width: innerWidth, height: sectionsAreaHeight, children: [sectionLayout.aboveCount > 0 ? (_jsxs(Text, { color: theme.textMuted, italic: true, wrap: "truncate-end", children: ["\u2191 ", sectionLayout.aboveCount, " more"] })) : null, renderableSections
494
+ .slice(sectionLayout.start, sectionLayout.end)
495
+ .map((entry) => renderSection(entry.index, entry.section)), sectionLayout.belowCount > 0 ? (_jsxs(Text, { color: theme.textMuted, italic: true, wrap: "truncate-end", children: ["\u2193 ", sectionLayout.belowCount, " more"] })) : null] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.textMuted, italic: true, children: editing
267
496
  ? focused?.kind === "section"
268
- ? "Esc back · Tab next field · Ctrl+S save"
497
+ ? "←/→/↑/↓ move · Ctrl+←/→ word · Ctrl+A/E line · Esc back · Ctrl+S save"
269
498
  : focused?.kind === "status" || focused?.kind === "priority"
270
499
  ? "↑/↓ change · Enter/Esc back · Ctrl+S save"
271
500
  : "Enter confirm · Esc back · Ctrl+S save"