-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
List element now has some responsive fields and dropdown of completed…
… items
- Loading branch information
1 parent
5b28e56
commit b6e1c39
Showing
17 changed files
with
983 additions
and
289 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,58 @@ | ||
<template> | ||
<div class="checkbox-container"> | ||
<label for="checkbox-input">{{ label }}</label> | ||
<input | ||
type="checkbox" | ||
id="checkbox-input" | ||
v-model="isChecked" | ||
@change="emitCheckboxChange" | ||
@keyup.enter="toggleCheckbox" | ||
tabindex="0" /> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
name: 'CheckboxInput', | ||
props: { | ||
label: { | ||
type: String, | ||
default: 'Checkbox' // Default label text | ||
} | ||
<div class="checkbox-container"> | ||
<label for="checkbox-input">{{ label }}</label> | ||
<input | ||
type="checkbox" | ||
id="checkbox-input" | ||
v-model="isChecked" | ||
@change="emitCheckboxChange" | ||
@keyup.enter="toggleCheckbox" | ||
tabindex="0" /> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
name: 'CheckboxInput', | ||
props: { | ||
label: { | ||
type: String, | ||
default: 'Checkbox' // Default label text | ||
}, | ||
data() { | ||
return { | ||
isChecked: false | ||
}; | ||
value: { | ||
type: Boolean, | ||
default: false // Default checked state | ||
} | ||
}, | ||
data() { | ||
return { | ||
isChecked: this.value // Initialize with the prop value | ||
}; | ||
}, | ||
watch: { | ||
value(newValue) { | ||
this.isChecked = newValue; // Update local state when prop changes | ||
} | ||
}, | ||
methods: { | ||
emitCheckboxChange() { | ||
this.$emit('checkbox-toggled', this.isChecked); // Emit the checked state to the parent | ||
this.$emit('input', this.isChecked); // Emit input event for v-model binding | ||
}, | ||
methods: { | ||
emitCheckboxChange() { | ||
this.$emit('checkbox-toggled', this.isChecked); // Emit the checked state to the parent | ||
}, | ||
toggleCheckbox() { | ||
// Toggle the checkbox value when Enter is pressed | ||
this.isChecked = !this.isChecked; | ||
this.emitCheckboxChange(); // Emit the change | ||
} | ||
toggleCheckbox() { | ||
// Toggle the checkbox value when Enter is pressed | ||
this.isChecked = !this.isChecked; | ||
this.emitCheckboxChange(); // Emit the change | ||
} | ||
}; | ||
</script> | ||
|
||
<style scoped> | ||
/* Add your styling here */ | ||
</style> | ||
|
||
}, | ||
mounted() { | ||
this.isChecked = this.value; // Set initial state based on prop value | ||
} | ||
}; | ||
</script> | ||
|
||
<style scoped> | ||
.checkbox-container { | ||
background-color: red; /* Change as needed */ | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<template> | ||
<div class="pretty-button-container"> | ||
<button | ||
class="pretty-button" | ||
@mouseenter="hoverButton" | ||
@mouseleave="resetButton" | ||
@click="toggleCheck" | ||
@keyup.enter="toggleCheck" | ||
> | ||
<span class="button-label">{{ buttonLabel }}</span> | ||
</button> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
name: 'PrettyButton', | ||
data() { | ||
return { | ||
isChecked: false, // Keeps track of whether the button is "checked" | ||
}; | ||
}, | ||
computed: { | ||
buttonLabel() { | ||
// Label changes based on whether the button is checked | ||
return this.isChecked ? '✓' : ''; | ||
} | ||
}, | ||
methods: { | ||
emitButtonChange() { | ||
this.$emit('checkbox-toggled', this.isChecked); // Emit the checked state to the parent | ||
}, | ||
hoverButton(event) { | ||
// Temporarily show the checkmark on hover | ||
event.target.innerHTML = '✓'; | ||
}, | ||
resetButton(event) { | ||
// Reset the button to its actual checked state after hover | ||
event.target.innerHTML = ''; | ||
}, | ||
toggleCheck() { | ||
// Permanently check or uncheck the button on click | ||
this.isChecked = !this.isChecked; | ||
this.emitButtonChange(); | ||
} | ||
} | ||
}; | ||
</script> | ||
|
||
<style scoped> | ||
.pretty-button-container { | ||
display: inline-block; | ||
padding-left: 3px; | ||
margin-bottom: 2px; | ||
} | ||
.pretty-button { | ||
display: inline-flex; | ||
align-items: center; | ||
justify-content: center; | ||
width: 25px; | ||
height: 25px; | ||
background-color: #ddd; | ||
border: 2px solid #2d5dc7; | ||
border-radius: 5px; | ||
cursor: pointer; | ||
user-select: none; | ||
transition: background-color 0.3s, border-color 0.3s; | ||
} | ||
.pretty-button:hover { | ||
background-color: #2d5dc7; | ||
} | ||
.button-label { | ||
font-size: 16px; | ||
color: white; | ||
} | ||
.pretty-button:hover .button-label { | ||
color: white; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,206 @@ | ||
<template> | ||
<div class="date-input-container"> | ||
<label for="date-input"></label> | ||
<input type="date" id="date-input" v-model="selectedDate" @change="emitDateChange" /> | ||
<div class="date-picker"> | ||
<input | ||
type="text" | ||
v-model="formattedDate" | ||
@focus="showCalendar" | ||
class="date-input" | ||
readonly | ||
/> | ||
<div v-if="isCalendarVisible" class="calendar"> | ||
<div class="calendar-header"> | ||
<button @click="prevMonth"><</button> | ||
<span>{{ monthNames[currentMonth] }} {{ currentYear }}</span> | ||
<button @click="nextMonth">></button> | ||
</div> | ||
<div class="calendar-grid"> | ||
<div class="day" v-for="(day, index) in weekDays" :key="index">{{ day }}</div> | ||
<div | ||
v-for="date in displayedDates" | ||
:key="date.dateString" | ||
class="day" | ||
:class="{ 'hover': date.isHover, 'selected': date.isSelected }" | ||
@mouseover="hoverDate(date.dateString)" | ||
@mouseleave="clearHover" | ||
@click="selectDate(date.dateString)" | ||
> | ||
{{ date.day }} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
props: { | ||
initialDate: { | ||
type: String, | ||
default: () => new Date().toISOString().split('T')[0], // Default to today | ||
}, | ||
}, | ||
data() { | ||
return { | ||
selectedDate: null, | ||
isCalendarVisible: false, | ||
currentYear: new Date().getFullYear(), | ||
currentMonth: new Date().getMonth(), | ||
selectedDate: this.initialDate, | ||
hoveredDate: null, | ||
}; | ||
}, | ||
computed: { | ||
formattedDate() { | ||
// Display the selected date directly without modification | ||
return this.hoveredDate || this.formatDate(this.incrementDate(this.selectedDate)); | ||
}, | ||
monthNames() { | ||
return [ | ||
'January', 'February', 'March', 'April', 'May', 'June', | ||
'July', 'August', 'September', 'October', 'November', 'December', | ||
]; | ||
}, | ||
weekDays() { | ||
return ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; | ||
}, | ||
displayedDates() { | ||
const dates = []; | ||
const firstDayOfMonth = new Date(this.currentYear, this.currentMonth, 1); | ||
const lastDayOfMonth = new Date(this.currentYear, this.currentMonth + 1, 0); | ||
// Fill in the days leading up to the first day of the month | ||
for (let i = 0; i < firstDayOfMonth.getDay(); i++) { | ||
dates.push({ day: '', dateString: '' }); | ||
} | ||
// Fill in the days of the month | ||
for (let day = 1; day <= lastDayOfMonth.getDate(); day++) { | ||
const dateString = new Date(this.currentYear, this.currentMonth, day).toISOString().split('T')[0]; | ||
dates.push({ | ||
day, | ||
dateString, | ||
isSelected: dateString === this.selectedDate, | ||
isHover: dateString === this.hoveredDate, | ||
}); | ||
} | ||
return dates; | ||
}, | ||
}, | ||
methods: { | ||
emitDateChange() { | ||
formatDate(date) { | ||
const options = { year: 'numeric', month: 'short', day: 'numeric' }; | ||
return new Date(date).toLocaleDateString(undefined, options); | ||
}, | ||
showCalendar() { | ||
this.isCalendarVisible = true; | ||
}, | ||
hoverDate(dateString) { | ||
this.hoveredDate = dateString; // Set the hovered date | ||
}, | ||
clearHover() { | ||
this.hoveredDate = null; // Clear the hover state | ||
}, | ||
selectDate(dateString) { | ||
this.selectedDate = dateString; // Set the selected date | ||
this.hoveredDate = null; // Clear hover state | ||
this.isCalendarVisible = false; // Hide calendar after selection | ||
this.$emit('date-selected', this.selectedDate); // Emit the selected date to the parent | ||
} | ||
} | ||
this.$emit('update:initialDate', this.selectedDate); // Sync with the parent | ||
}, | ||
prevMonth() { | ||
if (this.currentMonth === 0) { | ||
this.currentMonth = 11; | ||
this.currentYear--; | ||
} else { | ||
this.currentMonth--; | ||
} | ||
}, | ||
nextMonth() { | ||
if (this.currentMonth === 11) { | ||
this.currentMonth = 0; | ||
this.currentYear++; | ||
} else { | ||
this.currentMonth++; | ||
} | ||
}, | ||
incrementDate(dateString) { | ||
const date = new Date(dateString); | ||
date.setDate(date.getDate()+1); // Increment the date by 1 | ||
return date.toISOString().split('T')[0]; // Return the incremented date as a string in YYYY-MM-DD format | ||
}, | ||
}, | ||
watch: { | ||
initialDate(newValue) { | ||
this.selectedDate = newValue; | ||
const date = new Date(newValue); | ||
this.currentYear = date.getFullYear(); | ||
this.currentMonth = date.getMonth(); | ||
}, | ||
}, | ||
mounted() { | ||
this.selectedDate = this.initialDate; // Set the initial selected date | ||
}, | ||
}; | ||
</script> | ||
|
||
<style scoped> | ||
/* Add your styling here */ | ||
.date-picker { | ||
position: relative; | ||
} | ||
.date-input { | ||
background-color: #1e1e1e; | ||
color: #cfcfcf; | ||
border: 1px solid #4a4a4a; | ||
border-radius: 4px; | ||
padding: 8px; | ||
width: 90%; | ||
cursor: text; | ||
} | ||
.calendar { | ||
position: absolute; | ||
top: 40px; | ||
left: -10%; | ||
width: 90%; | ||
max-width: 300px; | ||
background-color: #2b2b2b; | ||
border: 1px solid #4a4a4a; | ||
border-radius: 4px; | ||
padding-left: 2px; | ||
padding-right: 25%; | ||
z-index: 1; | ||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); | ||
} | ||
.calendar-header { | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
font-size: 1.0em; | ||
} | ||
.calendar-grid { | ||
display: grid; | ||
grid-template-columns: repeat(7, 1fr); | ||
gap: 2px; | ||
} | ||
.day { | ||
padding: 1px; | ||
text-align: center; | ||
cursor: pointer; | ||
transition: background-color 0.3s; | ||
min-height: 5%; | ||
} | ||
.day.hover { | ||
background-color: rgba(0, 123, 255, 0.5); | ||
} | ||
.day.selected { | ||
background-color: rgba(0, 86, 179, 0.7); | ||
} | ||
</style> |
Oops, something went wrong.