2
0
mirror of https://github.com/tenrok/vue-ganttastic.git synced 2026-06-11 10:32:24 +03:00

feat: sass based themes (more customization)

This commit is contained in:
2021-12-14 17:50:06 +03:00
parent 070454a32b
commit d2cfbbfe0c
34 changed files with 758 additions and 329 deletions
-6
View File
@@ -1,6 +0,0 @@
{
"compilerOptions": {
"baseUrl": "."
},
"exclude": ["node_modules", "dist"]
}
+29 -33
View File
@@ -1,47 +1,48 @@
<template>
<div
class="g-gantt-chart"
:style="{ width, height, background: themeColors.background }"
class="g-gantt-chart-container"
:data-theme="theme"
:style="{ width, height }"
>
<g-gantt-timeaxis
v-if="!hideTimeaxis"
:chart-start="chartStart"
:chart-end="chartEnd"
:row-label-width="rowLabelWidth"
:timemarker-offset="timemarkerOffset"
:theme-colors="themeColors"
:locale="locale"
:precision="precision"
:time-format="timeFormat"
:time-count="timeCount"
:grid-size="gridSize"
:day-format="dayFormat"
:month-format="monthFormat"
/>
<div
class="g-gantt-rows-container"
:style="{ width: `${timeCount * gridSize + rowLabelWidth}px` }"
>
<g-gantt-grid
v-if="grid"
<div class="g-gantt-chart">
<g-gantt-timeaxis
v-if="!hideTimeaxis"
:chart-start="chartStart"
:chart-end="chartEnd"
:row-label-width="rowLabelWidth"
:highlighted-hours="highlightedHours"
:highlighted-days="highlightedDays"
:timemarker-offset="timemarkerOffset"
:locale="locale"
:precision="precision"
:time-format="timeFormat"
:time-count="timeCount"
:grid-size="gridSize"
:day-format="dayFormat"
:month-format="monthFormat"
/>
<slot />
<div
class="g-gantt-rows-container"
:style="{ width: `${timeCount * gridSize + rowLabelWidth}px` }"
>
<g-gantt-grid
v-if="grid"
:chart-start="chartStart"
:chart-end="chartEnd"
:row-label-width="rowLabelWidth"
:highlighted-hours="highlightedHours"
:highlighted-days="highlightedDays"
:precision="precision"
:time-count="timeCount"
:grid-size="gridSize"
/>
<slot />
</div>
</div>
</div>
</template>
<script>
import moment from 'moment'
import GanttasticThemeColors from './GanttasticThemeColors.js'
import GGanttTimeaxis from './GGanttTimeaxis.vue'
import GGanttGrid from './GGanttGrid.vue'
import GGanttRow from './GGanttRow.vue'
@@ -109,10 +110,6 @@ export default {
return Math.floor(
momentChartEnd.diff(momentChartStart, this.timeUnit, true)
)
},
themeColors() {
return GanttasticThemeColors[this.theme] || GanttasticThemeColors.default
}
},
@@ -467,7 +464,6 @@ export default {
return {
getTimeCount: () => this.timeCount,
getChartProps: () => this.$props,
getThemeColors: () => this.themeColors,
initDragOfBarsFromBundle: (bundleId, e) =>
this.initDragOfBarsFromBundle(bundleId, e),
moveBarsFromBundleOfPushedBar: (bar, minuteDiff, overlapType) =>
+5 -21
View File
@@ -56,13 +56,7 @@ export default {
highlightOnHover: { type: Boolean }
},
inject: [
'getChartProps',
'getThemeColors',
'getTimeCount',
'getTimeUnit',
'getTimeFormat'
],
inject: ['getChartProps', 'getTimeCount', 'getTimeUnit', 'getTimeFormat'],
data() {
return {
@@ -72,10 +66,6 @@ export default {
},
computed: {
themeColors() {
return this.getThemeColors()
},
defaultBarLength() {
return this.chartProps.defaultBarLength
},
@@ -107,10 +97,6 @@ export default {
rowLabelStyle() {
return {
width: `${this.chartProps.rowLabelWidth}px`,
background: this.themeColors.ternary,
color: this.themeColors.text,
borderTop: `1px solid ${this.themeColors.rowLabelBorder}`,
borderBottom: `1px solid ${this.themeColors.rowLabelBorder}`,
...this.labelStyle
}
}
@@ -151,13 +137,12 @@ export default {
onDragover(e) {
e.preventDefault() // enables dropping content on row
if (this.highlightOnHover) {
this.$refs['g-row'].style.backgroundColor =
this.themeColors.hoverHighlight
this.$refs['g-row'].classList.add('g-gantt-row-highlighted')
}
},
onDragleave() {
this.$refs['g-row'].style.backgroundColor = null
this.$refs['g-row'].classList.remove('g-gantt-row-highlighted')
},
onDrop(e) {
@@ -199,13 +184,12 @@ export default {
onMouseover() {
if (this.highlightOnHover) {
this.$refs['g-row'].style.backgroundColor =
this.themeColors.hoverHighlight
this.$refs['g-row'].classList.add('g-gantt-row-highlighted')
}
},
onMouseleave() {
this.$refs['g-row'].style.backgroundColor = null
this.$refs['g-row'].classList.remove('g-gantt-row-highlighted')
},
onWindowResize() {
+6 -23
View File
@@ -7,43 +7,27 @@
<div
class="g-gantt-timeaxis__empty-space"
:style="{
minWidth: `${rowLabelWidth}px`,
background: themeColors.secondary
minWidth: `${rowLabelWidth}px`
}"
/>
<div class="g-gantt-timeaxis__days">
<div
v-for="(point, index) in axisPoints"
v-for="point in axisPoints"
:key="point.text"
class="g-gantt-timeaxis__day"
:style="{
background:
index % 2 === 0 ? themeColors.primary : themeColors.secondary,
color: themeColors.text
}"
>
<div v-html="pointFormatted(point) || '&nbsp;'"></div>
<div
:style="{ background: themeColors.ternary, color: themeColors.text }"
>
<div class="g-gantt-timeaxis__hours">
<div
v-for="(childPoint, index) in point.childPoints"
v-for="childPoint in point.childPoints"
:key="childPoint.fullDatetime"
class="g-gantt-timeaxis__hour"
:style="{
width: `${gridSize}px`,
background:
index % 2 === 0 ? themeColors.primary : themeColors.secondary,
color: themeColors.text
}"
:style="{ width: `${gridSize}px` }"
>
<span :style="{ fontSize: hourFontSize }">{{
childPoint.text
}}</span>
<div
class="g-gantt-timeaxis__hour-pin"
:style="{ background: themeColors.text }"
/>
<div class="g-gantt-timeaxis__hour-pin" />
</div>
</div>
</div>
@@ -64,7 +48,6 @@ export default {
rowLabelWidth: { type: Number },
timemarkerOffset: { type: Number, default: 0 },
locale: { type: String },
themeColors: { type: Object },
precision: { type: String },
timeFormat: { type: String },
timeCount: { type: Number },
-113
View File
@@ -1,113 +0,0 @@
export default {
default: {
primary: '#eeeeee',
secondary: '#e0e0e0',
ternary: '#f5f5f5',
hoverHighlight: 'rgba(204, 216, 219, 0.5)',
text: '#404040',
background: 'white',
rowLabelBorder: '#eaeaea'
},
creamy: {
primary: '#ffe8d9',
secondary: '#fcdcc5',
ternary: '#fff6f0',
hoverHighlight: 'rgba(230, 221, 202, 0.5)',
text: '#542d05',
background: 'white',
rowLabelBorder: '#eaeaea'
},
crimson: {
primary: '#a82039',
secondary: '#c41238',
ternary: '#db4f56',
hoverHighlight: 'rgba(196, 141, 141, 0.5)',
text: 'white',
background: 'white',
rowLabelBorder: '#eaeaea'
},
dark: {
primary: '#404040',
secondary: '#303030',
ternary: '#353535',
hoverHighlight: 'rgba(159, 160, 161, 0.5)',
text: 'white',
background: '#525252',
toast: '#1f1f1f',
rowLabelBorder: '#eaeaea'
},
flare: {
primary: '#e08a38',
secondary: '#e67912',
ternary: '#5e5145',
hoverHighlight: 'rgba(196, 141, 141, 0.5)',
text: 'white',
background: 'white',
rowLabelBorder: '#eaeaea'
},
fuchsia: {
primary: '#de1d5a',
secondary: '#b50b41',
ternary: '#ff7da6',
hoverHighlight: 'rgba(196, 141, 141, 0.5)',
text: 'white',
background: 'white',
rowLabelBorder: '#eaeaea'
},
grove: {
primary: '#3d9960',
secondary: '#288542',
ternary: '#72b585',
hoverHighlight: 'rgba(160, 219, 171, 0.5)',
text: 'white',
background: 'white',
rowLabelBorder: '#eaeaea'
},
'material-blue': {
primary: '#0d47a1',
secondary: '#1565c0',
ternary: '#42a5f5',
hoverHighlight: 'rgba(110, 165, 196, 0.5)',
text: 'white',
background: 'white',
rowLabelBorder: '#eaeaea'
},
sky: {
primary: '#b5e3ff',
secondary: '#a1d6f7',
ternary: '#d6f7ff',
hoverHighlight: 'rgba(193, 202, 214, 0.5)',
text: '#022c47',
background: 'white',
rowLabelBorder: '#eaeaea'
},
slumber: {
primary: '#2c2e36',
secondary: '#2f3447',
ternary: '#35394d',
hoverHighlight: 'rgba(179, 162, 127, 0.5)',
text: '#ffe0b3',
background: '#38383b',
toast: '#1f1f1f',
rowLabelBorder: '#eaeaea'
},
vue: {
primary: '#258a5d',
secondary: '#41b883',
ternary: '#35495e',
hoverHighlight: 'rgba(160, 219, 171, 0.5)',
text: 'white',
background: 'white',
rowLabelBorder: '#384d63'
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
import GGanttChart from './components/GGanttChart.vue'
import GGanttRow from './components/GGanttRow.vue'
import './scss/vue-ganttastic.scss'
import './scss/index.scss'
const VueGanttastic = { GGanttChart, GGanttRow }
@@ -8,8 +8,10 @@
-ms-user-select: none;
user-select: none;
padding-bottom: 34px;
border: 1px solid #eaeaea;
border: 1px solid $border-color;
box-sizing: border-box;
background: $background;
flex: 1;
& >>> * {
font-family: Roboto, Verdana;
@@ -26,14 +28,14 @@
.g-gantt-timeaxis {
position: sticky;
top: 0;
background: white;
background: $timeaxis-background;
z-index: 4;
box-shadow: 0px 1px 3px 2px rgba(50, 50, 50, 0.5);
}
.g-gantt-timeaxis__empty-space {
min-height: 100%;
background: #f5f5f5;
background: $secondary;
z-index: 5;
left: 0;
position: sticky;
@@ -47,29 +49,29 @@
.g-gantt-timeaxis__day {
height: 100%;
flex-direction: column;
background: #e0e0e0;
color: $text;
&:nth-child(even) {
background: $secondary;
}
&:nth-child(odd) {
background: #e8e8e8;
background: $primary;
}
& > 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-gantt-timeaxis__days {
align-items: flex-end;
justify-content: space-between;
background: $ternary;
color: $text;
}
.g-gantt-timeaxis__hour {
@@ -78,20 +80,30 @@
align-items: flex-start;
flex-direction: column;
opacity: 0.5;
color: $text;
&:nth-child(even) {
background: $secondary;
}
&:nth-child(odd) {
background: $primary;
}
}
.g-gantt-timeaxis__hour-pin {
width: 1px;
height: 8px;
height: 5px;
background: $text;
}
.g-gantt-timeaxis__marker {
position: absolute;
top: 0;
left: 0;
height: 100%;
bottom: 0;
height: 5px;
width: 3px;
background: black;
background: $marker-background;
}
.g-gantt-rows-container {
@@ -108,17 +120,17 @@
.g-gantt-grid__line {
height: 100%;
border: 1px solid transparent;
border-left: 1px solid #eaeaea;
border-left: 1px solid $border-color;
box-sizing: border-box;
display: inline-block;
}
.g-gantt-grid-line-last {
border-right: 1px solid #eaeaea;
border-right: 1px solid $border-color;
}
.g-gantt-line-highlighted {
background: #dcefff;
.g-gantt-grid-line-highlighted {
background: $highlighted;
}
.g-gantt-row {
@@ -129,11 +141,15 @@
position: relative;
}
.g-gantt-row-highlighted {
background-color: $hover-highlight;
}
.g-gantt-row__label {
display: flex;
align-items: center;
background: #e8e8e8;
color: #424242;
background: $ternary;
color: $text;
font-size: 0.9em;
z-index: 3;
font-weight: bold;
@@ -141,8 +157,8 @@
position: sticky;
padding: 0 10px;
box-sizing: border-box;
border-top: 1px solid #eaeaea;
border-bottom: 1px solid #eaeaea;
border-top: 1px solid $row-label-border-color;
border-bottom: 1px solid $row-label-border-color;
& > * {
overflow: hidden;
@@ -153,8 +169,8 @@
.g-gantt-row__bars-container {
position: relative;
border-top: 1px solid #eaeaea;
border-bottom: 1px solid #eaeaea;
border-top: 1px solid $border-color;
border-bottom: 1px solid $border-color;
flex: 1;
}
@@ -224,8 +240,8 @@
.g-gantt-bar__tooltip {
position: absolute;
background: black;
color: white;
background: $tooltip-background;
color: $tooltip-color;
z-index: 3;
font-size: 0.7em;
padding: 3px;
@@ -242,7 +258,7 @@
width: 0;
height: 0;
border: 10px solid transparent;
border-bottom-color: black;
border-bottom-color: $tooltip-background;
border-top: 0;
margin-left: -5px;
margin-top: -5px;
@@ -255,20 +271,3 @@
margin-right: 4px;
}
}
.fade-enter-active {
animation: fade-in 0.3s;
}
.fade-leave-active {
animation: fade-in 0.3s reverse;
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
+13
View File
@@ -0,0 +1,13 @@
$primary: #eee !default;
$secondary: #e0e0e0 !default;
$ternary: #f5f5f5 !default;
$hover-highlight: rgba(204, 216, 219, 0.5) !default;
$text: #404040 !default;
$background: #fff !default;
$highlighted: #dcefff !default;
$border-color: #eaeaea !default;
$timeaxis-background: #fff !default;
$marker-background: #000 !default;
$row-label-border-color: $border-color !default;
$tooltip-background: #000;
$tooltip-color: #fff;
+36
View File
@@ -0,0 +1,36 @@
@use "sass:meta";
// default
@import './variables';
@import './ganttastic';
[data-theme] {
display: flex;
flex-direction: column;
}
$themes: 'creamy', 'crimson', 'dark', 'flare', 'fuchsia', 'grove',
'material-blue', 'sky', 'slumber', 'vue';
@each $theme in $themes {
[data-theme='#{$theme}'] {
@include meta.load-css('./themes/#{$theme}');
}
}
.fade-enter-active {
animation: fade-in 0.3s;
}
.fade-leave-active {
animation: fade-in 0.3s reverse;
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
+7
View File
@@ -0,0 +1,7 @@
$primary: #ffe8d9;
$secondary: #fcdcc5;
$ternary: #fff6f0;
$hover-highlight: rgba(230, 221, 202, 0.5);
$text: #542d05;
$background: #fff;
$row-label-border-color: #f7efe9;
+3
View File
@@ -0,0 +1,3 @@
@import '../../variables';
@import './variables';
@import '../../ganttastic';
+7
View File
@@ -0,0 +1,7 @@
$primary: #a82039;
$secondary: #c41238;
$ternary: #db4f56;
$hover-highlight: rgba(196, 141, 141, 0.5);
$text: white;
$background: white;
$row-label-border-color: #e6535a;
+3
View File
@@ -0,0 +1,3 @@
@import '../../variables';
@import './variables';
@import '../../ganttastic';
+10
View File
@@ -0,0 +1,10 @@
$primary: #404040;
$secondary: #303030;
$ternary: #353535;
$hover-highlight: rgba(159, 160, 161, 0.5);
$text: #adb5bd;
$background: #525252;
$highlighted: #7e7e7e;
$border-color: #444444;
$marker-background: #666666;
$row-label-border-color: $border-color;
+3
View File
@@ -0,0 +1,3 @@
@import '../../variables';
@import './variables';
@import '../../ganttastic';
+7
View File
@@ -0,0 +1,7 @@
$primary: #e08a38;
$secondary: #e67912;
$ternary: #5e5145;
$hover-highlight: rgba(196, 141, 141, 0.5);
$text: #fff;
$background: #fff;
$row-label-border-color: #6b5c4e;
+3
View File
@@ -0,0 +1,3 @@
@import '../../variables';
@import './variables';
@import '../../ganttastic';
+9
View File
@@ -0,0 +1,9 @@
$primary: #de1d5a;
$secondary: #b50b41;
$ternary: #ff7da6;
$hover-highlight: rgba(196, 141, 141, 0.5);
$text: #fff;
$background: #fff;
$row-label-border-color: #f2779e;
$tooltip-background: $primary;
$tooltip-color: #fff;
+3
View File
@@ -0,0 +1,3 @@
@import '../../variables';
@import './variables';
@import '../../ganttastic';
+7
View File
@@ -0,0 +1,7 @@
$primary: #3d9960;
$secondary: #288542;
$ternary: #72b585;
$hover-highlight: rgba(160, 219, 171, 0.5);
$text: white;
$background: white;
$row-label-border-color: #73bd88;
+3
View File
@@ -0,0 +1,3 @@
@import '../../variables';
@import './variables';
@import '../../ganttastic';
@@ -0,0 +1,7 @@
$primary: #0d47a1;
$secondary: #1565c0;
$ternary: #42a5f5;
$hover-highlight: rgba(110, 165, 196, 0.5);
$text: white;
$background: white;
$row-label-border-color: #45abff;
+3
View File
@@ -0,0 +1,3 @@
@import '../../variables';
@import './variables';
@import '../../ganttastic';
+7
View File
@@ -0,0 +1,7 @@
$primary: #b5e3ff;
$secondary: #a1d6f7;
$ternary: #d6f7ff;
$hover-highlight: rgba(193, 202, 214, 0.5);
$text: #022c47;
$background: white;
$row-label-border-color: #cbf4fe;
+3
View File
@@ -0,0 +1,3 @@
@import '../../variables';
@import './variables';
@import '../../ganttastic';
+10
View File
@@ -0,0 +1,10 @@
$primary: #2c2e36;
$secondary: #2f3447;
$ternary: #35394d;
$hover-highlight: rgba(179, 162, 127, 0.5);
$text: #ffe0b3;
$background: #38383b;
$highlighted: #7e7e7e;
$border-color: #444;
$marker-background: #666;
$row-label-border-color: $border-color;
+3
View File
@@ -0,0 +1,3 @@
@import '../../variables';
@import './variables';
@import '../../ganttastic';
+7
View File
@@ -0,0 +1,7 @@
$primary: #258a5d;
$secondary: #41b883;
$ternary: #35495e;
$hover-highlight: rgba(160, 219, 171, 0.5);
$text: #fff;
$background: #fff;
$row-label-border-color: #384d63;
+3
View File
@@ -0,0 +1,3 @@
@import '../../variables';
@import './variables';
@import '../../ganttastic';
+469 -74
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@tenrok/vue-ganttastic",
"version": "0.10.22",
"version": "0.11.0",
"description": "A simple and customizable Gantt chart component for Vue.js",
"keywords": [
"gantt",
@@ -55,7 +55,7 @@
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^8.2.0",
"node-sass": "^6.0.1",
"sass": "^1.45.0",
"sass-loader": "^10.2.0",
"vue-template-compiler": "^2.6.11"
},
+25 -6
View File
@@ -1,5 +1,11 @@
<template>
<div>
<select v-model="theme">
<option v-for="option in themes" :key="option" :value="option">
{{ option }}
</option>
</select>
<h2>Chart #1</h2>
<g-gantt-chart
@@ -17,7 +23,7 @@
:highlighted-days="chart1.highlightedDays"
:row-label-width="chart1.rowLabelWidth"
:row-height="chart1.rowHeight"
:theme="chart1.theme"
:theme="theme"
bar-config-key="config"
bar-start-key="myStart"
bar-end-key="myEnd"
@@ -53,7 +59,7 @@
:highlighted-days="chart2.highlightedDays"
:row-label-width="chart2.rowLabelWidth"
:row-height="chart2.rowHeight"
:theme="chart2.theme"
:theme="theme"
:width="chart2.width"
:height="chart2.height"
:allow-add="chart2.allowAdd"
@@ -77,6 +83,20 @@
<script>
export default {
data: () => ({
theme: 'default',
themes: [
'creamy',
'crimson',
'dark',
'default',
'flare',
'fuchsia',
'grove',
'material-blue',
'sky',
'slumber',
'vue'
],
chart1: {
chartStart: '2020-03-02 00:00',
chartEnd: '2020-03-10 10:00',
@@ -91,7 +111,6 @@ export default {
highlightOnHover: true,
highlightedDays: ['2020-03-08'],
highlightedHours: [10, 12],
theme: 'default', // 'default', 'vue', 'dark', 'material-blue', 'creamy', 'slumber', 'sky', 'crimson', 'grove', 'fuchsia', 'flare'
rows: [
{
label: 'Row #1',
@@ -259,7 +278,6 @@ export default {
'2020-03-22',
'2020-03-29'
],
theme: 'vue', // 'default', 'vue', 'dark', 'material-blue', 'creamy', 'slumber', 'sky', 'crimson', 'grove', 'fuchsia', 'flare'
width: '90vw',
height: '250px',
allowAdd: false,
@@ -353,11 +371,12 @@ export default {
methods: {
onDragend(e) {
let { event, bar, movedBars } = e
const { event, bar, movedBars } = e
// eslint-disable-next-line
console.log('onDragend', { event: event.type, bar, movedBars })
}
}
}
</script>
<style lang="scss" src="../lib/scss/vue-ganttastic.scss"></style>
<style lang="scss" src="../lib/scss/index.scss"></style>
+8
View File
@@ -0,0 +1,8 @@
// vetur.config.js
/** @type {import('vls').VeturConfig} */
module.exports = {
settings: {
'vetur.ignoreProjectWarning': true,
},
projects: ['./'],
}
+8 -1
View File
@@ -4,7 +4,14 @@ const isBuildLib =
module.exports = {
publicPath: '',
outputDir: isBuildLib ? 'dist' : 'demo',
css: { extract: true },
css: {
loaderOptions: {
sass: {
implementation: require('sass')
}
},
extract: true
},
productionSourceMap: false,
chainWebpack: config => {
if (process.env.VUE_CLI_BUILD_TARGET === 'lib') {