mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-05-21 13:18:53 +00:00
UI: redesign DatePicker (#12418)
* extract datepicker & settings as component + redesign * fix updating values + fix button styling + popover position * remove eslint-config-standard / html
This commit is contained in:
parent
13a5b276e9
commit
d2fc7c0c3d
10 changed files with 239 additions and 73 deletions
16
package-lock.json
generated
16
package-lock.json
generated
|
|
@ -1153,11 +1153,6 @@
|
|||
"uuid": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"@sindresorhus/is": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
|
||||
"integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ=="
|
||||
},
|
||||
"@sinonjs/commons": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz",
|
||||
|
|
@ -6665,9 +6660,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.0.0.tgz",
|
||||
"integrity": "sha512-kqA5I6Yun7PBHk8WN9BBP1c7FfN2SrD05GuVSEYPqDb4nerv7HqYfgBfMIKmT/EuejURkJKLZuLyGKGs6WEG9w=="
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.0.tgz",
|
||||
"integrity": "sha512-n4J+zu52VdY43kdi/XdI9DzuMr1Mur8zFL5ZRG2opCans9aiFwkPxHYFEb5Xgy7n1Z4K6WfI4FpqUqsh3E8BPQ=="
|
||||
},
|
||||
"@szmarczak/http-timer": {
|
||||
"version": "4.0.5",
|
||||
|
|
@ -10573,6 +10568,11 @@
|
|||
"semver": "^6.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
|
||||
"integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ=="
|
||||
},
|
||||
"got": {
|
||||
"version": "9.6.0",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
import { configure } from '@storybook/vue';
|
||||
import './margin.css';
|
||||
import '../../src/assets/scss/index.scss';
|
||||
import '../../src/assets/scss/spacing.scss';
|
||||
import '../../src/assets/css/sprites.css';
|
||||
|
||||
import '../../src/assets/css/sprites/spritesmith-main-0.css';
|
||||
|
|
|
|||
4
website/client/package-lock.json
generated
4
website/client/package-lock.json
generated
|
|
@ -19885,8 +19885,8 @@
|
|||
}
|
||||
},
|
||||
"vuejs-datepicker": {
|
||||
"version": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
|
||||
"from": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec"
|
||||
"version": "git://github.com/habitrpg/vuejs-datepicker.git#153d339e4dbebb73733658aeda1d5b7fcc55b0a0",
|
||||
"from": "git://github.com/habitrpg/vuejs-datepicker.git#153d339e4dbebb73733658aeda1d5b7fcc55b0a0"
|
||||
},
|
||||
"w3c-hr-time": {
|
||||
"version": "1.0.2",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
"vue-router": "^3.3.4",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuedraggable": "^2.24.0",
|
||||
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
|
||||
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#153d339e4dbebb73733658aeda1d5b7fcc55b0a0",
|
||||
"webpack": "^4.44.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
.vdp-datepicker .vdp-datepicker__calendar {
|
||||
|
||||
.cell:not(.blank):not(.disabled).day:hover {
|
||||
border-radius: 2px;
|
||||
border: 1px solid $purple-400;
|
||||
}
|
||||
|
||||
.cell.selected,
|
||||
.cell.selected.highlighted,
|
||||
.cell.selected:hover {
|
||||
color: $white;
|
||||
background: $purple-300;
|
||||
}
|
||||
|
||||
.cell.highlighted {
|
||||
background: rgba($purple-400, 0.24);
|
||||
color: $purple-200;
|
||||
}
|
||||
|
||||
.cell.highlighted,
|
||||
.cell.selected {
|
||||
border-radius: 2px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -36,5 +36,4 @@
|
|||
@import './iconalert';
|
||||
@import './tiers';
|
||||
@import './payments';
|
||||
@import './datepicker.scss';
|
||||
@import './spacing';
|
||||
|
|
|
|||
|
|
@ -264,13 +264,8 @@
|
|||
:text="$t('dueDate')"
|
||||
/>
|
||||
<datepicker
|
||||
v-model="task.date"
|
||||
:calendar-icon="icons.calendar"
|
||||
:clear-button="!challengeAccessRequired && !groupAccessRequiredAndOnPersonalPage"
|
||||
:clear-button-text="$t('clear')"
|
||||
:today-button="false"
|
||||
:disabled-picker="challengeAccessRequired || groupAccessRequiredAndOnPersonalPage"
|
||||
:class="{disabled: challengeAccessRequired || groupAccessRequiredAndOnPersonalPage}"
|
||||
:date.sync="task.date"
|
||||
:disabled="challengeAccessRequired || groupAccessRequiredAndOnPersonalPage"
|
||||
:highlighted="calendarHighlights"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -285,12 +280,8 @@
|
|||
:text="$t('startDate')"
|
||||
/>
|
||||
<datepicker
|
||||
v-model="task.startDate"
|
||||
:calendar-icon="icons.calendar"
|
||||
:clear-button="false"
|
||||
:today-button="false"
|
||||
:disabled-picker="challengeAccessRequired || groupAccessRequiredAndOnPersonalPage"
|
||||
:class="{disabled: challengeAccessRequired || groupAccessRequiredAndOnPersonalPage}"
|
||||
:date.sync="task.startDate"
|
||||
:disabled="challengeAccessRequired || groupAccessRequiredAndOnPersonalPage"
|
||||
:highlighted="calendarHighlights"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -787,27 +778,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
.vdp-datepicker.disabled, .input-group-outer.disabled {
|
||||
.input-group:hover {
|
||||
border-color: $gray-400;
|
||||
}
|
||||
.datetime-buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.input-group .form-control {
|
||||
background-color: $gray-700;
|
||||
border-color: $gray-500;
|
||||
color: $gray-200;
|
||||
}
|
||||
|
||||
svg path {
|
||||
opacity: 0.75;
|
||||
fill: $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
.vdp-datepicker {
|
||||
.input-group-append {
|
||||
width: auto;
|
||||
min-width: 2rem;
|
||||
.btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1067,8 +1043,8 @@
|
|||
<script>
|
||||
import axios from 'axios';
|
||||
import clone from 'lodash/clone';
|
||||
import Datepicker from 'vuejs-datepicker';
|
||||
import moment from 'moment';
|
||||
import Datepicker from '@/components/ui/datepicker';
|
||||
import toggleSwitch from '@/components/ui/toggleSwitch';
|
||||
import toggleCheckbox from '@/components/ui/toggleCheckbox';
|
||||
import markdownDirective from '@/directives/markdown';
|
||||
|
|
|
|||
19
website/client/src/components/ui/datepicker.stories.js
Normal file
19
website/client/src/components/ui/datepicker.stories.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { storiesOf } from '@storybook/vue';
|
||||
import { withKnobs } from '@storybook/addon-knobs';
|
||||
|
||||
import datepicker from './datepicker.vue';
|
||||
|
||||
const stories = storiesOf('Date Picker', module);
|
||||
|
||||
stories.addDecorator(withKnobs);
|
||||
|
||||
stories
|
||||
.add('simple', () => ({
|
||||
components: { datepicker },
|
||||
template: `
|
||||
<div style="position: absolute; margin: 20px">
|
||||
<datepicker></datepicker>
|
||||
</div>
|
||||
`,
|
||||
}));
|
||||
198
website/client/src/components/ui/datepicker.vue
Normal file
198
website/client/src/components/ui/datepicker.vue
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
<template>
|
||||
<datepicker
|
||||
v-model="value"
|
||||
@input="upDate($event)"
|
||||
:calendarButton="true"
|
||||
:calendarButtonIconContent="icons.calendar"
|
||||
:bootstrapStyling="true"
|
||||
:clear-button="false"
|
||||
:today-button="false"
|
||||
:disabled-picker="disabled"
|
||||
:class="{disabled: disabled}"
|
||||
:highlighted="highlighted"
|
||||
calendar-class="calendar-padding"
|
||||
>
|
||||
<div slot="beforeCalendarHeader">
|
||||
<div class="datetime-buttons">
|
||||
<button
|
||||
class="btn btn-flat"
|
||||
@click="setToday()"
|
||||
type="button"
|
||||
>
|
||||
{{ $t('today') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-flat"
|
||||
@click="setTomorrow()"
|
||||
type="button"
|
||||
>
|
||||
{{ $t('tomorrow') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</datepicker>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import datepicker from 'vuejs-datepicker';
|
||||
import calendarIcon from '@/assets/svg/calendar.svg';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
datepicker,
|
||||
},
|
||||
props: ['date', 'disabled', 'highlighted'],
|
||||
data () {
|
||||
return {
|
||||
value: this.date,
|
||||
icons: Object.freeze({
|
||||
calendar: calendarIcon,
|
||||
}),
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
date () {
|
||||
this.value = this.date;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
upDate (after) {
|
||||
this.value = after;
|
||||
this.$emit('update:date', after);
|
||||
},
|
||||
setToday () {
|
||||
this.upDate(moment().toDate());
|
||||
},
|
||||
setTomorrow () {
|
||||
this.upDate(moment().add(1, 'day').toDate());
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
.vdp-datepicker__calendar {
|
||||
bottom: 2.125rem; // 2rem input control height + 0.125rem margin above
|
||||
}
|
||||
|
||||
.vdp-datepicker {
|
||||
.input-group-append {
|
||||
width: auto;
|
||||
min-width: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.vdp-datepicker__calendar-button .svg-icon {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.vdp-datepicker.disabled, .input-group-outer.disabled {
|
||||
.input-group:hover {
|
||||
border-color: $gray-400;
|
||||
}
|
||||
|
||||
.input-group .form-control {
|
||||
background-color: $gray-700;
|
||||
border-color: $gray-500;
|
||||
color: $gray-200;
|
||||
}
|
||||
|
||||
svg path {
|
||||
opacity: 0.75;
|
||||
fill: $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
.vdp-datepicker .vdp-datepicker__calendar {
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
|
||||
.datetime-buttons {
|
||||
height: 50px;
|
||||
|
||||
button {
|
||||
padding: 0;
|
||||
margin: 0.5rem;
|
||||
height: 1.5rem;
|
||||
border-radius: 2px;
|
||||
background-color: $gray-600;
|
||||
color: $gray-100;
|
||||
|
||||
&:not(:hover) {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $purple-300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header, .datetime-buttons {
|
||||
min-height: 40px;
|
||||
margin-top: -0.5rem;
|
||||
margin-left: -0.5rem;
|
||||
margin-right: -0.5rem;
|
||||
background-color: $gray-700 !important;
|
||||
}
|
||||
|
||||
.calendar-padding {
|
||||
margin: 0.25rem;
|
||||
}
|
||||
|
||||
&.picker_day {
|
||||
.cell:not(.disabled) {
|
||||
width: calc(100% / 7);
|
||||
border-radius: 2px;
|
||||
font-size: 14px;
|
||||
line-height: 1.21;
|
||||
text-align: center;
|
||||
padding: 0.65rem 0.35rem;
|
||||
}
|
||||
}
|
||||
|
||||
.cell:not(.blank):not(.disabled).day:hover {
|
||||
border-radius: 2px;
|
||||
border: 1px solid $purple-400;
|
||||
}
|
||||
|
||||
.cell.selected,
|
||||
.cell.selected.highlighted,
|
||||
.cell.selected:hover {
|
||||
color: $white;
|
||||
background: $purple-300;
|
||||
}
|
||||
|
||||
.cell.highlighted {
|
||||
background: rgba($purple-600, 0.25);
|
||||
color: $purple-300;
|
||||
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.cell.highlighted,
|
||||
.cell.selected {
|
||||
border-radius: 2px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.cell.day-header {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
text-align: center;
|
||||
color: $gray-100;
|
||||
}
|
||||
|
||||
.month__year_btn, .day__month_btn {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
color: $gray-50;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -81,6 +81,7 @@
|
|||
"complete2": "Complete",
|
||||
"dated": "Dated",
|
||||
"today": "Today",
|
||||
"tomorrow": "Tomorrow",
|
||||
"dueIn": "Due <%= dueIn %>",
|
||||
"due": "Due",
|
||||
"notDue": "Not Due",
|
||||
|
|
|
|||
Loading…
Reference in a new issue