@tasks-timeline/components 0.0.6
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/README.md +524 -0
- package/dist/TasksTimelineApp.d.ts +17 -0
- package/dist/TasksTimelineApp.d.ts.map +1 -0
- package/dist/components/AppContext.d.ts +6 -0
- package/dist/components/AppContext.d.ts.map +1 -0
- package/dist/components/BacklogSection.d.ts +8 -0
- package/dist/components/BacklogSection.d.ts.map +1 -0
- package/dist/components/CategoryPopover.d.ts +9 -0
- package/dist/components/CategoryPopover.d.ts.map +1 -0
- package/dist/components/DateBadge.d.ts +15 -0
- package/dist/components/DateBadge.d.ts.map +1 -0
- package/dist/components/DaySection.d.ts +8 -0
- package/dist/components/DaySection.d.ts.map +1 -0
- package/dist/components/ErrorFallback.d.ts +10 -0
- package/dist/components/ErrorFallback.d.ts.map +1 -0
- package/dist/components/HelpModal.d.ts +8 -0
- package/dist/components/HelpModal.d.ts.map +1 -0
- package/dist/components/Icon.d.ts +8 -0
- package/dist/components/Icon.d.ts.map +1 -0
- package/dist/components/InputBar.d.ts +6 -0
- package/dist/components/InputBar.d.ts.map +1 -0
- package/dist/components/Motion.d.ts +7 -0
- package/dist/components/Motion.d.ts.map +1 -0
- package/dist/components/PriorityPopover.d.ts +8 -0
- package/dist/components/PriorityPopover.d.ts.map +1 -0
- package/dist/components/TagBadge.d.ts +12 -0
- package/dist/components/TagBadge.d.ts.map +1 -0
- package/dist/components/TaskEditModal.d.ts +12 -0
- package/dist/components/TaskEditModal.d.ts.map +1 -0
- package/dist/components/TaskItem.d.ts +10 -0
- package/dist/components/TaskItem.d.ts.map +1 -0
- package/dist/components/Toast.d.ts +15 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/TodoList.d.ts +7 -0
- package/dist/components/TodoList.d.ts.map +1 -0
- package/dist/components/YearSection.d.ts +8 -0
- package/dist/components/YearSection.d.ts.map +1 -0
- package/dist/components/index.d.ts +19 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/settings/About.d.ts +2 -0
- package/dist/components/settings/About.d.ts.map +1 -0
- package/dist/components/settings/Documentation.d.ts +2 -0
- package/dist/components/settings/Documentation.d.ts.map +1 -0
- package/dist/components/settings/SettingsModal.d.ts +15 -0
- package/dist/components/settings/SettingsModal.d.ts.map +1 -0
- package/dist/components/settings/SettingsPage.d.ts +16 -0
- package/dist/components/settings/SettingsPage.d.ts.map +1 -0
- package/dist/components/settings/SettingsPageAdvanced.d.ts +9 -0
- package/dist/components/settings/SettingsPageAdvanced.d.ts.map +1 -0
- package/dist/components/settings/SettingsPageGeneral.d.ts +9 -0
- package/dist/components/settings/SettingsPageGeneral.d.ts.map +1 -0
- package/dist/components/settings/ThemeSection.d.ts +8 -0
- package/dist/components/settings/ThemeSection.d.ts.map +1 -0
- package/dist/components/settings/TypographySection.d.ts +8 -0
- package/dist/components/settings/TypographySection.d.ts.map +1 -0
- package/dist/components/settings/ViewSection.d.ts +23 -0
- package/dist/components/settings/ViewSection.d.ts.map +1 -0
- package/dist/components/settings/ViewSectionConstants.d.ts +10 -0
- package/dist/components/settings/ViewSectionConstants.d.ts.map +1 -0
- package/dist/components/settings/index.d.ts +8 -0
- package/dist/components/settings/index.d.ts.map +1 -0
- package/dist/components/ui/badge-variants.d.ts +4 -0
- package/dist/components/ui/badge-variants.d.ts.map +1 -0
- package/dist/components/ui/badge.d.ts +8 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/button-variants.d.ts +5 -0
- package/dist/components/ui/button-variants.d.ts.map +1 -0
- package/dist/components/ui/button.d.ts +9 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/calendar.d.ts +11 -0
- package/dist/components/ui/calendar.d.ts.map +1 -0
- package/dist/components/ui/collapsible.d.ts +4 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/date-picker.d.ts +11 -0
- package/dist/components/ui/date-picker.d.ts.map +1 -0
- package/dist/components/ui/dialog.d.ts +16 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +22 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/input.d.ts +4 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/popover.d.ts +5 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/sonner.d.ts +5 -0
- package/dist/components/ui/sonner.d.ts.map +1 -0
- package/dist/contexts/SettingsContext.d.ts +22 -0
- package/dist/contexts/SettingsContext.d.ts.map +1 -0
- package/dist/contexts/TasksContext.d.ts +19 -0
- package/dist/contexts/TasksContext.d.ts.map +1 -0
- package/dist/contexts/index.d.ts +3 -0
- package/dist/contexts/index.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +11 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useAIAgent.d.ts +5 -0
- package/dist/hooks/useAIAgent.d.ts.map +1 -0
- package/dist/hooks/usePortalContainer.d.ts +6 -0
- package/dist/hooks/usePortalContainer.d.ts.map +1 -0
- package/dist/hooks/useTaskFiltering.d.ts +7 -0
- package/dist/hooks/useTaskFiltering.d.ts.map +1 -0
- package/dist/hooks/useTaskStats.d.ts +9 -0
- package/dist/hooks/useTaskStats.d.ts.map +1 -0
- package/dist/hooks/useVoiceInput.d.ts +5 -0
- package/dist/hooks/useVoiceInput.d.ts.map +1 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74888 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +258 -0
- package/dist/index.umd.cjs.map +1 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/storage.d.ts +44 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types.d.ts +127 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/ai-tools.d.ts +3 -0
- package/dist/utils/ai-tools.d.ts.map +1 -0
- package/dist/utils/cn.d.ts +3 -0
- package/dist/utils/cn.d.ts.map +1 -0
- package/dist/utils/date.d.ts +6 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/index.d.ts +11 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/parsing.d.ts +3 -0
- package/dist/utils/parsing.d.ts.map +1 -0
- package/dist/utils/task.d.ts +9 -0
- package/dist/utils/task.d.ts.map +1 -0
- package/dist/vite.svg +1 -0
- package/package.json +115 -0
package/README.md
ADDED
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
# Tasks Timeline Component Library
|
|
2
|
+
|
|
3
|
+
A comprehensive, production-ready React component library for building task management and timeline visualization applications.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@tasks-timeline/component-library)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
✨ **11 Professional UI Components**
|
|
11
|
+
|
|
12
|
+
- Task list with multiple grouping strategies (day, year, backlog)
|
|
13
|
+
- Task item with status, priority, and action controls
|
|
14
|
+
- AI-powered input bar for natural language task creation
|
|
15
|
+
- Comprehensive task editor with full configuration
|
|
16
|
+
- Settings and help modals
|
|
17
|
+
- Toast notifications
|
|
18
|
+
- Icon component wrapper
|
|
19
|
+
|
|
20
|
+
🎣 **Custom React Hooks**
|
|
21
|
+
|
|
22
|
+
- Task filtering and search
|
|
23
|
+
- Task statistics and progress tracking
|
|
24
|
+
- AI agent integration (Gemini, OpenAI, Anthropic)
|
|
25
|
+
- Voice input handling
|
|
26
|
+
|
|
27
|
+
📦 **Complete TypeScript Support**
|
|
28
|
+
|
|
29
|
+
- Fully typed components and hooks
|
|
30
|
+
- Comprehensive type definitions
|
|
31
|
+
- Excellent IDE autocomplete
|
|
32
|
+
|
|
33
|
+
🎨 **Modern Styling**
|
|
34
|
+
|
|
35
|
+
- Tailwind CSS v4 integration
|
|
36
|
+
- Radix UI components
|
|
37
|
+
- Responsive design
|
|
38
|
+
- Dark mode support
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install @tasks-timeline/component-library
|
|
44
|
+
# or
|
|
45
|
+
pnpm add @tasks-timeline/component-library
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
### Basic Usage
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import React, { useState } from "react";
|
|
54
|
+
import {
|
|
55
|
+
TodoList,
|
|
56
|
+
InputBar,
|
|
57
|
+
type Task,
|
|
58
|
+
} from "@tasks-timeline/component-library";
|
|
59
|
+
import "@tasks-timeline/component-library/styles";
|
|
60
|
+
|
|
61
|
+
function App() {
|
|
62
|
+
const [tasks, setTasks] = useState<Task[]>([]);
|
|
63
|
+
|
|
64
|
+
const handleAddTask = (task: Task) => {
|
|
65
|
+
setTasks([...tasks, task]);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div className="p-4">
|
|
70
|
+
<InputBar onTaskAdd={handleAddTask} />
|
|
71
|
+
<TodoList tasks={tasks} />
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default App;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### External Data Synchronization
|
|
80
|
+
|
|
81
|
+
The library supports efficient external synchronization with databases, REST APIs, or cloud services through operation-based callbacks:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { TasksTimelineApp } from "@tasks-timeline/component-library";
|
|
85
|
+
|
|
86
|
+
function App() {
|
|
87
|
+
return (
|
|
88
|
+
<TasksTimelineApp
|
|
89
|
+
// Called when a task is created (only serializes the new task)
|
|
90
|
+
onTaskAdded={async (task) => {
|
|
91
|
+
await fetch("/api/tasks", {
|
|
92
|
+
method: "POST",
|
|
93
|
+
body: JSON.stringify(task),
|
|
94
|
+
});
|
|
95
|
+
}}
|
|
96
|
+
// Called when a task is updated (only serializes the changed task)
|
|
97
|
+
onTaskUpdated={async (task, previous) => {
|
|
98
|
+
await fetch(`/api/tasks/${task.id}`, {
|
|
99
|
+
method: "PATCH",
|
|
100
|
+
body: JSON.stringify(task),
|
|
101
|
+
});
|
|
102
|
+
}}
|
|
103
|
+
// Called when a task is deleted (only sends the task ID)
|
|
104
|
+
onTaskDeleted={async (taskId, previous) => {
|
|
105
|
+
await fetch(`/api/tasks/${taskId}`, {
|
|
106
|
+
method: "DELETE",
|
|
107
|
+
});
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Performance Benefits:**
|
|
115
|
+
- ✅ 99% less data transfer (1KB vs 100KB for single task updates)
|
|
116
|
+
- ✅ 50-80% fewer database writes (change detection skips no-ops)
|
|
117
|
+
- ✅ Granular updates (UPDATE one row, not replace entire table)
|
|
118
|
+
- ✅ Perfect for REST APIs, GraphQL, Firebase, or any external storage
|
|
119
|
+
|
|
120
|
+
**Firebase Example:**
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { doc, setDoc, updateDoc, deleteDoc } from "firebase/firestore";
|
|
124
|
+
|
|
125
|
+
<TasksTimelineApp
|
|
126
|
+
onTaskAdded={async (task) => {
|
|
127
|
+
await setDoc(doc(db, "tasks", task.id), task);
|
|
128
|
+
}}
|
|
129
|
+
onTaskUpdated={async (task) => {
|
|
130
|
+
await updateDoc(doc(db, "tasks", task.id), task);
|
|
131
|
+
}}
|
|
132
|
+
onTaskDeleted={async (taskId) => {
|
|
133
|
+
await deleteDoc(doc(db, "tasks", taskId));
|
|
134
|
+
}}
|
|
135
|
+
/>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**LocalStorage with Granular Updates:**
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
<TasksTimelineApp
|
|
142
|
+
onTaskUpdated={async (task) => {
|
|
143
|
+
const tasks = JSON.parse(localStorage.getItem("tasks") || "[]");
|
|
144
|
+
const updated = tasks.map((t) => (t.id === task.id ? task : t));
|
|
145
|
+
localStorage.setItem("tasks", JSON.stringify(updated));
|
|
146
|
+
}}
|
|
147
|
+
/>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
> **Note:** Callbacks are optional. The component uses the repository pattern as a fallback for backwards compatibility.
|
|
151
|
+
|
|
152
|
+
### Using Components
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import {
|
|
156
|
+
TaskItem,
|
|
157
|
+
TaskEditModal,
|
|
158
|
+
SettingsModal,
|
|
159
|
+
} from "@tasks-timeline/component-library";
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Using Hooks
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import {
|
|
166
|
+
useTaskFiltering,
|
|
167
|
+
useTaskStats,
|
|
168
|
+
useAIAgent,
|
|
169
|
+
} from "@tasks-timeline/component-library/hooks";
|
|
170
|
+
|
|
171
|
+
function MyComponent({ tasks }) {
|
|
172
|
+
const { filteredTasks, filters } = useTaskFiltering(tasks, {
|
|
173
|
+
statuses: ["todo", "scheduled"],
|
|
174
|
+
priorities: ["high"],
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const stats = useTaskStats(tasks);
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<div>
|
|
181
|
+
<p>
|
|
182
|
+
Total: {stats.total}, Completed: {stats.completed}
|
|
183
|
+
</p>
|
|
184
|
+
</div>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Components
|
|
190
|
+
|
|
191
|
+
| Component | Description |
|
|
192
|
+
| ---------------- | ------------------------------------------- |
|
|
193
|
+
| `TodoList` | Main container component with task grouping |
|
|
194
|
+
| `TaskItem` | Individual task display with actions |
|
|
195
|
+
| `InputBar` | Create/edit tasks with AI support |
|
|
196
|
+
| `DaySection` | Tasks grouped by day |
|
|
197
|
+
| `YearSection` | Tasks grouped by year |
|
|
198
|
+
| `BacklogSection` | Unscheduled tasks view |
|
|
199
|
+
| `TaskEditModal` | Full-featured task editor |
|
|
200
|
+
| `SettingsModal` | Application settings |
|
|
201
|
+
| `HelpModal` | Help and documentation |
|
|
202
|
+
| `Toast` | Notification system |
|
|
203
|
+
| `Icon` | Icon wrapper for Lucide icons |
|
|
204
|
+
|
|
205
|
+
## Hooks
|
|
206
|
+
|
|
207
|
+
### useTaskFiltering
|
|
208
|
+
|
|
209
|
+
Filter tasks by status, priority, category, tags, and custom scripts.
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
const { filteredTasks, filters, setFilters } = useTaskFiltering(
|
|
213
|
+
tasks,
|
|
214
|
+
initialFilters
|
|
215
|
+
);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### useTaskStats
|
|
219
|
+
|
|
220
|
+
Calculate task statistics including completion percentage, counts by status, etc.
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
const stats = useTaskStats(tasks);
|
|
224
|
+
// { total, completed, byStatus, byPriority, ... }
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### useAIAgent
|
|
228
|
+
|
|
229
|
+
Integrate AI for task processing and insights.
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
const { processTask, generateSuggestions, isLoading } = useAIAgent(
|
|
233
|
+
settings.aiConfig
|
|
234
|
+
);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### useVoiceInput
|
|
238
|
+
|
|
239
|
+
Handle browser voice input or Whisper API integration.
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
const { transcript, isListening, startListening, stopListening } =
|
|
243
|
+
useVoiceInput();
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Types
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
type Priority = "low" | "medium" | "high";
|
|
250
|
+
type TaskStatus =
|
|
251
|
+
| "done"
|
|
252
|
+
| "scheduled"
|
|
253
|
+
| "todo"
|
|
254
|
+
| "due"
|
|
255
|
+
| "overdue"
|
|
256
|
+
| "cancelled"
|
|
257
|
+
| "unplanned";
|
|
258
|
+
|
|
259
|
+
interface Task {
|
|
260
|
+
id: string;
|
|
261
|
+
title: string;
|
|
262
|
+
description?: string;
|
|
263
|
+
status: TaskStatus;
|
|
264
|
+
priority: Priority;
|
|
265
|
+
dueDate?: string;
|
|
266
|
+
category?: string;
|
|
267
|
+
tags: Tag[];
|
|
268
|
+
isRecurring?: boolean;
|
|
269
|
+
// ... and more
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
interface AppSettings {
|
|
273
|
+
theme: "light" | "dark" | "midnight" | "coffee";
|
|
274
|
+
dateFormat: string;
|
|
275
|
+
showCompleted: boolean;
|
|
276
|
+
// ... and more
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Styling
|
|
281
|
+
|
|
282
|
+
### Import Styles
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import "@tasks-timeline/component-library/styles";
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Tailwind CSS
|
|
289
|
+
|
|
290
|
+
The library uses Tailwind CSS v4. Ensure your project has Tailwind configured:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
// vite.config.ts
|
|
294
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
295
|
+
|
|
296
|
+
export default {
|
|
297
|
+
plugins: [tailwindcss()],
|
|
298
|
+
};
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Customization
|
|
302
|
+
|
|
303
|
+
Components use Tailwind classes and can be customized through props and CSS overrides:
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
<TaskItem task={task} className="custom-class" />
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## Configuration
|
|
310
|
+
|
|
311
|
+
### TasksTimelineApp Props
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
interface TasksTimelineAppProps {
|
|
315
|
+
className?: string;
|
|
316
|
+
taskRepository?: TaskRepository;
|
|
317
|
+
settingsRepository?: SettingsRepository;
|
|
318
|
+
apiKey?: string;
|
|
319
|
+
systemInDarkMode?: boolean;
|
|
320
|
+
onItemClick?: (item: Task) => void;
|
|
321
|
+
|
|
322
|
+
// External synchronization callbacks (v0.0.4+)
|
|
323
|
+
onTaskAdded?: (task: Task) => void | Promise<void>;
|
|
324
|
+
onTaskUpdated?: (task: Task, previous: Task) => void | Promise<void>;
|
|
325
|
+
onTaskDeleted?: (taskId: string, previous: Task) => void | Promise<void>;
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Synchronization Strategy:**
|
|
330
|
+
- If callbacks (`onTaskAdded`, etc.) are provided, they take priority
|
|
331
|
+
- Otherwise, falls back to `taskRepository` methods
|
|
332
|
+
- Callbacks receive both new and previous state for conflict resolution
|
|
333
|
+
- All callbacks support async/await for database operations
|
|
334
|
+
|
|
335
|
+
### Theme
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
const settings: AppSettings = {
|
|
339
|
+
theme: "dark",
|
|
340
|
+
dateFormat: "MMM d, yyyy",
|
|
341
|
+
// ...
|
|
342
|
+
};
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### AI Integration
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
const settings: AppSettings = {
|
|
349
|
+
aiConfig: {
|
|
350
|
+
enabled: true,
|
|
351
|
+
activeProvider: "gemini",
|
|
352
|
+
providers: {
|
|
353
|
+
gemini: {
|
|
354
|
+
apiKey: "your-api-key",
|
|
355
|
+
model: "gemini-3-flash-preview",
|
|
356
|
+
baseUrl: "",
|
|
357
|
+
},
|
|
358
|
+
// ... other providers
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
};
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Development
|
|
365
|
+
|
|
366
|
+
### Setup
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
git clone <repository>
|
|
370
|
+
cd tasks-timeline
|
|
371
|
+
pnpm install
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Run Development Server
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
pnpm dev
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Run Storybook
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
pnpm storybook
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Build Library
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
pnpm build:lib
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Build Demo App
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
pnpm build
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## Project Structure
|
|
399
|
+
|
|
400
|
+
```
|
|
401
|
+
src/
|
|
402
|
+
├── components/ # UI Components
|
|
403
|
+
├── hooks/ # Custom React Hooks
|
|
404
|
+
├── types.ts # Type Definitions
|
|
405
|
+
├── utils.ts # Utilities
|
|
406
|
+
├── storage.ts # Browser Storage
|
|
407
|
+
├── App.tsx # Demo Application
|
|
408
|
+
└── index.ts # Library Entry Point
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## Development
|
|
412
|
+
|
|
413
|
+
### Local Development
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
# Install dependencies
|
|
417
|
+
pnpm install
|
|
418
|
+
|
|
419
|
+
# Start Storybook (interactive documentation)
|
|
420
|
+
pnpm storybook
|
|
421
|
+
|
|
422
|
+
# Run type checking
|
|
423
|
+
pnpm type-check
|
|
424
|
+
|
|
425
|
+
# Run linter
|
|
426
|
+
pnpm lint
|
|
427
|
+
|
|
428
|
+
# Build library
|
|
429
|
+
pnpm build
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Example Application
|
|
433
|
+
|
|
434
|
+
The `examples/app/` directory contains a fully functional demo application:
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
# Run example app
|
|
438
|
+
pnpm dev:example
|
|
439
|
+
|
|
440
|
+
# Build example app
|
|
441
|
+
pnpm build:example
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## Publishing
|
|
445
|
+
|
|
446
|
+
### Automated Publishing (GitHub Actions)
|
|
447
|
+
|
|
448
|
+
This project uses GitHub Actions to automate the build, testing, and publishing process.
|
|
449
|
+
|
|
450
|
+
**Requirements:**
|
|
451
|
+
|
|
452
|
+
1. Set up `NPM_TOKEN` secret in GitHub repository settings
|
|
453
|
+
2. Ensure main branch is protected with required status checks
|
|
454
|
+
|
|
455
|
+
**To publish a new version:**
|
|
456
|
+
|
|
457
|
+
```bash
|
|
458
|
+
# 1. Update version in package.json
|
|
459
|
+
npm version patch # or minor/major
|
|
460
|
+
|
|
461
|
+
# 2. Push to trigger GitHub Actions workflow
|
|
462
|
+
git push origin main --tags
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
The workflow will automatically:
|
|
466
|
+
|
|
467
|
+
- ✅ Run all tests (lint, type-check, build)
|
|
468
|
+
- ✅ Create a GitHub release
|
|
469
|
+
- ✅ Publish to npm
|
|
470
|
+
- ✅ Deploy Storybook to GitHub Pages
|
|
471
|
+
|
|
472
|
+
**Alternative:** Use `npm publish` directly (requires npm authentication):
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
npm publish --access public
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
See [.github/WORKFLOW_SETUP.md](.github/WORKFLOW_SETUP.md) for detailed setup and troubleshooting.
|
|
479
|
+
|
|
480
|
+
## Contributing
|
|
481
|
+
|
|
482
|
+
We welcome contributions! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on:
|
|
483
|
+
|
|
484
|
+
- Setting up your development environment
|
|
485
|
+
- Code style and standards
|
|
486
|
+
- Adding new components or hooks
|
|
487
|
+
- Writing Storybook stories
|
|
488
|
+
- Submitting pull requests
|
|
489
|
+
- Commit message conventions
|
|
490
|
+
|
|
491
|
+
**Quick start for contributors:**
|
|
492
|
+
|
|
493
|
+
```bash
|
|
494
|
+
git clone <repository>
|
|
495
|
+
cd tasks-timeline
|
|
496
|
+
pnpm install
|
|
497
|
+
pnpm storybook # View components
|
|
498
|
+
pnpm type-check # Verify types
|
|
499
|
+
pnpm lint # Check code style
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
## Documentation
|
|
503
|
+
|
|
504
|
+
- See [LIBRARY_SETUP.md](./LIBRARY_SETUP.md) for detailed setup and architecture
|
|
505
|
+
- Visit Storybook (run `pnpm storybook`) for interactive component documentation
|
|
506
|
+
- Check individual component files for JSDoc comments
|
|
507
|
+
- Read [.github/WORKFLOW_SETUP.md](.github/WORKFLOW_SETUP.md) for CI/CD configuration
|
|
508
|
+
- Write down every design you made in the ./.prd/ folder and keep them updated.
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
## Browser Support
|
|
512
|
+
|
|
513
|
+
- Chrome/Edge (latest 2 versions)
|
|
514
|
+
- Firefox (latest 2 versions)
|
|
515
|
+
- Safari 14+
|
|
516
|
+
|
|
517
|
+
## Peer Dependencies
|
|
518
|
+
|
|
519
|
+
- React 18.2.0+
|
|
520
|
+
- React DOM 18.2.0+
|
|
521
|
+
|
|
522
|
+
## License
|
|
523
|
+
|
|
524
|
+
MIT © zhuwenq
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { CustomSettingsTab, SettingsRepository, Task } from "./types";
|
|
3
|
+
export interface TasksTimelineAppProps {
|
|
4
|
+
className?: string;
|
|
5
|
+
tasks: Task[];
|
|
6
|
+
onTaskAdded: (task: Task) => void | Promise<void>;
|
|
7
|
+
onTaskUpdated: (task: Task, previous: Task) => void | Promise<void>;
|
|
8
|
+
onTaskDeleted: (taskId: string, previous: Task) => void | Promise<void>;
|
|
9
|
+
settingsRepository?: SettingsRepository;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
systemInDarkMode?: boolean;
|
|
12
|
+
onItemClick?: (item: Task) => void;
|
|
13
|
+
/** Custom tabs to inject into the Settings page */
|
|
14
|
+
customSettingsTabs?: CustomSettingsTab[];
|
|
15
|
+
}
|
|
16
|
+
export declare const TasksTimelineApp: React.FC<TasksTimelineAppProps>;
|
|
17
|
+
//# sourceMappingURL=TasksTimelineApp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TasksTimelineApp.d.ts","sourceRoot":"","sources":["../src/TasksTimelineApp.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyD,MAAM,OAAO,CAAC;AAQ9E,OAAO,KAAK,EAEV,iBAAiB,EAGjB,kBAAkB,EAElB,IAAI,EAEL,MAAM,SAAS,CAAC;AAuEjB,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGxE,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,mDAAmD;IACnD,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC1C;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA4gB5D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppContext.d.ts","sourceRoot":"","sources":["../../src/components/AppContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAKxC,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC;IACjC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAwBA,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BacklogSection.d.ts","sourceRoot":"","sources":["../../src/components/BacklogSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAWrC,UAAU,mBAAmB;IAC3B,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAwDxD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Task } from "@/types";
|
|
2
|
+
export interface CategoryPopoverProps {
|
|
3
|
+
task: Task;
|
|
4
|
+
onUpdate: (task: Task) => void;
|
|
5
|
+
availableCategories: string[];
|
|
6
|
+
badgeClass: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const CategoryPopover: ({ task, onUpdate, availableCategories, badgeClass, }: CategoryPopoverProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=CategoryPopover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CategoryPopover.d.ts","sourceRoot":"","sources":["../../src/components/CategoryPopover.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAYpC,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC/B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,eAAe,GAAI,sDAK7B,oBAAoB,4CAqEtB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Task } from "@/types";
|
|
2
|
+
import * as Lucide from "lucide-react";
|
|
3
|
+
interface DateBadgeProps {
|
|
4
|
+
task: Task;
|
|
5
|
+
onUpdate: (task: Task) => void;
|
|
6
|
+
type: "dueDate" | "startAt" | "createdAt" | "completedAt";
|
|
7
|
+
date?: string;
|
|
8
|
+
label: string;
|
|
9
|
+
icon: keyof typeof Lucide;
|
|
10
|
+
className: string;
|
|
11
|
+
prefix?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const DateBadge: ({ type, date, label, icon, className, prefix, onUpdate, task, }: DateBadgeProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=DateBadge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateBadge.d.ts","sourceRoot":"","sources":["../../src/components/DateBadge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAcvC,UAAU,cAAc;IACtB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC/B,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,OAAO,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,SAAS,GAAI,iEASvB,cAAc,4CAiHhB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DaySection.d.ts","sourceRoot":"","sources":["../../src/components/DaySection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAGpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAazC,UAAU,eAAe;IACvB,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAgVhD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface ErrorFallbackProps {
|
|
3
|
+
error: Error;
|
|
4
|
+
resetErrorBoundary: () => void;
|
|
5
|
+
}
|
|
6
|
+
export declare const TaskListErrorFallback: React.FC<ErrorFallbackProps>;
|
|
7
|
+
export declare const AIErrorFallback: React.FC<ErrorFallbackProps>;
|
|
8
|
+
export declare const ModalErrorFallback: React.FC<ErrorFallbackProps>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=ErrorFallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorFallback.d.ts","sourceRoot":"","sources":["../../src/components/ErrorFallback.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,kBAAkB;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,kBAAkB,EAAE,MAAM,IAAI,CAAC;CAChC;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAyB9D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA2BxD,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAuB3D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HelpModal.d.ts","sourceRoot":"","sources":["../../src/components/HelpModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,cAAc;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CA6L9C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import * as Lucide from "lucide-react";
|
|
3
|
+
export interface IconProps extends Omit<React.SVGProps<SVGSVGElement>, "name"> {
|
|
4
|
+
name: keyof typeof Lucide;
|
|
5
|
+
size?: number | string;
|
|
6
|
+
}
|
|
7
|
+
export declare const Icon: React.FC<IconProps>;
|
|
8
|
+
//# sourceMappingURL=Icon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/components/Icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAEvC,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAC5E,IAAI,EAAE,MAAM,OAAO,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAapC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputBar.d.ts","sourceRoot":"","sources":["../../src/components/InputBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAkBxC,UAAU,aAAa;CAAG;AAE1B,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA4Y5C,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type HTMLMotionProps } from "framer-motion";
|
|
3
|
+
export declare const MotionDiv: React.ForwardRefExoticComponent<Omit<HTMLMotionProps<"div">, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
4
|
+
export declare const MotionSpan: React.ForwardRefExoticComponent<Omit<HTMLMotionProps<"span">, "ref"> & React.RefAttributes<HTMLSpanElement>>;
|
|
5
|
+
export declare const MotionButton: React.ForwardRefExoticComponent<Omit<HTMLMotionProps<"button">, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
6
|
+
export declare const MotionInput: React.ForwardRefExoticComponent<Omit<HTMLMotionProps<"input">, "ref"> & React.RefAttributes<HTMLInputElement>>;
|
|
7
|
+
//# sourceMappingURL=Motion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Motion.d.ts","sourceRoot":"","sources":["../../src/components/Motion.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,eAAe,EAAU,MAAM,eAAe,CAAC;AAK7D,eAAO,MAAM,SAAS,4GAKpB,CAAC;AAEH,eAAO,MAAM,UAAU,8GAKrB,CAAC;AAEH,eAAO,MAAM,YAAY,kHAKvB,CAAC;AAEH,eAAO,MAAM,WAAW,gHAKtB,CAAC"}
|