Зібрав headless-компонент таймлайну та ґанту для React

💡 Усі статті, обговорення, новини про Front-end — в одному місці. Приєднуйтесь до Front-end спільноти!

Мені потрібен був екран планування, який лишається швидким на великій кількості елементів і виглядає так само, як решта застосунку. Готові рішення або тягнули за собою власні стилі, які доводилося перебивати, або починали гальмувати на кількох тисячах елементів. Тож я зібрав компонент сам — і він виріс у бібліотеку.

Two months per screen: nested rows with roll-up brackets above them, FS dependency arrows between bars, a milestone diamond and the today marker

Roadline — це headless timeline/Gantt для React, без рантайм-залежностей. Демо за цим посиланням.

import { Timeline, useTimeline } from '@roadline/react' 
import '@roadline/styles/roadline.css

const timeline = useTimeline({
  items,
  groups,
  defaultRange: { start, end },
  snap: 'day',
  onItemMove: ({ itemId, start, end }) => update(itemId, start, end),
})

return (
  <Timeline.Root instance={timeline} style={{ height: 400 }}>
    <Timeline.Sidebar />
    <Timeline.Header />
    <Timeline.Body>
      <Timeline.Grid />
    </Timeline.Body>
  </Timeline.Root>
)`

Тягнеш бар — рухається, тягнеш за краї — змінюється тривалість, скрол — панорама, ctrl/cmd + колесо — зум. Елемент без тривалості малюється як віха.

Що всередині:

  • Віртуалізація по обох осях, елементи проіндексовані за часом — великі дошки лишаються плавними
  • Headless: Sidebar, Header, Body, Grid, Dependencies, Marker — окремі частини, які рендериш або пропускаєш, а бари — це render props. Типова тема — необовʼязковий стайлшит на CSS-змінних, а не стилі, впорснуті з JS
  • Стрілки залежностей між задачами (FS, SS, FF, SF)
  • Вкладені елементи зі згорнутим баром батька, а не лише групи
  • Будь-яка зона IANA на інстанс, коректно з переходом на літній час
  • Редагування з клавіатури з озвученням для скрінрідерів
  • Повністю керований компонент: хук володіє вʼюпортом, даними володієш ти. onItemMove — це запит, нічого не рухається, доки не зміниться твій масив
  • 15 кБ gzip, React 18/19, ESM + CJS, працює в Next.js App Router

Версія 0.2.0, тож фіксуйте її — я ще можу щось змінити. Тільки сучасні браузери: ResizeObserver, PointerEvent, Intl.DateTimeFormat.formatToParts без поліфілів.

Буду вдячний за фідбек — особливо про відчуття від перетягування та зуму в демо і про те, чи зрозуміла вам форма API.

👍ПодобаєтьсяСподобалось3
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Фідбек:

  1. Відчуття перетягування та зуму дискомфорту не викликають.
  2. Не знайшов можливості видалити залежність.
  3. При зміні EndDate в задачі, варто автоматом зміщувати усі залежні задачі і їх підзадачі на відповідну к-сть днів. Цієї фічі дуже не вистачає в Jira Plans.

Підписатись на коментарі