デートピッカー Date Picker
カレンダーUIから日付を選択するフォーム要素。
ライブデモ
ソースコード
<div class="demo-datepicker">
<label class="demo-datepicker-label">日付を選択</label>
<div class="demo-datepicker-input-wrap">
<input class="demo-datepicker-input" type="text" placeholder="YYYY/MM/DD" readonly />
<svg class="demo-datepicker-cal-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
</div>
<div class="demo-datepicker-calendar" style="display:none;">
<div class="demo-datepicker-header">
<button class="demo-datepicker-prev">‹</button>
<span class="demo-datepicker-month-year"></span>
<button class="demo-datepicker-next">›</button>
</div>
<div class="demo-datepicker-weekdays">
<span>日</span><span>月</span><span>火</span><span>水</span><span>木</span><span>金</span><span>土</span>
</div>
<div class="demo-datepicker-days"></div>
</div>
</div>.demo-datepicker { position: relative; max-width: 280px; }
.demo-datepicker-label { display: block; font-size: 13px; font-weight: 600; color: #333; margin-bottom: 6px; }
.demo-datepicker-input-wrap { position: relative; }
.demo-datepicker-input {
width: 100%; padding: 10px 40px 10px 12px; border: 2px solid #d1d5db;
border-radius: 8px; font-size: 14px; cursor: pointer; outline: none;
transition: border-color 0.2s;
}
.demo-datepicker-input:focus { border-color: var(--ui-primary); }
.demo-datepicker-cal-icon { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); color: #999; pointer-events: none; }
.demo-datepicker-calendar {
position: absolute; top: 100%; left: 0; margin-top: 4px;
background: #fff; border: 1px solid #e5e7eb; border-radius: 12px;
padding: 12px; box-shadow: 0 4px 16px rgba(0,0,0,0.1); z-index: 20; width: 260px;
}
.demo-datepicker-header {
display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;
}
.demo-datepicker-header button {
background: none; border: none; font-size: 18px; cursor: pointer; color: var(--ui-primary);
width: 28px; height: 28px; border-radius: 6px;
}
.demo-datepicker-header button:hover { background: color-mix(in srgb, var(--ui-primary) 10%, transparent); }
.demo-datepicker-month-year { font-size: 14px; font-weight: 600; color: #333; }
.demo-datepicker-weekdays {
display: grid; grid-template-columns: repeat(7, 1fr); text-align: center;
font-size: 11px; color: #999; margin-bottom: 4px;
}
.demo-datepicker-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; }
.demo-datepicker-day {
padding: 6px; font-size: 13px; border-radius: 6px; cursor: pointer;
border: none; background: none; transition: background 0.15s;
}
.demo-datepicker-day:hover { background: color-mix(in srgb, var(--ui-primary) 10%, transparent); }
.demo-datepicker-day.today { font-weight: 700; color: var(--ui-primary); }
.demo-datepicker-day.selected { background: var(--ui-primary); color: #fff; }
.demo-datepicker-day.other-month { color: #ccc; }(function(){
const input = document.querySelector('.demo-datepicker-input');
const cal = document.querySelector('.demo-datepicker-calendar');
const daysEl = document.querySelector('.demo-datepicker-days');
const monthYearEl = document.querySelector('.demo-datepicker-month-year');
let current = new Date();
let selected = null;
function render() {
const y = current.getFullYear(), m = current.getMonth();
monthYearEl.textContent = y + '年' + (m+1) + '月';
const first = new Date(y, m, 1).getDay();
const last = new Date(y, m+1, 0).getDate();
const today = new Date();
let html = '';
for (let i = 0; i < first; i++) html += '<span class="demo-datepicker-day other-month"></span>';
for (let d = 1; d <= last; d++) {
const isToday = d === today.getDate() && m === today.getMonth() && y === today.getFullYear();
const isSel = selected && d === selected.getDate() && m === selected.getMonth() && y === selected.getFullYear();
html += '<button class="demo-datepicker-day'+(isToday?' today':'')+(isSel?' selected':'')+'" data-day="'+d+'">'+d+'</button>';
}
daysEl.innerHTML = html;
daysEl.querySelectorAll('.demo-datepicker-day[data-day]').forEach(btn => {
btn.addEventListener('click', function() {
selected = new Date(y, m, parseInt(this.dataset.day));
input.value = selected.getFullYear()+'/'+ String(selected.getMonth()+1).padStart(2,'0')+'/'+ String(selected.getDate()).padStart(2,'0');
cal.style.display = 'none';
render();
});
});
}
input.addEventListener('click', function() { cal.style.display = cal.style.display === 'none' ? 'block' : 'none'; render(); });
document.querySelector('.demo-datepicker-prev').addEventListener('click', function() { current.setMonth(current.getMonth()-1); render(); });
document.querySelector('.demo-datepicker-next').addEventListener('click', function() { current.setMonth(current.getMonth()+1); render(); });
document.addEventListener('click', function(e) { if (!e.target.closest('.demo-datepicker')) cal.style.display = 'none'; });
})();AIプロンプト
Basic
デートピッカーをHTML/CSS/JSで作ってください。カレンダーから日付を選択できるUIです。
Custom
以下の仕様でデートピッカーを実装してください。 - カレンダーグリッド表示 - プライマリカラー: #2563eb - 月の切り替えアニメーション(スライド) - 今日の日付をハイライト - 選択日の強調表示 - 日本語の曜日表示
Advanced
高機能デートピッカーを実装してください。 - 範囲選択モード(開始日〜終了日) - 無効な日付の設定(過去日、特定日) - キーボード操作(矢印キーで日付移動、Enter確定) - aria-label に日付を読み上げ用テキストで設定 - role="grid" + role="gridcell" の構造 - 年・月の直接選択(セレクトボックス) - 祝日の表示(日本の祝日API対応) - 国際化対応(ロケールで曜日・月名を変更)