podo-ui 0.9.7 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/cdn/podo-datepicker.css +1 -1
  2. package/cdn/podo-datepicker.js +1 -1
  3. package/cdn/podo-datepicker.min.css +1 -1
  4. package/cdn/podo-datepicker.min.js +1 -1
  5. package/cdn/podo-ui.css +4 -1
  6. package/cdn/podo-ui.min.css +1 -1
  7. package/dist/react/atom/editor.d.ts.map +1 -1
  8. package/dist/react/atom/editor.js +94 -2
  9. package/dist/svelte/actions/portal.d.ts +18 -0
  10. package/dist/svelte/actions/portal.js +42 -0
  11. package/dist/svelte/atom/Avatar.svelte +97 -0
  12. package/dist/svelte/atom/Avatar.svelte.d.ts +31 -0
  13. package/dist/svelte/atom/Button.svelte +86 -0
  14. package/dist/svelte/atom/Button.svelte.d.ts +26 -0
  15. package/dist/svelte/atom/Checkbox.svelte +56 -0
  16. package/dist/svelte/atom/Checkbox.svelte.d.ts +16 -0
  17. package/dist/svelte/atom/Chip.svelte +60 -0
  18. package/dist/svelte/atom/Chip.svelte.d.ts +25 -0
  19. package/dist/svelte/atom/Editor.svelte +1314 -0
  20. package/dist/svelte/atom/Editor.svelte.d.ts +30 -0
  21. package/dist/svelte/atom/EditorView.svelte +16 -0
  22. package/dist/svelte/atom/EditorView.svelte.d.ts +9 -0
  23. package/dist/svelte/atom/File.svelte +33 -0
  24. package/dist/svelte/atom/File.svelte.d.ts +14 -0
  25. package/dist/svelte/atom/Input.svelte +80 -0
  26. package/dist/svelte/atom/Input.svelte.d.ts +19 -0
  27. package/dist/svelte/atom/Label.svelte +43 -0
  28. package/dist/svelte/atom/Label.svelte.d.ts +19 -0
  29. package/dist/svelte/atom/Radio.svelte +69 -0
  30. package/dist/svelte/atom/Radio.svelte.d.ts +26 -0
  31. package/dist/svelte/atom/RadioGroup.svelte +46 -0
  32. package/dist/svelte/atom/RadioGroup.svelte.d.ts +16 -0
  33. package/dist/svelte/atom/Select.svelte +65 -0
  34. package/dist/svelte/atom/Select.svelte.d.ts +26 -0
  35. package/dist/svelte/atom/Textarea.svelte +53 -0
  36. package/dist/svelte/atom/Textarea.svelte.d.ts +13 -0
  37. package/dist/svelte/atom/Toggle.svelte +48 -0
  38. package/dist/svelte/atom/Toggle.svelte.d.ts +14 -0
  39. package/dist/svelte/atom/Tooltip.svelte +78 -0
  40. package/dist/svelte/atom/Tooltip.svelte.d.ts +23 -0
  41. package/dist/svelte/atom/avatar.module.scss +82 -0
  42. package/dist/svelte/atom/editor-view.module.scss +251 -0
  43. package/dist/svelte/atom/input.module.scss +98 -0
  44. package/dist/svelte/atom/textarea.module.scss +17 -0
  45. package/dist/svelte/atom/tooltip.module.scss +227 -0
  46. package/dist/svelte/index.d.ts +26 -0
  47. package/dist/svelte/index.js +30 -0
  48. package/dist/svelte/molecule/DatePicker.svelte +986 -0
  49. package/dist/svelte/molecule/DatePicker.svelte.d.ts +71 -0
  50. package/dist/svelte/molecule/Field.svelte +81 -0
  51. package/dist/svelte/molecule/Field.svelte.d.ts +26 -0
  52. package/dist/svelte/molecule/Pagination.svelte +95 -0
  53. package/dist/svelte/molecule/Pagination.svelte.d.ts +14 -0
  54. package/dist/svelte/molecule/Tab.svelte +69 -0
  55. package/dist/svelte/molecule/Tab.svelte.d.ts +26 -0
  56. package/dist/svelte/molecule/TabPanel.svelte +24 -0
  57. package/dist/svelte/molecule/TabPanel.svelte.d.ts +14 -0
  58. package/dist/svelte/molecule/Table.svelte +109 -0
  59. package/dist/svelte/molecule/Table.svelte.d.ts +54 -0
  60. package/dist/svelte/molecule/Toast.svelte +111 -0
  61. package/dist/svelte/molecule/Toast.svelte.d.ts +25 -0
  62. package/dist/svelte/molecule/ToastProvider.svelte +74 -0
  63. package/dist/svelte/molecule/ToastProvider.svelte.d.ts +8 -0
  64. package/dist/svelte/molecule/field.module.scss +22 -0
  65. package/dist/svelte/molecule/pagination.module.scss +61 -0
  66. package/dist/svelte/molecule/toast-container.module.scss +70 -0
  67. package/dist/svelte/molecule/toast.module.scss +12 -0
  68. package/dist/svelte/stores/toast.d.ts +45 -0
  69. package/dist/svelte/stores/toast.js +55 -0
  70. package/dist/svelte/stores/validation.d.ts +15 -0
  71. package/dist/svelte/stores/validation.js +38 -0
  72. package/global.scss +1 -0
  73. package/package.json +32 -5
  74. package/vite-fonts.scss +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Podo UI DatePicker CSS v0.9.7
2
+ * Podo UI DatePicker CSS v1.0.2
3
3
  * https://podoui.com
4
4
  * MIT License
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Podo UI DatePicker v0.9.7
2
+ * Podo UI DatePicker v1.0.2
3
3
  * https://podoui.com
4
4
  * MIT License
5
5
  */
@@ -1,2 +1,2 @@
1
- /*! Podo UI DatePicker CSS v0.9.7 | MIT License | https://podoui.com */
1
+ /*! Podo UI DatePicker CSS v1.0.2 | MIT License | https://podoui.com */
2
2
  .podo-datepicker{--podo-bg-block:var(--color-bg-block,#ffffff);--podo-bg-modal:var(--color-bg-modal,#ffffff);--podo-bg-disabled:var(--color-bg-disabled,#f5f5f5);--podo-border:var(--color-border,#e0e0e0);--podo-border-hover:var(--color-border-hover,#bdbdbd);--podo-text-body:var(--color-text-body,#212121);--podo-text-sub:var(--color-text-sub,#757575);--podo-text-disabled:var(--color-text-disabled,#9e9e9e);--podo-primary:var(--color-primary,#7c3aed);--podo-primary-hover:var(--color-primary-hover,#6d28d9);--podo-primary-fill:var(--color-primary-fill,rgba(124,58,237,0.1));--podo-primary-reverse:var(--color-primary-reverse,#ffffff);--podo-default:var(--color-default,#f5f5f5);--podo-default-fill:var(--color-default-fill,#eeeeee);--podo-default-hover:var(--color-default-hover,#e0e0e0);--podo-default-reverse:var(--color-default-reverse,#212121);--podo-radius-sm:var(--radius-2,4px);--podo-radius-md:var(--radius-3,8px);--podo-spacing-1:var(--spacing-1,4px);--podo-spacing-2:var(--spacing-2,8px);--podo-spacing-3:var(--spacing-3,12px);--podo-spacing-4:var(--spacing-4,16px);--podo-spacing-5:var(--spacing-5,20px);--podo-font-size-sm:13px;--podo-font-size-md:14px;--podo-font-size-lg:16px;}.podo-datepicker{position:relative;display:inline-block;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;font-size:var(--podo-font-size-md);line-height:1.5;}.podo-datepicker__input{display:flex;align-items:center;gap:var(--podo-spacing-2);padding:var(--podo-spacing-3) var(--podo-spacing-4);background:var(--podo-bg-block);border:1px solid var(--podo-border);border-radius:var(--podo-radius-md);cursor:pointer;transition:border-color 0.2s;}.podo-datepicker__input:hover{border-color:var(--podo-border-hover);}.podo-datepicker__input--active{border-color:var(--podo-primary);}.podo-datepicker__input--disabled{background:var(--podo-bg-disabled);cursor:not-allowed;opacity:0.6;}.podo-datepicker__input-content{flex:1;display:flex;align-items:center;gap:var(--podo-spacing-2);}.podo-datepicker__part{display:flex;flex:1;align-items:center;justify-content:center;padding:0 var(--podo-spacing-2);background:none;border:none;border-radius:var(--podo-radius-sm);cursor:pointer;transition:background 0.2s;color:var(--podo-text-body);white-space:nowrap;font-variant-numeric:tabular-nums;font-family:inherit;font-size:var(--podo-font-size-md);}.podo-datepicker__part:hover{background:var(--podo-default);}.podo-datepicker__part--active{background:var(--podo-default-fill);}.podo-datepicker__part--placeholder{color:var(--podo-text-disabled);}.podo-datepicker__separator{color:var(--podo-text-body);padding:0 var(--podo-spacing-1);font-size:var(--podo-font-size-md);}.podo-datepicker__time-section{display:flex;align-items:center;justify-content:center;gap:0;}.podo-datepicker__time-select{appearance:none;-webkit-appearance:none;-moz-appearance:none;background:none;border:none;padding:0 var(--podo-spacing-2);flex:1;text-align:center;text-align-last:center;color:var(--podo-text-body);cursor:pointer;border-radius:var(--podo-radius-sm);transition:background 0.2s;font-variant-numeric:tabular-nums;font-family:inherit;font-size:var(--podo-font-size-md);}.podo-datepicker__time-select:hover{background:var(--podo-default);}.podo-datepicker__time-select:focus{outline:none;background:var(--podo-default-fill);}.podo-datepicker__time-select--placeholder{color:var(--podo-text-disabled);}.podo-datepicker__time-select:disabled{cursor:not-allowed;opacity:0.6;}.podo-datepicker__time-separator{color:var(--podo-text-body);font-size:var(--podo-font-size-md);}.podo-datepicker__icon{display:flex;align-items:center;justify-content:center;width:20px;height:20px;font-size:20px;line-height:1;color:var(--podo-text-sub);flex-shrink:0;}.podo-datepicker__dropdown{position:absolute;top:calc(100%+var(--podo-spacing-2));left:0;z-index:1000;display:flex;flex-direction:column;gap:10px;padding:var(--podo-spacing-5);background:var(--podo-bg-modal);border-radius:var(--podo-radius-md);box-shadow:0 6px 18px -3px rgba(50,50,50,0.12);}.podo-datepicker__dropdown--right{left:auto;right:0;}.podo-datepicker__calendar{display:flex;flex-direction:column;gap:10px;min-width:280px;}.podo-datepicker__calendar-nav{display:flex;align-items:center;gap:var(--podo-spacing-4);height:40px;}.podo-datepicker__nav-button{display:flex;align-items:center;justify-content:center;width:40px;height:40px;background:var(--podo-default);border:none;border-radius:var(--podo-radius-md);cursor:pointer;transition:background 0.2s;}.podo-datepicker__nav-button:hover{background:var(--podo-default-hover);}.podo-datepicker__nav-button:disabled{opacity:0.5;cursor:not-allowed;}.podo-datepicker__nav-button i{font-size:20px;color:var(--podo-text-body);}.podo-datepicker__nav-title{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--podo-spacing-1);}.podo-datepicker__nav-select-wrapper{position:relative;display:flex;align-items:center;}.podo-datepicker__nav-select-wrapper::after{content:'';position:absolute;right:var(--podo-spacing-2);top:50%;transform:translateY(-50%);width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:5px solid var(--podo-text-body);pointer-events:none;}.podo-datepicker__nav-select{appearance:none;-webkit-appearance:none;-moz-appearance:none;background:none;border:none;padding:var(--podo-spacing-2) 24px var(--podo-spacing-2) var(--podo-spacing-2);border-radius:var(--podo-radius-sm);cursor:pointer;transition:background 0.2s;color:var(--podo-text-body);font-family:inherit;font-size:var(--podo-font-size-lg);font-weight:600;}.podo-datepicker__nav-select:hover{background:var(--podo-default);}.podo-datepicker__nav-select:focus{outline:none;background:var(--podo-default-fill);}.podo-datepicker__calendar-grid{display:flex;flex-direction:column;gap:var(--podo-spacing-2);padding-top:var(--podo-spacing-3);border-top:1px solid var(--podo-border);}.podo-datepicker__calendar-row{display:flex;width:100%;}.podo-datepicker__calendar-cell{flex:1;display:flex;align-items:center;justify-content:center;height:40px;font-size:var(--podo-font-size-md);background:none;border:none;border-radius:var(--podo-radius-md);cursor:pointer;transition:background 0.2s;font-family:inherit;color:var(--podo-text-body);}.podo-datepicker__calendar-cell--header{color:var(--podo-text-sub);cursor:default;font-weight:500;}.podo-datepicker__calendar-cell--other{color:var(--podo-text-disabled);}.podo-datepicker__calendar-cell--today{font-weight:600;color:var(--podo-primary);}.podo-datepicker__calendar-cell--selected{background:var(--podo-primary);color:var(--podo-primary-reverse);font-weight:600;}.podo-datepicker__calendar-cell--in-range{background:var(--podo-primary-fill);border-radius:0;}.podo-datepicker__calendar-cell--range-start{background:var(--podo-primary);color:var(--podo-primary-reverse);font-weight:600;border-radius:var(--podo-radius-md);}.podo-datepicker__calendar-cell--range-end{background:var(--podo-primary);color:var(--podo-primary-reverse);font-weight:600;border-radius:var(--podo-radius-md);}.podo-datepicker__calendar-cell--disabled{color:var(--podo-text-disabled);background:var(--podo-default);border:none;border-radius:0;outline:none;cursor:not-allowed;}.podo-datepicker__calendar-cell--disabled:hover{background:var(--podo-default);}.podo-datepicker__calendar-cell:not(.podo-datepicker__calendar-cell--header):not(.podo-datepicker__calendar-cell--selected):not(.podo-datepicker__calendar-cell--disabled):not(.podo-datepicker__calendar-cell--range-start):not(.podo-datepicker__calendar-cell--range-end):not(.podo-datepicker__calendar-cell--in-range):hover{background:var(--podo-default);}.podo-datepicker__period-calendars{display:flex;gap:var(--podo-spacing-4);}.podo-datepicker__period-calendar-left,.podo-datepicker__period-calendar-right{flex:1;}.podo-datepicker__actions{display:flex;align-items:center;justify-content:space-between;gap:var(--podo-spacing-3);padding-top:var(--podo-spacing-3);border-top:1px solid var(--podo-border);}.podo-datepicker__period-text{font-size:var(--podo-font-size-md);color:var(--podo-primary);flex:1;}.podo-datepicker__action-buttons{display:flex;gap:var(--podo-spacing-3);flex-shrink:0;}.podo-datepicker__action-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--podo-spacing-2);padding:var(--podo-spacing-3) var(--podo-spacing-4);border-radius:var(--podo-radius-md);cursor:pointer;transition:background 0.2s;white-space:nowrap;font-family:inherit;font-size:var(--podo-font-size-md);}.podo-datepicker__action-button i{display:flex;align-items:center;justify-content:center;width:18px;height:18px;font-size:18px;line-height:1;}.podo-datepicker__action-button--reset{background:var(--podo-default-fill);border:1px solid var(--podo-border);color:var(--podo-default-reverse);}.podo-datepicker__action-button--reset:hover{background:var(--podo-default-hover);}.podo-datepicker__action-button--apply{background:var(--podo-primary);border:none;color:var(--podo-primary-reverse);}.podo-datepicker__action-button--apply:hover{background:var(--podo-primary-hover);}
@@ -1,2 +1,2 @@
1
- /*! Podo UI DatePicker v0.9.7 | MIT License | https://podoui.com */
1
+ /*! Podo UI DatePicker v1.0.2 | MIT License | https://podoui.com */
2
2
  (function (global, factory) {typeof exports === 'object' && typeof module !== 'undefined'? (module.exports = factory()): typeof define === 'function' && define.amd? define(factory): ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),(global.PodoDatePicker = factory()));})(this, function () {'use strict';const PREFIX = 'podo-datepicker';const DEFAULT_TEXTS = {weekDays: ['일', '월', '화', '수', '목', '금', '토'],months: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],yearSuffix: '년',reset: '초기화',apply: '적용',};function resolveCalendarInitial(initial, fallback) {if (!initial) return fallback;if (initial instanceof Date) return initial;const now = new Date();switch (initial) {case 'now':return new Date(now.getFullYear(), now.getMonth(), 1);case 'prevMonth':return new Date(now.getFullYear(), now.getMonth() - 1, 1);case 'nextMonth':return new Date(now.getFullYear(), now.getMonth() + 1, 1);default:return fallback;}}function formatWithPattern(date, time, pattern) {if (!date && !time) return '';let result = pattern;if (date) {result = result.replace(/y/g, String(date.getFullYear()));result = result.replace(/m/g, String(date.getMonth() + 1).padStart(2, '0'));result = result.replace(/d/g, String(date.getDate()).padStart(2, '0'));}if (time) {result = result.replace(/h/g, String(time.hour).padStart(2, '0'));result = result.replace(/i/g, String(time.minute).padStart(2, '0'));}return result;}function getDateOnlyFormat(format) {if (!format) return undefined;return format.replace(/\s*h[:\s]*i[분]?/g, '').replace(/\s*h시\s*i분/g, '').trim();}function formatDate(date) {const year = date.getFullYear();const month = String(date.getMonth() + 1).padStart(2, '0');const day = String(date.getDate()).padStart(2, '0');return `${year} - ${month} - ${day}`;}function formatTime(hour, minute) {return `${String(hour).padStart(2, '0')} : ${String(minute).padStart(2, '0')}`;}function isSameDay(date1, date2) {if (!date1 || !date2) return false;return (date1.getFullYear() === date2.getFullYear() &&date1.getMonth() === date2.getMonth() &&date1.getDate() === date2.getDate());}function isInRange(date, start, end) {const d = new Date(date.getFullYear(), date.getMonth(), date.getDate());const s = new Date(start.getFullYear(), start.getMonth(), start.getDate());const e = new Date(end.getFullYear(), end.getMonth(), end.getDate());return d >= s && d <= e;}function isInRangeExclusive(date, start, end) {const d = new Date(date.getFullYear(), date.getMonth(), date.getDate());const s = new Date(start.getFullYear(), start.getMonth(), start.getDate());const e = new Date(end.getFullYear(), end.getMonth(), end.getDate());return d > s && d < e;}function getDaysInMonth(year, month) {return new Date(year, month + 1, 0).getDate();}function getFirstDayOfMonth(year, month) {return new Date(year, month, 1).getDay();}function isDateRange(condition) {return typeof condition === 'object' && condition !== null && 'from' in condition && 'to' in condition;}function matchesCondition(date, condition) {if (typeof condition === 'function') {return condition(date);}if (isDateRange(condition)) {return isInRange(date, condition.from, condition.to);}return isSameDay(date, condition);}function isDateDisabled(date, disable, enable) {if (enable && enable.length > 0) {const isEnabled = enable.some((condition) => matchesCondition(date, condition));return !isEnabled;}if (disable && disable.length > 0) {return disable.some((condition) => matchesCondition(date, condition));}return false;}function isDateTimeLimit(value) {return typeof value === 'object' && value !== null && 'date' in value && !(value instanceof Date);}function extractDateTimeLimit(limit) {if (isDateTimeLimit(limit)) {return { date: limit.date, time: limit.time };}return { date: limit };}function isBeforeMinDate(date, minDate) {if (!minDate) return false;const { date: minDateValue } = extractDateTimeLimit(minDate);const d = new Date(date.getFullYear(), date.getMonth(), date.getDate());const m = new Date(minDateValue.getFullYear(), minDateValue.getMonth(), minDateValue.getDate());return d < m;}function isAfterMaxDate(date, maxDate) {if (!maxDate) return false;const { date: maxDateValue } = extractDateTimeLimit(maxDate);const d = new Date(date.getFullYear(), date.getMonth(), date.getDate());const m = new Date(maxDateValue.getFullYear(), maxDateValue.getMonth(), maxDateValue.getDate());return d > m;}function createElement(tag, className, content) {const el = document.createElement(tag);if (className) el.className = className;if (content !== undefined) {if (typeof content === 'string' || typeof content === 'number') {el.textContent = content;} else if (content instanceof HTMLElement) {el.appendChild(content);}}return el;}class PodoDatePicker {constructor(container, options = {}) {this.container =typeof container === 'string' ? document.querySelector(container) : container;if (!this.container) {throw new Error('PodoDatePicker: Container element not found');}this.mode = options.mode || 'instant';this.type = options.type || 'date';this.value = options.value || {};this.tempValue = { ...this.value };this.onChange = options.onChange;this.placeholder = options.placeholder;this.disabled = options.disabled || false;this.showActions = options.showActions ?? this.mode === 'period';this.align = options.align || 'left';this.disable = options.disable || [];this.enable = options.enable || [];this.minDate = options.minDate;this.maxDate = options.maxDate;this.minuteStep = options.minuteStep || 1;this.texts = { ...DEFAULT_TEXTS, ...options.texts };this.format = options.format;this.initialCalendar = options.initialCalendar || {};this.yearRange = options.yearRange;this.isOpen = false;this.selectingPart = null;if (this.value.date) {this.viewDate = new Date(this.value.date);} else if (this.initialCalendar.start) {this.viewDate = resolveCalendarInitial(this.initialCalendar.start, new Date());} else {this.viewDate = new Date();}if (this.value.endDate) {this.endViewDate = new Date(this.value.endDate.getFullYear(),this.value.endDate.getMonth() + 1,1);} else if (this.initialCalendar.end) {this.endViewDate = resolveCalendarInitial(this.initialCalendar.end, new Date());} else {this.endViewDate = new Date(this.viewDate.getFullYear(),this.viewDate.getMonth() + 1,1);}this.render();this.bindEvents();}render() {this.container.innerHTML = '';this.container.className = PREFIX;this.inputEl = createElement('div', `${PREFIX}__input`);if (this.disabled) this.inputEl.classList.add(`${PREFIX}__input--disabled`);this.inputContentEl = createElement('div', `${PREFIX}__input-content`);this.renderInputContent();this.inputEl.appendChild(this.inputContentEl);const iconClass = this.type === 'time' ? 'icon-time' : 'icon-calendar';this.iconEl = createElement('i', `${PREFIX}__icon ${iconClass}`);this.inputEl.appendChild(this.iconEl);this.container.appendChild(this.inputEl);this.dropdownEl = createElement('div',`${PREFIX}__dropdown ${this.align === 'right' ? `${PREFIX}__dropdown--right` : ''}`);this.dropdownEl.style.display = 'none';this.container.appendChild(this.dropdownEl);}renderInputContent() {this.inputContentEl.innerHTML = '';const displayValue = this.showActions ? this.tempValue : this.value;if (this.type === 'date') {this.renderDateInput(displayValue);} else if (this.type === 'time') {this.renderTimeInput(displayValue);} else {this.renderDateTimeInput(displayValue);}}renderDateInput(displayValue) {this.startDateBtn = this.createDateButton(displayValue.date, 'date');this.inputContentEl.appendChild(this.startDateBtn);if (this.mode === 'period') {const sep = createElement('span', `${PREFIX}__separator`, '~');this.inputContentEl.appendChild(sep);this.endDateBtn = this.createDateButton(displayValue.endDate, 'endDate');this.inputContentEl.appendChild(this.endDateBtn);}}renderTimeInput(displayValue) {const startTimeSection = this.createTimeSection(displayValue.time, 'hour', 'minute');this.inputContentEl.appendChild(startTimeSection);if (this.mode === 'period') {const sep = createElement('span', `${PREFIX}__separator`, '~');this.inputContentEl.appendChild(sep);const endTimeSection = this.createTimeSection(displayValue.endTime, 'endHour', 'endMinute');this.inputContentEl.appendChild(endTimeSection);}}renderDateTimeInput(displayValue) {this.startDateBtn = this.createDateButton(displayValue.date, 'date');this.inputContentEl.appendChild(this.startDateBtn);const startTimeSection = this.createTimeSection(displayValue.time, 'hour', 'minute');this.inputContentEl.appendChild(startTimeSection);if (this.mode === 'period') {const sep = createElement('span', `${PREFIX}__separator`, '~');this.inputContentEl.appendChild(sep);this.endDateBtn = this.createDateButton(displayValue.endDate, 'endDate');this.inputContentEl.appendChild(this.endDateBtn);const endTimeSection = this.createTimeSection(displayValue.endTime, 'endHour', 'endMinute');this.inputContentEl.appendChild(endTimeSection);}}createDateButton(date, part) {const btn = createElement('button', `${PREFIX}__part`);btn.type = 'button';const dateFormat = getDateOnlyFormat(this.format);if (!date) {btn.classList.add(`${PREFIX}__part--placeholder`);const placeholderText = dateFormat? dateFormat.replace(/y/g, 'YYYY').replace(/m/g, 'MM').replace(/d/g, 'DD'): 'YYYY - MM - DD';btn.textContent = placeholderText;} else {const displayText = dateFormat? formatWithPattern(date, null, dateFormat): formatDate(date);btn.textContent = displayText;}btn.dataset.part = part;return btn;}createTimeSection(time, hourPart, minutePart) {const section = createElement('div', `${PREFIX}__time-section`);const hourSelect = this.createHourSelect(time, hourPart);section.appendChild(hourSelect);const sep = createElement('span', `${PREFIX}__time-separator`, ':');section.appendChild(sep);const minuteSelect = this.createMinuteSelect(time, minutePart);section.appendChild(minuteSelect);return section;}createHourSelect(time, part) {const select = createElement('select', `${PREFIX}__time-select`);if (!time) select.classList.add(`${PREFIX}__time-select--placeholder`);if (this.disabled) select.disabled = true;const isEnd = part === 'endHour';const currentDate = isEnd ? this.tempValue.endDate : this.tempValue.date;for (let h = 0; h < 24; h++) {const opt = createElement('option', null, String(h).padStart(2, '0'));opt.value = h;if (this.isHourDisabled(h, currentDate)) {opt.disabled = true;}select.appendChild(opt);}select.value = time?.hour ?? 0;select.dataset.part = part;return select;}createMinuteSelect(time, part) {const select = createElement('select', `${PREFIX}__time-select`);if (!time) select.classList.add(`${PREFIX}__time-select--placeholder`);if (this.disabled) select.disabled = true;const isEnd = part === 'endMinute';const currentDate = isEnd ? this.tempValue.endDate : this.tempValue.date;const currentTime = isEnd ? this.tempValue.endTime : this.tempValue.time;for (let m = 0; m < 60; m += this.minuteStep) {const opt = createElement('option', null, String(m).padStart(2, '0'));opt.value = m;if (this.isMinuteDisabled(m, currentDate, currentTime)) {opt.disabled = true;}select.appendChild(opt);}let minute = time?.minute ?? 0;if (minute % this.minuteStep !== 0) {minute = Math.floor(minute / this.minuteStep) * this.minuteStep;}select.value = minute;select.dataset.part = part;return select;}isHourDisabled(h, currentDate) {if (!currentDate) return false;const minLimit = this.minDate ? extractDateTimeLimit(this.minDate) : null;const maxLimit = this.maxDate ? extractDateTimeLimit(this.maxDate) : null;if (minLimit?.time && isSameDay(currentDate, minLimit.date)) {if (h < minLimit.time.hour) return true;}if (maxLimit?.time && isSameDay(currentDate, maxLimit.date)) {if (h > maxLimit.time.hour) return true;}return false;}isMinuteDisabled(m, currentDate, currentTime) {if (!currentDate || !currentTime) return false;const minLimit = this.minDate ? extractDateTimeLimit(this.minDate) : null;const maxLimit = this.maxDate ? extractDateTimeLimit(this.maxDate) : null;if (minLimit?.time && isSameDay(currentDate, minLimit.date) && currentTime.hour === minLimit.time.hour) {if (m < minLimit.time.minute) return true;}if (maxLimit?.time && isSameDay(currentDate, maxLimit.date) && currentTime.hour === maxLimit.time.hour) {if (m > maxLimit.time.minute) return true;}return false;}renderDropdown() {this.dropdownEl.innerHTML = '';if (this.mode === 'period') {this.renderPeriodCalendars();} else {this.renderCalendar(this.viewDate, (date) => this.handleViewDateChange(date));}if (this.showActions) {this.renderActions();}}renderCalendar(viewDate, onViewDateChange, opts = {}) {const calendar = createElement('div', `${PREFIX}__calendar`);const nav = this.renderCalendarNav(viewDate, onViewDateChange, opts);calendar.appendChild(nav);const grid = this.renderCalendarGrid(viewDate);calendar.appendChild(grid);this.dropdownEl.appendChild(calendar);return calendar;}renderPeriodCalendars() {const wrapper = createElement('div', `${PREFIX}__period-calendars`);const leftCal = createElement('div', `${PREFIX}__period-calendar-left`);const leftCalendar = this.createCalendarElement(this.viewDate,(date) => this.handleViewDateChange(date),{ maxViewDate: this.endViewDate });leftCal.appendChild(leftCalendar);wrapper.appendChild(leftCal);const rightCal = createElement('div', `${PREFIX}__period-calendar-right`);const rightCalendar = this.createCalendarElement(this.endViewDate,(date) => this.handleEndViewDateChange(date),{ minViewDate: this.viewDate });rightCal.appendChild(rightCalendar);wrapper.appendChild(rightCal);this.dropdownEl.appendChild(wrapper);}createCalendarElement(viewDate, onViewDateChange, opts = {}) {const calendar = createElement('div', `${PREFIX}__calendar`);const nav = this.renderCalendarNav(viewDate, onViewDateChange, opts);calendar.appendChild(nav);const grid = this.renderCalendarGrid(viewDate);calendar.appendChild(grid);return calendar;}calculateYearBounds(minViewYear, maxViewYear) {const currentYear = new Date().getFullYear();let minYearBound = currentYear - 100;let maxYearBound = currentYear + 100;if (this.minDate) {const { date } = extractDateTimeLimit(this.minDate);minYearBound = Math.max(minYearBound, date.getFullYear());}if (this.maxDate) {const { date } = extractDateTimeLimit(this.maxDate);maxYearBound = Math.min(maxYearBound, date.getFullYear());}if (this.yearRange?.min !== undefined) minYearBound = this.yearRange.min;if (this.yearRange?.max !== undefined) maxYearBound = this.yearRange.max;return { minYearBound, maxYearBound };}renderCalendarNav(viewDate, onViewDateChange, opts = {}) {const nav = createElement('div', `${PREFIX}__calendar-nav`);const year = viewDate.getFullYear();const month = viewDate.getMonth();const minViewDate = opts.minViewDate;const maxViewDate = opts.maxViewDate;const minYear = minViewDate?.getFullYear();const minMonth = minViewDate?.getMonth();const maxYear = maxViewDate?.getFullYear();const maxMonth = maxViewDate?.getMonth();const isPrevDisabled = minViewDate? year < minYear || (year === minYear && month <= minMonth): false;const isNextDisabled = maxViewDate? year > maxYear || (year === maxYear && month >= maxMonth): false;const prevBtn = createElement('button', `${PREFIX}__nav-button`);prevBtn.type = 'button';prevBtn.innerHTML = '<i class="icon-expand-left"></i>';if (isPrevDisabled) prevBtn.disabled = true;prevBtn.addEventListener('click', () => {if (!isPrevDisabled) {onViewDateChange(new Date(year, month - 1, 1));this.renderDropdown();}});nav.appendChild(prevBtn);const title = createElement('div', `${PREFIX}__nav-title`);const yearWrapper = createElement('div', `${PREFIX}__nav-select-wrapper`);const yearSelect = createElement('select', `${PREFIX}__nav-select`);const { minYearBound, maxYearBound } = this.calculateYearBounds(minYear, maxYear);for (let y = minYearBound; y <= maxYearBound; y++) {if (minYear !== undefined && y < minYear) continue;if (maxYear !== undefined && y > maxYear) continue;const opt = createElement('option', null, `${y}${this.texts.yearSuffix}`);opt.value = y;yearSelect.appendChild(opt);}yearSelect.value = year;yearSelect.addEventListener('change', (e) => {onViewDateChange(new Date(parseInt(e.target.value), month, 1));this.renderDropdown();});yearWrapper.appendChild(yearSelect);title.appendChild(yearWrapper);const monthWrapper = createElement('div', `${PREFIX}__nav-select-wrapper`);const monthSelect = createElement('select', `${PREFIX}__nav-select`);for (let m = 0; m < 12; m++) {if (minYear !== undefined && minMonth !== undefined && year === minYear && m < minMonth) continue;if (maxYear !== undefined && maxMonth !== undefined && year === maxYear && m > maxMonth) continue;const opt = createElement('option', null, this.texts.months[m]);opt.value = m;monthSelect.appendChild(opt);}monthSelect.value = month;monthSelect.addEventListener('change', (e) => {onViewDateChange(new Date(year, parseInt(e.target.value), 1));this.renderDropdown();});monthWrapper.appendChild(monthSelect);title.appendChild(monthWrapper);nav.appendChild(title);const nextBtn = createElement('button', `${PREFIX}__nav-button`);nextBtn.type = 'button';nextBtn.innerHTML = '<i class="icon-expand-right"></i>';if (isNextDisabled) nextBtn.disabled = true;nextBtn.addEventListener('click', () => {if (!isNextDisabled) {onViewDateChange(new Date(year, month + 1, 1));this.renderDropdown();}});nav.appendChild(nextBtn);return nav;}renderCalendarGrid(viewDate) {const grid = createElement('div', `${PREFIX}__calendar-grid`);const year = viewDate.getFullYear();const month = viewDate.getMonth();const today = new Date();const headerRow = createElement('div', `${PREFIX}__calendar-row`);this.texts.weekDays.forEach((day) => {const cell = createElement('div', `${PREFIX}__calendar-cell ${PREFIX}__calendar-cell--header`, day);headerRow.appendChild(cell);});grid.appendChild(headerRow);const daysInMonth = getDaysInMonth(year, month);const firstDay = getFirstDayOfMonth(year, month);const prevMonthDays = getDaysInMonth(year, month - 1);let days = [];for (let i = firstDay - 1; i >= 0; i--) {const day = prevMonthDays - i;const date = new Date(year, month - 1, day);days.push({ day, date, isOther: true });}for (let day = 1; day <= daysInMonth; day++) {const date = new Date(year, month, day);days.push({ day, date, isOther: false });}const totalCells = Math.ceil((firstDay + daysInMonth) / 7) * 7;const remainingDays = totalCells - (firstDay + daysInMonth);for (let day = 1; day <= remainingDays; day++) {const date = new Date(year, month + 1, day);days.push({ day, date, isOther: true });}for (let i = 0; i < days.length; i += 7) {const row = createElement('div', `${PREFIX}__calendar-row`);for (let j = 0; j < 7 && i + j < days.length; j++) {const { day, date, isOther } = days[i + j];const cell = this.createDayCell(day, date, isOther, today);row.appendChild(cell);}grid.appendChild(row);}return grid;}createDayCell(day, date, isOther, today) {const cell = createElement('button', `${PREFIX}__calendar-cell`);cell.type = 'button';cell.textContent = day;const isDisabled = this.checkDateDisabled(date);if (isOther) cell.classList.add(`${PREFIX}__calendar-cell--other`);if (isDisabled) {cell.classList.add(`${PREFIX}__calendar-cell--disabled`);cell.disabled = true;}const isToday = isSameDay(date, today);const isSelected = this.mode === 'instant' && isSameDay(date, this.tempValue.date);const isRangeStart = this.mode === 'period' && isSameDay(date, this.tempValue.date);const isRangeEnd = this.mode === 'period' && isSameDay(date, this.tempValue.endDate);const isInRangeDay =this.mode === 'period' &&this.tempValue.date &&this.tempValue.endDate &&isInRangeExclusive(date, this.tempValue.date, this.tempValue.endDate);if (isToday && !isSelected && !isRangeStart && !isRangeEnd) {cell.classList.add(`${PREFIX}__calendar-cell--today`);}if (isSelected) cell.classList.add(`${PREFIX}__calendar-cell--selected`);if (isRangeStart) cell.classList.add(`${PREFIX}__calendar-cell--range-start`);if (isRangeEnd) cell.classList.add(`${PREFIX}__calendar-cell--range-end`);if (isInRangeDay) cell.classList.add(`${PREFIX}__calendar-cell--in-range`);if (!isDisabled) {cell.addEventListener('click', () => this.handleDateSelect(date));}return cell;}checkDateDisabled(date) {if (isDateDisabled(date, this.disable, this.enable)) return true;if (isBeforeMinDate(date, this.minDate)) return true;if (isAfterMaxDate(date, this.maxDate)) return true;return false;}renderActions() {const actions = createElement('div', `${PREFIX}__actions`);const periodText = createElement('span', `${PREFIX}__period-text`);if (this.mode === 'period' && this.tempValue.date) {periodText.textContent = this.formatPeriodText();}actions.appendChild(periodText);const buttons = createElement('div', `${PREFIX}__action-buttons`);const resetBtn = createElement('button', `${PREFIX}__action-button ${PREFIX}__action-button--reset`);resetBtn.type = 'button';resetBtn.innerHTML = `<i class="icon-refresh"></i>${this.texts.reset}`;resetBtn.addEventListener('click', () => this.handleReset());buttons.appendChild(resetBtn);const applyBtn = createElement('button', `${PREFIX}__action-button ${PREFIX}__action-button--apply`);applyBtn.type = 'button';applyBtn.textContent = this.texts.apply;applyBtn.addEventListener('click', () => this.handleApply());buttons.appendChild(applyBtn);actions.appendChild(buttons);this.dropdownEl.appendChild(actions);}formatPeriodText() {if (!this.tempValue.date) return '';if (this.format) {const startText = formatWithPattern(this.tempValue.date, this.tempValue.time, this.format);if (this.tempValue.endDate) {const endText = formatWithPattern(this.tempValue.endDate, this.tempValue.endTime, this.format);return `${startText} ~ ${endText}`;}return startText;}const formatKoreanDateTime = (date, time) => {const year = date.getFullYear();const month = date.getMonth() + 1;const day = date.getDate();let dateStr = `${year}년 ${month}월 ${day}일`;if (this.type === 'datetime' && time) {const hours = String(time.hour).padStart(2, '0');const minutes = String(time.minute).padStart(2, '0');dateStr += ` ${hours}:${minutes}`;}return dateStr;};const startText = formatKoreanDateTime(this.tempValue.date, this.tempValue.time);if (this.tempValue.endDate) {const endText = formatKoreanDateTime(this.tempValue.endDate, this.tempValue.endTime);return `${startText} ~ ${endText}`;}return startText;}bindEvents() {this.inputEl.addEventListener('click', (e) => {if (this.disabled) return;const target = e.target;if (target.dataset.part === 'date' || target.dataset.part === 'endDate') {this.toggleDropdown(target.dataset.part);}});this.inputContentEl.addEventListener('change', (e) => {if (e.target.tagName !== 'SELECT') return;const part = e.target.dataset.part;const value = parseInt(e.target.value);this.handleTimeChange(part, value);});document.addEventListener('mousedown', (e) => {if (!this.container.contains(e.target) && this.isOpen) {this.close();}});}toggleDropdown(part) {if (this.selectingPart === part && this.isOpen) {this.close();} else {this.selectingPart = part;this.open();}}open() {this.isOpen = true;this.inputEl.classList.add(`${PREFIX}__input--active`);this.dropdownEl.style.display = 'flex';this.renderDropdown();}close() {this.isOpen = false;this.selectingPart = null;this.inputEl.classList.remove(`${PREFIX}__input--active`);this.dropdownEl.style.display = 'none';}handleViewDateChange(date) {this.viewDate = date;}handleEndViewDateChange(date) {this.endViewDate = date;}handleDateSelect(date) {const newDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());if (this.mode === 'instant') {const adjustedTime = this.adjustTimeForDate(newDate, this.tempValue.time);this.tempValue = { ...this.tempValue, date: newDate, time: adjustedTime };if (!this.showActions) {this.value = { ...this.tempValue };this.emitChange();}this.close();this.renderInputContent();return;}const existingStartDate = this.tempValue.date;const existingEndDate = this.tempValue.endDate;if (!existingStartDate) {const adjustedTime = this.adjustTimeForDate(newDate, this.tempValue.time);this.tempValue = { ...this.tempValue, date: newDate, time: adjustedTime };} else if (!existingEndDate) {const dateOnly = new Date(newDate.getFullYear(), newDate.getMonth(), newDate.getDate());const startDateOnly = new Date(existingStartDate.getFullYear(),existingStartDate.getMonth(),existingStartDate.getDate());if (dateOnly < startDateOnly) {const adjustedStartTime = this.adjustTimeForDate(newDate, this.tempValue.time);const adjustedEndTime = this.adjustTimeForDate(existingStartDate, this.tempValue.time);this.tempValue = {date: newDate,time: adjustedStartTime,endDate: existingStartDate,endTime: adjustedEndTime,};} else {const adjustedEndTime = this.adjustTimeForDate(newDate, this.tempValue.endTime);this.tempValue = { ...this.tempValue, endDate: newDate, endTime: adjustedEndTime };}} else {const adjustedTime = this.adjustTimeForDate(newDate, this.tempValue.time);this.tempValue = { date: newDate, time: adjustedTime, endDate: undefined, endTime: undefined };}this.renderDropdown();this.renderInputContent();}adjustTimeForDate(date, time) {if (!time) return time;const minLimit = this.minDate ? extractDateTimeLimit(this.minDate) : null;const maxLimit = this.maxDate ? extractDateTimeLimit(this.maxDate) : null;let adjustedHour = time.hour;let adjustedMinute = time.minute;if (minLimit?.time && isSameDay(date, minLimit.date)) {if (adjustedHour < minLimit.time.hour) {adjustedHour = minLimit.time.hour;adjustedMinute = Math.ceil(minLimit.time.minute / this.minuteStep) * this.minuteStep;} else if (adjustedHour === minLimit.time.hour && adjustedMinute < minLimit.time.minute) {adjustedMinute = Math.ceil(minLimit.time.minute / this.minuteStep) * this.minuteStep;}}if (maxLimit?.time && isSameDay(date, maxLimit.date)) {if (adjustedHour > maxLimit.time.hour) {adjustedHour = maxLimit.time.hour;adjustedMinute = Math.floor(maxLimit.time.minute / this.minuteStep) * this.minuteStep;} else if (adjustedHour === maxLimit.time.hour && adjustedMinute > maxLimit.time.minute) {adjustedMinute = Math.floor(maxLimit.time.minute / this.minuteStep) * this.minuteStep;}}if (adjustedHour !== time.hour || adjustedMinute !== time.minute) {return { hour: adjustedHour, minute: adjustedMinute };}return time;}handleTimeChange(part, value) {const isEnd = part === 'endHour' || part === 'endMinute';const isHour = part === 'hour' || part === 'endHour';const currentTime = isEnd ? this.tempValue.endTime : this.tempValue.time;let newTime = { hour: currentTime?.hour ?? 0, minute: currentTime?.minute ?? 0 };if (isHour) {newTime.hour = value;const currentDate = isEnd ? this.tempValue.endDate : this.tempValue.date;if (currentDate) {const minLimit = this.minDate ? extractDateTimeLimit(this.minDate) : null;const maxLimit = this.maxDate ? extractDateTimeLimit(this.maxDate) : null;if (minLimit?.time && isSameDay(currentDate, minLimit.date) && value === minLimit.time.hour) {if (newTime.minute < minLimit.time.minute) {newTime.minute = Math.ceil(minLimit.time.minute / this.minuteStep) * this.minuteStep;}}if (maxLimit?.time && isSameDay(currentDate, maxLimit.date) && value === maxLimit.time.hour) {if (newTime.minute > maxLimit.time.minute) {newTime.minute = Math.floor(maxLimit.time.minute / this.minuteStep) * this.minuteStep;}}}} else {newTime.minute = value;}if (isEnd) {this.tempValue = { ...this.tempValue, endTime: newTime };} else {this.tempValue = { ...this.tempValue, time: newTime };}if (!this.showActions) {this.value = { ...this.tempValue };this.emitChange();}this.renderInputContent();}handleReset() {this.tempValue = {};this.close();this.renderInputContent();}handleApply() {this.value = { ...this.tempValue };this.emitChange();this.close();this.renderInputContent();}emitChange() {if (this.onChange) {this.onChange(this.value);}}getValue() {return { ...this.value };}setValue(value) {this.value = value || {};this.tempValue = { ...this.value };if (value?.date) {this.viewDate = new Date(value.date);}if (value?.endDate) {this.endViewDate = new Date(value.endDate.getFullYear(), value.endDate.getMonth() + 1, 1);}this.renderInputContent();}clear() {this.value = {};this.tempValue = {};this.renderInputContent();this.emitChange();}enable() {this.disabled = false;this.inputEl.classList.remove(`${PREFIX}__input--disabled`);this.renderInputContent();}disable() {this.disabled = true;this.inputEl.classList.add(`${PREFIX}__input--disabled`);this.close();this.renderInputContent();}destroy() {this.container.innerHTML = '';}}return PodoDatePicker;});
package/cdn/podo-ui.css CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Podo UI CSS v0.9.7
2
+ * Podo UI CSS v1.0.2
3
3
  * https://podoui.com
4
4
  * MIT License
5
5
  */
@@ -17305,6 +17305,9 @@ body h3:not(button) {
17305
17305
  content: "\e9a1";
17306
17306
  }
17307
17307
 
17308
+ /*
17309
+ Icon
17310
+ */
17308
17311
  /*
17309
17312
  Button
17310
17313
  */