@operato/gantt 8.0.0-beta.0 β†’ 8.0.0-beta.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/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [8.0.0-beta.1](https://github.com/hatiolab/operato/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2025-01-08)
7
+
8
+
9
+ ### :bug: Bug Fix
10
+
11
+ * missing .npmignore ([be05985](https://github.com/hatiolab/operato/commit/be05985abfae4af53501f718dd52932099f7fbcb))
12
+
13
+
14
+
6
15
  ## [8.0.0-beta.0](https://github.com/hatiolab/operato/compare/v8.0.0-alpha.56...v8.0.0-beta.0) (2025-01-07)
7
16
 
8
17
  **Note:** Version bump only for package @operato/gantt
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/gantt",
3
3
  "description": "Webcomponents for gantt chart following open-wc recommendations",
4
4
  "author": "heartyoh@hatiolab.com",
5
- "version": "8.0.0-beta.0",
5
+ "version": "8.0.0-beta.1",
6
6
  "main": "dist/src/index.js",
7
7
  "module": "dist/src/index.js",
8
8
  "license": "MIT",
@@ -42,9 +42,9 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
- "@operato/i18n": "^8.0.0-beta.0",
46
- "@operato/styles": "^8.0.0-beta.0",
47
- "@operato/utils": "^8.0.0-beta.0",
45
+ "@operato/i18n": "^8.0.0-beta.1",
46
+ "@operato/styles": "^8.0.0-beta.1",
47
+ "@operato/utils": "^8.0.0-beta.1",
48
48
  "d3": "^7.8.5",
49
49
  "d3-time-format": "^4.1.0",
50
50
  "i18next": "^23.11.5",
@@ -85,5 +85,5 @@
85
85
  "prettier --write"
86
86
  ]
87
87
  },
88
- "gitHead": "c4e9cc245659d050a9ffd66542083a6daad4bcb9"
88
+ "gitHead": "d5b28a2e9deb632c0dc80132f6a7196dd6fe4220"
89
89
  }
package/.editorconfig DELETED
@@ -1,29 +0,0 @@
1
- # EditorConfig helps developers define and maintain consistent
2
- # coding styles between different editors and IDEs
3
- # editorconfig.org
4
-
5
- root = true
6
-
7
-
8
- [*]
9
-
10
- # Change these settings to your own preference
11
- indent_style = space
12
- indent_size = 2
13
-
14
- # We recommend you to keep these unchanged
15
- end_of_line = lf
16
- charset = utf-8
17
- trim_trailing_whitespace = true
18
- insert_final_newline = true
19
-
20
- [*.md]
21
- trim_trailing_whitespace = false
22
-
23
- [*.json]
24
- indent_size = 2
25
-
26
- [*.{html,js,md}]
27
- block_comment_start = /**
28
- block_comment = *
29
- block_comment_end = */
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- stories: ['../dist/stories/**/*.stories.{js,md,mdx}']
3
- }
@@ -1,52 +0,0 @@
1
- import { i18next } from '@operato/i18n'
2
-
3
- export const globalTypes = {
4
- locale: {
5
- name: 'Locale',
6
- description: 'Internationalization locale',
7
- toolbar: {
8
- icon: 'globe',
9
- items: [
10
- { value: 'en', right: 'πŸ‡ΊπŸ‡Έ', title: 'English' },
11
- { value: 'ko', right: 'πŸ‡°πŸ‡·', title: 'ν•œκ΅­μ–΄' },
12
- { value: 'zh', right: 'πŸ‡¨πŸ‡³', title: 'δΈ­ζ–‡' },
13
- { value: 'ja', right: 'πŸ‡―πŸ‡΅', title: 'ζ—₯本θͺž' },
14
- { value: 'ms', right: 'πŸ‡²πŸ‡Ύ', title: 'Bahasa Melayu' }
15
- ],
16
- showName: true
17
- }
18
- },
19
- theme: {
20
- name: 'Theme',
21
- description: 'Global theme for components',
22
- toolbar: {
23
- icon: 'paintbrush',
24
- items: [
25
- { value: 'light', title: 'Light' },
26
- { value: 'dark', title: 'Dark' }
27
- ],
28
- showName: true
29
- }
30
- }
31
- }
32
-
33
- export const decorators = [
34
- (Story, context) => {
35
- const { locale, theme } = context.globals
36
-
37
- if (locale) {
38
- i18next.changeLanguage(locale)
39
- }
40
-
41
- // Set the theme class for the document
42
- if (theme === 'dark') {
43
- document.documentElement.classList.add('dark')
44
- document.documentElement.classList.remove('light')
45
- } else {
46
- document.documentElement.classList.add('light')
47
- document.documentElement.classList.remove('dark')
48
- }
49
-
50
- return Story()
51
- }
52
- ]
@@ -1,8 +0,0 @@
1
- import { storybookPlugin } from '@web/dev-server-storybook'
2
- import baseConfig from '../web-dev-server.config.mjs'
3
-
4
- export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
5
- ...baseConfig,
6
- open: '/',
7
- plugins: [storybookPlugin({ type: 'web-components' }), ...baseConfig.plugins]
8
- })
@@ -1,142 +0,0 @@
1
- import * as d3 from 'd3'
2
- import { TimeScale } from './types'
3
-
4
- export function drawTimeScaleHeader(
5
- svgHeader: SVGElement,
6
- timeScale: d3.ScaleTime<number, number, never>,
7
- fromTime: Date,
8
- toTime: Date,
9
- baseWidth: number,
10
- level: TimeScale,
11
- isTwoLevelHeader: boolean = true
12
- ) {
13
- const header = d3.select(svgHeader)
14
-
15
- header.selectAll('*').remove()
16
- header.attr('width', getChartWidth(fromTime, toTime, baseWidth, level))
17
-
18
- if (!isTwoLevelHeader) {
19
- header.attr('height', '30px')
20
- } else {
21
- header.attr('height', '40px')
22
- }
23
-
24
- const addGridLines = (ticks: Date[], yStart: number, yEnd: number) => {
25
- ticks.forEach(tick => {
26
- const startX = timeScale(tick)
27
- header
28
- .append('line')
29
- .attr('x1', startX)
30
- .attr('x2', startX)
31
- .attr('y1', yStart)
32
- .attr('y2', yEnd)
33
- .attr('stroke', 'var(--ox-gantt-color-gridlines, var(--md-sys-color-outline))')
34
- .attr('stroke-width', 1)
35
- })
36
- }
37
-
38
- const centerLabel = (
39
- selection: d3.Selection<SVGGElement, unknown, null, undefined>,
40
- tickInterval: d3.CountableTimeInterval
41
- ) => {
42
- selection.selectAll('text').attr('transform', (d: any) => {
43
- const tickIntervalWidth = timeScale(tickInterval.offset(d, 1)) - timeScale(d)
44
- return `translate(${tickIntervalWidth / 2}, ${isTwoLevelHeader ? -2 : -8})`
45
- })
46
- }
47
-
48
- const drawLevel = (
49
- mainTicks: Date[],
50
- mainFormat: (d: Date) => string,
51
- mainInterval: d3.CountableTimeInterval,
52
- detailTicks: Date[],
53
- detailFormat: (d: Date) => string,
54
- detailInterval: d3.CountableTimeInterval
55
- ) => {
56
- if (isTwoLevelHeader) {
57
- const mainAxis = d3
58
- .axisTop(timeScale)
59
- .ticks(mainInterval)
60
- .tickFormat(mainFormat as any)
61
- .tickSize(0)
62
- addGridLines(mainTicks, 0, 20)
63
-
64
- const mainAxisG = header
65
- .append('g')
66
- .classed('main-axis no-select md-typescale-label-small', true)
67
- .attr('transform', 'translate(0, 20)')
68
- .call(mainAxis)
69
-
70
- centerLabel(mainAxisG, mainInterval)
71
- }
72
-
73
- const detailAxis = d3
74
- .axisTop(timeScale)
75
- .ticks(detailInterval)
76
- .tickFormat(detailFormat as any)
77
- .tickSize(0)
78
- addGridLines(detailTicks, isTwoLevelHeader ? 20 : 0, isTwoLevelHeader ? 40 : 30)
79
-
80
- const detailAxisG = header
81
- .append('g')
82
- .classed('detail-axis no-select md-typescale-label-small', true)
83
- .attr('transform', `translate(0, ${isTwoLevelHeader ? 40 : 30})`)
84
- .call(detailAxis)
85
-
86
- centerLabel(detailAxisG, detailInterval)
87
- }
88
-
89
- if (level === 'week-day') {
90
- drawLevel(
91
- d3.timeWeek.every(1)!.range(d3.timeWeek.floor(fromTime), d3.timeWeek.offset(toTime, 1)),
92
- d3.timeFormat('%B %d'),
93
- d3.timeWeek,
94
- d3.timeDay.every(1)!.range(d3.timeDay.floor(fromTime), d3.timeDay.offset(toTime, 1)),
95
- d3.timeFormat('%d'),
96
- d3.timeDay
97
- )
98
- } else if (level === 'quarter-week') {
99
- drawLevel(
100
- d3.timeMonth.every(3)!.range(d3.timeMonth.floor(fromTime), d3.timeMonth.offset(toTime, 3)),
101
- d3.timeFormat('%Y %b'),
102
- d3.timeMonth.every(3)! as any,
103
- d3.timeWeek.every(1)!.range(d3.timeWeek.floor(fromTime), d3.timeWeek.offset(toTime, 1)),
104
- d3.timeFormat('%b %d'),
105
- d3.timeWeek
106
- )
107
- } else if (level === 'year-month') {
108
- drawLevel(
109
- d3.timeYear.every(1)!.range(d3.timeYear.floor(fromTime), d3.timeYear.offset(toTime, 1)),
110
- d3.timeFormat('%Y'),
111
- d3.timeYear,
112
- d3.timeMonth.every(1)!.range(d3.timeMonth.floor(fromTime), d3.timeMonth.offset(toTime, 1)),
113
- d3.timeFormat('%b'),
114
- d3.timeMonth
115
- )
116
- } else if (level === 'year-quarter') {
117
- drawLevel(
118
- d3.timeYear.every(1)!.range(d3.timeYear.floor(fromTime), d3.timeYear.offset(toTime, 1)),
119
- d3.timeFormat('%Y'),
120
- d3.timeYear,
121
- d3.timeMonth.every(3)!.range(d3.timeMonth.floor(fromTime), d3.timeMonth.offset(toTime, 3)),
122
- d3.timeFormat('%Y %b'),
123
- d3.timeMonth.every(3)! as any
124
- )
125
- }
126
- }
127
-
128
- export function getChartWidth(fromTime: Date, toTime: Date, baseWidth: number, level: TimeScale): number {
129
- const totalDays = d3.timeDay.count(fromTime, d3.timeDay.offset(toTime, 1))
130
- return (totalDays * baseWidth) / getScale(level)
131
- }
132
-
133
- export function getScale(level: TimeScale): number {
134
- if (level === 'quarter-week') {
135
- return 7 / 2
136
- } else if (level === 'year-month') {
137
- return 30 / 2
138
- } else if (level === 'year-quarter') {
139
- return 90 / 2
140
- }
141
- return 1
142
- }
@@ -1,402 +0,0 @@
1
- import { LitElement, ReactiveController, ReactiveControllerHost } from 'lit'
2
- import * as d3 from 'd3'
3
- import { TimeScale, Task, TaskTag } from './types'
4
- import { OxTaskTooltip } from './ox-task-tooltip'
5
- import { drawTimeScaleHeader, getScale, getChartWidth } from './draw-time-scale-header'
6
- import { levelDown, levelUp } from './utils'
7
- import { GestureEventPinch, GestureEventDoubleTap, GestureEventDrag } from '@operato/utils/gesture-mixin.js'
8
-
9
- export class GanttChartController implements ReactiveController {
10
- private host: (ReactiveControllerHost & LitElement) | null
11
- private fromTime: Date
12
- private toTime: Date
13
- private totalDays: number
14
- private _timeScale?: d3.ScaleTime<number, number, never>
15
-
16
- private colorProvider?: (task: Task) => string
17
-
18
- public baseWidth: number = 30
19
- public level: TimeScale
20
- public selectedTaskId?: string
21
-
22
- public tasks: Task[] = []
23
- public extendGridLines: boolean = false
24
-
25
- constructor(host: ReactiveControllerHost & LitElement, fromDate: string, toDate: string, axisScale: TimeScale) {
26
- this.host = host
27
- this.fromTime = new Date(fromDate)
28
- this.toTime = new Date(toDate)
29
- this.level = axisScale
30
- this.totalDays = d3.timeDay.count(this.fromTime, d3.timeDay.offset(this.toTime, 1))
31
- this.host.addController(this)
32
- }
33
-
34
- dispose() {
35
- this.host = null
36
- }
37
-
38
- hostConnected() {
39
- this.updateTimeScale()
40
- }
41
-
42
- setColorProvider(colorProvider: (task: Task) => string) {
43
- this.colorProvider = colorProvider
44
- }
45
-
46
- get timeScale() {
47
- if (!this._timeScale) {
48
- this._timeScale = d3
49
- .scaleTime()
50
- .domain([d3.timeDay.floor(this.fromTime), d3.timeDay.offset(this.toTime, 1)])
51
- .range([0, this.getChartWidth()])
52
- }
53
- return this._timeScale
54
- }
55
-
56
- updateRange(fromDate: string, toDate: string) {
57
- this.fromTime = new Date(fromDate)
58
- this.toTime = new Date(toDate)
59
- this.totalDays = d3.timeDay.count(this.fromTime, d3.timeDay.offset(this.toTime, 1))
60
- this._timeScale = undefined
61
- this.host?.requestUpdate()
62
- }
63
-
64
- setTasks(tasks: Task[]) {
65
- this.tasks = tasks
66
- this.host?.requestUpdate()
67
- }
68
-
69
- updateTimeScale() {
70
- this.timeScale.range([0, this.getChartWidth()])
71
- }
72
-
73
- getScale() {
74
- return getScale(this.level)
75
- }
76
-
77
- getChartWidth() {
78
- return getChartWidth(this.fromTime, this.toTime, this.baseWidth, this.level)
79
- }
80
-
81
- drawAxes(svgHeader: SVGElement) {
82
- drawTimeScaleHeader(svgHeader, this.timeScale, this.fromTime, this.toTime, this.baseWidth, this.level)
83
- }
84
-
85
- drawBody(svgBody: SVGElement, tooltip: OxTaskTooltip) {
86
- const body = d3.select(svgBody)
87
-
88
- body.selectAll('*').remove()
89
- body.attr('width', this.getChartWidth())
90
-
91
- // Define the arrow marker
92
- const defs = body.append('defs')
93
- defs
94
- .append('marker')
95
- .attr('id', 'arrow')
96
- .attr('viewBox', '0 0 10 10')
97
- .attr('refX', 10)
98
- .attr('refY', 5)
99
- .attr('markerWidth', 6)
100
- .attr('markerHeight', 6)
101
- .attr('orient', 'auto-start-reverse')
102
- .append('path')
103
- .attr('d', 'M 0 0 L 10 5 L 0 10 z')
104
- .attr('fill', 'var(--md-sys-color-on-primary-container, black)')
105
-
106
- if (this.extendGridLines) {
107
- const addGridLines = (ticks: Date[]) => {
108
- ticks.forEach(tick => {
109
- const startX = this.timeScale(tick)
110
- body
111
- .append('line')
112
- .attr('x1', startX)
113
- .attr('x2', startX)
114
- .attr('y1', 0)
115
- .attr('y2', Number(svgBody.getBoundingClientRect().height) || 0)
116
- .attr('stroke', 'var(--ox-gantt-color-gridlines, var(--md-sys-color-outline))')
117
- .attr('stroke-width', 1)
118
- })
119
- }
120
-
121
- if (this.level === 'week-day') {
122
- const dayTicks = d3.timeDay.every(1)!.range(d3.timeDay.floor(this.fromTime), d3.timeDay.offset(this.toTime, 1))
123
- addGridLines(dayTicks)
124
- } else if (this.level === 'quarter-week') {
125
- const weekTicks = d3.timeWeek
126
- .every(1)!
127
- .range(d3.timeWeek.floor(this.fromTime), d3.timeWeek.offset(this.toTime, 1))
128
- addGridLines(weekTicks)
129
- } else if (this.level === 'year-month') {
130
- const monthTicks = d3.timeMonth
131
- .every(1)!
132
- .range(d3.timeMonth.floor(this.fromTime), d3.timeMonth.offset(this.toTime, 1))
133
- addGridLines(monthTicks)
134
- } else if (this.level === 'year-quarter') {
135
- const quarterTicks = d3.timeMonth
136
- .every(3)!
137
- .range(d3.timeMonth.floor(this.fromTime), d3.timeMonth.offset(this.toTime, 3))
138
- addGridLines(quarterTicks)
139
- }
140
- }
141
-
142
- const taskPositions: { [key: string]: { x: number; y: number; width: number } } = {}
143
-
144
- this.tasks.forEach((task, index) => {
145
- const startDate = new Date(task.startDate)
146
- const endDate = new Date(task.endDate)
147
-
148
- const startX = this.timeScale(d3.timeDay.floor(d3.min([startDate, endDate])!))
149
- const endX = this.timeScale(d3.timeDay.offset(d3.timeDay.ceil(d3.max([startDate, endDate])!), -1))
150
-
151
- const taskWidth = endX - startX + this.baseWidth / this.getScale()
152
- const taskY = index * 30 + 7.5
153
-
154
- const showTooltip = (event: MouseEvent | TouchEvent) => {
155
- tooltip.hide()
156
-
157
- const touch = 'touches' in event
158
- const x = touch ? event.touches[0].clientX : event.clientX
159
- const y = touch ? event.touches[0].clientY : event.clientY
160
-
161
- tooltip.title = task.title
162
- tooltip.startDate = startDate.toISOString().split('T')[0]
163
- tooltip.endDate = endDate.toISOString().split('T')[0]
164
- tooltip.progress = task.progress ?? 0
165
- tooltip.type = task.type
166
-
167
- tooltip.show(x, y)
168
- }
169
-
170
- const hideTooltip = () => {
171
- tooltip.hide()
172
- }
173
-
174
- if (this.selectedTaskId === task.id) {
175
- body
176
- .append('rect')
177
- .attr('x', 0)
178
- .attr('y', taskY - 7.5)
179
- .attr('width', this.getChartWidth())
180
- .attr('height', 30)
181
- .attr('fill', 'var(--ox-gantt-selected-row-background-color, var(--md-sys-color-surface-variant))')
182
- }
183
-
184
- const taskBar = body
185
- .append('rect')
186
- .attr('x', startX)
187
- .attr('y', taskY)
188
- .attr('width', taskWidth)
189
- .attr('height', 15)
190
- .attr('fill', this.colorProvider ? this.colorProvider(task) : 'gray')
191
- .attr('stroke', 'black')
192
- .attr('stroke-width', 1)
193
-
194
- taskBar
195
- .on('click', e => {
196
- this.selectedTaskId = task.id
197
- const customEvent = new CustomEvent('task-clicked', {
198
- detail: { taskId: task.id },
199
- bubbles: true,
200
- composed: true
201
- })
202
-
203
- showTooltip(e)
204
-
205
- this.host?.dispatchEvent(customEvent)
206
- this.host?.requestUpdate()
207
- })
208
- .on('mouseover', showTooltip)
209
- .on('mouseout', hideTooltip)
210
-
211
- if (task.progress !== undefined) {
212
- const progressWidth = taskWidth * (task.progress / 100)
213
- const progressBar = body
214
- .append('rect')
215
- .attr('x', startX)
216
- .attr('y', taskY + 7.5 - 3.75)
217
- .attr('width', progressWidth)
218
- .attr('height', 7.5)
219
- .attr('fill', 'lightgreen')
220
-
221
- progressBar
222
- .on('click', e => {
223
- this.selectedTaskId = task.id
224
- const customEvent = new CustomEvent('task-clicked', {
225
- detail: { taskId: task.id },
226
- bubbles: true,
227
- composed: true
228
- })
229
-
230
- showTooltip(e)
231
-
232
- this.host?.dispatchEvent(customEvent)
233
- this.host?.requestUpdate()
234
- })
235
- .on('mouseover', showTooltip)
236
- .on('mouseout', hideTooltip)
237
- }
238
-
239
- taskPositions[task.id] = { x: endX + this.baseWidth / this.getScale(), y: taskY + 7.5, width: taskWidth }
240
- })
241
-
242
- this.tasks.forEach(task => {
243
- if (task.dependsOn && taskPositions[task.dependsOn]) {
244
- const prevTask = taskPositions[task.dependsOn]
245
- const currTask = taskPositions[task.id]
246
-
247
- body
248
- .append('path')
249
- .attr(
250
- 'd',
251
- `
252
- M${prevTask.x},${prevTask.y}
253
- L${prevTask.x + 10},${prevTask.y}
254
- ${
255
- prevTask.x + 10 < currTask.x - 10 - currTask.width
256
- ? `
257
- L${(prevTask.x + currTask.x - currTask.width) / 2},${prevTask.y}
258
- L${(prevTask.x + currTask.x - currTask.width) / 2},${currTask.y}
259
- `
260
- : `
261
- L${prevTask.x + 10},${(prevTask.y + currTask.y) / 2}
262
- L${currTask.x - 10 - currTask.width},${(prevTask.y + currTask.y) / 2}
263
- `
264
- }
265
- L${currTask.x - 10 - currTask.width},${currTask.y}
266
- L${currTask.x - currTask.width},${currTask.y}
267
- `
268
- )
269
- .attr('stroke', 'var(--md-sys-color-on-primary-container, black)')
270
- .attr('fill', 'none')
271
- .attr('stroke-width', 1)
272
- .attr('marker-end', 'url(#arrow)')
273
- }
274
- })
275
- }
276
-
277
- getTaskColor(tags: TaskTag[]): string {
278
- if (tags.includes('critical')) {
279
- return 'red'
280
- } else if (tags.includes('milestone')) {
281
- return 'blue'
282
- } else if (tags.includes('done')) {
283
- return 'green'
284
- } else {
285
- return 'grey'
286
- }
287
- }
288
-
289
- handleWheelForBody(event: WheelEvent, container: HTMLDivElement) {
290
- event.preventDefault()
291
- event.stopPropagation()
292
-
293
- const { offsetHeight } = container
294
-
295
- const deltaModeFactor =
296
- event.deltaMode === WheelEvent.DOM_DELTA_LINE
297
- ? 16
298
- : event.deltaMode === WheelEvent.DOM_DELTA_PAGE
299
- ? container.clientHeight
300
- : 1
301
- const deltaX = event.deltaX * deltaModeFactor
302
- const deltaY = event.deltaY * deltaModeFactor
303
-
304
- // κ°€λ‘œ 슀크둀 및 μ„Έλ‘œ 슀크둀 λͺ¨λ‘ 처리
305
- container.scrollLeft += deltaX
306
- // container.scrollTop += deltaY
307
- container.scrollTop = Math.min(this.tasks.length * 30 - (offsetHeight - 40), container.scrollTop + deltaY)
308
-
309
- const customEvent = new CustomEvent('scroll', {
310
- detail: {
311
- scrollLeft: container.scrollLeft,
312
- scrollTop: container.scrollTop
313
- },
314
- bubbles: true,
315
- composed: true
316
- })
317
-
318
- this.host?.dispatchEvent(customEvent)
319
- }
320
-
321
- handlePinchForBody = (event: GestureEventPinch) => {
322
- const { scale } = event.detail
323
-
324
- this.baseWidth *= scale
325
-
326
- if (this.baseWidth > 40) {
327
- if (this.level === 'week-day') {
328
- this.baseWidth = 40
329
- } else {
330
- this.level = levelDown(this.level)
331
- this.baseWidth = 30
332
- }
333
- } else if (this.baseWidth < 30) {
334
- if (this.level === 'year-quarter') {
335
- this.baseWidth = 30
336
- }
337
- }
338
-
339
- if (this.baseWidth < 20) {
340
- this.level = levelUp(this.level)
341
- this.baseWidth = 30
342
- }
343
-
344
- this.updateTimeScale()
345
- this.host?.requestUpdate()
346
-
347
- const customEvent = new CustomEvent('timescale-changed', {
348
- detail: {
349
- baseWidth: this.baseWidth,
350
- level: this.level
351
- },
352
- bubbles: true,
353
- composed: true
354
- })
355
-
356
- this.host?.dispatchEvent(customEvent)
357
- }
358
-
359
- handleDoubleTapForBody = (event: GestureEventDoubleTap) => {
360
- const container = (this.host as any).container
361
-
362
- container.scrollLeft = 0
363
- container.scrollTop = 0
364
-
365
- this.baseWidth = 30
366
- this.level = 'week-day'
367
-
368
- this.updateTimeScale()
369
- this.host?.requestUpdate()
370
-
371
- const customEvent = new CustomEvent('timescale-changed', {
372
- detail: {
373
- baseWidth: this.baseWidth,
374
- level: this.level
375
- },
376
- bubbles: true,
377
- composed: true
378
- })
379
-
380
- this.host?.dispatchEvent(customEvent)
381
- }
382
-
383
- handleDragForBody = (event: GestureEventDrag) => {
384
- const { deltaX: dx, deltaY: dy } = event.detail
385
- const container = (this.host as any).container
386
- const { offsetHeight } = container
387
-
388
- container.scrollLeft -= dx
389
- container.scrollTop = Math.min(this.tasks.length * 30 - (offsetHeight - 40), container.scrollTop - dy)
390
-
391
- const customEvent = new CustomEvent('scroll', {
392
- detail: {
393
- scrollLeft: container.scrollLeft,
394
- scrollTop: container.scrollTop
395
- },
396
- bubbles: true,
397
- composed: true
398
- })
399
-
400
- this.host?.dispatchEvent(customEvent)
401
- }
402
- }
package/src/index.ts DELETED
File without changes