2
0
mirror of https://github.com/tenrok/vue-ganttastic.git synced 2026-06-25 03:30:34 +03:00

BEM methodology

This commit is contained in:
2021-12-01 14:16:03 +03:00
parent 3ca4d05082
commit 723d346605
7 changed files with 138 additions and 134 deletions
+1 -1
View File
@@ -116,7 +116,7 @@ The following code showcases a simple usage example in a .vue SFC (Single File C
@import '~@tenrok/vue-ganttastic/dist/vue-ganttastic.css'; @import '~@tenrok/vue-ganttastic/dist/vue-ganttastic.css';
/* Custom */ /* Custom */
.g-grid-line-highlighted { .g-gantt-line-highlighted {
background: #ffb0b0 !important; background: #ffb0b0 !important;
} }
</style> </style>
+14 -10
View File
@@ -1,8 +1,12 @@
<template> <template>
<div> <div>
<div <div
ref="g-gantt-bar" ref="g-bar"
:class="['g-gantt-bar', { 'g-gantt-bar-immobile': barConfig.immobile }]" :class="[
'g-gantt-bar',
{ 'g-gantt-bar-immobile': barConfig.immobile },
{ 'g-gantt-bar-resizable': barConfig.handles }
]"
:style="barStyle" :style="barStyle"
@mouseenter.stop="onMouseenter($event)" @mouseenter.stop="onMouseenter($event)"
@mouseleave.stop="onMouseleave($event)" @mouseleave.stop="onMouseleave($event)"
@@ -11,21 +15,21 @@
@dblclick="onDblclick($event)" @dblclick="onDblclick($event)"
@contextmenu="onContextmenu($event)" @contextmenu="onContextmenu($event)"
> >
<div class="g-gantt-bar-label"> <div class="g-gantt-bar__label">
<slot name="bar-label" :bar="localBar"> <slot name="bar-label" :bar="localBar">
{{ barConfig.label || '' }} {{ barConfig.label || '' }}
</slot> </slot>
</div> </div>
<template v-if="barConfig.handles"> <template v-if="barConfig.handles">
<div class="g-gantt-bar-handle-left" /> <div class="g-gantt-bar__handle-left" />
<div class="g-gantt-bar-handle-right" /> <div class="g-gantt-bar__handle-right" />
</template> </template>
</div> </div>
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
<div <div
v-if="!barConfig.noTooltip && (showTooltip || isDragging)" v-if="!barConfig.noTooltip && (showTooltip || isDragging)"
class="g-gantt-tooltip" class="g-gantt-bar__tooltip"
:style="tooltipStyle" :style="tooltipStyle"
> >
<div <div
@@ -287,15 +291,15 @@ export default {
this.barStartBeforeDrag = this.localBar[this.barStartKey] this.barStartBeforeDrag = this.localBar[this.barStartKey]
this.barEndBeforeDrag = this.localBar[this.barEndKey] this.barEndBeforeDrag = this.localBar[this.barEndKey]
let barX = this.$refs['g-gantt-bar'].getBoundingClientRect().left let barX = this.$refs['g-bar'].getBoundingClientRect().left
this.cursorOffsetX = e.clientX - barX this.cursorOffsetX = e.clientX - barX
let mousedownType = e.target.className let mousedownType = e.target.className
switch (mousedownType) { switch (mousedownType) {
case 'g-gantt-bar-handle-left': case 'g-gantt-bar__handle-left':
document.body.style.cursor = 'w-resize' document.body.style.cursor = 'w-resize'
this.mousemoveCallback = this.dragByHandleLeft this.mousemoveCallback = this.dragByHandleLeft
break break
case 'g-gantt-bar-handle-right': case 'g-gantt-bar__handle-right':
document.body.style.cursor = 'e-resize' document.body.style.cursor = 'e-resize'
this.mousemoveCallback = this.dragByHandleRight this.mousemoveCallback = this.dragByHandleRight
break break
@@ -315,7 +319,7 @@ export default {
drag(e) { drag(e) {
const chart = e.target.closest('.g-gantt-chart') const chart = e.target.closest('.g-gantt-chart')
if (!chart) return if (!chart) return
let barWidth = this.$refs['g-gantt-bar'].getBoundingClientRect().width let barWidth = this.$refs['g-bar'].getBoundingClientRect().width
let newXStart = let newXStart =
chart.scrollLeft + chart.scrollLeft +
e.clientX - e.clientX -
+15 -20
View File
@@ -334,12 +334,11 @@ export default {
}) })
} }
if (totalGapDistance != null && side === 'left') { if (totalGapDistance != null && side === 'left') {
bar.dragLimitLeft = bar.dragLimitLeft = bar.$refs['g-bar'].offsetLeft - totalGapDistance
bar.$refs['g-gantt-bar'].offsetLeft - totalGapDistance
} else if (totalGapDistance != null && side === 'right') { } else if (totalGapDistance != null && side === 'right') {
bar.dragLimitRight = bar.dragLimitRight =
bar.$refs['g-gantt-bar'].offsetLeft + bar.$refs['g-bar'].offsetLeft +
bar.$refs['g-gantt-bar'].offsetWidth + bar.$refs['g-bar'].offsetWidth +
totalGapDistance totalGapDistance
} }
} }
@@ -371,10 +370,10 @@ export default {
if (side === 'left') { if (side === 'left') {
while (nextBar) { while (nextBar) {
let nextBarOffsetRight = let nextBarOffsetRight =
nextBar.$refs['g-gantt-bar'].offsetLeft + nextBar.$refs['g-bar'].offsetLeft +
nextBar.$refs['g-gantt-bar'].offsetWidth nextBar.$refs['g-bar'].offsetWidth
gapDistanceSoFar += gapDistanceSoFar +=
currentBar.$refs['g-gantt-bar'].offsetLeft - nextBarOffsetRight currentBar.$refs['g-bar'].offsetLeft - nextBarOffsetRight
if ( if (
nextBar.barConfig.immobile || nextBar.barConfig.immobile ||
(nextBar.barConfig.isShadow && !ignoreShadows) (nextBar.barConfig.isShadow && !ignoreShadows)
@@ -393,10 +392,10 @@ export default {
if (side === 'right') { if (side === 'right') {
while (nextBar) { while (nextBar) {
let currentBarOffsetRight = let currentBarOffsetRight =
currentBar.$refs['g-gantt-bar'].offsetLeft + currentBar.$refs['g-bar'].offsetLeft +
currentBar.$refs['g-gantt-bar'].offsetWidth currentBar.$refs['g-bar'].offsetWidth
gapDistanceSoFar += gapDistanceSoFar +=
nextBar.$refs['g-gantt-bar'].offsetLeft - currentBarOffsetRight nextBar.$refs['g-bar'].offsetLeft - currentBarOffsetRight
if ( if (
nextBar.barConfig.immobile || nextBar.barConfig.immobile ||
(nextBar.barConfig.isShadow && !ignoreShadows) (nextBar.barConfig.isShadow && !ignoreShadows)
@@ -422,9 +421,8 @@ export default {
return ( return (
gBar.$options.name === GGanttBar.name && gBar.$options.name === GGanttBar.name &&
gBar.$parent === bar.$parent && gBar.$parent === bar.$parent &&
gBar.$refs['g-gantt-bar'] && gBar.$refs['g-bar'] &&
gBar.$refs['g-gantt-bar'].offsetLeft < gBar.$refs['g-bar'].offsetLeft < bar.$refs['g-bar'].offsetLeft &&
bar.$refs['g-gantt-bar'].offsetLeft &&
gBar.barConfig.pushOnOverlap !== false gBar.barConfig.pushOnOverlap !== false
) )
}) })
@@ -433,9 +431,8 @@ export default {
return ( return (
gBar.$options.name === GGanttBar.name && gBar.$options.name === GGanttBar.name &&
gBar.$parent === bar.$parent && gBar.$parent === bar.$parent &&
gBar.$refs['g-gantt-bar'] && gBar.$refs['g-bar'] &&
gBar.$refs['g-gantt-bar'].offsetLeft > gBar.$refs['g-bar'].offsetLeft > bar.$refs['g-bar'].offsetLeft &&
bar.$refs['g-gantt-bar'].offsetLeft &&
gBar.barConfig.pushOnOverlap !== false gBar.barConfig.pushOnOverlap !== false
) )
}) })
@@ -443,12 +440,10 @@ export default {
if (allBarsLeftOrRight.length > 0) { if (allBarsLeftOrRight.length > 0) {
return allBarsLeftOrRight.reduce((bar1, bar2) => { return allBarsLeftOrRight.reduce((bar1, bar2) => {
let bar1Dist = Math.abs( let bar1Dist = Math.abs(
bar1.$refs['g-gantt-bar'].offsetLeft - bar1.$refs['g-bar'].offsetLeft - bar.$refs['g-bar'].offsetLeft
bar.$refs['g-gantt-bar'].offsetLeft
) )
let bar2Dist = Math.abs( let bar2Dist = Math.abs(
bar2.$refs['g-gantt-bar'].offsetLeft - bar2.$refs['g-bar'].offsetLeft - bar.$refs['g-bar'].offsetLeft
bar.$refs['g-gantt-bar'].offsetLeft
) )
return bar1Dist < bar2Dist ? bar1 : bar2 return bar1Dist < bar2Dist ? bar1 : bar2
}, allBarsLeftOrRight[0]) }, allBarsLeftOrRight[0])
+4 -5
View File
@@ -1,16 +1,15 @@
<template> <template>
<div <div
ref="g-grid-container" class="g-gantt-grid"
class="g-grid-container"
:style="{ left: `${rowLabelWidth}px`, width: `${timeCount * gridSize}px` }" :style="{ left: `${rowLabelWidth}px`, width: `${timeCount * gridSize}px` }"
> >
<div <div
v-for="(childPoint, index) in allChildPoints" v-for="(childPoint, index) in allChildPoints"
:key="index" :key="index"
:class="[ :class="[
'g-grid-line', 'g-gantt-grid__line',
{ 'g-grid-line-last': index === allChildPoints.length - 1 }, { 'g-gantt-grid-line-last': index === allChildPoints.length - 1 },
{ 'g-grid-line-highlighted': isHighlighted(childPoint) } { 'g-gantt-line-highlighted': isHighlighted(childPoint) }
]" ]"
:style="{ width: `${gridSize}px` }" :style="{ width: `${gridSize}px` }"
/> />
+7 -7
View File
@@ -1,17 +1,17 @@
<template> <template>
<div <div
ref="g-row"
class="g-gantt-row" class="g-gantt-row"
ref="g-gantt-row"
:style="{ height: `${chartProps.rowHeight}px` }" :style="{ height: `${chartProps.rowHeight}px` }"
v-on="$listeners" v-on="$listeners"
> >
<div class="g-gantt-row-label" :style="rowLabelStyle"> <div class="g-gantt-row__label" :style="rowLabelStyle">
<span :title="label"> <span :title="label">
<slot name="label">{{ label }}</slot> <slot name="label">{{ label }}</slot>
</span> </span>
</div> </div>
<div <div
class="g-gantt-row-bars-container" class="g-gantt-row__bars-container"
ref="barContainer" ref="barContainer"
:style="rowStyle" :style="rowStyle"
@dragover="onDragover($event)" @dragover="onDragover($event)"
@@ -151,13 +151,13 @@ export default {
onDragover(e) { onDragover(e) {
e.preventDefault() // enables dropping content on row e.preventDefault() // enables dropping content on row
if (this.highlightOnHover) { if (this.highlightOnHover) {
this.$refs['g-gantt-row'].style.backgroundColor = this.$refs['g-row'].style.backgroundColor =
this.themeColors.hoverHighlight this.themeColors.hoverHighlight
} }
}, },
onDragleave() { onDragleave() {
this.$refs['g-gantt-row'].style.backgroundColor = null this.$refs['g-row'].style.backgroundColor = null
}, },
onDrop(e) { onDrop(e) {
@@ -199,13 +199,13 @@ export default {
onMouseover() { onMouseover() {
if (this.highlightOnHover) { if (this.highlightOnHover) {
this.$refs['g-gantt-row'].style.backgroundColor = this.$refs['g-row'].style.backgroundColor =
this.themeColors.hoverHighlight this.themeColors.hoverHighlight
} }
}, },
onMouseleave() { onMouseleave() {
this.$refs['g-gantt-row'].style.backgroundColor = null this.$refs['g-row'].style.backgroundColor = null
}, },
onWindowResize() { onWindowResize() {
+10 -8
View File
@@ -1,21 +1,21 @@
<template> <template>
<div <div
ref="g-timeaxis" ref="g-timeaxis"
class="g-timeaxis" class="g-gantt-timeaxis"
:style="{ width: `${timeCount * gridSize + rowLabelWidth}px` }" :style="{ width: `${timeCount * gridSize + rowLabelWidth}px` }"
> >
<div <div
class="g-timeaxis-empty-space" class="g-gantt-timeaxis__empty-space"
:style="{ :style="{
minWidth: `${rowLabelWidth}px`, minWidth: `${rowLabelWidth}px`,
background: themeColors.secondary background: themeColors.secondary
}" }"
/> />
<div class="g-timeaxis-days"> <div class="g-gantt-timeaxis__days">
<div <div
v-for="(point, index) in axisPoints" v-for="(point, index) in axisPoints"
:key="point.text" :key="point.text"
class="g-timeaxis-day" class="g-gantt-timeaxis__day"
:style="{ :style="{
background: background:
index % 2 === 0 ? themeColors.primary : themeColors.secondary, index % 2 === 0 ? themeColors.primary : themeColors.secondary,
@@ -29,7 +29,7 @@
<div <div
v-for="(childPoint, index) in point.childPoints" v-for="(childPoint, index) in point.childPoints"
:key="childPoint.fullDatetime" :key="childPoint.fullDatetime"
class="g-timeaxis-hour" class="g-gantt-timeaxis__hour"
:style="{ :style="{
width: `${gridSize}px`, width: `${gridSize}px`,
background: background:
@@ -41,14 +41,14 @@
childPoint.text childPoint.text
}}</span> }}</span>
<div <div
class="g-timeaxis-hour-pin" class="g-gantt-timeaxis__hour-pin"
:style="{ background: themeColors.text }" :style="{ background: themeColors.text }"
/> />
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div ref="g-timeaxis-marker" class="g-timeaxis-marker" /> <div ref="g-timeaxis-marker" class="g-gantt-timeaxis__marker" />
</div> </div>
</template> </template>
@@ -110,7 +110,9 @@ export default {
methods: { methods: {
initAxis() { initAxis() {
this.precision === 'day'? this.initAxisDaysAndHours() : this.initAxisMonthsAndDays() this.precision === 'day'
? this.initAxisDaysAndHours()
: this.initAxisMonthsAndDays()
}, },
initAxisMonthsAndDays() { initAxisMonthsAndDays() {
+87 -83
View File
@@ -10,20 +10,20 @@
padding-bottom: 34px; padding-bottom: 34px;
border: 1px solid #eaeaea; border: 1px solid #eaeaea;
box-sizing: border-box; box-sizing: border-box;
& >>> * {
font-family: Roboto, Verdana;
}
} }
.g-gantt-chart >>> * { .g-gantt-timeaxis,
font-family: Roboto, Verdana; .g-gantt-timeaxis__days,
} .g-gantt-timeaxis__day,
.g-gantt-timeaxis__day > div {
.g-timeaxis,
.g-timeaxis-days,
.g-timeaxis-day,
.g-timeaxis-day > div {
display: flex; display: flex;
} }
.g-timeaxis { .g-gantt-timeaxis {
position: sticky; position: sticky;
top: 0; top: 0;
background: white; background: white;
@@ -31,7 +31,7 @@
box-shadow: 0px 1px 3px 2px rgba(50, 50, 50, 0.5); box-shadow: 0px 1px 3px 2px rgba(50, 50, 50, 0.5);
} }
.g-timeaxis > .g-timeaxis-empty-space { .g-gantt-timeaxis__empty-space {
min-height: 100%; min-height: 100%;
background: #f5f5f5; background: #f5f5f5;
z-index: 5; z-index: 5;
@@ -39,40 +39,40 @@
position: sticky; position: sticky;
} }
.g-timeaxis > .g-timeaxis-days { .g-gantt-timeaxis__days {
position: relative; position: relative;
height: 100%; height: 100%;
} }
.g-timeaxis-day { .g-gantt-timeaxis__day {
height: 100%; height: 100%;
flex-direction: column; flex-direction: column;
background: #e0e0e0; background: #e0e0e0;
&:nth-child(odd) {
background: #e8e8e8;
}
& > div:nth-child(1) {
/* day text */
height: 50%;
justify-content: space-around;
font-weight: bold;
align-items: center;
}
& > div:nth-child(2) {
/* hours of a day */
align-items: flex-end;
height: 50%;
justify-content: space-between;
background: #f5f5f5;
padding-top: 2px;
color: #212121;
}
} }
.g-timeaxis-day:nth-child(odd) { .g-gantt-timeaxis__hour {
background: #e8e8e8;
}
.g-timeaxis-day > div:nth-child(1) {
/* day text */
height: 50%;
justify-content: space-around;
font-weight: bold;
align-items: center;
}
.g-timeaxis-day > div:nth-child(2) {
/* hours of a day */
align-items: flex-end;
height: 50%;
justify-content: space-between;
background: #f5f5f5;
padding-top: 2px;
color: #212121;
}
.g-timeaxis-hour {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: flex-start; align-items: flex-start;
@@ -80,12 +80,12 @@
opacity: 0.5; opacity: 0.5;
} }
.g-timeaxis-hour-pin { .g-gantt-timeaxis__hour-pin {
width: 1px; width: 1px;
height: 8px; height: 8px;
} }
.g-timeaxis-marker { .g-gantt-timeaxis__marker {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
@@ -98,14 +98,14 @@
position: relative; position: relative;
} }
.g-grid-container { .g-gantt-grid {
position: absolute; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;
overflow: hidden; overflow: hidden;
} }
.g-grid-line { .g-gantt-grid__line {
height: 100%; height: 100%;
border: 1px solid transparent; border: 1px solid transparent;
border-left: 1px solid #eaeaea; border-left: 1px solid #eaeaea;
@@ -113,11 +113,11 @@
display: inline-block; display: inline-block;
} }
.g-grid-line-last { .g-gantt-grid-line-last {
border-right: 1px solid #eaeaea; border-right: 1px solid #eaeaea;
} }
.g-grid-line-highlighted { .g-gantt-line-highlighted {
background: #dcefff; background: #dcefff;
} }
@@ -129,7 +129,7 @@
position: relative; position: relative;
} }
.g-gantt-row > .g-gantt-row-label { .g-gantt-row__label {
display: flex; display: flex;
align-items: center; align-items: center;
background: #e8e8e8; background: #e8e8e8;
@@ -143,15 +143,15 @@
box-sizing: border-box; box-sizing: border-box;
border-top: 1px solid #eaeaea; border-top: 1px solid #eaeaea;
border-bottom: 1px solid #eaeaea; border-bottom: 1px solid #eaeaea;
& > * {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
} }
.g-gantt-row > .g-gantt-row-label > * { .g-gantt-row__bars-container {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.g-gantt-row > .g-gantt-row-bars-container {
position: relative; position: relative;
border-top: 1px solid #eaeaea; border-top: 1px solid #eaeaea;
border-bottom: 1px solid #eaeaea; border-bottom: 1px solid #eaeaea;
@@ -178,24 +178,32 @@
cursor: unset; cursor: unset;
} }
.g-gantt-bar-label { .g-gantt-bar__label {
width: 100%; width: 100%;
height: 100%; height: 100%;
box-sizing: border-box; box-sizing: border-box;
padding: 0 14px 0 14px; /* 14px is the width of the handle */ padding: 0 4px 0 4px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
img {
pointer-events: none;
}
& > * {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
} }
.g-gantt-bar-label > * { .g-gantt-bar-resizable .g-gantt-bar__label {
white-space: nowrap; padding: 0 14px 0 14px; /* 14px is the width of the handle */
overflow: hidden;
text-overflow: ellipsis;
} }
.g-gantt-bar > .g-gantt-bar-handle-left, .g-gantt-bar__handle-left,
.g-gantt-bar > .g-gantt-bar-handle-right { .g-gantt-bar__handle-right {
position: absolute; position: absolute;
width: 10px; width: 10px;
height: 100%; height: 100%;
@@ -204,21 +212,17 @@
border-radius: 40px; border-radius: 40px;
} }
.g-gantt-bar-handle-left { .g-gantt-bar__handle-left {
left: 0; left: 0;
cursor: w-resize; cursor: w-resize;
} }
.g-gantt-bar-handle-right { .g-gantt-bar__handle-right {
right: 0; right: 0;
cursor: e-resize; cursor: e-resize;
} }
.g-gantt-bar-label img { .g-gantt-bar__tooltip {
pointer-events: none;
}
.g-gantt-tooltip {
position: absolute; position: absolute;
background: black; background: black;
color: white; color: white;
@@ -229,27 +233,27 @@
transition: opacity 0.2s; transition: opacity 0.2s;
display: flex; display: flex;
align-items: center; align-items: center;
}
.g-gantt-tooltip:before { &:before {
content: ''; content: '';
position: absolute; position: absolute;
top: 0; top: 0;
left: 10%; left: 10%;
width: 0; width: 0;
height: 0; height: 0;
border: 10px solid transparent; border: 10px solid transparent;
border-bottom-color: black; border-bottom-color: black;
border-top: 0; border-top: 0;
margin-left: -5px; margin-left: -5px;
margin-top: -5px; margin-top: -5px;
} }
.g-gantt-tooltip > .color-indicator { & > .color-indicator {
width: 8px; width: 8px;
height: 8px; height: 8px;
border-radius: 100%; border-radius: 100%;
margin-right: 4px; margin-right: 4px;
}
} }
.fade-enter-active { .fade-enter-active {