@editora/ui-core 0.1.23 → 0.1.25

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 CHANGED
@@ -252,11 +252,218 @@ and resize, and a toolbar for zoom, filter and sort. Give it `tasks` and `links`
252
252
  <img src="https://raw.githubusercontent.com/ajaykr089/Editora/main/packages/ui-core/docs/images/gantt.png" alt="A Gantt chart with a task bar for API contracts, a baseline under it, and an arrow to the QA sign-off milestone" width="900">
253
253
  </p>
254
254
 
255
- - `zoom`: `day`, `week`, `month`, `quarter` or `year`. `sort`: `none`, `start`, `end`, `label` or `progress`.
256
- - `bar-variant`: `solid`, `soft`, `striped`, `outline` or `glass`.
257
- - Dependency types: `e2s`, `s2s`, `e2e` and `s2e`.
258
- - Also: `readonly`, `show-toolbar`, `show-today`, `filter`, and `virtualized="false"` for small layouts (large task sets are
259
- virtualized automatically).
255
+ That is the whole setup for a basic chart. The rest of this section builds on it.
256
+
257
+ ### A full planner
258
+
259
+ This one turns on most of the features at once: a two-level time header, weekends and a holiday shaded, parents that
260
+ follow their children, scheduling that pushes the tasks after one you move, the critical path, dependencies you draw
261
+ by dragging, and a date the host refuses to let slip. The chart draws what it is given and reports what the user does;
262
+ the plan lives in your code, so every edit arrives as an event and you decide whether to keep it.
263
+
264
+ ```html
265
+ <ui-gantt
266
+ id="planner"
267
+ zoom="week"
268
+ week-start="1"
269
+ bar-variant="soft"
270
+ columns='["label", "assignee", "start", "end", "progress"]'
271
+ non-working-days
272
+ auto-summary
273
+ cascade
274
+ schedule="auto"
275
+ critical-path
276
+ linkable
277
+ creatable
278
+ ></ui-gantt>
279
+
280
+ <script type="module">
281
+ import '@editora/ui-core';
282
+
283
+ const planner = document.getElementById('planner');
284
+ const day = (offset) => {
285
+ const date = new Date();
286
+ date.setHours(0, 0, 0, 0);
287
+ date.setDate(date.getDate() + offset);
288
+ return date;
289
+ };
290
+
291
+ // The chart draws what it is given and reports what the user does; the plan lives here.
292
+ let tasks = [
293
+ { id: 'discovery', label: 'Discovery', type: 'summary' },
294
+ { id: 'research', label: 'User research', parent: 'discovery', start: day(-21), end: day(-12), progress: 100, assignee: 'Mina', baselineStart: day(-21), baselineEnd: day(-13) },
295
+ { id: 'interviews', label: 'Interviews', parent: 'discovery', start: day(-12), end: day(-5), progress: 100, assignee: 'Jonas' },
296
+ { id: 'scope', label: 'Scope signed off', parent: 'discovery', start: day(-5), type: 'milestone', tone: 'success' },
297
+ { id: 'build', label: 'Build', type: 'summary' },
298
+ { id: 'api', label: 'API and data model', parent: 'build', start: day(-4), end: day(10), progress: 70, assignee: 'Priya' },
299
+ {
300
+ id: 'ui',
301
+ label: 'Planner UI',
302
+ parent: 'build',
303
+ start: day(-2),
304
+ end: day(18),
305
+ progress: 45,
306
+ assignee: 'Tomás',
307
+ segments: [{ start: day(-2), end: day(5) }, { start: day(8), end: day(18) }]
308
+ },
309
+ { id: 'integration', label: 'Integration', parent: 'build', start: day(18), end: day(26), progress: 0, assignee: 'Priya' },
310
+ { id: 'launch', label: 'Launch', type: 'summary' },
311
+ { id: 'qa', label: 'QA and fixes', parent: 'launch', start: day(26), end: day(33), assignee: 'Aiko' },
312
+ { id: 'beta', label: 'Beta', parent: 'launch', start: day(33), end: day(40), assignee: 'Aiko' },
313
+ { id: 'release', label: 'Release', parent: 'launch', start: day(40), type: 'milestone', tone: 'danger' },
314
+ { id: 'docs', label: 'Write the docs', start: day(30), end: day(38), progress: 20, assignee: 'Sam' }
315
+ ];
316
+ let links = [
317
+ { id: 'l1', source: 'research', target: 'interviews' },
318
+ { id: 'l2', source: 'interviews', target: 'scope' },
319
+ { id: 'l3', source: 'scope', target: 'api', lag: 1 },
320
+ { id: 'l4', source: 'scope', target: 'ui', type: 's2s', lag: 3 },
321
+ { id: 'l5', source: 'api', target: 'integration' },
322
+ { id: 'l6', source: 'ui', target: 'integration' },
323
+ { id: 'l7', source: 'integration', target: 'qa' },
324
+ { id: 'l8', source: 'qa', target: 'beta' },
325
+ { id: 'l9', source: 'beta', target: 'release' },
326
+ { id: 'l10', source: 'beta', target: 'docs' } // docs are planned before beta ends: drawn red
327
+ ];
328
+ const sync = () => {
329
+ planner.tasks = tasks;
330
+ planner.links = links;
331
+ };
332
+ planner.holidays = [{ date: day(12), label: 'Founders day' }];
333
+ const patch = (id, changes) => {
334
+ tasks = tasks.map((task) => (task.id === id ? { ...task, ...changes } : task));
335
+ };
336
+ sync();
337
+
338
+ // Keep the release date: refuse any change that would push it.
339
+ planner.addEventListener('beforetaskchange', (event) => {
340
+ if (event.detail.affected.some((change) => change.id === 'release')) event.preventDefault();
341
+ });
342
+ planner.addEventListener('taskchange', ({ detail }) => {
343
+ patch(detail.id, { start: detail.start, end: detail.end });
344
+ sync();
345
+ });
346
+ planner.addEventListener('taskrename', ({ detail }) => {
347
+ patch(detail.id, { label: detail.label });
348
+ sync();
349
+ });
350
+ planner.addEventListener('taskcreate', ({ detail }) => {
351
+ const id = `task-${tasks.length + 1}`;
352
+ tasks = [...tasks, { id, label: 'New task', start: detail.start, end: detail.end, parent: detail.parent }];
353
+ sync();
354
+ planner.scrollToTask(id);
355
+ });
356
+ planner.addEventListener('linkcreate', ({ detail }) => {
357
+ links = [...links, { id: `l${links.length + 1}`, ...detail }];
358
+ sync();
359
+ });
360
+ planner.addEventListener('linkdelete', ({ detail }) => {
361
+ links = links.filter((link) => link.id !== detail.id);
362
+ sync();
363
+ });
364
+ </script>
365
+ ```
366
+
367
+ <p align="center">
368
+ <img src="https://raw.githubusercontent.com/ajaykr089/Editora/main/packages/ui-core/docs/images/gantt-planner.png" alt="A project planner: three summary rows, red critical-path bars joined by dependency arrows, shaded weekends and a holiday, a Today marker, a red dashed link for a task planned before its predecessor ends, and a tooltip on the Beta bar" width="900">
369
+ </p>
370
+
371
+ The red bars are the critical path (`critical-path`), the red dashed arrow is a dependency that is already broken
372
+ (Write the docs is planned before Beta ends), the grey strip under User research is its baseline, and the dots on
373
+ Beta are the handles `linkable` adds.
374
+
375
+ ### Timeline and display
376
+
377
+ - `zoom`: `day`, `week`, `month`, `quarter`, `year` or `fit` (the whole project scaled to the chart's width, re-fitted when it is
378
+ resized). The time header has two rows (month over days or weeks, year over months or quarters), a pill marks today, and the chart
379
+ opens on today when it is off the first screen (`initial-scroll="start"` keeps the start).
380
+ - `week-start` (`0` is Sunday) sets the first day of the week; it defaults to the locale's.
381
+ - `bar-variant`: `solid`, `soft`, `striped`, `outline` or `glass`. Progress is drawn inside each bar, and a task with `segments` is drawn in parts,
382
+ each with its own progress. `sort`: `none`, `start`, `end`, `label` or `progress`.
383
+ - Non-working time: `non-working-days` (the attribute alone means the weekend, or `0,6` / `[1,2]`) and `holidays` (`["2026-12-25", {"date": "2026-12-26", "label": "Boxing Day"}]`)
384
+ shade those days behind the rows (not at month scales and wider, where a day is a few pixels) and mute them in the day header. They are shown, not scheduled
385
+ around: task lengths are calendar days.
386
+ - Size: by default the chart grows with its rows up to 620px (`max-height="60vh"` or the `--ui-gantt-max-height` variable change that); add
387
+ `fill` and give the element a height (or a flex/grid cell) and it fills it, with the rows scrolling inside. Below 640px of width only the
388
+ name column is kept. Large task sets (over 240 rows) are virtualized automatically; `virtualized="false"` turns that off.
389
+ - Dates are calendar days (`YYYY-MM-DD`). A time or offset after the day (`2026-03-02T23:30:00Z`) is ignored, so a task never moves a
390
+ day with the viewer's time zone; `taskchange` reports plain `YYYY-MM-DD`.
391
+ - Translate every word with `labels` (a JSON object with any subset of the label keys, e.g. `{"title": "Planning", "zoomWeek": "semaine"}`) and
392
+ set `locale` (`fr-FR`) for month names, date formats and the first day of the week.
393
+
394
+ ### Task list
395
+
396
+ - Choose the columns with `columns` (`["label", "assignee", "start", "end", "duration", "progress"]`, or objects with a `label` and a
397
+ `width`) and size the list with `grid-width`; a splitter on its edge resizes it (mouse, touch, or the arrow keys) and fires `gridresize`.
398
+ - Parents: opening or closing a branch fires `tasktoggle`. `auto-summary` makes a parent span its children and take their progress (weighted by length)
399
+ when it has none; `cascade` lets you move a parent and everything under it together (`beforetaskchange` lists the tasks it moves in `affected`,
400
+ `taskchange` fires for each).
401
+
402
+ ### Dependencies and scheduling
403
+
404
+ - A link may carry a `lag` (days) and its `type` says what it ties: `e2s` (the default), `s2s`, `e2e` or `s2e`. A link whose target is too early is
405
+ drawn red and dashed.
406
+ - `schedule="auto"` also pushes the tasks that follow a task you move (later only, keeping their length, down the chain, as one change you can
407
+ refuse in `beforetaskchange`); `schedule="off"` turns both off. The pushing counts calendar days.
408
+ - `critical-path` computes the critical path from the links (no slack on a chain that is tight all the way) and draws those bars as critical, on top of any
409
+ task you flag `critical`.
410
+ - `linkable` shows dots beside each bar: drag one onto another bar and the chart fires `linkcreate` with the source, the target and the type the two ends
411
+ give (`e2s`, `s2s`, `e2e`, `s2e`); click a link to select it and press Delete to get `linkdelete`. As with tasks, your code owns the data.
412
+
413
+ ### Editing
414
+
415
+ - Dragging: a bar can be dragged, resized from its ends, or moved with the arrow keys (Shift extends the end). The chart scrolls when a drag is held
416
+ near the left or right edge, Escape cancels it, and `snap="week"` or `snap="month"` snaps it to whole weeks or months. `beforetaskchange`
417
+ (cancelable) fires before the dates change, so a host can refuse the change with `event.preventDefault()`; `taskchange` fires after.
418
+ - Rename in place: double-click a task's name (or press F2 on a row or a bar). Enter or leaving the field keeps it and fires `taskrename`
419
+ (cancelable), Escape drops it.
420
+ - With `creatable` there is a **+ Add task** button, and a double-click on empty timeline space does the same for that
421
+ day: the chart fires `taskcreate` with the dates and the neighbour and your code adds the task. Nothing is written to your data by the chart.
422
+ - `readonly` turns all of this off and keeps the browsing.
423
+
424
+ ### Keyboard and accessibility
425
+
426
+ - Tab enters the task list once (a row) and once more for the bars. On a row, Up/Down, Home/End and PageUp/PageDown move between rows, Right
427
+ opens a branch or steps into it, Left closes it or climbs to the parent, Enter or Space selects. On a bar the same keys move between rows, and
428
+ Left/Right move the bar a day (Shift: extend the end), Delete asks to remove it, and Escape closes the tooltip.
429
+ - Each bar is named for assistive technology with its dates, progress, owner and critical flag, and shows the same facts in a tooltip on
430
+ hover or keyboard focus. While you drag a bar, the tooltip shows the dates it would take. Bars and the touch targets of the splitter and the
431
+ link handles grow on touch screens.
432
+
433
+ ### Export and print
434
+
435
+ `exportSvg()` returns the whole chart (not just the part on screen) as a standalone SVG string, and the chart prints as a whole (no scroll
436
+ area, no sticky headers, no controls; use `zoom="fit"` for a wide project).
437
+
438
+ ### Reference
439
+
440
+ | Attribute | Values |
441
+ | --- | --- |
442
+ | `zoom` | `day`, `week` (default), `month`, `quarter`, `year`, `fit` |
443
+ | `week-start`, `locale`, `labels` | first weekday (`0`-`6`), a locale tag, a JSON object of label overrides |
444
+ | `bar-variant`, `sort`, `variant` | bar skin, sort key, `contrast` for a dark surface |
445
+ | `columns`, `grid-width` | task list columns and width |
446
+ | `fill`, `max-height`, `virtualized` | sizing and row virtualization |
447
+ | `non-working-days`, `holidays` | shaded days: weekdays, dates |
448
+ | `auto-summary`, `cascade` | parents follow their children, parents move their children |
449
+ | `schedule`, `critical-path` | `auto` pushes successors, red critical bars |
450
+ | `linkable`, `creatable`, `readonly`, `snap`, `initial-scroll` | editing and scrolling behaviour |
451
+ | `filter`, `show-toolbar`, `show-today`, `headless` | toolbar |
452
+
453
+ | Event | `detail` |
454
+ | --- | --- |
455
+ | `beforetaskchange` (cancelable) | `{ id, start, end, previousStart, previousEnd, source, affected }`, `affected` lists the other tasks the change moves in the same shape |
456
+ | `taskchange` | `{ id, start, end }`, once for each task that moved |
457
+ | `taskselect`, `taskdelete` | `{ id }` |
458
+ | `tasktoggle` | `{ id, open }` |
459
+ | `taskrename` (cancelable) | `{ id, label, previousLabel }` |
460
+ | `taskcreate` | `{ start, end, parent, after }` |
461
+ | `linkcreate` | `{ source, target, type }` |
462
+ | `linkselect`, `linkdelete` | `{ id, source, target, type }` |
463
+ | `zoomchange`, `sortchange`, `filterchange`, `gridresize` | `{ zoom }`, `{ sort }`, `{ filter }`, `{ width }` |
464
+
465
+ Methods: `scrollToDate(date)`, `scrollToTask(id)`, `toggleTask(id, open?)`, `expandAll()`, `collapseAll()` and `exportSvg()`. `tasks`, `links`
466
+ and `holidays` are also properties that take arrays (with `Date`s if you like).
260
467
 
261
468
  ## Promise dialogs
262
469
 
@@ -408,6 +615,9 @@ Working examples:
408
615
  [guide](https://github.com/ajaykr089/Editora/blob/main/packages/ui-core/docs/FRAMEWORK_DIRECT_USAGE.md). For React,
409
616
  use [`@editora/ui-react`](https://www.npmjs.com/package/@editora/ui-react).
410
617
 
618
+ `@editora/ui-vue`, `@editora/ui-svelte` and `@editora/ui-angular` are deprecated: they never grew past a few stub
619
+ components. Use `@editora/ui-core` directly instead.
620
+
411
621
  ## Good to know
412
622
 
413
623
  - Components register when their module is imported, so the package is marked `sideEffects: true`. Import it before the
@@ -0,0 +1,79 @@
1
+ export type SchedTask = {
2
+ id: string;
3
+ start: number;
4
+ end: number;
5
+ parent?: string;
6
+ type?: 'task' | 'summary' | 'milestone';
7
+ readonly?: boolean;
8
+ progress?: number;
9
+ };
10
+ export type LinkType = 'e2s' | 's2s' | 'e2e' | 's2e';
11
+ export type SchedLink = {
12
+ id: string;
13
+ source: string;
14
+ target: string;
15
+ type: LinkType;
16
+ lag: number;
17
+ };
18
+ /** A date moved by whole calendar days (DST-safe, unlike adding 24 hours). */
19
+ export declare function shiftDays(ms: number, days: number): number;
20
+ /** Whole days between two local-midnight timestamps. */
21
+ export declare function daysBetween(from: number, to: number): number;
22
+ /** Every task under `id`, at any depth (a parent that points back into its own branch is not followed twice). */
23
+ export declare function descendantsOf(tasks: SchedTask[], id: string): SchedTask[];
24
+ export type RolledUp = {
25
+ start: number;
26
+ end: number;
27
+ progress?: number;
28
+ };
29
+ /**
30
+ * What each parent's dates and progress are when they follow their children: the earliest start and the latest end
31
+ * below it, and the progress of the children weighted by their length (only the children that have one). Computed
32
+ * from the bottom up, so a parent of parents works. Tasks without children are not in the result.
33
+ */
34
+ export declare function rollUp(tasks: SchedTask[]): Map<string, RolledUp>;
35
+ /**
36
+ * The earliest the target may start (for `e2s` and `s2s`) or end (for `e2e` and `s2e`) given where the source is: the
37
+ * source's end or start, plus the link's lag in days (which may be negative).
38
+ */
39
+ export declare function constraintBound(link: SchedLink, source: {
40
+ start: number;
41
+ end: number;
42
+ }): {
43
+ side: 'start' | 'end';
44
+ min: number;
45
+ };
46
+ export declare function linkSatisfied(link: SchedLink, source: {
47
+ start: number;
48
+ end: number;
49
+ }, target: {
50
+ start: number;
51
+ end: number;
52
+ }): boolean;
53
+ /** The ids of the links whose target starts or ends earlier than its source allows. A link to a missing task is not one. */
54
+ export declare function violatedLinks(tasks: SchedTask[], links: SchedLink[]): Set<string>;
55
+ export type TaskMove = {
56
+ id: string;
57
+ start: number;
58
+ end: number;
59
+ };
60
+ /**
61
+ * After some tasks have moved (`moved`: id to their new dates), push the tasks that follow them later until every link holds
62
+ * again, keeping each pushed task's length. Only forward: a task is never pulled earlier. A read-only task is not pushed (its
63
+ * link stays violated), and with `cascade` the tasks under a pushed parent go with it. Returns the tasks that changed beyond
64
+ * `moved`, with their final dates, and gives up on a task after as many pushes as there are tasks (a cycle of links).
65
+ */
66
+ export declare function pushSuccessors(tasks: SchedTask[], links: SchedLink[], moved: Map<string, {
67
+ start: number;
68
+ end: number;
69
+ }>, cascade?: boolean): TaskMove[];
70
+ /**
71
+ * The critical path of the schedule as it stands: the tasks with no slack on a chain of links that is tight all the way.
72
+ * Slack is how far a task could finish later without a link pushing something past the end of the project, found with a
73
+ * backward pass over the links (every type and lag). Only tasks without children count (a parent is its children), a
74
+ * task without links is never critical, and neither is one whose own incoming links all have room: a task is critical
75
+ * when it has no slack and either nothing precedes it or something that does is tight against it. Tasks caught in a
76
+ * cycle of links are left out.
77
+ */
78
+ export declare function criticalPath(tasks: SchedTask[], links: SchedLink[]): Set<string>;
79
+ //# sourceMappingURL=gantt-schedule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gantt-schedule.d.ts","sourceRoot":"","sources":["../../src/components/gantt-schedule.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAErD,MAAM,MAAM,SAAS,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpG,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK1D;AAED,wDAAwD;AACxD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5D;AAcD,iHAAiH;AACjH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,CAczE;AAED,MAAM,MAAM,QAAQ,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAgChE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAG/H;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAGtI;AAED,4HAA4H;AAC5H,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CASjF;AAED,MAAM,MAAM,QAAQ,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,OAAO,UAAQ,GAAG,QAAQ,EAAE,CAoDtJ;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CA6DhF"}
@@ -1,7 +1,54 @@
1
1
  import { ElementBase } from '../ElementBase';
2
+ /** Every word the component shows or announces, so a host can translate it. `tasksCount` takes {shown} and {total}. */
3
+ export type GanttLabels = {
4
+ title: string;
5
+ tasksCount: string;
6
+ filterPlaceholder: string;
7
+ filterLabel: string;
8
+ sortLabel: string;
9
+ sortManual: string;
10
+ sortStart: string;
11
+ sortEnd: string;
12
+ sortName: string;
13
+ sortProgress: string;
14
+ zoomDay: string;
15
+ zoomWeek: string;
16
+ zoomMonth: string;
17
+ zoomQuarter: string;
18
+ zoomYear: string;
19
+ zoomFit: string;
20
+ zoomFitTitle: string;
21
+ columnTask: string;
22
+ columnOwner: string;
23
+ columnDates: string;
24
+ columnProgress: string;
25
+ columnStart: string;
26
+ columnEnd: string;
27
+ columnDuration: string;
28
+ splitter: string;
29
+ scrollToToday: string;
30
+ addTask: string;
31
+ rename: string;
32
+ linkViolated: string;
33
+ empty: string;
34
+ noMatches: string;
35
+ expand: string;
36
+ collapse: string;
37
+ timeline: string;
38
+ today: string;
39
+ summary: string;
40
+ milestone: string;
41
+ to: string;
42
+ complete: string;
43
+ assigned: string;
44
+ critical: string;
45
+ };
2
46
  export declare class UIGantt extends ElementBase {
3
47
  static get observedAttributes(): string[];
48
+ private focusRequest;
4
49
  private collapsed;
50
+ /** Task ids already seen, so `open: false` collapses a branch once and never fights the user's toggle. */
51
+ private seededIds;
5
52
  private overrides;
6
53
  private drag;
7
54
  private selectedId;
@@ -9,6 +56,31 @@ export declare class UIGantt extends ElementBase {
9
56
  private viewportTop;
10
57
  private viewportLeft;
11
58
  private viewportWidth;
59
+ private hostWidth;
60
+ /** Where the scroll area was when the header cells and shading were last built: they cover a window around it. */
61
+ private renderedLeft;
62
+ /** A smooth scroll in progress, so a render that replaces the scroll area can carry on with it. */
63
+ private smoothTarget;
64
+ private selectedLinkId;
65
+ private linking;
66
+ private editingId;
67
+ private editingValue;
68
+ private suppressBlur;
69
+ private layoutInfo;
70
+ private visibleIds;
71
+ private initialScrollPending;
72
+ private pendingReveal;
73
+ private hostHeight;
74
+ private virtualizedNow;
75
+ private gridBounds;
76
+ private descriptions;
77
+ private tipTimer;
78
+ private pointerFocus;
79
+ /** Width of the scroll area's vertical scrollbar, measured after a render; `fit` leaves room for it. */
80
+ private scrollbarWidth;
81
+ /** The pixels per day the last render used, for dragging. */
82
+ private dayWidthNow;
83
+ private resizeObserver;
12
84
  private viewportHeight;
13
85
  private renderedFirstRow;
14
86
  private renderedLastRow;
@@ -16,21 +88,133 @@ export declare class UIGantt extends ElementBase {
16
88
  private overridesVersion;
17
89
  private taskCacheRaw;
18
90
  private taskCacheVersion;
91
+ private taskCacheAuto;
92
+ private taskCacheCritical;
19
93
  private taskCache;
20
94
  private linkCacheRaw;
21
95
  private linkCache;
22
96
  private visibleCacheKey;
23
97
  private visibleCache;
98
+ connectedCallback(): void;
99
+ disconnectedCallback(): void;
100
+ private labelsRaw;
101
+ private labelsCache;
102
+ /** The labels: the defaults with whatever the `labels` attribute (a JSON object) overrides. */
103
+ private labelSet;
24
104
  protected render(): void;
105
+ /**
106
+ * Every render replaces the whole shadow tree, which drops focus. Remember which control had it so
107
+ * the replacement can take it back (and the caret, for the filter box); without this the filter
108
+ * accepts one character per click.
109
+ */
110
+ private captureFocus;
111
+ private restoreFocus;
25
112
  private bindEvents;
113
+ private snapUnit;
114
+ /** The nearest boundary of the snap unit (a week start, a 1st of the month), or the day itself. */
115
+ private snapDate;
116
+ private startDrag;
117
+ /** The dates the bar would take for the pointer's position, snapped, and a repaint of the bar and the tooltip. */
118
+ private updateDrag;
119
+ /** While a drag is held near the left or right edge of the timeline the chart scrolls, faster the nearer the edge. */
120
+ private autoScrollLoop;
121
+ /** Finish a drag: drop it (commit the new dates), or cancel it (the bar goes back where it was). */
122
+ private endDrag;
123
+ /**
124
+ * With `cascade`, moving a parent moves everything under it by the same number of days (a read-only task stays
125
+ * put). Anything else is the one change.
126
+ */
127
+ private plan;
128
+ private withCascade;
129
+ /**
130
+ * Apply a change to dates. First a cancelable `beforetaskchange` (a host that rejects the change calls
131
+ * preventDefault and nothing moves), then the new dates are kept and `taskchange` fires for each task.
132
+ */
133
+ private applyChanges;
134
+ /**
135
+ * Keyboard on a bar. Moving between rows (and selecting) works on every bar, summaries and read-only
136
+ * charts included; only the keys that change dates or delete need an editable bar.
137
+ */
138
+ private handleBarKeydown;
139
+ /**
140
+ * Show the tooltip for a bar: above its visible part, centred, kept inside the scroll area; below the bar when
141
+ * there is no room under the sticky header.
142
+ */
143
+ private showTip;
144
+ private hideTip;
145
+ /** Links: select one by clicking it (then Delete asks to remove it), and with `linkable` draw new ones from the dots beside a bar. */
146
+ private bindLinks;
147
+ private startLink;
148
+ /** The rubber-band line follows the pointer; the bar (or dot) under it, and which end of it, is the target. */
149
+ private updateLink;
150
+ /** Let go: a drop on another task asks the host for a link (`linkcreate`), anywhere else nothing happens. */
151
+ private endLink;
152
+ /** Rename a task in place: the name becomes a text field. Does nothing in a read-only chart or for a read-only task. */
153
+ private startRename;
154
+ /** Leave the rename field: keep the new name (when `save` and it is not empty or unchanged and nobody refuses it) or drop it. */
155
+ private finishRename;
156
+ /** Create a task: the host is told where (`taskcreate`) and adds it; nothing is added here. */
157
+ private requestCreate;
158
+ private bindEditing;
159
+ /** The task list is a treegrid: a row takes focus and the arrow keys move around it. */
160
+ private bindRows;
161
+ /** Drag the splitter (or use the arrow keys on it) to resize the task list; it is kept in `grid-width`. */
162
+ private bindSplitters;
163
+ private bindTooltips;
164
+ /** The tasks as an array. Setting it writes the `tasks` attribute (dates may be `Date`s: they become `YYYY-MM-DD`). */
165
+ get tasks(): Array<Record<string, unknown>>;
166
+ set tasks(value: Array<Record<string, unknown>> | null | undefined);
167
+ /** The holidays as an array of `YYYY-MM-DD` strings or `{ date, label }` objects. Setting it writes the attribute (a `Date` becomes its local day). */
168
+ get holidays(): Array<unknown>;
169
+ set holidays(value: Array<unknown> | null | undefined);
170
+ /** The links as an array. Setting it writes the `links` attribute. */
171
+ get links(): Array<Record<string, unknown>>;
172
+ set links(value: Array<Record<string, unknown>> | null | undefined);
173
+ private resolveBehavior;
174
+ private scrollViewport;
175
+ /**
176
+ * Scroll the timeline to a date: a `YYYY-MM-DD` string, a `Date`, a timestamp, or `"today"`. `align` is `center`
177
+ * (the default) or `start`, which leaves a little room before the date. Does nothing for a date that is not valid.
178
+ */
179
+ scrollToDate(date: string | number | Date, options?: {
180
+ behavior?: ScrollBehavior;
181
+ align?: 'center' | 'start';
182
+ }): void;
183
+ private leftFor;
184
+ /**
185
+ * Bring a task into view: open the branches above it, then scroll its row (and its bar) on screen when they are
186
+ * not. Returns false for an id that is not there or is filtered out.
187
+ */
188
+ scrollToTask(id: string, options?: {
189
+ behavior?: ScrollBehavior;
190
+ }): boolean;
191
+ private reveal;
192
+ /** Open or close a branch (`open` omitted toggles it) and fire `tasktoggle`. */
193
+ toggleTask(id: string, open?: boolean): void;
194
+ expandAll(): void;
195
+ collapseAll(): void;
196
+ /**
197
+ * The whole chart as a standalone SVG string (not just the part on screen): the time header, the task names, the bars with
198
+ * their progress, baselines, parts, milestones and links, the today line and any non-working days. Rows follow the current
199
+ * filter, sort and collapsed branches; the scale is the one on screen. Colours are the theme's resolved at this moment.
200
+ * Returns an empty string when there is nothing to draw.
201
+ */
202
+ exportSvg(): string;
26
203
  private rangeMin;
27
204
  private selectTask;
28
- private selectAdjacentTask;
205
+ /** Select a task and give focus to its row or its bar, scrolling it into view first. */
206
+ private focusTask;
207
+ /**
208
+ * Keyboard movement between rows, the same from a row and from a bar: Up and Down, Home and End, PageUp and PageDown. From a row,
209
+ * Right and Left also open, close and climb the tree. Returns whether the key was one of these.
210
+ */
211
+ private navigate;
29
212
  private captureViewport;
30
213
  private getTasks;
214
+ private seedCollapsed;
31
215
  private getLinks;
32
216
  private getVisibleTasks;
33
217
  private bumpOverrides;
34
- protected shouldRenderOnAttributeChange(name: string, _oldValue: string | null, _newValue: string | null): boolean;
218
+ protected shouldRenderOnAttributeChange(name: string, oldValue: string | null, newValue: string | null): boolean;
35
219
  }
36
220
  //# sourceMappingURL=ui-gantt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ui-gantt.d.ts","sourceRoot":"","sources":["../../src/components/ui-gantt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA+/B7C,qBAAa,OAAQ,SAAQ,WAAW;IACtC,MAAM,KAAK,kBAAkB,aAE5B;IAED,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,cAAc,CAAO;IAC7B,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,YAAY,CAAqB;cAEtB,MAAM,IAAI,IAAI;IAmMjC,OAAO,CAAC,UAAU;IAgPlB,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,aAAa;cAMF,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO;CAU5H"}
1
+ {"version":3,"file":"ui-gantt.d.ts","sourceRoot":"","sources":["../../src/components/ui-gantt.ts"],"names":[],"mappings":"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"}