Skip to content

Commit

Permalink
List element now has some responsive fields and dropdown of completed…
Browse files Browse the repository at this point in the history
… items
  • Loading branch information
philwing100 committed Sep 27, 2024
1 parent 5b28e56 commit b6e1c39
Show file tree
Hide file tree
Showing 17 changed files with 983 additions and 289 deletions.
94 changes: 54 additions & 40 deletions src/components/ListItems/CheckBox.vue
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>
83 changes: 83 additions & 0 deletions src/components/ListItems/CheckboxOneWay.vue
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>
197 changes: 189 additions & 8 deletions src/components/ListItems/DateInput.vue
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">&lt;</button>
<span>{{ monthNames[currentMonth] }} {{ currentYear }}</span>
<button @click="nextMonth">&gt;</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>
Loading

0 comments on commit b6e1c39

Please sign in to comment.