@ikenga/pkg-tasks 0.4.0 → 0.4.1
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/dist/app.js +14 -23
- package/dist/features/tasks/done-view.js +6 -6
- package/dist/features/tasks/sweeper-view.js +7 -7
- package/dist/features/tasks/task-detail-pane.js +10 -10
- package/dist/features/tasks/task-row.js +6 -6
- package/dist/features/tasks/tasks-view.js +5 -5
- package/dist/index.html +9 -1
- package/dist/lib/app-kit-css.js +3 -0
- package/dist/lib/tasks-css.js +4 -5
- package/dist/lib/tokens-css.js +3 -5
- package/dist/tasks.css +40 -313
- package/package.json +6 -3
package/dist/app.js
CHANGED
|
@@ -17,13 +17,18 @@ import {
|
|
|
17
17
|
import { connectBridge, isStandalone } from './lib/bridge.js';
|
|
18
18
|
import { TasksView } from './features/tasks/tasks-view.js';
|
|
19
19
|
import tokensCss from './lib/tokens-css.js';
|
|
20
|
+
import appKitCss from './lib/app-kit-css.js';
|
|
20
21
|
import tasksCss from './lib/tasks-css.js';
|
|
21
22
|
|
|
22
23
|
// Styling, the no-build way. A <link>/fetch to a .css fails inside the shell's
|
|
23
24
|
// about:srcdoc iframe (WebKitGTK subresource bug — see index.html), so CSS
|
|
24
25
|
// rides the script path as JS strings and is injected as inline <style>
|
|
25
|
-
// (style-src 'unsafe-inline' permits it). Order matters: tokens first
|
|
26
|
-
// define --fg/--bg-base/--space-*/etc.),
|
|
26
|
+
// (style-src 'unsafe-inline' permits it). Order matters (cascade): tokens first
|
|
27
|
+
// (they define --fg/--bg-base/--space-*/etc.), THEN the app-kit component layer
|
|
28
|
+
// (.frame*/.ip-*/.dense-row*/.tk-badge/.tk-execmode — the kit primitives tasks
|
|
29
|
+
// now consumes, P3 inc-3), THEN tasks.css (the slim domain residue, which is
|
|
30
|
+
// injected LAST so its scoped rules win over any kit base it intentionally
|
|
31
|
+
// overrides, e.g. the .ag-block agenda variant).
|
|
27
32
|
function injectCss(id, css) {
|
|
28
33
|
if (document.querySelector(`style[${id}]`)) return;
|
|
29
34
|
const el = document.createElement('style');
|
|
@@ -31,28 +36,14 @@ function injectCss(id, css) {
|
|
|
31
36
|
el.textContent = css;
|
|
32
37
|
document.head.appendChild(el);
|
|
33
38
|
}
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
// tokens.
|
|
39
|
-
//
|
|
40
|
-
// keep their inline fallbacks in tasks.css and aren't aliased here.)
|
|
41
|
-
const aliasCss = `
|
|
42
|
-
:root {
|
|
43
|
-
--live: var(--success);
|
|
44
|
-
--live-soft: color-mix(in srgb, var(--success) 14%, transparent);
|
|
45
|
-
--agent-soft: color-mix(in srgb, var(--agent) 14%, transparent);
|
|
46
|
-
--achievement-soft: color-mix(in srgb, var(--achievement) 14%, transparent);
|
|
47
|
-
--fg-faint: var(--fg-subtle);
|
|
48
|
-
--text-body-sm: var(--text-body);
|
|
49
|
-
--text-h4: var(--text-h3);
|
|
50
|
-
--font-body: var(--font-sans);
|
|
51
|
-
--motion-fast: 120ms;
|
|
52
|
-
--ease-calm: ease;
|
|
53
|
-
}`;
|
|
39
|
+
// Token-alias shim REMOVED (P3 retrofit, 2026-06-03). @ikenga/tokens@0.3.0 now
|
|
40
|
+
// defines --live/--live-soft/--live-fg, --agent-soft, --achievement-soft,
|
|
41
|
+
// --fg-faint, --text-body-sm, --text-h4, --font-body, and --motion-*/--ease-*
|
|
42
|
+
// natively (the P0 reconciliation), so the hand-maintained drift-prone shim is
|
|
43
|
+
// gone. tokens-css.js below is the reconciled @ikenga/tokens (Dusk Wood);
|
|
44
|
+
// app-kit-css.js is the kit component layer vendored alongside it (P3 inc-3).
|
|
54
45
|
injectCss('data-tokens-css', tokensCss);
|
|
55
|
-
injectCss('data-
|
|
46
|
+
injectCss('data-app-kit-css', appKitCss);
|
|
56
47
|
injectCss('data-tasks-css', tasksCss);
|
|
57
48
|
|
|
58
49
|
// Theme — own it directly by mirroring the shell's <html> attributes, NOT via
|
|
@@ -134,10 +134,10 @@ export function DoneView() {
|
|
|
134
134
|
? t.outcome_notes.replace(/^Auto-closed by task-health:?\s*/, '') || 'auto-closed'
|
|
135
135
|
: null;
|
|
136
136
|
return html`
|
|
137
|
-
<div class="
|
|
138
|
-
<span class=${`
|
|
139
|
-
<div class="body">
|
|
140
|
-
<div class="title">${t.title}</div>
|
|
137
|
+
<div class="dense-row dense-row--task is-completed" key=${t.id}>
|
|
138
|
+
<span class=${`dense-row-dot ${priClass(t.priority)}`}></span>
|
|
139
|
+
<div class="dense-row-body">
|
|
140
|
+
<div class="dense-row-title">${t.title}</div>
|
|
141
141
|
<div class="meta">
|
|
142
142
|
<span class="tk-badge is-completed"><span class="dot"></span>completed</span>
|
|
143
143
|
${isAuto && html`
|
|
@@ -148,8 +148,8 @@ export function DoneView() {
|
|
|
148
148
|
`}
|
|
149
149
|
</div>
|
|
150
150
|
</div>
|
|
151
|
-
<div class="right">
|
|
152
|
-
<span class="due">${relTime(t.completed_at ?? t.updated_at)}</span>
|
|
151
|
+
<div class="dense-row-right">
|
|
152
|
+
<span class="dense-row-due">${relTime(t.completed_at ?? t.updated_at)}</span>
|
|
153
153
|
</div>
|
|
154
154
|
</div>
|
|
155
155
|
`;
|
|
@@ -116,10 +116,10 @@ export function SweeperView() {
|
|
|
116
116
|
Awaiting your call · ${awaitingRows.length}
|
|
117
117
|
</div>
|
|
118
118
|
${awaitingRows.map((t) => html`
|
|
119
|
-
<div class="
|
|
120
|
-
<span class=${`
|
|
121
|
-
<div class="body">
|
|
122
|
-
<div class="title">${t.title}</div>
|
|
119
|
+
<div class="dense-row dense-row--task" key=${t.id}>
|
|
120
|
+
<span class=${`dense-row-dot ${priClass(t.priority)}`}></span>
|
|
121
|
+
<div class="dense-row-body">
|
|
122
|
+
<div class="dense-row-title">${t.title}</div>
|
|
123
123
|
<div class="meta">
|
|
124
124
|
<span class="tk-autoclose" style=${{ color: 'var(--achievement)' }}>
|
|
125
125
|
<${Icon} name="alert-circle" size=${11} />
|
|
@@ -127,7 +127,7 @@ export function SweeperView() {
|
|
|
127
127
|
</span>
|
|
128
128
|
</div>
|
|
129
129
|
</div>
|
|
130
|
-
<div class="right" style=${{ display: 'flex', gap: 'var(--space-2)', alignItems: 'center' }}>
|
|
130
|
+
<div class="dense-row-right" style=${{ display: 'flex', gap: 'var(--space-2)', alignItems: 'center' }}>
|
|
131
131
|
<${Button} size="sm" variant="ghost">Keep open</${Button}>
|
|
132
132
|
<${Button} size="sm" variant="affirmative">Approve close</${Button}>
|
|
133
133
|
</div>
|
|
@@ -150,7 +150,7 @@ export function SweeperView() {
|
|
|
150
150
|
</div>
|
|
151
151
|
`}
|
|
152
152
|
${recentRows.map((t) => html`
|
|
153
|
-
<div class="
|
|
153
|
+
<div class="dense-row dense-row--task is-completed" key=${t.id}>
|
|
154
154
|
<span class=${`pri-dot ${priClass(t.priority)}`}></span>
|
|
155
155
|
<div class="body">
|
|
156
156
|
<div class="title">${t.title}</div>
|
|
@@ -162,7 +162,7 @@ export function SweeperView() {
|
|
|
162
162
|
</span>
|
|
163
163
|
</div>
|
|
164
164
|
</div>
|
|
165
|
-
<div class="right"><span class="due">${relTime(t.completed_at)}</span></div>
|
|
165
|
+
<div class="dense-row-right"><span class="dense-row-due">${relTime(t.completed_at)}</span></div>
|
|
166
166
|
</div>
|
|
167
167
|
`)}
|
|
168
168
|
</div>
|
|
@@ -113,11 +113,11 @@ export function TaskDetailPane({ taskId, density = 'full', onNavigateTask }) {
|
|
|
113
113
|
|
|
114
114
|
return html`
|
|
115
115
|
<div class=${cn('tk-detail-pane', `is-${density}`)}>
|
|
116
|
-
<div class="
|
|
117
|
-
<div class="
|
|
116
|
+
<div class="ip-head">
|
|
117
|
+
<div class="ip-topline">
|
|
118
118
|
<span class="id">task · ${shortId(task.id)}</span>
|
|
119
119
|
${density === 'full' && html`
|
|
120
|
-
<div class="
|
|
120
|
+
<div class="ip-topline-actions">
|
|
121
121
|
<${Button} variant="outline" size="sm" type="button">Reschedule</${Button}>
|
|
122
122
|
<${Button}
|
|
123
123
|
variant=${reassignOpen ? 'default' : 'outline'}
|
|
@@ -190,7 +190,7 @@ export function TaskDetailPane({ taskId, density = 'full', onNavigateTask }) {
|
|
|
190
190
|
</div>
|
|
191
191
|
`}
|
|
192
192
|
|
|
193
|
-
<h2 class="
|
|
193
|
+
<h2 class="ip-title">${task.title}</h2>
|
|
194
194
|
|
|
195
195
|
<div class="tk-det-meta-row">
|
|
196
196
|
<span class=${cn('tk-badge', statusClass(task.status))}>
|
|
@@ -229,7 +229,7 @@ export function TaskDetailPane({ taskId, density = 'full', onNavigateTask }) {
|
|
|
229
229
|
</div>
|
|
230
230
|
</div>
|
|
231
231
|
|
|
232
|
-
<div class="
|
|
232
|
+
<div class="ip-body">
|
|
233
233
|
${autoClosed && task.outcome_notes && html`
|
|
234
234
|
<div class="tk-evidence">
|
|
235
235
|
<div class="tk-evidence-head">
|
|
@@ -275,7 +275,7 @@ export function TaskDetailPane({ taskId, density = 'full', onNavigateTask }) {
|
|
|
275
275
|
${task.description && html`
|
|
276
276
|
<div>
|
|
277
277
|
<div class="tk-section-label"><span>Description</span></div>
|
|
278
|
-
<div class="
|
|
278
|
+
<div class="ip-desc">${task.description}</div>
|
|
279
279
|
</div>
|
|
280
280
|
`}
|
|
281
281
|
|
|
@@ -307,8 +307,8 @@ export function TaskDetailPane({ taskId, density = 'full', onNavigateTask }) {
|
|
|
307
307
|
${task.progress_pct !== null && html`
|
|
308
308
|
<dt>Progress</dt>
|
|
309
309
|
<dd>
|
|
310
|
-
<div class="
|
|
311
|
-
<span style=${{ width: `${task.progress_pct}%` }}></span>
|
|
310
|
+
<div class="ip-progress">
|
|
311
|
+
<span class="ip-progress-fill" style=${{ width: `${task.progress_pct}%` }}></span>
|
|
312
312
|
</div>
|
|
313
313
|
<span style=${{ fontFamily: 'var(--font-mono)', fontSize: 10.5, color: 'var(--fg-muted)' }}>
|
|
314
314
|
${task.progress_pct}%
|
|
@@ -447,9 +447,9 @@ export function TaskDetailPane({ taskId, density = 'full', onNavigateTask }) {
|
|
|
447
447
|
</div>
|
|
448
448
|
|
|
449
449
|
${density !== 'full' && html`
|
|
450
|
-
<div class="
|
|
450
|
+
<div class="ip-action-bar">
|
|
451
451
|
<${Button} variant="outline" size="sm" type="button">Reschedule</${Button}>
|
|
452
|
-
<span class="spacer"></span>
|
|
452
|
+
<span class="ip-action-bar-spacer"></span>
|
|
453
453
|
<${Button}
|
|
454
454
|
size="sm"
|
|
455
455
|
type="button"
|
|
@@ -29,12 +29,12 @@ export function TaskRow({ task, selected, onSelect }) {
|
|
|
29
29
|
return html`
|
|
30
30
|
<button
|
|
31
31
|
type="button"
|
|
32
|
-
class=${cn('
|
|
32
|
+
class=${cn('dense-row dense-row--task', selected && 'is-on', autoClosed && 'is-completed')}
|
|
33
33
|
onClick=${() => onSelect(task.id)}
|
|
34
34
|
>
|
|
35
|
-
<span class=${cn('
|
|
36
|
-
<div class="body">
|
|
37
|
-
<div class="title">${task.title}</div>
|
|
35
|
+
<span class=${cn('dense-row-dot', priorityClass(task.priority))}></span>
|
|
36
|
+
<div class="dense-row-body">
|
|
37
|
+
<div class="dense-row-title">${task.title}</div>
|
|
38
38
|
<div class="meta">
|
|
39
39
|
<span class=${cn('tk-badge', statusClass(task.status))}>
|
|
40
40
|
<span class="dot"></span>
|
|
@@ -62,8 +62,8 @@ export function TaskRow({ task, selected, onSelect }) {
|
|
|
62
62
|
`}
|
|
63
63
|
</div>
|
|
64
64
|
</div>
|
|
65
|
-
<div class="right">
|
|
66
|
-
<span class=${cn('due', due.cls)}>${due.label}</span>
|
|
65
|
+
<div class="dense-row-right">
|
|
66
|
+
<span class=${cn('dense-row-due', due.cls)}>${due.label}</span>
|
|
67
67
|
</div>
|
|
68
68
|
</button>
|
|
69
69
|
`;
|
|
@@ -399,11 +399,11 @@ export function TasksView({ activeFeature } = {}) {
|
|
|
399
399
|
|
|
400
400
|
return html`
|
|
401
401
|
<div class="tk-screen">
|
|
402
|
-
<div class="
|
|
403
|
-
<div class="
|
|
404
|
-
<div class="
|
|
405
|
-
<${Icon} name="check-square" size=${15} className="
|
|
406
|
-
<h2 class="
|
|
402
|
+
<div class="frame" style=${{ flex: 1 }}>
|
|
403
|
+
<div class="frame-head">
|
|
404
|
+
<div class="frame-title-wrap">
|
|
405
|
+
<${Icon} name="check-square" size=${15} className="frame-title-mark" />
|
|
406
|
+
<h2 class="frame-title">
|
|
407
407
|
${VIEW_LABELS[view] ?? 'Tasks'}
|
|
408
408
|
${autoClosedCount > 0 &&
|
|
409
409
|
html`<span class="tk-frame-count">· ${autoClosedCount} auto-closed</span>`}
|
package/dist/index.html
CHANGED
|
@@ -24,7 +24,15 @@
|
|
|
24
24
|
whole iframe document scroll, which also defeats sticky group headers
|
|
25
25
|
(they'd stick to the page, not the list). */
|
|
26
26
|
html, body, #root { height: 100%; overflow: hidden; }
|
|
27
|
-
|
|
27
|
+
/* `html body` (specificity 0,0,2), not `body` (0,0,1): app.js injects the
|
|
28
|
+
vendored app-kit-css AFTER this <style> (P3 inc-3), and its 00-base
|
|
29
|
+
`body {}` reset sets font-family:var(--font-body) (Inter) / 13px / 1.55.
|
|
30
|
+
The shipped Tasks pane has always rendered its inherited text in
|
|
31
|
+
var(--font-sans) (Plus Jakarta Sans) at 14px/1.4 — bumping the
|
|
32
|
+
specificity here keeps that base intact so adopting the kit introduces
|
|
33
|
+
no pane-wide font/size shift (the kit's box-sizing + margin resets are
|
|
34
|
+
duplicates of the rules above, so they stay no-ops). */
|
|
35
|
+
html body { margin: 0; background: var(--tasks-bg); color: var(--tasks-fg); font: 14px/1.4 var(--font-sans, system-ui); -webkit-font-smoothing: antialiased; }
|
|
28
36
|
#root > .boot { padding: 1rem 1.25rem; font-size: 0.85rem; color: var(--tasks-muted); }
|
|
29
37
|
</style>
|
|
30
38
|
</head>
|