SelectDate Component Design Document
Overview
The SelectDate component is an interactive component in this component library used for date selection. It continues the consistent design philosophy of our component library, adopting the principles of "separation of concerns" and "logic abstraction." It implements a complete and easy-to-use date selection solution through core logic such as useSelectDate.
The SelectDate component focuses on handling users' date selection operations, providing an intuitive and visually appealing date selection feature that supports multiple date modes (date, month, year), range selection, time selection, and custom styles.
Design Philosophy
Layered Architecture
The SelectDate component strictly follows a three-layer architecture design:
- Structure Layer selectDate.vue - Responsible for the component's DOM structure and basic layout
- Logic Layer selectDateComputed.ts - Handles complex reactive computations and interaction logic
- Presentation Layer selectDate.scss - Defines the component's visual presentation and style rules
Logic Abstraction
The SelectDate component abstracts complex logic into core functions:
- useSelectDate - Handles the core logic of the date picker
This design allows the component itself to only declare the required logic, while the specific computations are handled by the logic functions.
Core Feature Design
Structured Props Design
The props design of the SelectDate component is concise and clear:
export const selectDateProps = {
modelValue: {
type: [String, Array] as PropType<string | string[]>,
default: ''
},
type: {
type: String,
default: 'date'
},
disabled: {
type: Boolean,
default: false
},
year: {
type: Boolean,
default: false
},
month: {
type: Boolean,
default: false
},
range: {
type: Boolean,
default: false
},
time: {
type: Boolean,
default: false
},
showToday: {
type: Boolean,
default: true
},
width: {
type: [String, Number] as PropType<SelectSize>,
default: '260px'
},
height: {
type: [String, Number] as PropType<SelectSize>,
default: '20px'
},
};This design provides sufficient flexibility and supports multiple usage scenarios.
Mode System
The SelectDate component supports multiple modes:
- Date Mode - Select a specific date
- Month Mode - Select a month
- Year Mode - Select a year
- Range Mode - Select a date range
- Time Mode - Select time
Style System Design
CSS Variable Control
The SelectDate component implements style control through SCSS variables:
$bg- Background color$border- Border color$text- Text color$hover- Hover color$sel- Selected color$today- Today indicator color
Size System
The SelectDate component supports flexible size control:
- Default Size - 350px × 20px
- Custom Size - Supports px, em, % and other units
- Responsive Design - Supports adaptation to different screen sizes
State Styles
The SelectDate component provides corresponding styles according to different states:
- Default State - Standard input box style
- Hover State - Style when mouse hovers
- Focus State - Style when focused
- Disabled State - Semi-transparent effect when disabled
- Selected State - Highlight effect when a date is selected
- Range State - Indicator effect within the date range
Component Structure Design
Overall Structure
The overall structure of the SelectDate component is as follows:
<div class="date-picker-container">
<div class="input-container">
<input :value="formattedDateTime" class="my-selectDate" :placeholder="placeholderText" readonly
@click="toggleDropdown" :style="selectStyle" />
<date-range-icon class="date-range-icon" />
</div>
<div v-if="showDropdown" class="date-picker-dropdown">
<!-- Time picker -->
<div v-if="props.time" class="time-picker-container">
<!-- ... -->
</div>
<!-- Range picker -->
<div v-if="mode.startsWith('range')" class="range-container">
<!-- ... -->
</div>
<!-- Single picker -->
<div v-else-if="mode === 'year'" class="year-picker">
<!-- ... -->
</div>
<div v-else-if="mode === 'month'" class="month-picker">
<!-- ... -->
</div>
<div v-else class="date-picker-default">
<!-- ... -->
</div>
</div>
</div>Calendar Grid Structure
The date selection grid structure is as follows:
<div class="date-grid grid-date">
<div v-for="d in daysOfWeek" :key="d" class="day-header">{{ d }}</div>
<div v-for="cell in calendarCells" :key="cell.key" class="day-cell">
<button type="button" v-if="cell.date" :class="{
selected: isSelected(cell.date),
disabled: !cell.isCurrentMonth,
today: isToday(cell.date)
}" :disabled="!cell.isCurrentMonth" @click="selectDate(cell.date)">
{{ cell.date.getDate() }}
<span v-if="isToday(cell.date)" class="today-badge">今</span>
</button>
</div>
</div>Interaction Design
Dropdown Expand/Collapse
The SelectDate component supports clicking to expand/collapse the dropdown:
function toggleDropdown() {
showDropdown.value = !showDropdown.value;
if (showDropdown.value) initFromModelValue();
}Date Selection
The SelectDate component supports multiple date selection methods:
function selectDate(date: Date) {
const val = formatDateTime(date, false, false);
emit('update:modelValue', val);
emit('change', val);
showDropdown.value = false;
}
function selectRangeDate(date: Date) {
if (isSelectingStart.value) {
startDate.value = date;
isSelectingStart.value = false;
emit('update:modelValue', [formatDateTime(date, true, true)]);
} else {
endDate.value = date;
const s = formatDateTime(startDate.value!, true, true);
const e = formatDateTime(date, true, false);
emit('update:modelValue', [s, e]);
emit('change', [s, e]);
showDropdown.value = false;
isSelectingStart.value = true;
}
}Close on Outside Click
The SelectDate component supports closing the dropdown when clicking outside:
function handleOutsideClick(e: MouseEvent) {
if (!(e.target as HTMLElement).closest('.date-picker-container')) {
showDropdown.value = false;
}
}Extensibility Design
The SelectDate component has excellent extensibility:
- Multiple Mode Support: Supports date, month, year, range, and time selection
- Custom Size: Control component size through width and height properties
- Disabled State: Control disabled state through the disabled property
- Time Selection: Control time selection functionality through the time property
- Today Indicator: Control today indicator display through the showToday property
- Style Customization: Support style customization through CSS variables
- Theme Adaptation: Supports theme customization through CSS variables
Style Details
The SelectDate component has the following characteristics in style handling:
- Transition Animation: Smooth transition effects when the dropdown expands/collapses
- Responsive Design: Supports flexible size adaptation
- Accessibility Design: Supports keyboard navigation and screen readers
- Consistency: Maintains style consistency with other form components in the component library
- Highlighting: Selected dates and ranges have obvious highlight effects
- Today Indicator: Today’s date has a special indicator
Performance Optimization
Performance is optimized through the following methods:
- Use computed properties to cache calculation results
- Move complex logic to independent functions
- Avoid unnecessary re-renders
- Use Vue 3 Composition API to improve runtime efficiency
- Reasonably add and remove event listeners
- Delay initialization of state to improve first render performance
Design Value
The SelectDate component continues the design philosophy of our component library:
- Separation of concerns: Structure, styles, and logic are completely decoupled
- High reusability: Abstract common logic through functions
- Easy maintenance: Clear code structure and naming conventions
- Strong extensibility: Supports rich customization options
- Consistency: Maintains a consistent design language with other components such as Select, PickColor, Rate, Switch, Checkbox, and Radio