tyrell-components 1.0.0-RC13 → 1.0.0-RC14
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.
- package/README.md +1 -1
- package/css/tyrell-theme.css +167 -178
- package/css/tyrell.css +19 -0
- package/dist/tyrell-theme.css +167 -178
- package/dist/tyrell.css +19 -0
- package/dist/tyrell.js +1 -1
- package/lib/base/ty-component.d.ts +20 -10
- package/lib/base/ty-component.js +21 -144
- package/lib/components/button.d.ts +2 -16
- package/lib/components/button.js +0 -36
- package/lib/components/calendar-month.d.ts +2 -48
- package/lib/components/calendar-month.js +4 -166
- package/lib/components/calendar-navigation.d.ts +3 -48
- package/lib/components/calendar-navigation.js +3 -126
- package/lib/components/calendar.d.ts +3 -80
- package/lib/components/calendar.js +8 -230
- package/lib/components/checkbox.d.ts +4 -71
- package/lib/components/checkbox.js +7 -151
- package/lib/components/copy.d.ts +3 -56
- package/lib/components/copy.js +1 -120
- package/lib/components/date-picker.d.ts +13 -162
- package/lib/components/date-picker.js +41 -592
- package/lib/components/file-upload.d.ts +9 -15
- package/lib/components/file-upload.js +19 -41
- package/lib/components/icon.d.ts +3 -24
- package/lib/components/icon.js +1 -90
- package/lib/components/input.d.ts +7 -107
- package/lib/components/input.js +5 -193
- package/lib/components/modal.d.ts +17 -26
- package/lib/components/modal.js +57 -201
- package/lib/components/option.d.ts +2 -9
- package/lib/components/option.js +0 -48
- package/lib/components/popup.d.ts +2 -17
- package/lib/components/popup.js +8 -139
- package/lib/components/radio.d.ts +3 -23
- package/lib/components/radio.js +10 -65
- package/lib/components/resize-observer.d.ts +3 -30
- package/lib/components/resize-observer.js +12 -46
- package/lib/components/scroll-container.d.ts +2 -12
- package/lib/components/scroll-container.js +3 -46
- package/lib/components/select.d.ts +22 -153
- package/lib/components/select.js +33 -590
- package/lib/components/selected-tags.d.ts +4 -47
- package/lib/components/selected-tags.js +1 -95
- package/lib/components/step.d.ts +1 -6
- package/lib/components/step.js +0 -6
- package/lib/components/switch.d.ts +0 -11
- package/lib/components/switch.js +2 -36
- package/lib/components/tab.d.ts +1 -6
- package/lib/components/tab.js +0 -7
- package/lib/components/tabs.d.ts +5 -63
- package/lib/components/tabs.js +20 -283
- package/lib/components/tag.d.ts +2 -36
- package/lib/components/tag.js +5 -105
- package/lib/components/textarea.d.ts +6 -86
- package/lib/components/textarea.js +2 -173
- package/lib/components/tooltip.d.ts +3 -11
- package/lib/components/tooltip.js +24 -160
- package/lib/components/wizard.d.ts +6 -54
- package/lib/components/wizard.js +15 -228
- package/lib/icons/fontawesome/brands.d.ts +0 -1
- package/lib/icons/fontawesome/brands.js +0 -8
- package/lib/icons/fontawesome/regular.d.ts +0 -1
- package/lib/icons/fontawesome/regular.js +0 -8
- package/lib/icons/fontawesome/solid.d.ts +0 -1
- package/lib/icons/fontawesome/solid.js +0 -8
- package/lib/icons/heroicons/micro.d.ts +0 -1
- package/lib/icons/heroicons/micro.js +0 -8
- package/lib/icons/heroicons/mini.d.ts +0 -1
- package/lib/icons/heroicons/mini.js +0 -8
- package/lib/icons/heroicons/outline.d.ts +0 -1
- package/lib/icons/heroicons/outline.js +0 -8
- package/lib/icons/heroicons/solid.d.ts +0 -1
- package/lib/icons/heroicons/solid.js +0 -8
- package/lib/icons/lucide.d.ts +0 -1
- package/lib/icons/lucide.js +0 -1872
- package/lib/icons/material/filled.d.ts +0 -1
- package/lib/icons/material/filled.js +0 -10
- package/lib/icons/material/outlined.d.ts +0 -1
- package/lib/icons/material/outlined.js +0 -10
- package/lib/icons/material/round.d.ts +0 -1
- package/lib/icons/material/round.js +0 -10
- package/lib/icons/material/sharp.d.ts +0 -1
- package/lib/icons/material/sharp.js +0 -10
- package/lib/icons/material/two-tone.d.ts +0 -1
- package/lib/icons/material/two-tone.js +0 -10
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -20
- package/lib/styles/button.d.ts +2 -20
- package/lib/styles/button.js +22 -122
- package/lib/styles/calendar-month.d.ts +1 -5
- package/lib/styles/calendar-month.js +4 -61
- package/lib/styles/calendar-navigation.d.ts +2 -6
- package/lib/styles/calendar-navigation.js +2 -27
- package/lib/styles/calendar.d.ts +1 -2
- package/lib/styles/calendar.js +1 -14
- package/lib/styles/checkbox.d.ts +0 -1
- package/lib/styles/checkbox.js +1 -23
- package/lib/styles/copy.d.ts +0 -1
- package/lib/styles/copy.js +2 -17
- package/lib/styles/custom-scrollbar.d.ts +1 -2
- package/lib/styles/custom-scrollbar.js +3 -18
- package/lib/styles/date-picker.d.ts +1 -5
- package/lib/styles/date-picker.js +35 -39
- package/lib/styles/file-upload.d.ts +1 -2
- package/lib/styles/file-upload.js +1 -16
- package/lib/styles/icon.d.ts +2 -6
- package/lib/styles/icon.js +7 -21
- package/lib/styles/input.d.ts +1 -6
- package/lib/styles/input.js +5 -54
- package/lib/styles/modal.d.ts +1 -2
- package/lib/styles/modal.js +21 -23
- package/lib/styles/option.d.ts +2 -6
- package/lib/styles/option.js +17 -12
- package/lib/styles/popup.d.ts +1 -2
- package/lib/styles/popup.js +26 -30
- package/lib/styles/radio.d.ts +0 -1
- package/lib/styles/radio.js +2 -16
- package/lib/styles/resize-observer.d.ts +1 -2
- package/lib/styles/resize-observer.js +0 -7
- package/lib/styles/scroll-container.d.ts +1 -2
- package/lib/styles/scroll-container.js +0 -19
- package/lib/styles/select-base.d.ts +0 -1
- package/lib/styles/select-base.js +68 -79
- package/lib/styles/select.d.ts +1 -2
- package/lib/styles/select.js +7 -15
- package/lib/styles/step.d.ts +1 -2
- package/lib/styles/step.js +0 -4
- package/lib/styles/switch.d.ts +0 -1
- package/lib/styles/switch.js +2 -20
- package/lib/styles/tab.d.ts +1 -2
- package/lib/styles/tab.js +0 -5
- package/lib/styles/tabs.d.ts +3 -11
- package/lib/styles/tabs.js +10 -48
- package/lib/styles/tag.d.ts +1 -5
- package/lib/styles/tag.js +2 -31
- package/lib/styles/textarea.d.ts +1 -2
- package/lib/styles/textarea.js +2 -45
- package/lib/styles/tooltip.d.ts +0 -1
- package/lib/styles/tooltip.js +0 -10
- package/lib/styles/wizard.d.ts +5 -21
- package/lib/styles/wizard.js +8 -88
- package/lib/types/common.d.ts +0 -2
- package/lib/types/common.js +0 -12
- package/lib/utils/calendar-utils.d.ts +4 -21
- package/lib/utils/calendar-utils.js +4 -177
- package/lib/utils/custom-scrollbar.d.ts +6 -20
- package/lib/utils/custom-scrollbar.js +1 -45
- package/lib/utils/flavor-sheet.d.ts +0 -1
- package/lib/utils/flavor-sheet.js +0 -23
- package/lib/utils/icon-registry.d.ts +0 -2
- package/lib/utils/icon-registry.js +1 -107
- package/lib/utils/icons.d.ts +0 -1
- package/lib/utils/icons.js +0 -9
- package/lib/utils/loader-registry.d.ts +0 -1
- package/lib/utils/loader-registry.js +0 -32
- package/lib/utils/locale.d.ts +2 -23
- package/lib/utils/locale.js +0 -86
- package/lib/utils/mobile.d.ts +0 -1
- package/lib/utils/mobile.js +0 -17
- package/lib/utils/number-format.d.ts +6 -3
- package/lib/utils/number-format.js +11 -67
- package/lib/utils/positioning.d.ts +50 -7
- package/lib/utils/positioning.js +52 -62
- package/lib/utils/property-capture.d.ts +5 -27
- package/lib/utils/property-capture.js +0 -108
- package/lib/utils/property-manager.d.ts +0 -1
- package/lib/utils/property-manager.js +0 -70
- package/lib/utils/resize-observer.d.ts +0 -1
- package/lib/utils/resize-observer.js +0 -36
- package/lib/utils/scroll-lock.d.ts +4 -11
- package/lib/utils/scroll-lock.js +0 -107
- package/lib/utils/styles.d.ts +0 -1
- package/lib/utils/styles.js +0 -24
- package/lib/version.d.ts +1 -2
- package/lib/version.js +1 -11
- package/package.json +2 -2
- package/lib/base/ty-component.d.ts.map +0 -1
- package/lib/base/ty-component.js.map +0 -1
- package/lib/components/button.d.ts.map +0 -1
- package/lib/components/button.js.map +0 -1
- package/lib/components/calendar-month.d.ts.map +0 -1
- package/lib/components/calendar-month.js.map +0 -1
- package/lib/components/calendar-navigation.d.ts.map +0 -1
- package/lib/components/calendar-navigation.js.map +0 -1
- package/lib/components/calendar.d.ts.map +0 -1
- package/lib/components/calendar.js.map +0 -1
- package/lib/components/checkbox.d.ts.map +0 -1
- package/lib/components/checkbox.js.map +0 -1
- package/lib/components/copy.d.ts.map +0 -1
- package/lib/components/copy.js.map +0 -1
- package/lib/components/date-picker.d.ts.map +0 -1
- package/lib/components/date-picker.js.map +0 -1
- package/lib/components/file-upload.d.ts.map +0 -1
- package/lib/components/file-upload.js.map +0 -1
- package/lib/components/icon.d.ts.map +0 -1
- package/lib/components/icon.js.map +0 -1
- package/lib/components/input.d.ts.map +0 -1
- package/lib/components/input.js.map +0 -1
- package/lib/components/modal.d.ts.map +0 -1
- package/lib/components/modal.js.map +0 -1
- package/lib/components/option.d.ts.map +0 -1
- package/lib/components/option.js.map +0 -1
- package/lib/components/popup.d.ts.map +0 -1
- package/lib/components/popup.js.map +0 -1
- package/lib/components/radio.d.ts.map +0 -1
- package/lib/components/radio.js.map +0 -1
- package/lib/components/resize-observer.d.ts.map +0 -1
- package/lib/components/resize-observer.js.map +0 -1
- package/lib/components/scroll-container.d.ts.map +0 -1
- package/lib/components/scroll-container.js.map +0 -1
- package/lib/components/select.d.ts.map +0 -1
- package/lib/components/select.js.map +0 -1
- package/lib/components/selected-tags.d.ts.map +0 -1
- package/lib/components/selected-tags.js.map +0 -1
- package/lib/components/step.d.ts.map +0 -1
- package/lib/components/step.js.map +0 -1
- package/lib/components/switch.d.ts.map +0 -1
- package/lib/components/switch.js.map +0 -1
- package/lib/components/tab.d.ts.map +0 -1
- package/lib/components/tab.js.map +0 -1
- package/lib/components/tabs.d.ts.map +0 -1
- package/lib/components/tabs.js.map +0 -1
- package/lib/components/tag.d.ts.map +0 -1
- package/lib/components/tag.js.map +0 -1
- package/lib/components/textarea.d.ts.map +0 -1
- package/lib/components/textarea.js.map +0 -1
- package/lib/components/tooltip.d.ts.map +0 -1
- package/lib/components/tooltip.js.map +0 -1
- package/lib/components/wizard.d.ts.map +0 -1
- package/lib/components/wizard.js.map +0 -1
- package/lib/icons/fontawesome/brands.d.ts.map +0 -1
- package/lib/icons/fontawesome/brands.js.map +0 -1
- package/lib/icons/fontawesome/regular.d.ts.map +0 -1
- package/lib/icons/fontawesome/regular.js.map +0 -1
- package/lib/icons/fontawesome/solid.d.ts.map +0 -1
- package/lib/icons/fontawesome/solid.js.map +0 -1
- package/lib/icons/heroicons/micro.d.ts.map +0 -1
- package/lib/icons/heroicons/micro.js.map +0 -1
- package/lib/icons/heroicons/mini.d.ts.map +0 -1
- package/lib/icons/heroicons/mini.js.map +0 -1
- package/lib/icons/heroicons/outline.d.ts.map +0 -1
- package/lib/icons/heroicons/outline.js.map +0 -1
- package/lib/icons/heroicons/solid.d.ts.map +0 -1
- package/lib/icons/heroicons/solid.js.map +0 -1
- package/lib/icons/lucide.d.ts.map +0 -1
- package/lib/icons/lucide.js.map +0 -1
- package/lib/icons/material/filled.d.ts.map +0 -1
- package/lib/icons/material/filled.js.map +0 -1
- package/lib/icons/material/outlined.d.ts.map +0 -1
- package/lib/icons/material/outlined.js.map +0 -1
- package/lib/icons/material/round.d.ts.map +0 -1
- package/lib/icons/material/round.js.map +0 -1
- package/lib/icons/material/sharp.d.ts.map +0 -1
- package/lib/icons/material/sharp.js.map +0 -1
- package/lib/icons/material/two-tone.d.ts.map +0 -1
- package/lib/icons/material/two-tone.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/styles/button.d.ts.map +0 -1
- package/lib/styles/button.js.map +0 -1
- package/lib/styles/calendar-month.d.ts.map +0 -1
- package/lib/styles/calendar-month.js.map +0 -1
- package/lib/styles/calendar-navigation.d.ts.map +0 -1
- package/lib/styles/calendar-navigation.js.map +0 -1
- package/lib/styles/calendar.d.ts.map +0 -1
- package/lib/styles/calendar.js.map +0 -1
- package/lib/styles/checkbox.d.ts.map +0 -1
- package/lib/styles/checkbox.js.map +0 -1
- package/lib/styles/copy.d.ts.map +0 -1
- package/lib/styles/copy.js.map +0 -1
- package/lib/styles/custom-scrollbar.d.ts.map +0 -1
- package/lib/styles/custom-scrollbar.js.map +0 -1
- package/lib/styles/date-picker.d.ts.map +0 -1
- package/lib/styles/date-picker.js.map +0 -1
- package/lib/styles/file-upload.d.ts.map +0 -1
- package/lib/styles/file-upload.js.map +0 -1
- package/lib/styles/icon.d.ts.map +0 -1
- package/lib/styles/icon.js.map +0 -1
- package/lib/styles/input.d.ts.map +0 -1
- package/lib/styles/input.js.map +0 -1
- package/lib/styles/modal.d.ts.map +0 -1
- package/lib/styles/modal.js.map +0 -1
- package/lib/styles/multiselect.d.ts +0 -8
- package/lib/styles/multiselect.d.ts.map +0 -1
- package/lib/styles/multiselect.js +0 -849
- package/lib/styles/multiselect.js.map +0 -1
- package/lib/styles/option.d.ts.map +0 -1
- package/lib/styles/option.js.map +0 -1
- package/lib/styles/popup.d.ts.map +0 -1
- package/lib/styles/popup.js.map +0 -1
- package/lib/styles/radio.d.ts.map +0 -1
- package/lib/styles/radio.js.map +0 -1
- package/lib/styles/resize-observer.d.ts.map +0 -1
- package/lib/styles/resize-observer.js.map +0 -1
- package/lib/styles/scroll-container.d.ts.map +0 -1
- package/lib/styles/scroll-container.js.map +0 -1
- package/lib/styles/select-base.d.ts.map +0 -1
- package/lib/styles/select-base.js.map +0 -1
- package/lib/styles/select.d.ts.map +0 -1
- package/lib/styles/select.js.map +0 -1
- package/lib/styles/step.d.ts.map +0 -1
- package/lib/styles/step.js.map +0 -1
- package/lib/styles/switch.d.ts.map +0 -1
- package/lib/styles/switch.js.map +0 -1
- package/lib/styles/tab.d.ts.map +0 -1
- package/lib/styles/tab.js.map +0 -1
- package/lib/styles/tabs.d.ts.map +0 -1
- package/lib/styles/tabs.js.map +0 -1
- package/lib/styles/tag.d.ts.map +0 -1
- package/lib/styles/tag.js.map +0 -1
- package/lib/styles/textarea.d.ts.map +0 -1
- package/lib/styles/textarea.js.map +0 -1
- package/lib/styles/tooltip.d.ts.map +0 -1
- package/lib/styles/tooltip.js.map +0 -1
- package/lib/styles/wizard.d.ts.map +0 -1
- package/lib/styles/wizard.js.map +0 -1
- package/lib/types/common.d.ts.map +0 -1
- package/lib/types/common.js.map +0 -1
- package/lib/utils/calendar-utils.d.ts.map +0 -1
- package/lib/utils/calendar-utils.js.map +0 -1
- package/lib/utils/custom-scrollbar.d.ts.map +0 -1
- package/lib/utils/custom-scrollbar.js.map +0 -1
- package/lib/utils/flavor-sheet.d.ts.map +0 -1
- package/lib/utils/flavor-sheet.js.map +0 -1
- package/lib/utils/icon-registry.d.ts.map +0 -1
- package/lib/utils/icon-registry.js.map +0 -1
- package/lib/utils/icons.d.ts.map +0 -1
- package/lib/utils/icons.js.map +0 -1
- package/lib/utils/loader-registry.d.ts.map +0 -1
- package/lib/utils/loader-registry.js.map +0 -1
- package/lib/utils/locale.d.ts.map +0 -1
- package/lib/utils/locale.js.map +0 -1
- package/lib/utils/mobile.d.ts.map +0 -1
- package/lib/utils/mobile.js.map +0 -1
- package/lib/utils/number-format.d.ts.map +0 -1
- package/lib/utils/number-format.js.map +0 -1
- package/lib/utils/parse-boolean.d.ts +0 -39
- package/lib/utils/parse-boolean.d.ts.map +0 -1
- package/lib/utils/parse-boolean.js +0 -58
- package/lib/utils/parse-boolean.js.map +0 -1
- package/lib/utils/positioning.d.ts.map +0 -1
- package/lib/utils/positioning.js.map +0 -1
- package/lib/utils/property-capture.d.ts.map +0 -1
- package/lib/utils/property-capture.js.map +0 -1
- package/lib/utils/property-manager.d.ts.map +0 -1
- package/lib/utils/property-manager.js.map +0 -1
- package/lib/utils/resize-observer.d.ts.map +0 -1
- package/lib/utils/resize-observer.js.map +0 -1
- package/lib/utils/scroll-lock.d.ts.map +0 -1
- package/lib/utils/scroll-lock.js.map +0 -1
- package/lib/utils/styles.d.ts.map +0 -1
- package/lib/utils/styles.js.map +0 -1
- package/lib/version.d.ts.map +0 -1
- package/lib/version.js.map +0 -1
|
@@ -1,121 +1,41 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TyCalendar Web Component
|
|
3
|
-
* PORTED FROM: cljs/ty/components/calendar.cljs
|
|
4
|
-
*
|
|
5
|
-
* A complete calendar orchestration component that combines navigation and month display.
|
|
6
|
-
* Manages selection state, form participation, and event coordination.
|
|
7
|
-
*
|
|
8
|
-
* Architecture:
|
|
9
|
-
* - year/month/day HTML attributes for intuitive API
|
|
10
|
-
* - Internal state management (private properties)
|
|
11
|
-
* - Distributes properties to child components (navigation + month)
|
|
12
|
-
* - Single 'change' event with complete day context
|
|
13
|
-
* - Form participation via ElementInternals
|
|
14
|
-
*
|
|
15
|
-
* Features:
|
|
16
|
-
* - Combines ty-calendar-navigation + ty-calendar-month
|
|
17
|
-
* - Date selection with visual feedback
|
|
18
|
-
* - Form integration (works with FormData)
|
|
19
|
-
* - Custom render functions (dayContentFn)
|
|
20
|
-
* - Custom CSS injection
|
|
21
|
-
* - Automatic date validation
|
|
22
|
-
* - Event coordination between components
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```html
|
|
26
|
-
* <!-- Basic usage -->
|
|
27
|
-
* <ty-calendar
|
|
28
|
-
* year="2025"
|
|
29
|
-
* month="10"
|
|
30
|
-
* day="15">
|
|
31
|
-
* </ty-calendar>
|
|
32
|
-
*
|
|
33
|
-
* <!-- Form integration -->
|
|
34
|
-
* <form>
|
|
35
|
-
* <ty-calendar name="booking-date"></ty-calendar>
|
|
36
|
-
* <button type="submit">Submit</button>
|
|
37
|
-
* </form>
|
|
38
|
-
*
|
|
39
|
-
* <!-- With custom rendering -->
|
|
40
|
-
* <ty-calendar id="custom"></ty-calendar>
|
|
41
|
-
* <script type="module">
|
|
42
|
-
* const cal = document.getElementById('custom');
|
|
43
|
-
* cal.dayContentFn = (ctx) => {
|
|
44
|
-
* const el = document.createElement('div');
|
|
45
|
-
* el.textContent = ctx.dayInMonth;
|
|
46
|
-
* if (ctx.today) el.style.fontWeight = 'bold';
|
|
47
|
-
* return el;
|
|
48
|
-
* };
|
|
49
|
-
* </script>
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
1
|
import { ensureStyles } from '../utils/styles.js';
|
|
53
2
|
import { calendarStyles } from '../styles/calendar.js';
|
|
54
|
-
// Side-effect imports: register the child elements this component createElements
|
|
55
3
|
import './calendar-month.js';
|
|
56
4
|
import './calendar-navigation.js';
|
|
57
5
|
import { parseISODate } from '../utils/calendar-utils.js';
|
|
58
6
|
import { getEffectiveLocale, observeLocaleChanges } from '../utils/locale.js';
|
|
59
|
-
// ============================================================================
|
|
60
|
-
// Helper Functions
|
|
61
|
-
// ============================================================================
|
|
62
|
-
/**
|
|
63
|
-
* Get current date for defaults
|
|
64
|
-
*/
|
|
65
7
|
function getCurrentDate() {
|
|
66
8
|
const now = new Date();
|
|
67
9
|
return {
|
|
68
10
|
year: now.getFullYear(),
|
|
69
|
-
month: now.getMonth() + 1,
|
|
11
|
+
month: now.getMonth() + 1,
|
|
70
12
|
day: now.getDate(),
|
|
71
13
|
};
|
|
72
14
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Validate and parse year from string
|
|
75
|
-
*/
|
|
76
15
|
function parseYear(yearStr) {
|
|
77
16
|
if (!yearStr || !/^\d{4}$/.test(yearStr))
|
|
78
17
|
return null;
|
|
79
18
|
return parseInt(yearStr, 10);
|
|
80
19
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Validate and parse month from string (1-12)
|
|
83
|
-
*/
|
|
84
20
|
function parseMonth(monthStr) {
|
|
85
21
|
if (!monthStr || !/^\d{1,2}$/.test(monthStr))
|
|
86
22
|
return null;
|
|
87
23
|
const month = parseInt(monthStr, 10);
|
|
88
24
|
return month >= 1 && month <= 12 ? month : null;
|
|
89
25
|
}
|
|
90
|
-
/**
|
|
91
|
-
* Validate and parse day from string (1-31, validated against month)
|
|
92
|
-
*/
|
|
93
26
|
function parseDay(dayStr, year, month) {
|
|
94
27
|
if (!dayStr || !/^\d{1,2}$/.test(dayStr))
|
|
95
28
|
return null;
|
|
96
29
|
const day = parseInt(dayStr, 10);
|
|
97
|
-
// Get days in month for validation
|
|
98
30
|
const daysInMonth = new Date(year, month, 0).getDate();
|
|
99
31
|
return day >= 1 && day <= daysInMonth ? day : null;
|
|
100
32
|
}
|
|
101
|
-
/**
|
|
102
|
-
* Format date as ISO string (YYYY-MM-DD) for form submission
|
|
103
|
-
*/
|
|
104
33
|
function formatDateISO(year, month, day) {
|
|
105
34
|
const monthStr = month.toString().padStart(2, '0');
|
|
106
35
|
const dayStr = day.toString().padStart(2, '0');
|
|
107
36
|
return `${year}-${monthStr}-${dayStr}`;
|
|
108
37
|
}
|
|
109
|
-
// ============================================================================
|
|
110
|
-
// Component Implementation
|
|
111
|
-
// ============================================================================
|
|
112
|
-
/**
|
|
113
|
-
* TyCalendar Web Component
|
|
114
|
-
*/
|
|
115
38
|
export class TyCalendar extends HTMLElement {
|
|
116
|
-
/**
|
|
117
|
-
* Observed attributes
|
|
118
|
-
*/
|
|
119
39
|
static get observedAttributes() {
|
|
120
40
|
return ['year', 'month', 'day', 'show-navigation', 'stateless', 'locale', 'name', 'size', 'width', 'min', 'max', 'flavor'];
|
|
121
41
|
}
|
|
@@ -124,44 +44,31 @@ export class TyCalendar extends HTMLElement {
|
|
|
124
44
|
this._showNavigation = true;
|
|
125
45
|
this._stateless = false;
|
|
126
46
|
this._size = 'md';
|
|
127
|
-
this._flavor = 'primary';
|
|
128
|
-
// Initialize state with current date
|
|
47
|
+
this._flavor = 'primary';
|
|
129
48
|
const current = getCurrentDate();
|
|
130
49
|
this._state = {
|
|
131
50
|
displayYear: current.year,
|
|
132
51
|
displayMonth: current.month,
|
|
133
52
|
};
|
|
134
53
|
this.attachShadow({ mode: 'open' });
|
|
135
|
-
// Attach ElementInternals for form participation
|
|
136
54
|
if ('attachInternals' in this) {
|
|
137
55
|
this._internals = this.attachInternals();
|
|
138
56
|
}
|
|
139
57
|
}
|
|
140
|
-
// ==========================================================================
|
|
141
|
-
// Lifecycle Methods
|
|
142
|
-
// ==========================================================================
|
|
143
58
|
connectedCallback() {
|
|
144
|
-
// Parse initial attributes
|
|
145
59
|
this.initializeFromAttributes();
|
|
146
|
-
// ✅ CHECK: Properties set before custom element upgrade
|
|
147
|
-
// When scripts run before element is fully upgraded, properties are set as plain properties
|
|
148
|
-
// without triggering setters. We need to migrate them to private fields.
|
|
149
|
-
// Check for dayContentFn set before upgrade
|
|
150
60
|
const plainDayContentFn = this.dayContentFn;
|
|
151
61
|
if (plainDayContentFn && !this._dayContentFn) {
|
|
152
62
|
this._dayContentFn = plainDayContentFn;
|
|
153
|
-
delete this.dayContentFn;
|
|
63
|
+
delete this.dayContentFn;
|
|
154
64
|
}
|
|
155
|
-
// Check for customCSS set before upgrade
|
|
156
65
|
const plainCustomCSS = this.customCSS;
|
|
157
66
|
if (plainCustomCSS && !this._customCSS) {
|
|
158
67
|
this._customCSS = plainCustomCSS;
|
|
159
|
-
delete this.customCSS;
|
|
68
|
+
delete this.customCSS;
|
|
160
69
|
}
|
|
161
|
-
// Check for value set before upgrade
|
|
162
70
|
const plainValue = this.value;
|
|
163
71
|
if (plainValue && typeof plainValue === 'string' && plainValue !== this.value) {
|
|
164
|
-
// Parse and set the value properly
|
|
165
72
|
const match = plainValue.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
166
73
|
if (match) {
|
|
167
74
|
const year = parseInt(match[1], 10);
|
|
@@ -172,31 +79,25 @@ export class TyCalendar extends HTMLElement {
|
|
|
172
79
|
this._state.selectedDay = day;
|
|
173
80
|
this._state.displayYear = year;
|
|
174
81
|
this._state.displayMonth = month;
|
|
175
|
-
// Update attributes if not in stateless mode
|
|
176
82
|
if (!this._stateless) {
|
|
177
83
|
this.setAttribute('year', year.toString());
|
|
178
84
|
this.setAttribute('month', month.toString());
|
|
179
85
|
this.setAttribute('day', day.toString());
|
|
180
86
|
}
|
|
181
87
|
}
|
|
182
|
-
delete this.value;
|
|
88
|
+
delete this.value;
|
|
183
89
|
}
|
|
184
|
-
// Render the calendar
|
|
185
90
|
this.render();
|
|
186
|
-
// Set initial form value if date is selected
|
|
187
91
|
this.updateFormValue();
|
|
188
|
-
// Setup locale observer to watch for ancestor lang changes
|
|
189
92
|
this._localeObserver = observeLocaleChanges(this, () => {
|
|
190
93
|
this.render();
|
|
191
94
|
});
|
|
192
95
|
}
|
|
193
96
|
disconnectedCallback() {
|
|
194
|
-
// Cleanup locale observer
|
|
195
97
|
if (this._localeObserver) {
|
|
196
98
|
this._localeObserver();
|
|
197
99
|
this._localeObserver = undefined;
|
|
198
100
|
}
|
|
199
|
-
// Cleanup references
|
|
200
101
|
this._navigation = undefined;
|
|
201
102
|
this._monthDisplay = undefined;
|
|
202
103
|
}
|
|
@@ -217,17 +118,13 @@ export class TyCalendar extends HTMLElement {
|
|
|
217
118
|
break;
|
|
218
119
|
case 'stateless':
|
|
219
120
|
this._stateless = newValue !== null && newValue !== 'false';
|
|
220
|
-
// No re-render needed, just changes behavior
|
|
221
121
|
break;
|
|
222
122
|
case 'locale':
|
|
223
|
-
// Attribute is the source of truth — `get locale` resolves it via
|
|
224
|
-
// getEffectiveLocale; children just need a re-sync.
|
|
225
123
|
this.syncChildComponents();
|
|
226
124
|
break;
|
|
227
125
|
case 'size':
|
|
228
126
|
if (newValue === 'sm' || newValue === 'md' || newValue === 'lg') {
|
|
229
127
|
this._size = newValue;
|
|
230
|
-
// Clear width when size is set (mutually exclusive)
|
|
231
128
|
this._width = undefined;
|
|
232
129
|
this.removeAttribute('width');
|
|
233
130
|
this.syncChildComponents();
|
|
@@ -235,22 +132,20 @@ export class TyCalendar extends HTMLElement {
|
|
|
235
132
|
break;
|
|
236
133
|
case 'width':
|
|
237
134
|
this._width = newValue || undefined;
|
|
238
|
-
// Clear size when width is set (mutually exclusive)
|
|
239
135
|
if (newValue) {
|
|
240
|
-
this._size = 'md';
|
|
136
|
+
this._size = 'md';
|
|
241
137
|
this.removeAttribute('size');
|
|
242
138
|
}
|
|
243
139
|
this.syncChildComponents();
|
|
244
140
|
break;
|
|
245
141
|
case 'name':
|
|
246
|
-
// Name change triggers form value update
|
|
247
142
|
this.updateFormValue();
|
|
248
143
|
break;
|
|
249
144
|
case 'min':
|
|
250
145
|
case 'max':
|
|
251
146
|
this[name === 'min' ? '_min' : '_max'] = newValue || undefined;
|
|
252
147
|
this.syncChildComponents();
|
|
253
|
-
this.updateValidity();
|
|
148
|
+
this.updateValidity();
|
|
254
149
|
break;
|
|
255
150
|
case 'flavor':
|
|
256
151
|
this._flavor = newValue || 'primary';
|
|
@@ -258,14 +153,10 @@ export class TyCalendar extends HTMLElement {
|
|
|
258
153
|
break;
|
|
259
154
|
}
|
|
260
155
|
}
|
|
261
|
-
// ==========================================================================
|
|
262
|
-
// Property Getters/Setters
|
|
263
|
-
// ==========================================================================
|
|
264
156
|
get min() {
|
|
265
157
|
return this._min;
|
|
266
158
|
}
|
|
267
159
|
set min(value) {
|
|
268
|
-
// Reflect to attribute; attributeChangedCallback syncs children
|
|
269
160
|
if (value)
|
|
270
161
|
this.setAttribute('min', value);
|
|
271
162
|
else
|
|
@@ -294,13 +185,11 @@ export class TyCalendar extends HTMLElement {
|
|
|
294
185
|
}
|
|
295
186
|
set year(value) {
|
|
296
187
|
if (value !== undefined) {
|
|
297
|
-
// In stateless mode, only update display
|
|
298
188
|
if (this._stateless) {
|
|
299
189
|
this._state.displayYear = value;
|
|
300
190
|
this.setAttribute('year', value.toString());
|
|
301
191
|
}
|
|
302
192
|
else {
|
|
303
|
-
// In stateful mode, update both selection and display
|
|
304
193
|
this._state.selectedYear = value;
|
|
305
194
|
this._state.displayYear = value;
|
|
306
195
|
this.setAttribute('year', value.toString());
|
|
@@ -322,13 +211,11 @@ export class TyCalendar extends HTMLElement {
|
|
|
322
211
|
}
|
|
323
212
|
set month(value) {
|
|
324
213
|
if (value !== undefined) {
|
|
325
|
-
// In stateless mode, only update display
|
|
326
214
|
if (this._stateless) {
|
|
327
215
|
this._state.displayMonth = value;
|
|
328
216
|
this.setAttribute('month', value.toString());
|
|
329
217
|
}
|
|
330
218
|
else {
|
|
331
|
-
// In stateful mode, update both selection and display
|
|
332
219
|
this._state.selectedMonth = value;
|
|
333
220
|
this._state.displayMonth = value;
|
|
334
221
|
this.setAttribute('month', value.toString());
|
|
@@ -391,7 +278,6 @@ export class TyCalendar extends HTMLElement {
|
|
|
391
278
|
set size(value) {
|
|
392
279
|
if (this._size !== value) {
|
|
393
280
|
this._size = value;
|
|
394
|
-
// Clear width when size is set (mutually exclusive)
|
|
395
281
|
this._width = undefined;
|
|
396
282
|
this.removeAttribute('width');
|
|
397
283
|
this.setAttribute('size', value);
|
|
@@ -405,8 +291,7 @@ export class TyCalendar extends HTMLElement {
|
|
|
405
291
|
if (this._width !== value) {
|
|
406
292
|
this._width = value;
|
|
407
293
|
if (value) {
|
|
408
|
-
|
|
409
|
-
this._size = 'md'; // Reset to default
|
|
294
|
+
this._size = 'md';
|
|
410
295
|
this.removeAttribute('size');
|
|
411
296
|
this.setAttribute('width', value);
|
|
412
297
|
}
|
|
@@ -439,11 +324,9 @@ export class TyCalendar extends HTMLElement {
|
|
|
439
324
|
}
|
|
440
325
|
set value(isoDate) {
|
|
441
326
|
if (!isoDate) {
|
|
442
|
-
// Clear selection
|
|
443
327
|
delete this._state.selectedYear;
|
|
444
328
|
delete this._state.selectedMonth;
|
|
445
329
|
delete this._state.selectedDay;
|
|
446
|
-
// In normal mode, also clear attributes
|
|
447
330
|
if (!this._stateless) {
|
|
448
331
|
this.removeAttribute('year');
|
|
449
332
|
this.removeAttribute('month');
|
|
@@ -451,21 +334,16 @@ export class TyCalendar extends HTMLElement {
|
|
|
451
334
|
}
|
|
452
335
|
}
|
|
453
336
|
else {
|
|
454
|
-
// Parse ISO date (YYYY-MM-DD)
|
|
455
337
|
const match = isoDate.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
456
338
|
if (match) {
|
|
457
339
|
const year = parseInt(match[1], 10);
|
|
458
340
|
const month = parseInt(match[2], 10);
|
|
459
341
|
const day = parseInt(match[3], 10);
|
|
460
|
-
// Update internal selection state
|
|
461
342
|
this._state.selectedYear = year;
|
|
462
343
|
this._state.selectedMonth = month;
|
|
463
344
|
this._state.selectedDay = day;
|
|
464
|
-
// Update display to show this month
|
|
465
345
|
this._state.displayYear = year;
|
|
466
346
|
this._state.displayMonth = month;
|
|
467
|
-
// In normal mode, update attributes
|
|
468
|
-
// In stateless mode, skip attribute updates (parent controls attributes)
|
|
469
347
|
if (!this._stateless) {
|
|
470
348
|
this.setAttribute('year', year.toString());
|
|
471
349
|
this.setAttribute('month', month.toString());
|
|
@@ -474,17 +352,10 @@ export class TyCalendar extends HTMLElement {
|
|
|
474
352
|
}
|
|
475
353
|
}
|
|
476
354
|
this.syncChildComponents();
|
|
477
|
-
// In normal mode, update form value
|
|
478
355
|
if (!this._stateless) {
|
|
479
356
|
this.updateFormValue();
|
|
480
357
|
}
|
|
481
358
|
}
|
|
482
|
-
// ==========================================================================
|
|
483
|
-
// State Management
|
|
484
|
-
// ==========================================================================
|
|
485
|
-
/**
|
|
486
|
-
* Initialize state from HTML attributes on first load
|
|
487
|
-
*/
|
|
488
359
|
initializeFromAttributes() {
|
|
489
360
|
const yearStr = this.getAttribute('year');
|
|
490
361
|
const monthStr = this.getAttribute('month');
|
|
@@ -493,20 +364,16 @@ export class TyCalendar extends HTMLElement {
|
|
|
493
364
|
const statelessStr = this.getAttribute('stateless');
|
|
494
365
|
const sizeStr = this.getAttribute('size');
|
|
495
366
|
const widthStr = this.getAttribute('width');
|
|
496
|
-
// Date bounds
|
|
497
367
|
this._min = this.getAttribute('min') || undefined;
|
|
498
368
|
this._max = this.getAttribute('max') || undefined;
|
|
499
|
-
// Parse year
|
|
500
369
|
const year = parseYear(yearStr);
|
|
501
370
|
if (year) {
|
|
502
371
|
this._state.displayYear = year;
|
|
503
372
|
}
|
|
504
|
-
// Parse month
|
|
505
373
|
const month = parseMonth(monthStr);
|
|
506
374
|
if (month) {
|
|
507
375
|
this._state.displayMonth = month;
|
|
508
376
|
}
|
|
509
|
-
// Parse day (only if year and month are valid)
|
|
510
377
|
if (year && month) {
|
|
511
378
|
const day = parseDay(dayStr, year, month);
|
|
512
379
|
if (day) {
|
|
@@ -515,38 +382,29 @@ export class TyCalendar extends HTMLElement {
|
|
|
515
382
|
this._state.selectedDay = day;
|
|
516
383
|
}
|
|
517
384
|
}
|
|
518
|
-
// Show navigation
|
|
519
385
|
if (showNavStr) {
|
|
520
386
|
this._showNavigation = showNavStr !== 'false';
|
|
521
387
|
}
|
|
522
|
-
// Stateless mode
|
|
523
388
|
if (statelessStr !== null) {
|
|
524
389
|
this._stateless = statelessStr !== 'false';
|
|
525
390
|
}
|
|
526
|
-
// Size
|
|
527
391
|
if (sizeStr && (sizeStr === 'sm' || sizeStr === 'md' || sizeStr === 'lg')) {
|
|
528
392
|
this._size = sizeStr;
|
|
529
393
|
}
|
|
530
|
-
// Width
|
|
531
394
|
if (widthStr) {
|
|
532
395
|
this._width = widthStr;
|
|
533
396
|
}
|
|
534
397
|
}
|
|
535
|
-
/**
|
|
536
|
-
* Sync state from changed attributes
|
|
537
|
-
*/
|
|
538
398
|
syncStateFromAttributes() {
|
|
539
399
|
const yearStr = this.getAttribute('year');
|
|
540
400
|
const monthStr = this.getAttribute('month');
|
|
541
401
|
const dayStr = this.getAttribute('day');
|
|
542
402
|
const year = parseYear(yearStr);
|
|
543
403
|
const month = parseMonth(monthStr);
|
|
544
|
-
// Update display year/month
|
|
545
404
|
if (year)
|
|
546
405
|
this._state.displayYear = year;
|
|
547
406
|
if (month)
|
|
548
407
|
this._state.displayMonth = month;
|
|
549
|
-
// Update selection (only if all three are valid)
|
|
550
408
|
if (year && month) {
|
|
551
409
|
const day = parseDay(dayStr, year, month);
|
|
552
410
|
if (day) {
|
|
@@ -555,24 +413,18 @@ export class TyCalendar extends HTMLElement {
|
|
|
555
413
|
this._state.selectedDay = day;
|
|
556
414
|
}
|
|
557
415
|
else {
|
|
558
|
-
// Clear selection if day is invalid
|
|
559
416
|
delete this._state.selectedYear;
|
|
560
417
|
delete this._state.selectedMonth;
|
|
561
418
|
delete this._state.selectedDay;
|
|
562
419
|
}
|
|
563
420
|
}
|
|
564
421
|
else {
|
|
565
|
-
// Clear selection if year or month is invalid
|
|
566
422
|
delete this._state.selectedYear;
|
|
567
423
|
delete this._state.selectedMonth;
|
|
568
424
|
delete this._state.selectedDay;
|
|
569
425
|
}
|
|
570
426
|
}
|
|
571
|
-
/**
|
|
572
|
-
* Update child components with current state
|
|
573
|
-
*/
|
|
574
427
|
syncChildComponents() {
|
|
575
|
-
// Update navigation
|
|
576
428
|
if (this._navigation) {
|
|
577
429
|
this._navigation.displayMonth = this._state.displayMonth;
|
|
578
430
|
this._navigation.displayYear = this._state.displayYear;
|
|
@@ -580,10 +432,8 @@ export class TyCalendar extends HTMLElement {
|
|
|
580
432
|
this._navigation.size = this._size;
|
|
581
433
|
this._navigation.min = this._min ?? '';
|
|
582
434
|
this._navigation.max = this._max ?? '';
|
|
583
|
-
// Always sync width (set or clear)
|
|
584
435
|
this._navigation.width = this._width;
|
|
585
436
|
}
|
|
586
|
-
// Update month display
|
|
587
437
|
if (this._monthDisplay) {
|
|
588
438
|
this._monthDisplay.displayMonth = this._state.displayMonth;
|
|
589
439
|
this._monthDisplay.displayYear = this._state.displayYear;
|
|
@@ -592,17 +442,13 @@ export class TyCalendar extends HTMLElement {
|
|
|
592
442
|
this._monthDisplay.min = this._min;
|
|
593
443
|
this._monthDisplay.max = this._max;
|
|
594
444
|
this._monthDisplay.flavor = this._flavor;
|
|
595
|
-
// Always sync width (set or clear)
|
|
596
445
|
this._monthDisplay.width = this._width;
|
|
597
|
-
// Pass render functions
|
|
598
446
|
if (this._dayContentFn) {
|
|
599
447
|
this._monthDisplay.dayContentFn = this._dayContentFn;
|
|
600
448
|
}
|
|
601
|
-
// Pass custom CSS
|
|
602
449
|
if (this._customCSS) {
|
|
603
450
|
this._monthDisplay.customCSS = this._customCSS;
|
|
604
451
|
}
|
|
605
|
-
// Update selection value (convert to Date timestamp)
|
|
606
452
|
const { selectedYear, selectedMonth, selectedDay } = this._state;
|
|
607
453
|
if (selectedYear && selectedMonth && selectedDay) {
|
|
608
454
|
const date = new Date(selectedYear, selectedMonth - 1, selectedDay);
|
|
@@ -613,11 +459,7 @@ export class TyCalendar extends HTMLElement {
|
|
|
613
459
|
}
|
|
614
460
|
}
|
|
615
461
|
}
|
|
616
|
-
/**
|
|
617
|
-
* Update form value using ElementInternals
|
|
618
|
-
*/
|
|
619
462
|
updateFormValue() {
|
|
620
|
-
// Skip form participation in stateless mode
|
|
621
463
|
if (this._stateless)
|
|
622
464
|
return;
|
|
623
465
|
if (!this._internals)
|
|
@@ -633,10 +475,6 @@ export class TyCalendar extends HTMLElement {
|
|
|
633
475
|
}
|
|
634
476
|
this.updateValidity();
|
|
635
477
|
}
|
|
636
|
-
/**
|
|
637
|
-
* Selection outside [min, max] => rangeUnderflow/rangeOverflow.
|
|
638
|
-
* UI can't produce this (days are disabled), but programmatic values can.
|
|
639
|
-
*/
|
|
640
478
|
updateValidity() {
|
|
641
479
|
if (!this._internals)
|
|
642
480
|
return;
|
|
@@ -656,22 +494,13 @@ export class TyCalendar extends HTMLElement {
|
|
|
656
494
|
}
|
|
657
495
|
this._internals.setValidity({});
|
|
658
496
|
}
|
|
659
|
-
// ==========================================================================
|
|
660
|
-
// Event Handlers
|
|
661
|
-
// ==========================================================================
|
|
662
|
-
/**
|
|
663
|
-
* Handle navigation change (month/year navigation)
|
|
664
|
-
*/
|
|
665
497
|
handleNavigationChange(event) {
|
|
666
498
|
event.preventDefault();
|
|
667
499
|
event.stopPropagation();
|
|
668
500
|
const { month, year } = event.detail;
|
|
669
|
-
// Update display state
|
|
670
501
|
this._state.displayMonth = month;
|
|
671
502
|
this._state.displayYear = year;
|
|
672
|
-
// Sync child components
|
|
673
503
|
this.syncChildComponents();
|
|
674
|
-
// Emit navigate event
|
|
675
504
|
const navigateDetail = {
|
|
676
505
|
month,
|
|
677
506
|
year,
|
|
@@ -685,16 +514,11 @@ export class TyCalendar extends HTMLElement {
|
|
|
685
514
|
cancelable: false,
|
|
686
515
|
}));
|
|
687
516
|
}
|
|
688
|
-
/**
|
|
689
|
-
* Handle day click (day selection)
|
|
690
|
-
*/
|
|
691
517
|
handleDayClick(event) {
|
|
692
518
|
event.preventDefault();
|
|
693
519
|
event.stopPropagation();
|
|
694
520
|
const { dayContext, year, month, day } = event.detail;
|
|
695
|
-
// In stateless mode, just re-dispatch the event without updating internal state
|
|
696
521
|
if (this._stateless) {
|
|
697
|
-
// Re-dispatch day-click event for parent to handle
|
|
698
522
|
this.dispatchEvent(new CustomEvent('day-click', {
|
|
699
523
|
detail: event.detail,
|
|
700
524
|
bubbles: true,
|
|
@@ -703,21 +527,16 @@ export class TyCalendar extends HTMLElement {
|
|
|
703
527
|
}));
|
|
704
528
|
return;
|
|
705
529
|
}
|
|
706
|
-
// Normal mode: update selection state
|
|
707
530
|
this._state.selectedYear = year;
|
|
708
531
|
this._state.selectedMonth = month;
|
|
709
532
|
this._state.selectedDay = day;
|
|
710
533
|
this._state.displayYear = year;
|
|
711
534
|
this._state.displayMonth = month;
|
|
712
|
-
// Update HTML attributes
|
|
713
535
|
this.setAttribute('year', year.toString());
|
|
714
536
|
this.setAttribute('month', month.toString());
|
|
715
537
|
this.setAttribute('day', day.toString());
|
|
716
|
-
// Update form value
|
|
717
538
|
this.updateFormValue();
|
|
718
|
-
// Sync child components
|
|
719
539
|
this.syncChildComponents();
|
|
720
|
-
// Emit change event
|
|
721
540
|
const changeDetail = {
|
|
722
541
|
year,
|
|
723
542
|
month,
|
|
@@ -733,51 +552,29 @@ export class TyCalendar extends HTMLElement {
|
|
|
733
552
|
cancelable: false,
|
|
734
553
|
}));
|
|
735
554
|
}
|
|
736
|
-
// ==========================================================================
|
|
737
|
-
// Public Methods
|
|
738
|
-
// ==========================================================================
|
|
739
|
-
/**
|
|
740
|
-
* Force re-render of the calendar
|
|
741
|
-
* Useful after updating dayContentFn or other dynamic properties
|
|
742
|
-
*/
|
|
743
555
|
refresh() {
|
|
744
556
|
this.syncChildComponents();
|
|
745
|
-
// Force month display to re-render (for async data updates)
|
|
746
557
|
if (this._monthDisplay && typeof this._monthDisplay.refresh === 'function') {
|
|
747
558
|
this._monthDisplay.refresh();
|
|
748
559
|
}
|
|
749
560
|
}
|
|
750
|
-
// ==========================================================================
|
|
751
|
-
// Rendering
|
|
752
|
-
// ==========================================================================
|
|
753
|
-
/**
|
|
754
|
-
* Create navigation element
|
|
755
|
-
*/
|
|
756
561
|
createNavigation() {
|
|
757
562
|
const nav = document.createElement('ty-calendar-navigation');
|
|
758
|
-
// Set properties
|
|
759
563
|
nav.displayMonth = this._state.displayMonth;
|
|
760
564
|
nav.displayYear = this._state.displayYear;
|
|
761
565
|
nav.locale = this.locale;
|
|
762
566
|
nav.size = this._size;
|
|
763
567
|
nav.min = this._min ?? '';
|
|
764
568
|
nav.max = this._max ?? '';
|
|
765
|
-
// Only set width if explicitly provided
|
|
766
569
|
if (this._width) {
|
|
767
570
|
nav.width = this._width;
|
|
768
571
|
}
|
|
769
|
-
// Listen for change events
|
|
770
572
|
nav.addEventListener('change', (e) => this.handleNavigationChange(e));
|
|
771
|
-
// Store reference
|
|
772
573
|
this._navigation = nav;
|
|
773
574
|
return nav;
|
|
774
575
|
}
|
|
775
|
-
/**
|
|
776
|
-
* Create month display element
|
|
777
|
-
*/
|
|
778
576
|
createMonthDisplay() {
|
|
779
577
|
const month = document.createElement('ty-calendar-month');
|
|
780
|
-
// Set properties
|
|
781
578
|
month.displayMonth = this._state.displayMonth;
|
|
782
579
|
month.displayYear = this._state.displayYear;
|
|
783
580
|
month.locale = this.locale;
|
|
@@ -785,61 +582,42 @@ export class TyCalendar extends HTMLElement {
|
|
|
785
582
|
month.min = this._min;
|
|
786
583
|
month.max = this._max;
|
|
787
584
|
month.flavor = this._flavor;
|
|
788
|
-
// Only set width if explicitly provided
|
|
789
585
|
if (this._width) {
|
|
790
586
|
month.width = this._width;
|
|
791
587
|
}
|
|
792
|
-
// Set selection value if exists
|
|
793
588
|
const { selectedYear, selectedMonth, selectedDay } = this._state;
|
|
794
589
|
if (selectedYear && selectedMonth && selectedDay) {
|
|
795
590
|
const date = new Date(selectedYear, selectedMonth - 1, selectedDay);
|
|
796
591
|
month.value = date.getTime();
|
|
797
592
|
}
|
|
798
|
-
// Pass render functions
|
|
799
593
|
if (this._dayContentFn) {
|
|
800
594
|
month.dayContentFn = this._dayContentFn;
|
|
801
595
|
}
|
|
802
|
-
// Pass custom CSS
|
|
803
596
|
if (this._customCSS) {
|
|
804
597
|
month.customCSS = this._customCSS;
|
|
805
598
|
}
|
|
806
|
-
// Listen for day-click events
|
|
807
599
|
month.addEventListener('day-click', (e) => this.handleDayClick(e));
|
|
808
|
-
// Store reference
|
|
809
600
|
this._monthDisplay = month;
|
|
810
601
|
return month;
|
|
811
602
|
}
|
|
812
|
-
/**
|
|
813
|
-
* Main render function
|
|
814
|
-
*/
|
|
815
603
|
render() {
|
|
816
604
|
const root = this.shadowRoot;
|
|
817
605
|
if (!root)
|
|
818
606
|
return;
|
|
819
|
-
// Ensure styles are loaded
|
|
820
607
|
ensureStyles(root, { css: calendarStyles, id: 'ty-calendar' });
|
|
821
|
-
// Clear and rebuild
|
|
822
608
|
root.innerHTML = '';
|
|
823
|
-
// Create main container
|
|
824
609
|
const container = document.createElement('div');
|
|
825
610
|
container.className = 'calendar-container';
|
|
826
|
-
// Add navigation if requested
|
|
827
611
|
if (this._showNavigation) {
|
|
828
612
|
const nav = this.createNavigation();
|
|
829
613
|
container.appendChild(nav);
|
|
830
614
|
}
|
|
831
|
-
// Add month display
|
|
832
615
|
const month = this.createMonthDisplay();
|
|
833
616
|
container.appendChild(month);
|
|
834
617
|
root.appendChild(container);
|
|
835
618
|
}
|
|
836
619
|
}
|
|
837
|
-
/**
|
|
838
|
-
* Form-associated custom element
|
|
839
|
-
*/
|
|
840
620
|
TyCalendar.formAssociated = true;
|
|
841
|
-
// Register the custom element
|
|
842
621
|
if (!customElements.get('ty-calendar')) {
|
|
843
622
|
customElements.define('ty-calendar', TyCalendar);
|
|
844
623
|
}
|
|
845
|
-
//# sourceMappingURL=calendar.js.map
|